如何根据依赖关系列出Maven构建/编译序列?

cfh9epnr  于 2022-11-22  发布在  Maven
关注(0)|答案(5)|浏览(114)

如果我有一个pom层次结构,其中superpom调用了多个相互依赖的子模块,我如何根据依赖关系列出构建/编译顺序?IOW,如果superpom有模块mod 1,mod 2和mod 3,mod 2依赖于mod 3,mod 3依赖于mod 1,那么顺序是mod 1,mod 3,然后是mod 2。如何在不对pom中的数据层次结构进行复杂的XML解析的情况下列出该顺序呢?

hsgswve4

hsgswve41#

你想知道的是所谓的React堆建造顺序
reactor根据每个项目在其各自的项目描述符中声明的依赖关系确定正确的构建顺序,然后执行一组声明的目标。它可以用于构建项目和其他目标,如站点生成。(来源:(第10页)
它收集所有要构建的模块,对项目进行排序,并按顺序构建它们。它保证任何模块在被其他模块需要之前构建。
据我所知,没有直接的方法来创建这些项目的列表,但最接近的方法是:

mvn validate

它将在顶部显示您的 * React堆建造顺序 *:

~/parent$ mvn validate
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO] 
[INFO] simple.parent
[INFO] simple.child
[INFO] simple.anotherchild
[...]

除了验证项目的正确性以及所有必要信息是否可用外,不执行其他工作。
如需详细信息,另请参阅guide to working with multiple modulesthis answer about what the maven reactor is

jk9hmnmh

jk9hmnmh2#

也许您正在寻找Maven dependency:tree选项?您可能需要调整includes以仅包含您的模块。http://maven.apache.org/plugins/maven-dependency-plugin/tree-mojo.html

mvn dependency:tree -Dverbose -DoutputFile=tree.txt -DoutputType=text -Dincludes=com.mycompany.*
okxuctiv

okxuctiv3#

@rhinoceros.xn的改进版本:

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'
kxeu7u2r

kxeu7u2r4#

shell脚本

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()
dba5bblo

dba5bblo5#

一种方法是使用help:evaluate plugin as a actual plugin for your modules.在pom.xml中包含以下内容,让所有模块都继承自该pom.大多数情况下,项目的模块都将其父模块设置为上面一个文件夹中的pom.否则,您可以将其复制并粘贴到任何不遵循继承结构的模块中。

<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的构建顺序输出模块的路径,我认为这个输出比maven在“Reactor Build Order”一节中打印的机器可读性要好得多。
注意路径分隔符包含在<expression>标记中。这只在项目变量有特殊情况时才起作用。-q -DforceStdout不会在模块的不同路径输出之间输出任何分隔符。添加换行符(\n)很困难,因为在过程中的某个地方,表达式的开头和结尾会删除空格,所以我放弃了,使用了${path.separator},在将XML解析为“:“或“;“这取决于您的平台。
使用一个单独的配置文件可以让你像平常一样运行help:evaluate插件,并保持正常构建的日志不受路径输出的影响。插件更喜欢pom中的表达式,而不是你用参数设置的表达式。

$> mvn help:evaluate -Dexpression=project.version -q -DforceStdout
1.0.0.0

注意,插件仍然必须包含在常规的<build>标签中,配置文件只能覆盖其配置。

相关问题