如果我有一个
pom
层次结构,其中 superpom
调用多个相互依赖的子模块,我如何根据依赖关系列出构建/编译顺序? IOW,如果 superpom 具有模块 mod1、mod2 和 mod3,并且 mod2 依赖于 mod3,mod3 依赖于 mod1,则顺序是 mod1、mod3,然后是 mod2。我怎样才能列出该顺序,而不需要对 pom 中的数据层次结构进行复杂的 XML 解析?
你想知道的是所谓的反应堆建造顺序。
反应器根据每个项目在各自项目描述符中声明的依赖关系确定正确的构建顺序,然后执行一组声明的目标。它既可用于建筑项目,也可用于其他目标,例如站点生成。 (来源:旧的多模块文档)
它收集所有要构建的模块,对项目进行排序并按顺序构建它们。它保证任何模块在其他模块需要之前就已构建。
据我所知,没有直接的方法来创建这些项目的列表,但最接近获取信息的是:
mvn validate
它将在顶部显示您的反应堆构建顺序:
~/parent$ mvn validate
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] simple.parent
[INFO] simple.child
[INFO] simple.anotherchild
[...]
除了验证项目的正确性以及所有必要的信息是否可用之外,无需执行任何其他工作。
有关更多信息,另请参阅使用多个模块的指南和有关 Maven Reactor 是什么的答案。
mvn validate > validate.log
project_name=$(mvn org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate -Dexpression=project.name -q -DforceStdout)
sed '1,/^\[INFO\] Reactor Build Order:/ d' validate.log | awk '/\[INFO\] -+</ {exit} {print}' | awk '{ print $2 }' | awk \!/^"$project_name"$/ | awk 'NF'
mvn validate >validate.log
project_name=$(mvn org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate -Dexpression=project.name -q -DforceStdout)
sed '1,/^\[INFO\] Reactor Build Order:/ d' validate.log | awk "/\[INFO\] ${project_name} +/ {exit} {print}" | awk '{ print $2 }'
python脚本
def write_multi_module_pom(sub_module_path_list):
head_text = '''<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mavenbook.multi</groupId>
<artifactId>simple-parent</artifactId>
<packaging>pom</packaging>
<version>1.0</version>
<name>Multi Chapter Simple Parent Project</name>
<modules>'''
tail_text = '''</modules>
</project>
'''
pom_content = head_text + '\n'.join(['<module>{}</module>'.format(p) for p in sub_module_path_list]) + tail_text
with open('pom.xml', 'w') as fw:
fw.write(pom_content)
def mvn_validate_and_get_orders():
process = subprocess.Popen('mvn clean validate -Denforcer.skip', shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
output, error = process.communicate()
result = process.wait()
if result != 0:
logging.error(error)
logging.error("mvn error")
exit(1)
text_regex = re.compile(
r'\[INFO\] Reactor Build Order:((?:.|\n)*?)\[INFO\] Multi Chapter Simple Parent Project')
if sys.version_info.major == 2:
text_matched_list = text_regex.findall(output)
else:
text_matched_list = text_regex.findall(output.decode('utf8'))
if len(text_matched_list) == 0:
return
projects = [item.strip() for item in text_matched_list[0].replace('[INFO] ', '').splitlines() if
len(item.strip()) > 0]
return projects
write_multi_module_pom(["sub-module-1","sub-module-2","sub-module-3"])
mvn_validate_and_get_orders()
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-help-plugin</artifactId>
<version>3.3.0</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-help-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>EvaluateReactorBuildOrder</id>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-help-plugin</artifactId>
<inherited>true</inherited>
<executions>
<execution>
<id>echo-basedir</id>
<phase>validate</phase>
<goals>
<goal>evaluate</goal>
</goals>
</execution>
</executions>
<configuration>
<expression>project.basedir/${path.separator}</expression>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
</profiles>
这可以使用此命令评估构建顺序:
$>mvn -PEvaluateReactorBuildOrder validate -q -DforceStdout
/root/:/root/module1/:/root/module2/:
插件将输出反应器构建顺序中模块的路径。我认为这个输出比“Reactor Build Order”部分中的任何 maven 打印的机器可读性都要好得多。请注意,路径分隔符包含在
<expression>
标签中。这只有效,因为项目变量有特殊情况。
-q -DforceStdout
模块不同路径的输出之间不会输出任何分隔符。添加换行符 ( )最后很困难,因为在这个过程中的某个地方,表达式的开头和结尾被删除了空格,所以我放弃并使用了
${path.separator}
,它在将 xml 解析为“:”或“;”时进行评估。取决于您的平台。使用单独的配置文件进行配置使您能够像往常一样运行 help:evaluate 插件,并使正常构建的日志不受路径输出的影响。该插件更喜欢 pom 中的表达式,而不是您使用参数设置的表达式。
$> mvn help:evaluate -Dexpression=project.version -q -DforceStdout
1.0.0.0
注意,插件仍然必须包含在常规 <build>
标签中,配置文件只能覆盖其配置。
-pl :<artifactId> -am -amd
开关加速 CI/CD 管道时遇到了同样的问题。对于我来说,列出 Maven poms 中出现的 groupId/artifactId 的解决方案是:
mvn validate | grep '<'| cut -d ' ' -f 3
org.connectorio:addons
org.connectorio.addons:parent
org.connectorio.addons:bddhab
org.connectorio.bddhab:org.connectorio.bddhab.rest
org.connectorio.addons:bundles
org.connectorio.addons:org.connectorio.addons.binding