From 74101fd9138d7000b2064c1c4c3e9bd3c5352e76 Mon Sep 17 00:00:00 2001 From: Tiago Santos Date: Fri, 29 Nov 2019 14:50:13 +0000 Subject: [PATCH 1/4] [Issue #48] Fix rootlocation goal. --- .../invoker.properties | 3 ++ src/it/rootlocation-in-submodule/pom.xml | 36 +++++++++++++++++ .../submodule/pom.xml | 16 ++++++++ .../rootlocation-in-submodule/verify.groovy | 8 ++++ .../invoker.properties | 2 + .../pom.xml | 39 +++++++++++++++++++ .../submodule/pom.xml | 16 ++++++++ .../verify.groovy | 9 +++++ src/it/rootlocation/invoker.properties | 2 + src/it/rootlocation/pom.xml | 32 +++++++++++++++ src/it/rootlocation/verify.groovy | 8 ++++ .../mojo/buildhelper/RootLocationMojo.java | 22 ++++++++++- 12 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 src/it/rootlocation-in-submodule/invoker.properties create mode 100644 src/it/rootlocation-in-submodule/pom.xml create mode 100644 src/it/rootlocation-in-submodule/submodule/pom.xml create mode 100644 src/it/rootlocation-in-submodule/verify.groovy create mode 100644 src/it/rootlocation-run-only-at-exec-root/invoker.properties create mode 100644 src/it/rootlocation-run-only-at-exec-root/pom.xml create mode 100644 src/it/rootlocation-run-only-at-exec-root/submodule/pom.xml create mode 100644 src/it/rootlocation-run-only-at-exec-root/verify.groovy create mode 100644 src/it/rootlocation/invoker.properties create mode 100644 src/it/rootlocation/pom.xml create mode 100644 src/it/rootlocation/verify.groovy diff --git a/src/it/rootlocation-in-submodule/invoker.properties b/src/it/rootlocation-in-submodule/invoker.properties new file mode 100644 index 00000000..5bc9fafe --- /dev/null +++ b/src/it/rootlocation-in-submodule/invoker.properties @@ -0,0 +1,3 @@ +invoker.goals = validate +invoker.buildResult = success +invoker.project = submodule \ No newline at end of file diff --git a/src/it/rootlocation-in-submodule/pom.xml b/src/it/rootlocation-in-submodule/pom.xml new file mode 100644 index 00000000..eba54610 --- /dev/null +++ b/src/it/rootlocation-in-submodule/pom.xml @@ -0,0 +1,36 @@ + + 4.0.0 + + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + pom + + rootlocation search top root + + Tests that rootlocation finds the highest basedir. + + + + submodule + + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + rootlocation + + + + + + + + \ No newline at end of file diff --git a/src/it/rootlocation-in-submodule/submodule/pom.xml b/src/it/rootlocation-in-submodule/submodule/pom.xml new file mode 100644 index 00000000..252b3185 --- /dev/null +++ b/src/it/rootlocation-in-submodule/submodule/pom.xml @@ -0,0 +1,16 @@ + + 4.0.0 + + + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + + + project + jar + + rootlocation sub project + + \ No newline at end of file diff --git a/src/it/rootlocation-in-submodule/verify.groovy b/src/it/rootlocation-in-submodule/verify.groovy new file mode 100644 index 00000000..2b95127c --- /dev/null +++ b/src/it/rootlocation-in-submodule/verify.groovy @@ -0,0 +1,8 @@ +File file = new File( basedir, "build.log" ) +assert file.exists() + +String text = file.getText("utf-8") + +assert text.matches('(?ms)(.*?)define property rootlocation = "(.*)/rootlocation-in-submodule"(.*?)') + +return true \ No newline at end of file diff --git a/src/it/rootlocation-run-only-at-exec-root/invoker.properties b/src/it/rootlocation-run-only-at-exec-root/invoker.properties new file mode 100644 index 00000000..877b4904 --- /dev/null +++ b/src/it/rootlocation-run-only-at-exec-root/invoker.properties @@ -0,0 +1,2 @@ +invoker.goals = validate +invoker.buildResult = success diff --git a/src/it/rootlocation-run-only-at-exec-root/pom.xml b/src/it/rootlocation-run-only-at-exec-root/pom.xml new file mode 100644 index 00000000..1b37d098 --- /dev/null +++ b/src/it/rootlocation-run-only-at-exec-root/pom.xml @@ -0,0 +1,39 @@ + + 4.0.0 + + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + pom + + rootlocation run only at execution root + + Tests that rootlocation is executed only at execution top level. + + + + submodule + + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + rootlocation + + + true + + + + + + + + \ No newline at end of file diff --git a/src/it/rootlocation-run-only-at-exec-root/submodule/pom.xml b/src/it/rootlocation-run-only-at-exec-root/submodule/pom.xml new file mode 100644 index 00000000..252b3185 --- /dev/null +++ b/src/it/rootlocation-run-only-at-exec-root/submodule/pom.xml @@ -0,0 +1,16 @@ + + 4.0.0 + + + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + + + project + jar + + rootlocation sub project + + \ No newline at end of file diff --git a/src/it/rootlocation-run-only-at-exec-root/verify.groovy b/src/it/rootlocation-run-only-at-exec-root/verify.groovy new file mode 100644 index 00000000..28dceb5c --- /dev/null +++ b/src/it/rootlocation-run-only-at-exec-root/verify.groovy @@ -0,0 +1,9 @@ +File file = new File( basedir, "build.log" ) +assert file.exists() + +String text = file.getText("utf-8") + +assert text.matches('(?ms)(.*?)define property rootlocation = "(.*)/rootlocation-run-only-at-exec-root"(.*?)') +assert text.contains("Skip getting the rootlocation in this project because it's not the Execution Root") + +return true \ No newline at end of file diff --git a/src/it/rootlocation/invoker.properties b/src/it/rootlocation/invoker.properties new file mode 100644 index 00000000..877b4904 --- /dev/null +++ b/src/it/rootlocation/invoker.properties @@ -0,0 +1,2 @@ +invoker.goals = validate +invoker.buildResult = success diff --git a/src/it/rootlocation/pom.xml b/src/it/rootlocation/pom.xml new file mode 100644 index 00000000..27a57386 --- /dev/null +++ b/src/it/rootlocation/pom.xml @@ -0,0 +1,32 @@ + + 4.0.0 + + org.codehaus.mojo + build-helper-rootlocation + 1-SNAPSHOT + jar + + rootlocation + + Tests that rootlocation is set. + + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + rootlocation + + + + + + + + \ No newline at end of file diff --git a/src/it/rootlocation/verify.groovy b/src/it/rootlocation/verify.groovy new file mode 100644 index 00000000..a515cbf0 --- /dev/null +++ b/src/it/rootlocation/verify.groovy @@ -0,0 +1,8 @@ +File file = new File( basedir, "build.log" ) +assert file.exists() + +String text = file.getText("utf-8") + +assert text.matches('(?ms)(.*?)define property rootlocation = "(.*)/rootlocation"(.*?)') + +return true \ No newline at end of file diff --git a/src/main/java/org/codehaus/mojo/buildhelper/RootLocationMojo.java b/src/main/java/org/codehaus/mojo/buildhelper/RootLocationMojo.java index 1c221442..22b104f0 100644 --- a/src/main/java/org/codehaus/mojo/buildhelper/RootLocationMojo.java +++ b/src/main/java/org/codehaus/mojo/buildhelper/RootLocationMojo.java @@ -4,6 +4,9 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; + +import javax.annotation.Nonnull; /** * This goal will get the location of the root folder within a multi module build as a property {@code rootlocation}. @@ -42,8 +45,25 @@ public void execute() } else { - defineProperty( rootLocationProperty, session.getTopLevelProject().getBasedir().getAbsolutePath() ); + MavenProject topLevelProject = findHighestParentProject(session.getTopLevelProject()); + defineProperty( rootLocationProperty, topLevelProject.getBasedir().getAbsolutePath() ); + } + } + + private MavenProject findHighestParentProject(@Nonnull MavenProject project) + { + // search up model hierarchy to find the highest basedir location + MavenProject parent = project; + while (parent.getParent() != null) + { + if (parent.getParent().getBasedir() == null) + { + // we've hit a parent that was resolved. Stop going higher up in the hierarchy + break; + } + parent = parent.getParent(); } + return parent; } } \ No newline at end of file From b8f2c971e1542ac067a24f1a6d13e46c2ad83603 Mon Sep 17 00:00:00 2001 From: sseifert Date: Tue, 2 Jun 2020 11:04:09 +0200 Subject: [PATCH 2/4] [Issue #48] fix ITs running on windows machines (\ instead of / as file separator) --- src/it/rootlocation-in-submodule/verify.groovy | 2 +- src/it/rootlocation-run-only-at-exec-root/verify.groovy | 2 +- src/it/rootlocation/verify.groovy | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/it/rootlocation-in-submodule/verify.groovy b/src/it/rootlocation-in-submodule/verify.groovy index 2b95127c..cca71596 100644 --- a/src/it/rootlocation-in-submodule/verify.groovy +++ b/src/it/rootlocation-in-submodule/verify.groovy @@ -3,6 +3,6 @@ assert file.exists() String text = file.getText("utf-8") -assert text.matches('(?ms)(.*?)define property rootlocation = "(.*)/rootlocation-in-submodule"(.*?)') +assert text.matches('(?ms)(.*?)define property rootlocation = "(.*)[/\\\\]rootlocation-in-submodule"(.*?)') return true \ No newline at end of file diff --git a/src/it/rootlocation-run-only-at-exec-root/verify.groovy b/src/it/rootlocation-run-only-at-exec-root/verify.groovy index 28dceb5c..03454c41 100644 --- a/src/it/rootlocation-run-only-at-exec-root/verify.groovy +++ b/src/it/rootlocation-run-only-at-exec-root/verify.groovy @@ -3,7 +3,7 @@ assert file.exists() String text = file.getText("utf-8") -assert text.matches('(?ms)(.*?)define property rootlocation = "(.*)/rootlocation-run-only-at-exec-root"(.*?)') +assert text.matches('(?ms)(.*?)define property rootlocation = "(.*)[/\\\\]rootlocation-run-only-at-exec-root"(.*?)') assert text.contains("Skip getting the rootlocation in this project because it's not the Execution Root") return true \ No newline at end of file diff --git a/src/it/rootlocation/verify.groovy b/src/it/rootlocation/verify.groovy index a515cbf0..1db557e1 100644 --- a/src/it/rootlocation/verify.groovy +++ b/src/it/rootlocation/verify.groovy @@ -3,6 +3,6 @@ assert file.exists() String text = file.getText("utf-8") -assert text.matches('(?ms)(.*?)define property rootlocation = "(.*)/rootlocation"(.*?)') +assert text.matches('(?ms)(.*?)define property rootlocation = "(.*)[/\\\\]rootlocation"(.*?)') return true \ No newline at end of file From d73b14e0a9b265805b44acd5f71260fd38fde807 Mon Sep 17 00:00:00 2001 From: sseifert Date: Tue, 2 Jun 2020 11:38:36 +0200 Subject: [PATCH 3/4] cosmetic: normalize whitespaces --- .../invoker.properties | 2 +- src/it/rootlocation-in-submodule/pom.xml | 56 ++++++++--------- .../submodule/pom.xml | 22 +++---- .../rootlocation-in-submodule/verify.groovy | 2 +- .../pom.xml | 62 +++++++++---------- .../submodule/pom.xml | 22 +++---- .../verify.groovy | 2 +- src/it/rootlocation/pom.xml | 50 +++++++-------- src/it/rootlocation/verify.groovy | 2 +- 9 files changed, 110 insertions(+), 110 deletions(-) diff --git a/src/it/rootlocation-in-submodule/invoker.properties b/src/it/rootlocation-in-submodule/invoker.properties index 5bc9fafe..965fc19f 100644 --- a/src/it/rootlocation-in-submodule/invoker.properties +++ b/src/it/rootlocation-in-submodule/invoker.properties @@ -1,3 +1,3 @@ invoker.goals = validate invoker.buildResult = success -invoker.project = submodule \ No newline at end of file +invoker.project = submodule diff --git a/src/it/rootlocation-in-submodule/pom.xml b/src/it/rootlocation-in-submodule/pom.xml index eba54610..41b0646e 100644 --- a/src/it/rootlocation-in-submodule/pom.xml +++ b/src/it/rootlocation-in-submodule/pom.xml @@ -1,36 +1,36 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - org.codehaus.mojo - build-helper-rootlocation-parent - 1-SNAPSHOT - pom + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + pom - rootlocation search top root - + rootlocation search top root + Tests that rootlocation finds the highest basedir. - - submodule - + + submodule + - - - - @project.groupId@ - @project.artifactId@ - @project.version@ - - - - rootlocation - - - - - - + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + rootlocation + + + + + + - \ No newline at end of file + diff --git a/src/it/rootlocation-in-submodule/submodule/pom.xml b/src/it/rootlocation-in-submodule/submodule/pom.xml index 252b3185..f3ac5ef4 100644 --- a/src/it/rootlocation-in-submodule/submodule/pom.xml +++ b/src/it/rootlocation-in-submodule/submodule/pom.xml @@ -1,16 +1,16 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - - org.codehaus.mojo - build-helper-rootlocation-parent - 1-SNAPSHOT - + + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + - project - jar + project + jar - rootlocation sub project + rootlocation sub project - \ No newline at end of file + diff --git a/src/it/rootlocation-in-submodule/verify.groovy b/src/it/rootlocation-in-submodule/verify.groovy index cca71596..fdca3325 100644 --- a/src/it/rootlocation-in-submodule/verify.groovy +++ b/src/it/rootlocation-in-submodule/verify.groovy @@ -5,4 +5,4 @@ String text = file.getText("utf-8") assert text.matches('(?ms)(.*?)define property rootlocation = "(.*)[/\\\\]rootlocation-in-submodule"(.*?)') -return true \ No newline at end of file +return true diff --git a/src/it/rootlocation-run-only-at-exec-root/pom.xml b/src/it/rootlocation-run-only-at-exec-root/pom.xml index 1b37d098..0492b34b 100644 --- a/src/it/rootlocation-run-only-at-exec-root/pom.xml +++ b/src/it/rootlocation-run-only-at-exec-root/pom.xml @@ -1,39 +1,39 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - org.codehaus.mojo - build-helper-rootlocation-parent - 1-SNAPSHOT - pom + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + pom - rootlocation run only at execution root - + rootlocation run only at execution root + Tests that rootlocation is executed only at execution top level. - - submodule - + + submodule + - - - - @project.groupId@ - @project.artifactId@ - @project.version@ - - - - rootlocation - - - true - - - - - - + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + rootlocation + + + true + + + + + + - \ No newline at end of file + diff --git a/src/it/rootlocation-run-only-at-exec-root/submodule/pom.xml b/src/it/rootlocation-run-only-at-exec-root/submodule/pom.xml index 252b3185..f3ac5ef4 100644 --- a/src/it/rootlocation-run-only-at-exec-root/submodule/pom.xml +++ b/src/it/rootlocation-run-only-at-exec-root/submodule/pom.xml @@ -1,16 +1,16 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - - org.codehaus.mojo - build-helper-rootlocation-parent - 1-SNAPSHOT - + + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + - project - jar + project + jar - rootlocation sub project + rootlocation sub project - \ No newline at end of file + diff --git a/src/it/rootlocation-run-only-at-exec-root/verify.groovy b/src/it/rootlocation-run-only-at-exec-root/verify.groovy index 03454c41..53d6f4be 100644 --- a/src/it/rootlocation-run-only-at-exec-root/verify.groovy +++ b/src/it/rootlocation-run-only-at-exec-root/verify.groovy @@ -6,4 +6,4 @@ String text = file.getText("utf-8") assert text.matches('(?ms)(.*?)define property rootlocation = "(.*)[/\\\\]rootlocation-run-only-at-exec-root"(.*?)') assert text.contains("Skip getting the rootlocation in this project because it's not the Execution Root") -return true \ No newline at end of file +return true diff --git a/src/it/rootlocation/pom.xml b/src/it/rootlocation/pom.xml index 27a57386..ef682e63 100644 --- a/src/it/rootlocation/pom.xml +++ b/src/it/rootlocation/pom.xml @@ -1,32 +1,32 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - org.codehaus.mojo - build-helper-rootlocation - 1-SNAPSHOT - jar + org.codehaus.mojo + build-helper-rootlocation + 1-SNAPSHOT + jar - rootlocation - + rootlocation + Tests that rootlocation is set. - - - - @project.groupId@ - @project.artifactId@ - @project.version@ - - - - rootlocation - - - - - - + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + rootlocation + + + + + + - \ No newline at end of file + diff --git a/src/it/rootlocation/verify.groovy b/src/it/rootlocation/verify.groovy index 1db557e1..0296fb92 100644 --- a/src/it/rootlocation/verify.groovy +++ b/src/it/rootlocation/verify.groovy @@ -5,4 +5,4 @@ String text = file.getText("utf-8") assert text.matches('(?ms)(.*?)define property rootlocation = "(.*)[/\\\\]rootlocation"(.*?)') -return true \ No newline at end of file +return true From 933dccfd6493d515a311127eeefd39464ebbf239 Mon Sep 17 00:00:00 2001 From: sseifert Date: Tue, 2 Jun 2020 11:39:00 +0200 Subject: [PATCH 4/4] [Issue #48] detect root project location also in special cases: - maven is executed on a submodule - projects aggregation root and parent is not the same - child modules may reside in deeper nested folders without a pom.xml in between --- .../invoker.properties | 3 + .../modules/submodule/pom.xml | 17 +++ .../parent/pom.xml | 27 ++++ .../pom.xml | 27 ++++ .../verify.groovy | 9 ++ .../invoker.properties | 3 + .../modules/pom.xml | 19 +++ .../modules/submodule/pom.xml | 17 +++ .../parent/pom.xml | 27 ++++ .../pom.xml | 27 ++++ .../verify.groovy | 9 ++ .../invoker.properties | 3 + .../parent/pom.xml | 27 ++++ .../pom.xml | 27 ++++ .../submodule/pom.xml | 17 +++ .../verify.groovy | 9 ++ .../rootlocation-in-submodule/verify.groovy | 3 +- .../verify.groovy | 4 +- src/it/rootlocation/verify.groovy | 3 +- .../AbstractDefinePropertyMojo.java | 2 +- .../mojo/buildhelper/RootLocationMojo.java | 117 +++++++++++++++--- 21 files changed, 377 insertions(+), 20 deletions(-) create mode 100644 src/it/rootlocation-in-submodule-deeperlevel-separate-parent/invoker.properties create mode 100644 src/it/rootlocation-in-submodule-deeperlevel-separate-parent/modules/submodule/pom.xml create mode 100644 src/it/rootlocation-in-submodule-deeperlevel-separate-parent/parent/pom.xml create mode 100644 src/it/rootlocation-in-submodule-deeperlevel-separate-parent/pom.xml create mode 100644 src/it/rootlocation-in-submodule-deeperlevel-separate-parent/verify.groovy create mode 100644 src/it/rootlocation-in-submodule-nested-separate-parent/invoker.properties create mode 100644 src/it/rootlocation-in-submodule-nested-separate-parent/modules/pom.xml create mode 100644 src/it/rootlocation-in-submodule-nested-separate-parent/modules/submodule/pom.xml create mode 100644 src/it/rootlocation-in-submodule-nested-separate-parent/parent/pom.xml create mode 100644 src/it/rootlocation-in-submodule-nested-separate-parent/pom.xml create mode 100644 src/it/rootlocation-in-submodule-nested-separate-parent/verify.groovy create mode 100644 src/it/rootlocation-in-submodule-separate-parent/invoker.properties create mode 100644 src/it/rootlocation-in-submodule-separate-parent/parent/pom.xml create mode 100644 src/it/rootlocation-in-submodule-separate-parent/pom.xml create mode 100644 src/it/rootlocation-in-submodule-separate-parent/submodule/pom.xml create mode 100644 src/it/rootlocation-in-submodule-separate-parent/verify.groovy diff --git a/src/it/rootlocation-in-submodule-deeperlevel-separate-parent/invoker.properties b/src/it/rootlocation-in-submodule-deeperlevel-separate-parent/invoker.properties new file mode 100644 index 00000000..e6f1b830 --- /dev/null +++ b/src/it/rootlocation-in-submodule-deeperlevel-separate-parent/invoker.properties @@ -0,0 +1,3 @@ +invoker.goals = validate +invoker.buildResult = success +invoker.project = modules/submodule diff --git a/src/it/rootlocation-in-submodule-deeperlevel-separate-parent/modules/submodule/pom.xml b/src/it/rootlocation-in-submodule-deeperlevel-separate-parent/modules/submodule/pom.xml new file mode 100644 index 00000000..a7a57802 --- /dev/null +++ b/src/it/rootlocation-in-submodule-deeperlevel-separate-parent/modules/submodule/pom.xml @@ -0,0 +1,17 @@ + + 4.0.0 + + + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + ../../parent/pom.xml + + + project + jar + + rootlocation sub project + + diff --git a/src/it/rootlocation-in-submodule-deeperlevel-separate-parent/parent/pom.xml b/src/it/rootlocation-in-submodule-deeperlevel-separate-parent/parent/pom.xml new file mode 100644 index 00000000..270a9014 --- /dev/null +++ b/src/it/rootlocation-in-submodule-deeperlevel-separate-parent/parent/pom.xml @@ -0,0 +1,27 @@ + + 4.0.0 + + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + pom + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + rootlocation + + + + + + + + diff --git a/src/it/rootlocation-in-submodule-deeperlevel-separate-parent/pom.xml b/src/it/rootlocation-in-submodule-deeperlevel-separate-parent/pom.xml new file mode 100644 index 00000000..c0d6f0d6 --- /dev/null +++ b/src/it/rootlocation-in-submodule-deeperlevel-separate-parent/pom.xml @@ -0,0 +1,27 @@ + + 4.0.0 + + + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + parent/pom.xml + + + org.codehaus.mojo + build-helper-rootlocation-root + 1-SNAPSHOT + pom + + rootlocation search top root + + Tests that rootlocation finds the highest basedir. + + + + parent + modules/submodule + + + diff --git a/src/it/rootlocation-in-submodule-deeperlevel-separate-parent/verify.groovy b/src/it/rootlocation-in-submodule-deeperlevel-separate-parent/verify.groovy new file mode 100644 index 00000000..d52f9903 --- /dev/null +++ b/src/it/rootlocation-in-submodule-deeperlevel-separate-parent/verify.groovy @@ -0,0 +1,9 @@ +File file = new File( basedir, "build.log" ) +assert file.exists() + +String text = file.getText("utf-8") + +def rootFolderName = (text =~ /(?ms)(.*?)define property rootlocation = "(.*?)[\/\\]([^\/\\"]+)"(.*?)/)[0][3] +assert rootFolderName == "rootlocation-in-submodule-deeperlevel-separate-parent" + +return true diff --git a/src/it/rootlocation-in-submodule-nested-separate-parent/invoker.properties b/src/it/rootlocation-in-submodule-nested-separate-parent/invoker.properties new file mode 100644 index 00000000..e6f1b830 --- /dev/null +++ b/src/it/rootlocation-in-submodule-nested-separate-parent/invoker.properties @@ -0,0 +1,3 @@ +invoker.goals = validate +invoker.buildResult = success +invoker.project = modules/submodule diff --git a/src/it/rootlocation-in-submodule-nested-separate-parent/modules/pom.xml b/src/it/rootlocation-in-submodule-nested-separate-parent/modules/pom.xml new file mode 100644 index 00000000..ee662c13 --- /dev/null +++ b/src/it/rootlocation-in-submodule-nested-separate-parent/modules/pom.xml @@ -0,0 +1,19 @@ + + 4.0.0 + + + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + ../parent/pom.xml + + + build-helper-rootlocation-modules + pom + + + submodule + + + diff --git a/src/it/rootlocation-in-submodule-nested-separate-parent/modules/submodule/pom.xml b/src/it/rootlocation-in-submodule-nested-separate-parent/modules/submodule/pom.xml new file mode 100644 index 00000000..a7a57802 --- /dev/null +++ b/src/it/rootlocation-in-submodule-nested-separate-parent/modules/submodule/pom.xml @@ -0,0 +1,17 @@ + + 4.0.0 + + + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + ../../parent/pom.xml + + + project + jar + + rootlocation sub project + + diff --git a/src/it/rootlocation-in-submodule-nested-separate-parent/parent/pom.xml b/src/it/rootlocation-in-submodule-nested-separate-parent/parent/pom.xml new file mode 100644 index 00000000..270a9014 --- /dev/null +++ b/src/it/rootlocation-in-submodule-nested-separate-parent/parent/pom.xml @@ -0,0 +1,27 @@ + + 4.0.0 + + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + pom + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + rootlocation + + + + + + + + diff --git a/src/it/rootlocation-in-submodule-nested-separate-parent/pom.xml b/src/it/rootlocation-in-submodule-nested-separate-parent/pom.xml new file mode 100644 index 00000000..2ca2aed9 --- /dev/null +++ b/src/it/rootlocation-in-submodule-nested-separate-parent/pom.xml @@ -0,0 +1,27 @@ + + 4.0.0 + + + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + parent/pom.xml + + + org.codehaus.mojo + build-helper-rootlocation-root + 1-SNAPSHOT + pom + + rootlocation search top root + + Tests that rootlocation finds the highest basedir. + + + + parent + modules + + + diff --git a/src/it/rootlocation-in-submodule-nested-separate-parent/verify.groovy b/src/it/rootlocation-in-submodule-nested-separate-parent/verify.groovy new file mode 100644 index 00000000..290b6724 --- /dev/null +++ b/src/it/rootlocation-in-submodule-nested-separate-parent/verify.groovy @@ -0,0 +1,9 @@ +File file = new File( basedir, "build.log" ) +assert file.exists() + +String text = file.getText("utf-8") + +def rootFolderName = (text =~ /(?ms)(.*?)define property rootlocation = "(.*?)[\/\\]([^\/\\"]+)"(.*?)/)[0][3] +assert rootFolderName == "rootlocation-in-submodule-nested-separate-parent" + +return true diff --git a/src/it/rootlocation-in-submodule-separate-parent/invoker.properties b/src/it/rootlocation-in-submodule-separate-parent/invoker.properties new file mode 100644 index 00000000..965fc19f --- /dev/null +++ b/src/it/rootlocation-in-submodule-separate-parent/invoker.properties @@ -0,0 +1,3 @@ +invoker.goals = validate +invoker.buildResult = success +invoker.project = submodule diff --git a/src/it/rootlocation-in-submodule-separate-parent/parent/pom.xml b/src/it/rootlocation-in-submodule-separate-parent/parent/pom.xml new file mode 100644 index 00000000..270a9014 --- /dev/null +++ b/src/it/rootlocation-in-submodule-separate-parent/parent/pom.xml @@ -0,0 +1,27 @@ + + 4.0.0 + + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + pom + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + rootlocation + + + + + + + + diff --git a/src/it/rootlocation-in-submodule-separate-parent/pom.xml b/src/it/rootlocation-in-submodule-separate-parent/pom.xml new file mode 100644 index 00000000..922e02c3 --- /dev/null +++ b/src/it/rootlocation-in-submodule-separate-parent/pom.xml @@ -0,0 +1,27 @@ + + 4.0.0 + + + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + parent/pom.xml + + + org.codehaus.mojo + build-helper-rootlocation-root + 1-SNAPSHOT + pom + + rootlocation search top root + + Tests that rootlocation finds the highest basedir. + + + + parent + submodule + + + diff --git a/src/it/rootlocation-in-submodule-separate-parent/submodule/pom.xml b/src/it/rootlocation-in-submodule-separate-parent/submodule/pom.xml new file mode 100644 index 00000000..610c201f --- /dev/null +++ b/src/it/rootlocation-in-submodule-separate-parent/submodule/pom.xml @@ -0,0 +1,17 @@ + + 4.0.0 + + + org.codehaus.mojo + build-helper-rootlocation-parent + 1-SNAPSHOT + ../parent/pom.xml + + + project + jar + + rootlocation sub project + + diff --git a/src/it/rootlocation-in-submodule-separate-parent/verify.groovy b/src/it/rootlocation-in-submodule-separate-parent/verify.groovy new file mode 100644 index 00000000..133d0e5f --- /dev/null +++ b/src/it/rootlocation-in-submodule-separate-parent/verify.groovy @@ -0,0 +1,9 @@ +File file = new File( basedir, "build.log" ) +assert file.exists() + +String text = file.getText("utf-8") + +def rootFolderName = (text =~ /(?ms)(.*?)define property rootlocation = "(.*?)[\/\\]([^\/\\"]+)"(.*?)/)[0][3] +assert rootFolderName == "rootlocation-in-submodule-separate-parent" + +return true diff --git a/src/it/rootlocation-in-submodule/verify.groovy b/src/it/rootlocation-in-submodule/verify.groovy index fdca3325..fa263525 100644 --- a/src/it/rootlocation-in-submodule/verify.groovy +++ b/src/it/rootlocation-in-submodule/verify.groovy @@ -3,6 +3,7 @@ assert file.exists() String text = file.getText("utf-8") -assert text.matches('(?ms)(.*?)define property rootlocation = "(.*)[/\\\\]rootlocation-in-submodule"(.*?)') +def rootFolderName = (text =~ /(?ms)(.*?)define property rootlocation = "(.*?)[\/\\]([^\/\\"]+)"(.*?)/)[0][3] +assert rootFolderName == "rootlocation-in-submodule" return true diff --git a/src/it/rootlocation-run-only-at-exec-root/verify.groovy b/src/it/rootlocation-run-only-at-exec-root/verify.groovy index 53d6f4be..ed9f620b 100644 --- a/src/it/rootlocation-run-only-at-exec-root/verify.groovy +++ b/src/it/rootlocation-run-only-at-exec-root/verify.groovy @@ -3,7 +3,9 @@ assert file.exists() String text = file.getText("utf-8") -assert text.matches('(?ms)(.*?)define property rootlocation = "(.*)[/\\\\]rootlocation-run-only-at-exec-root"(.*?)') +def rootFolderName = (text =~ /(?ms)(.*?)define property rootlocation = "(.*?)[\/\\]([^\/\\"]+)"(.*?)/)[0][3] +assert rootFolderName == "rootlocation-run-only-at-exec-root" + assert text.contains("Skip getting the rootlocation in this project because it's not the Execution Root") return true diff --git a/src/it/rootlocation/verify.groovy b/src/it/rootlocation/verify.groovy index 0296fb92..9d631cf1 100644 --- a/src/it/rootlocation/verify.groovy +++ b/src/it/rootlocation/verify.groovy @@ -3,6 +3,7 @@ assert file.exists() String text = file.getText("utf-8") -assert text.matches('(?ms)(.*?)define property rootlocation = "(.*)[/\\\\]rootlocation"(.*?)') +def rootFolderName = (text =~ /(?ms)(.*?)define property rootlocation = "(.*?)[\/\\]([^\/\\"]+)"(.*?)/)[0][3] +assert rootFolderName == "rootlocation" return true diff --git a/src/main/java/org/codehaus/mojo/buildhelper/AbstractDefinePropertyMojo.java b/src/main/java/org/codehaus/mojo/buildhelper/AbstractDefinePropertyMojo.java index 7564d27b..f9459ad1 100644 --- a/src/main/java/org/codehaus/mojo/buildhelper/AbstractDefinePropertyMojo.java +++ b/src/main/java/org/codehaus/mojo/buildhelper/AbstractDefinePropertyMojo.java @@ -35,7 +35,7 @@ public abstract class AbstractDefinePropertyMojo * The maven project */ @Parameter( readonly = true, defaultValue = "${project}" ) - private MavenProject project; + protected MavenProject project; protected void defineProperty( String name, String value ) { diff --git a/src/main/java/org/codehaus/mojo/buildhelper/RootLocationMojo.java b/src/main/java/org/codehaus/mojo/buildhelper/RootLocationMojo.java index 22b104f0..6f6b2a9c 100644 --- a/src/main/java/org/codehaus/mojo/buildhelper/RootLocationMojo.java +++ b/src/main/java/org/codehaus/mojo/buildhelper/RootLocationMojo.java @@ -1,12 +1,24 @@ package org.codehaus.mojo.buildhelper; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Model; +import org.apache.maven.model.Profile; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; - -import javax.annotation.Nonnull; +import org.apache.maven.project.ProjectBuilder; +import org.apache.maven.project.ProjectBuildingException; +import org.apache.maven.project.ProjectBuildingResult; /** * This goal will get the location of the root folder within a multi module build as a property {@code rootlocation}. @@ -14,13 +26,15 @@ * @author Karl Heinz Marbaise * @since 3.0.0 */ -@Mojo( name = "rootlocation", defaultPhase = LifecyclePhase.VALIDATE, threadSafe = true ) +@Mojo( name = "rootlocation", defaultPhase = LifecyclePhase.VALIDATE, threadSafe = true, requiresProject = true ) public class RootLocationMojo extends AbstractDefinePropertyMojo { @Parameter( defaultValue = "${session}", readonly = true, required = true ) private MavenSession session; + @Component + private ProjectBuilder projectBuilder; /** * This will cause the execution to be run only at the top of a given module tree. @@ -37,7 +51,7 @@ public class RootLocationMojo /** * Main plugin execution */ - public void execute() + public void execute() throws MojoFailureException { if ( runOnlyAtExecutionRoot && !getProject().isExecutionRoot() ) { @@ -45,25 +59,96 @@ public void execute() } else { - MavenProject topLevelProject = findHighestParentProject(session.getTopLevelProject()); - defineProperty( rootLocationProperty, topLevelProject.getBasedir().getAbsolutePath() ); + try { + MavenProject topLevelProject = getLocalRoot(project); + defineProperty( rootLocationProperty, topLevelProject.getBasedir().getAbsolutePath() ); + } + catch (IOException ex) { + throw new MojoFailureException("Unable to detect root location: " + ex.getMessage(), ex); + } } } - private MavenProject findHighestParentProject(@Nonnull MavenProject project) + /** + * Finds the local root of the specified project. + * + * @param project The project to find the local root for. + * @return The local root project (this may be the current project) + */ + private MavenProject getLocalRoot( final MavenProject project ) throws IOException { - // search up model hierarchy to find the highest basedir location - MavenProject parent = project; - while (parent.getParent() != null) - { - if (parent.getParent().getBasedir() == null) + MavenProject currentProject = project; + MavenProject localRootProject = project; + + List parentDirs = new ArrayList<>(); + getAllParentDirectories( project.getBasedir(), parentDirs ); + + for (File parentDir : parentDirs) { + getLog().debug( "Checking to see if " + parentDir + " is an aggregator parent" ); + File parent = new File( parentDir, "pom.xml" ); + if ( parent.isFile() ) { - // we've hit a parent that was resolved. Stop going higher up in the hierarchy - break; + try + { + final ProjectBuildingResult result = projectBuilder.build( parent, session.getProjectBuildingRequest() ); + final MavenProject parentProject = result.getProject(); + final String currentProjectCanonicalPath = currentProject.getBasedir().getCanonicalPath(); + if ( getAllChildModules( parentProject ).contains( currentProjectCanonicalPath ) ) + { + getLog().debug( parentDir + " is an aggregator parent of current project " ); + localRootProject = parentProject; + currentProject = parentProject; + } + else + { + getLog().debug( parentDir + " is not an aggregator parent of current project ("+getAllChildModules( parentProject )+"/"+currentProjectCanonicalPath+") " ); + } + } + catch ( ProjectBuildingException e ) + { + getLog().warn( e ); + } } - parent = parent.getParent(); } - return parent; + + getLog().debug( "Local aggregation root is " + localRootProject.getBasedir() ); + return localRootProject; + } + + private void getAllParentDirectories( File directory, List parents ) { + File parent = directory.getParentFile(); + if ( parent != null && parent.isDirectory() ) { + parents.add( parent ); + getAllParentDirectories( parent, parents ); + } + } + + /** + * Returns a set of all child modules for a project, including any defined in profiles (ignoring profile activation). + * + * @param project The project. + * @param logger The logger to use. + * @return the set of all child modules of the project (canonical paths). + */ + private Set getAllChildModules( MavenProject project ) throws IOException + { + Model model = project.getOriginalModel(); + Set paths = new TreeSet<>(); + paths.addAll( getChildModuleCanoncialPath( project, model.getModules() )); + for ( Profile profile : model.getProfiles() ) + { + paths.addAll( getChildModuleCanoncialPath( project, profile.getModules() )); + } + return paths; + } + + private Set getChildModuleCanoncialPath( MavenProject project, List modules ) throws IOException { + Set paths = new TreeSet<>(); + for (String module : modules) { + File file = new File( project.getBasedir(), module ); + paths.add(file.getCanonicalPath()); + } + return paths; } } \ No newline at end of file