如何将变量扩展到 maven-archetype 中的嵌套目录

Posted

技术标签:

【中文标题】如何将变量扩展到 maven-archetype 中的嵌套目录【英文标题】:How to expand variable into nested directory in maven-archetype 【发布时间】:2016-03-03 10:14:56 【问题描述】:

假设我已将groupId 设置为com.example,并将artifactId 设置为fancy.project,现在我想创建一个原型,以便在创建时扩展为以下结构:

|--src
  |--main
    |--com
      |--example
        |-fancy
          |-project
            |-App.java

也就是说,我想知道如何将变量展开到嵌套目录中。

我知道双下划线包装的变量将被替换为文件/目录名称,但我只能使用__groupId__ 获得以下内容。

|--src
  |--main
    |--com.example
      |-fancy.project
        |-App.java

【问题讨论】:

【参考方案1】:

作为原型的输入,您可以指定package 选项(如果您愿意,它会跟随您的输入、groupId 和 artifactId 连接,尽管并非总是如此,因此提供了更大的灵活性)。

然后,在您的原型中,您可以使用 packageInPathFormat 选项(自原型 2.2 起可用),它将任何点 . 替换为斜杠 \ 并因此将其转换为路径进入生成的项目。

但是,即使支持该选项并且在这种情况下工作正常,该选项也没有正式记录(遗憾)。

Looking at the code、DefaultFilesetArchetypeGenerator 及其getPackageInPathFormat 提供了从package 选项到路径的相关转换,而org.apache.maven.archetype.common.Constants.PACKAGE_IN_PATH_FORMAT 是该选项的官方入口点。

关于此选项使用的一些外部指针:

http://geekofficedog.blogspot.be/2013/08/creating-maven-archetypes-tutorial.html http://www.theotherian.com/2012/05/maven-archetypes-part-2-how-do-i-create.html

进一步解释:

例如,您可以在 src/main/java 下拥有 __packageInPathFormat__ 文件夹 __packageInPathFormat 将被替换为 package 选项,将点转换为斜线 package 选项的默认值为groupId,因此如果您不指定它,对于值为com.samplegroupId,路径将为com/sample 因此,您可以在调用时通过 -Dpackage=your.package 指定所需的包,重复 -DgroupId-DartifactId 的值(虽然有点冗长且容易出错),最终结果实际上将是您所期望的(转换为正确的路径)。

您可以通过archetype-metada.xml 文件指定新的默认值,如official documentation 中指定的那样,通过requiredProperties 部分,您可以有类似的东西:

<requiredProperties>
    <requiredProperty key="package">
        <defaultValue>__groupId__.__artifactId__</defaultValue>
    </requiredProperty>
</requiredProperties>

但是,生成的路径将是 com.sample/artifactid 而不是 com/sample/artifactid。因此,由于处理工作流程会在将占位符转换为路径后替换占位符(可惜!),因此它不会按预期工作。 (注意:它会将我们提供的点转换为配置值,但不会将点转换为替换的占位符)。

作为快速代码分析,DefaultFilesetArchetypeGenerator 类在其generateArchetype 方法中似乎过早地准备上下文(在其prepareVelocityContext 方法中,packageInPathFormat 被转换并添加到上下文中) ,然后将上下文传递给 processArchetypeTemplate* 方法,该方法最终将调用 Velocity 引擎(然后将替换占位符)。虽然我不是 Velocity 专家,因此我可能会错过一些胶水,但观察到的行为和代码工作流程似乎得出了这个结论。

【讨论】:

@Matteo 实际上我之前已经使用过这个packageInPathFormat 选项,但在我的情况下,这仅提供了groupId 的格式化路径。 artifactId 不包括在内,所以我仍然需要自己扩展它。知道如何一般地做到这一点吗? 啊,我明白你的意思了。我应该将包选项设置为groupIdartifactId 的串联。但是,我必须明确指定-Dpackage=blahblah。是否可以自动化这种连接? @Davyzhu 我更新了我的答案,但没有好消息,您可以重新定义默认值,甚至可以使用占位符,但路径不会是我们预期的 @Matteo 感谢您的时间和精力!我曾尝试使用像$groupId.$artifactId 这样的花括号占位符设置defaultValue,但只会得到垃圾。他们按字面意思对待。你能指出我为什么这个占位符失败的正确方向吗?为了使其更通用,谁(或代码的哪一部分)负责替换花括号占位符以及何时发生?无论如何,你的回答已经足够我原来的帖子了。接受。 @Davyzhu 我已经在我的答案底部添加了一些关于代码的更多细节,希望它可以提供进一步的帮助!【参考方案2】:

您可以分别使用$groupId$artifactId 而不是使用变量__groupId____artifactId__(我不知道发布此问题时是否存在这些变量),所以它看起来像这个:

<requiredProperties>
    <requiredProperty key="package">
        <defaultValue>$groupId.$artifactId</defaultValue>
    </requiredProperty>
</requiredProperties>

使用这些生成项目时,在交互模式下它实际上会请求进入包,而在批处理模式下它会自动生成 CLOSE 到 OP 想要的。

例如。 groupIdme.zenisbestwolfartifactIdfancy-app 将生成me/zenisbestwolf/fancy-app 的路径。不幸的是,如果不手动定义包 AFAIK,就无法像 OP 想要的那样自动将工件 ID 从 fancy.app 变为 fancy/app

【讨论】:

以上是关于如何将变量扩展到 maven-archetype 中的嵌套目录的主要内容,如果未能解决你的问题,请参考以下文章

#私藏项目实操分享#Maven实战技巧「插件使用专题」Maven-Archetype插件创建自定义maven项目骨架

[工具/Maven]Maven自动构建骨架(maven-archetype)中quickstart与webapp的区别

React.js Chrome 扩展 - 如何将 Background.js 中的数据存储在 React 内部的变量中?

为啥要使用扩展运算符将变量扩展到自身?

如何使用 WebStorm 进行 Chrome 扩展开发?

如何将实例变量或属性添加到 XCTestCase?