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

How to expand variable into nested directory in maven-archetype

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

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

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

我知道双下划线包裹的变量将在 file/directory 名称中被替换,但我只能用 __groupId__ 得到以下内容。

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

作为原型的输入,您可以指定 package 选项(如果您愿意,它会跟随您的输入、groupId 和 artifactId 串联,即使情况并非总是如此,因此提供更多灵活性)。

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

然而,该选项没有正式记录(可惜),尽管支持并且在这种情况下工作正常。

Looking at the code, the DefaultFilesetArchetypeGenerator and its getPackageInPathFormat provide the concerned transformation from the package option to a path, while the org.apache.maven.archetype.common.Constants.PACKAGE_IN_PATH_FORMAT 是该选项的官方入口点。

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


进一步说明:

  • 您可以在 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 class 在其 generateArchetype 方法中过早准备上下文(在其 prepareVelocityContext 方法中,其中packageInPathFormat 被转换并添加到上下文中),然后上下文被传递给 processArchetypeTemplate* 方法,这些方法最终会调用 Velocity 引擎(然后将替换占位符)。虽然我不是 Velocity 专家,因此我可能会遗漏一些胶水,但观察到的行为和代码工作流程似乎得出了这个结论。

您可以分别使用 ${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