如何将变量扩展到 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.sample
的groupId
,路径将为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
不包括在内,所以我仍然需要自己扩展它。知道如何一般地做到这一点吗?
啊,我明白你的意思了。我应该将包选项设置为groupId
和artifactId
的串联。但是,我必须明确指定-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 想要的。
例如。 groupId
是me.zenisbestwolf
和artifactId
是fancy-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 内部的变量中?