From e386ef747ca4ab1d7c6d0d9614c472a320f222ce Mon Sep 17 00:00:00 2001 From: SergeDemoulinGebit <135312848+SergeDemoulinGebit@users.noreply.github.com> Date: Fri, 13 Sep 2024 20:16:26 +0200 Subject: [PATCH] Feature/extended interpolate (#384) --- .../bom/pom.xml | 31 +++ .../pom.xml | 45 ++++ .../verify.groovy | 64 ++++++ .../bom/pom.xml | 59 +++++ .../pom.xml | 21 ++ .../verify.groovy | 51 +++++ .../bom/pom.xml | 31 +++ .../pom.xml | 46 ++++ .../verify.groovy | 64 ++++++ .../bom/pom.xml | 59 +++++ .../pom.xml | 21 ++ .../verify.groovy | 51 +++++ .../pom.xml | 41 ++++ .../verify.groovy | 62 ++++++ .../pom.xml | 41 ++++ .../verify.groovy | 62 ++++++ .../pom.xml | 59 +++++ .../verify.groovy | 39 ++++ .../pom.xml | 63 ++++++ .../verify.groovy | 39 ++++ .../bom/pom.xml | 31 +++ .../pom.xml | 45 ++++ .../verify.groovy | 69 ++++++ .../mojo/flatten/ElementHandling.java | 6 + .../mojo/flatten/FlattenDescriptor.java | 5 + .../codehaus/mojo/flatten/FlattenMojo.java | 210 ++++++++++++------ .../ExtendedModelInterpolator.java | 17 ++ .../ExtendedModelInterpolatorException.java | 7 + ...ExtendedStringSearchModelInterpolator.java | 79 +++++++ .../FilteringValueSourceWrapper.java | 60 +++++ .../mojo/flatten/CreateEffectivePomTest.java | 2 +- 31 files changed, 1414 insertions(+), 66 deletions(-) create mode 100644 src/it/projects/issue-382-project-version-from-parent-is-not-interpolated/bom/pom.xml create mode 100644 src/it/projects/issue-382-project-version-from-parent-is-not-interpolated/pom.xml create mode 100644 src/it/projects/issue-382-project-version-from-parent-is-not-interpolated/verify.groovy create mode 100644 src/it/projects/issue-382-properties-from-parent-are-not-interpolated/bom/pom.xml create mode 100644 src/it/projects/issue-382-properties-from-parent-are-not-interpolated/pom.xml create mode 100644 src/it/projects/issue-382-properties-from-parent-are-not-interpolated/verify.groovy create mode 100644 src/it/projects/issue-382-with-extended_interpolate-project-version-from-parent-is-interpolated/bom/pom.xml create mode 100644 src/it/projects/issue-382-with-extended_interpolate-project-version-from-parent-is-interpolated/pom.xml create mode 100644 src/it/projects/issue-382-with-extended_interpolate-project-version-from-parent-is-interpolated/verify.groovy create mode 100644 src/it/projects/issue-382-with-extended_interpolate-properties-from-parent-are-interpolated/bom/pom.xml create mode 100644 src/it/projects/issue-382-with-extended_interpolate-properties-from-parent-are-interpolated/pom.xml create mode 100644 src/it/projects/issue-382-with-extended_interpolate-properties-from-parent-are-interpolated/verify.groovy create mode 100644 src/it/projects/issue-383-project-basedir-and-baseUri-for-are-interpolated/pom.xml create mode 100644 src/it/projects/issue-383-project-basedir-and-baseUri-for-are-interpolated/verify.groovy create mode 100644 src/it/projects/issue-383-with-extended_interpolate-project-basedir-and-baseUri-for-are-not-interpolated/pom.xml create mode 100644 src/it/projects/issue-383-with-extended_interpolate-project-basedir-and-baseUri-for-are-not-interpolated/verify.groovy create mode 100644 src/it/projects/removing-pluginManagement-if-build-is-empty/pom.xml create mode 100644 src/it/projects/removing-pluginManagement-if-build-is-empty/verify.groovy create mode 100644 src/it/projects/removing-pluginManagement-if-build-is-flatten/pom.xml create mode 100644 src/it/projects/removing-pluginManagement-if-build-is-flatten/verify.groovy create mode 100644 src/it/projects/with-extended_interpolate-parent-version-is-interpolated/bom/pom.xml create mode 100644 src/it/projects/with-extended_interpolate-parent-version-is-interpolated/pom.xml create mode 100644 src/it/projects/with-extended_interpolate-parent-version-is-interpolated/verify.groovy create mode 100644 src/main/java/org/codehaus/mojo/flatten/extendedinterpolation/ExtendedModelInterpolator.java create mode 100644 src/main/java/org/codehaus/mojo/flatten/extendedinterpolation/ExtendedModelInterpolatorException.java create mode 100644 src/main/java/org/codehaus/mojo/flatten/extendedinterpolation/ExtendedStringSearchModelInterpolator.java create mode 100644 src/main/java/org/codehaus/mojo/flatten/extendedinterpolation/FilteringValueSourceWrapper.java diff --git a/src/it/projects/issue-382-project-version-from-parent-is-not-interpolated/bom/pom.xml b/src/it/projects/issue-382-project-version-from-parent-is-not-interpolated/bom/pom.xml new file mode 100644 index 00000000..4dfdda61 --- /dev/null +++ b/src/it/projects/issue-382-project-version-from-parent-is-not-interpolated/bom/pom.xml @@ -0,0 +1,31 @@ + + 4.0.0 + + + org.codehaus.mojo.flatten.its + issue-382-project-version-from-parent-is-not-interpolated + 0.0.1-SNAPSHOT + ../pom.xml + + + bom + + pom + + + ${project.version} + + + + + + io.grpc + grpc-netty + ${project.version} + + + + + \ No newline at end of file diff --git a/src/it/projects/issue-382-project-version-from-parent-is-not-interpolated/pom.xml b/src/it/projects/issue-382-project-version-from-parent-is-not-interpolated/pom.xml new file mode 100644 index 00000000..819a43d8 --- /dev/null +++ b/src/it/projects/issue-382-project-version-from-parent-is-not-interpolated/pom.xml @@ -0,0 +1,45 @@ + + 4.0.0 + + org.codehaus.mojo.flatten.its + issue-382-project-version-from-parent-is-not-interpolated + 0.0.1-SNAPSHOT + pom + + + ${project.version} + + + + bom + + + + + + io.grpc + grpc-netty + ${project.version} + + + + + + + + org.codehaus.mojo + flatten-maven-plugin + @project.version@ + + + remove + interpolate + interpolate + + + + + + \ No newline at end of file diff --git a/src/it/projects/issue-382-project-version-from-parent-is-not-interpolated/verify.groovy b/src/it/projects/issue-382-project-version-from-parent-is-not-interpolated/verify.groovy new file mode 100644 index 00000000..b417c47e --- /dev/null +++ b/src/it/projects/issue-382-project-version-from-parent-is-not-interpolated/verify.groovy @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import groovy.xml.XmlSlurper + +{ + final File parentOriginalFile = new File(basedir, 'pom.xml') + assert parentOriginalFile.exists() + + final parentOriginal = new XmlSlurper().parse(parentOriginalFile) + assert '${project.version}' == parentOriginal.dependencyManagement.dependencies.dependency[0].version.text() + +} + +{ + final File flattenedParentPomFile = new File(basedir, '.flattened-pom.xml') + assert flattenedParentPomFile.exists() + + final flattenedParent = new XmlSlurper().parse(flattenedParentPomFile) + assert 0 == flattenedParent.parent.size() + assert '0.0.1-SNAPSHOT' == flattenedParent.properties.'interpolated-project-version'.text() + assert '0.0.1-SNAPSHOT' == flattenedParent.dependencyManagement.dependencies.dependency[0].version.text() +} + + +{ + final File bomOriginalFile = new File(basedir, 'bom/pom.xml') + assert bomOriginalFile.exists() + + final bomOriginal = new XmlSlurper().parse(bomOriginalFile) + assert '0.0.1-SNAPSHOT' == bomOriginal.parent.version.text() + assert 1 == bomOriginal.parent.size() + assert 1 == bomOriginal.dependencyManagement.size() + assert 1 == bomOriginal.dependencyManagement.dependencies.size() + assert 1 == bomOriginal.dependencyManagement.dependencies.dependency.size() + assert '${project.version}' == bomOriginal.properties.'interpolated-project-version'.text() + assert '${project.version}' == bomOriginal.dependencyManagement.dependencies.dependency[0].version.text() +} + +{ + final File flattenedBomPomFile = new File(basedir, 'bom/.flattened-pom.xml') + assert flattenedBomPomFile.exists() + + final flattenedBom = new XmlSlurper().parse(flattenedBomPomFile) + assert 0 == flattenedBom.parent.size() + assert '${project.version}' == flattenedBom.properties.'interpolated-project-version'.text() + assert '${project.version}' == flattenedBom.dependencyManagement.dependencies.dependency[0].version.text() +} + diff --git a/src/it/projects/issue-382-properties-from-parent-are-not-interpolated/bom/pom.xml b/src/it/projects/issue-382-properties-from-parent-are-not-interpolated/bom/pom.xml new file mode 100644 index 00000000..a807c84e --- /dev/null +++ b/src/it/projects/issue-382-properties-from-parent-are-not-interpolated/bom/pom.xml @@ -0,0 +1,59 @@ + + 4.0.0 + + + org.codehaus.mojo.flatten.its + issue-382-properties-from-parent-are-not-interpolated + 0.0.1-SNAPSHOT + ../pom.xml + + + bom + + pom + + + 1.57.1 + ${version.springboot} + + + + + + org.springframework.boot + spring-boot-dependencies + ${version.springboot} + pom + import + + + + + io.grpc + grpc-netty + ${version.grpc} + + + + + + + + + org.codehaus.mojo + flatten-maven-plugin + @project.version@ + + + remove + interpolate + interpolate + + + + + + + \ No newline at end of file diff --git a/src/it/projects/issue-382-properties-from-parent-are-not-interpolated/pom.xml b/src/it/projects/issue-382-properties-from-parent-are-not-interpolated/pom.xml new file mode 100644 index 00000000..ac12b71c --- /dev/null +++ b/src/it/projects/issue-382-properties-from-parent-are-not-interpolated/pom.xml @@ -0,0 +1,21 @@ + + 4.0.0 + + org.codehaus.mojo.flatten.its + issue-382-properties-from-parent-are-not-interpolated + 0.0.1-SNAPSHOT + pom + + + 3.1.2 + + + + + bom + + + + \ No newline at end of file diff --git a/src/it/projects/issue-382-properties-from-parent-are-not-interpolated/verify.groovy b/src/it/projects/issue-382-properties-from-parent-are-not-interpolated/verify.groovy new file mode 100644 index 00000000..a92a9e2d --- /dev/null +++ b/src/it/projects/issue-382-properties-from-parent-are-not-interpolated/verify.groovy @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import groovy.xml.XmlSlurper + +{ + final File bomOriginalFile = new File(basedir, 'bom/pom.xml') + assert bomOriginalFile.exists() + + final bomOriginal = new XmlSlurper().parse(bomOriginalFile) + assert 1 == bomOriginal.parent.size() + assert 1 == bomOriginal.dependencyManagement.size() + assert 1 == bomOriginal.dependencyManagement.dependencies.size() + assert 2 == bomOriginal.dependencyManagement.dependencies.dependency.size() + assert 'grpc-netty' == bomOriginal.dependencyManagement.dependencies.dependency[1].artifactId.text() + assert '${version.grpc}' == bomOriginal.dependencyManagement.dependencies.dependency[1].version.text() + assert 'spring-boot-dependencies' == bomOriginal.dependencyManagement.dependencies.dependency[0].artifactId.text() + assert '${version.springboot}' == bomOriginal.dependencyManagement.dependencies.dependency[0].version.text() + assert '${version.springboot}' == bomOriginal.properties.'interpolated-version-springboot'.text() +} +{ + final File flattenedBomPomFile = new File(basedir, 'bom/.flattened-pom.xml') + assert flattenedBomPomFile.exists() + + final flattenedBom = new XmlSlurper().parse(flattenedBomPomFile) + + assert 1 == flattenedBom.dependencyManagement.size() + assert 1 == flattenedBom.dependencyManagement.dependencies.size() + assert 2 == flattenedBom.dependencyManagement.dependencies.dependency.size() + assert 'grpc-netty' == flattenedBom.dependencyManagement.dependencies.dependency[1].artifactId.text() + assert '1.57.1' == flattenedBom.dependencyManagement.dependencies.dependency[1].version.text() + assert 'spring-boot-dependencies' == flattenedBom.dependencyManagement.dependencies.dependency[0].artifactId.text() + assert '${version.springboot}' == flattenedBom.properties.'interpolated-version-springboot'.text() + assert '${version.springboot}' == flattenedBom.dependencyManagement.dependencies.dependency[0].version.text() + +} \ No newline at end of file diff --git a/src/it/projects/issue-382-with-extended_interpolate-project-version-from-parent-is-interpolated/bom/pom.xml b/src/it/projects/issue-382-with-extended_interpolate-project-version-from-parent-is-interpolated/bom/pom.xml new file mode 100644 index 00000000..44cbce19 --- /dev/null +++ b/src/it/projects/issue-382-with-extended_interpolate-project-version-from-parent-is-interpolated/bom/pom.xml @@ -0,0 +1,31 @@ + + 4.0.0 + + + org.codehaus.mojo.flatten.its + issue-382-with-extended_interpolate-project-version-from-parent-is-interpolated + 0.0.1-SNAPSHOT + ../pom.xml + + + bom + + pom + + + ${project.version} + + + + + + io.grpc + grpc-netty + ${project.version} + + + + + \ No newline at end of file diff --git a/src/it/projects/issue-382-with-extended_interpolate-project-version-from-parent-is-interpolated/pom.xml b/src/it/projects/issue-382-with-extended_interpolate-project-version-from-parent-is-interpolated/pom.xml new file mode 100644 index 00000000..25ce7152 --- /dev/null +++ b/src/it/projects/issue-382-with-extended_interpolate-project-version-from-parent-is-interpolated/pom.xml @@ -0,0 +1,46 @@ + + 4.0.0 + + org.codehaus.mojo.flatten.its + issue-382-with-extended_interpolate-project-version-from-parent-is-interpolated + 0.0.1-SNAPSHOT + pom + + + 1.0.0-gebit15 + ${project.version} + + + + bom + + + + + + io.grpc + grpc-netty + ${project.version} + + + + + + + + org.codehaus.mojo + flatten-maven-plugin + @project.version@ + + + remove + extended_interpolate + extended_interpolate + + + + + + \ No newline at end of file diff --git a/src/it/projects/issue-382-with-extended_interpolate-project-version-from-parent-is-interpolated/verify.groovy b/src/it/projects/issue-382-with-extended_interpolate-project-version-from-parent-is-interpolated/verify.groovy new file mode 100644 index 00000000..f3c866bf --- /dev/null +++ b/src/it/projects/issue-382-with-extended_interpolate-project-version-from-parent-is-interpolated/verify.groovy @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import groovy.xml.XmlSlurper + +{ + final File parentOriginalFile = new File(basedir, 'pom.xml') + assert parentOriginalFile.exists() + + final parentOriginal = new XmlSlurper().parse(parentOriginalFile) + assert '${project.version}' == parentOriginal.dependencyManagement.dependencies.dependency[0].version.text() + +} + +{ + final File flattenedParentPomFile = new File(basedir, '.flattened-pom.xml') + assert flattenedParentPomFile.exists() + + final flattenedParent = new XmlSlurper().parse(flattenedParentPomFile) + assert 0 == flattenedParent.parent.size() + assert '0.0.1-SNAPSHOT' == flattenedParent.properties.'interpolated-project-version'.text() + assert '0.0.1-SNAPSHOT' == flattenedParent.dependencyManagement.dependencies.dependency[0].version.text() +} + + +{ + final File bomOriginalFile = new File(basedir, 'bom/pom.xml') + assert bomOriginalFile.exists() + + final bomOriginal = new XmlSlurper().parse(bomOriginalFile) + assert '0.0.1-SNAPSHOT' == bomOriginal.parent.version.text() + assert 1 == bomOriginal.parent.size() + assert 1 == bomOriginal.dependencyManagement.size() + assert 1 == bomOriginal.dependencyManagement.dependencies.size() + assert 1 == bomOriginal.dependencyManagement.dependencies.dependency.size() + assert '${project.version}' == bomOriginal.properties.'interpolated-project-version'.text() + assert '${project.version}' == bomOriginal.dependencyManagement.dependencies.dependency[0].version.text() +} + +{ + final File flattenedBomPomFile = new File(basedir, 'bom/.flattened-pom.xml') + assert flattenedBomPomFile.exists() + + final flattenedBom = new XmlSlurper().parse(flattenedBomPomFile) + assert 0 == flattenedBom.parent.size() + assert '0.0.1-SNAPSHOT' == flattenedBom.properties.'interpolated-project-version'.text() + assert '0.0.1-SNAPSHOT' == flattenedBom.dependencyManagement.dependencies.dependency[0].version.text() +} + diff --git a/src/it/projects/issue-382-with-extended_interpolate-properties-from-parent-are-interpolated/bom/pom.xml b/src/it/projects/issue-382-with-extended_interpolate-properties-from-parent-are-interpolated/bom/pom.xml new file mode 100644 index 00000000..47f97b6c --- /dev/null +++ b/src/it/projects/issue-382-with-extended_interpolate-properties-from-parent-are-interpolated/bom/pom.xml @@ -0,0 +1,59 @@ + + 4.0.0 + + + org.codehaus.mojo.flatten.its + issue-382-with-extended_interpolate-properties-from-parent-are-interpolated + 0.0.1-SNAPSHOT + ../pom.xml + + + bom + + pom + + + 1.57.1 + ${version.springboot} + + + + + + org.springframework.boot + spring-boot-dependencies + ${version.springboot} + pom + import + + + + + io.grpc + grpc-netty + ${version.grpc} + + + + + + + + + org.codehaus.mojo + flatten-maven-plugin + @project.version@ + + + remove + extended_interpolate + extended_interpolate + + + + + + + \ No newline at end of file diff --git a/src/it/projects/issue-382-with-extended_interpolate-properties-from-parent-are-interpolated/pom.xml b/src/it/projects/issue-382-with-extended_interpolate-properties-from-parent-are-interpolated/pom.xml new file mode 100644 index 00000000..c30bdf2c --- /dev/null +++ b/src/it/projects/issue-382-with-extended_interpolate-properties-from-parent-are-interpolated/pom.xml @@ -0,0 +1,21 @@ + + 4.0.0 + + org.codehaus.mojo.flatten.its + issue-382-with-extended_interpolate-properties-from-parent-are-interpolated + 0.0.1-SNAPSHOT + pom + + + 3.1.2 + + + + + bom + + + + \ No newline at end of file diff --git a/src/it/projects/issue-382-with-extended_interpolate-properties-from-parent-are-interpolated/verify.groovy b/src/it/projects/issue-382-with-extended_interpolate-properties-from-parent-are-interpolated/verify.groovy new file mode 100644 index 00000000..2a33b972 --- /dev/null +++ b/src/it/projects/issue-382-with-extended_interpolate-properties-from-parent-are-interpolated/verify.groovy @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import groovy.xml.XmlSlurper + +{ + final File bomOriginalFile = new File(basedir, 'bom/pom.xml') + assert bomOriginalFile.exists() + + final bomOriginal = new XmlSlurper().parse(bomOriginalFile) + assert 1 == bomOriginal.parent.size() + assert 1 == bomOriginal.dependencyManagement.size() + assert 1 == bomOriginal.dependencyManagement.dependencies.size() + assert 2 == bomOriginal.dependencyManagement.dependencies.dependency.size() + assert 'grpc-netty' == bomOriginal.dependencyManagement.dependencies.dependency[1].artifactId.text() + assert '${version.grpc}' == bomOriginal.dependencyManagement.dependencies.dependency[1].version.text() + assert 'spring-boot-dependencies' == bomOriginal.dependencyManagement.dependencies.dependency[0].artifactId.text() + assert '${version.springboot}' == bomOriginal.dependencyManagement.dependencies.dependency[0].version.text() + assert '${version.springboot}' == bomOriginal.properties.'interpolated-version-springboot'.text() +} +{ + final File flattenedBomPomFile = new File(basedir, 'bom/.flattened-pom.xml') + assert flattenedBomPomFile.exists() + + final flattenedBom = new XmlSlurper().parse(flattenedBomPomFile) + + assert 1 == flattenedBom.dependencyManagement.size() + assert 1 == flattenedBom.dependencyManagement.dependencies.size() + assert 2 == flattenedBom.dependencyManagement.dependencies.dependency.size() + assert 'grpc-netty' == flattenedBom.dependencyManagement.dependencies.dependency[1].artifactId.text() + assert '1.57.1' == flattenedBom.dependencyManagement.dependencies.dependency[1].version.text() + assert 'spring-boot-dependencies' == flattenedBom.dependencyManagement.dependencies.dependency[0].artifactId.text() + assert '3.1.2' == flattenedBom.properties.'interpolated-version-springboot'.text() + assert '3.1.2' == flattenedBom.dependencyManagement.dependencies.dependency[0].version.text() + +} \ No newline at end of file diff --git a/src/it/projects/issue-383-project-basedir-and-baseUri-for-are-interpolated/pom.xml b/src/it/projects/issue-383-project-basedir-and-baseUri-for-are-interpolated/pom.xml new file mode 100644 index 00000000..6440149f --- /dev/null +++ b/src/it/projects/issue-383-project-basedir-and-baseUri-for-are-interpolated/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + + org.codehaus.mojo.flatten.its + issue-383-project-basedir-and-baseUri-for-are-not-interpolated + 0.0.1-SNAPSHOT + + + + x${project.build}y + x${project.artifactId}y + x${project.groupId}y + x${project.version}y + x${project.parent.artifactId}y + x${project.parent.groupId}y + x${project.build.sourceDirectory}y + x${project.build.outputDirectory}y + x${project.build.directory}y + x${project.basedir}y + x${project.baseUri}y + x${project.build.scriptSourceDirectory}y + x${project.build.testSourceDirectory}y + x${project.reporting.outputDirectory}y + + + + + + org.codehaus.mojo + flatten-maven-plugin + @project.version@ + + + interpolate + + + + + + diff --git a/src/it/projects/issue-383-project-basedir-and-baseUri-for-are-interpolated/verify.groovy b/src/it/projects/issue-383-project-basedir-and-baseUri-for-are-interpolated/verify.groovy new file mode 100644 index 00000000..6708729b --- /dev/null +++ b/src/it/projects/issue-383-project-basedir-and-baseUri-for-are-interpolated/verify.groovy @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import groovy.xml.XmlSlurper + +{ + final File pom = new File(basedir, 'pom.xml') + assert pom.exists() + + final pomOriginal = new XmlSlurper().parse(pom) + + assert 'x${project.artifactId}y' == pomOriginal.properties.projectArtifactId.text() + assert 'x${project.groupId}y' == pomOriginal.properties.projectGroupId.text() + assert 'x${project.version}y' == pomOriginal.properties.projectVersion.text() + assert 'x${project.parent.artifactId}y' == pomOriginal.properties.projectParentArtifactId.text() + assert 'x${project.parent.groupId}y' == pomOriginal.properties.projectParentGroupId.text() + assert 'x${project.build.directory}y' == pomOriginal.properties.projectBuildDirectory.text() + assert 'x${project.build.outputDirectory}y' == pomOriginal.properties.projectBuildOutputDirectory.text() + assert 'x${project.build.sourceDirectory}y' == pomOriginal.properties.projectBuildSourceDirectory.text() + assert 'x${project.basedir}y' == pomOriginal.properties.projectBasedir.text() + assert 'x${project.baseUri}y' == pomOriginal.properties.projectBaseUri.text() + assert 'x${project.build.scriptSourceDirectory}y' == pomOriginal.properties.projectBuildScriptSourceDirectory.text() + assert 'x${project.build.testSourceDirectory}y' == pomOriginal.properties.projectBuildTestSourceDirectory.text() + assert 'x${project.reporting.outputDirectory}y' == pomOriginal.properties.projectReportingOutputDirectory.text() +} + + +{ + final File flattenedPomFile = new File(basedir, '.flattened-pom.xml') + assert flattenedPomFile.exists() + + final flattenedPom = new XmlSlurper().parse(flattenedPomFile) + + + assert 'xissue-383-project-basedir-and-baseUri-for-are-not-interpolatedy' == flattenedPom.properties.projectArtifactId.text() + assert 'xorg.codehaus.mojo.flatten.itsy' == flattenedPom.properties.projectGroupId.text() + assert 'x0.0.1-SNAPSHOTy' == flattenedPom.properties.projectVersion.text() + assert "x${basedir}y" == flattenedPom.properties.projectBasedir.text() + assert 'x${project.baseUri}y' != flattenedPom.properties.projectBaseUri.text() + assert 'x${project.build.directory}y' == flattenedPom.properties.projectBuildDirectory.text() + assert 'x${project.build.outputDirectory}y' == flattenedPom.properties.projectBuildOutputDirectory.text() + assert 'x${project.build.sourceDirectory}y' == flattenedPom.properties.projectBuildSourceDirectory.text() + assert 'x${project.build.scriptSourceDirectory}y' == flattenedPom.properties.projectBuildScriptSourceDirectory.text() + assert 'x${project.build.testSourceDirectory}y' == flattenedPom.properties.projectBuildTestSourceDirectory.text() + assert 'x${project.reporting.outputDirectory}y' == flattenedPom.properties.projectReportingOutputDirectory.text() +} \ No newline at end of file diff --git a/src/it/projects/issue-383-with-extended_interpolate-project-basedir-and-baseUri-for-are-not-interpolated/pom.xml b/src/it/projects/issue-383-with-extended_interpolate-project-basedir-and-baseUri-for-are-not-interpolated/pom.xml new file mode 100644 index 00000000..d8a250d7 --- /dev/null +++ b/src/it/projects/issue-383-with-extended_interpolate-project-basedir-and-baseUri-for-are-not-interpolated/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + + org.codehaus.mojo.flatten.its + issue-383-project-basedir-and-baseUri-for-are-not-interpolated + 0.0.1-SNAPSHOT + + + + x${project.build}y + x${project.artifactId}y + x${project.groupId}y + x${project.version}y + x${project.parent.artifactId}y + x${project.parent.groupId}y + x${project.build.sourceDirectory}y + x${project.build.outputDirectory}y + x${project.build.directory}y + x${project.basedir}y + x${project.baseUri}y + x${project.build.scriptSourceDirectory}y + x${project.build.testSourceDirectory}y + x${project.reporting.outputDirectory}y + + + + + + org.codehaus.mojo + flatten-maven-plugin + @project.version@ + + + extended_interpolate + + + + + + diff --git a/src/it/projects/issue-383-with-extended_interpolate-project-basedir-and-baseUri-for-are-not-interpolated/verify.groovy b/src/it/projects/issue-383-with-extended_interpolate-project-basedir-and-baseUri-for-are-not-interpolated/verify.groovy new file mode 100644 index 00000000..34bfac38 --- /dev/null +++ b/src/it/projects/issue-383-with-extended_interpolate-project-basedir-and-baseUri-for-are-not-interpolated/verify.groovy @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import groovy.xml.XmlSlurper + + +{ + final File pom = new File(basedir, 'pom.xml') + assert pom.exists() + + final pomOriginal = new XmlSlurper().parse(pom) + + assert 'x${project.artifactId}y' == pomOriginal.properties.projectArtifactId.text() + assert 'x${project.groupId}y' == pomOriginal.properties.projectGroupId.text() + assert 'x${project.version}y' == pomOriginal.properties.projectVersion.text() + assert 'x${project.parent.artifactId}y' == pomOriginal.properties.projectParentArtifactId.text() + assert 'x${project.parent.groupId}y' == pomOriginal.properties.projectParentGroupId.text() + assert 'x${project.build.directory}y' == pomOriginal.properties.projectBuildDirectory.text() + assert 'x${project.build.outputDirectory}y' == pomOriginal.properties.projectBuildOutputDirectory.text() + assert 'x${project.build.sourceDirectory}y' == pomOriginal.properties.projectBuildSourceDirectory.text() + assert 'x${project.basedir}y' == pomOriginal.properties.projectBasedir.text() + assert 'x${project.baseUri}y' == pomOriginal.properties.projectBaseUri.text() + assert 'x${project.build.scriptSourceDirectory}y' == pomOriginal.properties.projectBuildScriptSourceDirectory.text() + assert 'x${project.build.testSourceDirectory}y' == pomOriginal.properties.projectBuildTestSourceDirectory.text() + assert 'x${project.reporting.outputDirectory}y' == pomOriginal.properties.projectReportingOutputDirectory.text() +} + + +{ + final File flattenedPomFile = new File(basedir, '.flattened-pom.xml') + assert flattenedPomFile.exists() + + final flattenedPom = new XmlSlurper().parse(flattenedPomFile) + + + assert 'xissue-383-project-basedir-and-baseUri-for-are-not-interpolatedy' == flattenedPom.properties.projectArtifactId.text() + assert 'xorg.codehaus.mojo.flatten.itsy' == flattenedPom.properties.projectGroupId.text() + assert 'x0.0.1-SNAPSHOTy' == flattenedPom.properties.projectVersion.text() + assert 'x${project.build.directory}y' == flattenedPom.properties.projectBuildDirectory.text() + assert 'x${project.build.outputDirectory}y' == flattenedPom.properties.projectBuildOutputDirectory.text() + assert 'x${project.build.sourceDirectory}y' == flattenedPom.properties.projectBuildSourceDirectory.text() + assert 'x${project.basedir}y' == flattenedPom.properties.projectBasedir.text() + assert 'x${project.baseUri}y' == flattenedPom.properties.projectBaseUri.text() + assert 'x${project.build.scriptSourceDirectory}y' == flattenedPom.properties.projectBuildScriptSourceDirectory.text() + assert 'x${project.build.testSourceDirectory}y' == flattenedPom.properties.projectBuildTestSourceDirectory.text() + assert 'x${project.reporting.outputDirectory}y' == flattenedPom.properties.projectReportingOutputDirectory.text() +} \ No newline at end of file diff --git a/src/it/projects/removing-pluginManagement-if-build-is-empty/pom.xml b/src/it/projects/removing-pluginManagement-if-build-is-empty/pom.xml new file mode 100644 index 00000000..7b8da7de --- /dev/null +++ b/src/it/projects/removing-pluginManagement-if-build-is-empty/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + + org.codehaus.mojo.flatten.its + removing-pluginManagement-if-build-is-empty + 0.0.1-SNAPSHOT + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + biz.aQute.bnd + bnd-maven-plugin + [1.0,) + + bnd-process + + + + + false + true + + + + + + + + + + + + org.codehaus.mojo + flatten-maven-plugin + @project.version@ + + + + remove + + + + + + + \ No newline at end of file diff --git a/src/it/projects/removing-pluginManagement-if-build-is-empty/verify.groovy b/src/it/projects/removing-pluginManagement-if-build-is-empty/verify.groovy new file mode 100644 index 00000000..c68e53e5 --- /dev/null +++ b/src/it/projects/removing-pluginManagement-if-build-is-empty/verify.groovy @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import groovy.xml.XmlSlurper + + +{ + File pom = new File(basedir, 'pom.xml') + assert pom.exists() + + def pomOriginal = new XmlSlurper().parse(pom) + + assert 1 == pomOriginal.build.pluginManagement.size() +} + + +{ + File flattenedPomFile = new File(basedir, '.flattened-pom.xml') + assert flattenedPomFile.exists() + + def flattenedPom = new XmlSlurper().parse(flattenedPomFile) + + assert 0 == flattenedPom.build.pluginManagement.size() +} \ No newline at end of file diff --git a/src/it/projects/removing-pluginManagement-if-build-is-flatten/pom.xml b/src/it/projects/removing-pluginManagement-if-build-is-flatten/pom.xml new file mode 100644 index 00000000..6f23ff00 --- /dev/null +++ b/src/it/projects/removing-pluginManagement-if-build-is-flatten/pom.xml @@ -0,0 +1,63 @@ + + + 4.0.0 + + org.codehaus.mojo.flatten.its + removing-pluginManagement-if-build-is-flatten + 0.0.1-SNAPSHOT + + + flatten + remove + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + biz.aQute.bnd + bnd-maven-plugin + [1.0,) + + bnd-process + + + + + false + true + + + + + + + + + + + + org.codehaus.mojo + flatten-maven-plugin + @project.version@ + + + flatten + remove + + + + + + + \ No newline at end of file diff --git a/src/it/projects/removing-pluginManagement-if-build-is-flatten/verify.groovy b/src/it/projects/removing-pluginManagement-if-build-is-flatten/verify.groovy new file mode 100644 index 00000000..c68e53e5 --- /dev/null +++ b/src/it/projects/removing-pluginManagement-if-build-is-flatten/verify.groovy @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import groovy.xml.XmlSlurper + + +{ + File pom = new File(basedir, 'pom.xml') + assert pom.exists() + + def pomOriginal = new XmlSlurper().parse(pom) + + assert 1 == pomOriginal.build.pluginManagement.size() +} + + +{ + File flattenedPomFile = new File(basedir, '.flattened-pom.xml') + assert flattenedPomFile.exists() + + def flattenedPom = new XmlSlurper().parse(flattenedPomFile) + + assert 0 == flattenedPom.build.pluginManagement.size() +} \ No newline at end of file diff --git a/src/it/projects/with-extended_interpolate-parent-version-is-interpolated/bom/pom.xml b/src/it/projects/with-extended_interpolate-parent-version-is-interpolated/bom/pom.xml new file mode 100644 index 00000000..c66a3bb0 --- /dev/null +++ b/src/it/projects/with-extended_interpolate-parent-version-is-interpolated/bom/pom.xml @@ -0,0 +1,31 @@ + + 4.0.0 + + + org.codehaus.mojo.flatten.its + with-extended_interpolate-parent-version-is-interpolated + ${revision} + ../pom.xml + + + bom + + pom + + + ${project.version} + + + + + + io.grpc + grpc-netty + ${project.version} + + + + + \ No newline at end of file diff --git a/src/it/projects/with-extended_interpolate-parent-version-is-interpolated/pom.xml b/src/it/projects/with-extended_interpolate-parent-version-is-interpolated/pom.xml new file mode 100644 index 00000000..73960bf8 --- /dev/null +++ b/src/it/projects/with-extended_interpolate-parent-version-is-interpolated/pom.xml @@ -0,0 +1,45 @@ + + 4.0.0 + + org.codehaus.mojo.flatten.its + with-extended_interpolate-parent-version-is-interpolated + ${revision} + pom + + + ${project.version} + + + + bom + + + + + + io.grpc + grpc-netty + ${project.version} + + + + + + + + org.codehaus.mojo + flatten-maven-plugin + @project.version@ + + + extended_interpolate + extended_interpolate + extended_interpolate + + + + + + \ No newline at end of file diff --git a/src/it/projects/with-extended_interpolate-parent-version-is-interpolated/verify.groovy b/src/it/projects/with-extended_interpolate-parent-version-is-interpolated/verify.groovy new file mode 100644 index 00000000..8244f713 --- /dev/null +++ b/src/it/projects/with-extended_interpolate-parent-version-is-interpolated/verify.groovy @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import groovy.xml.XmlSlurper + +{ + final File parentOriginalFile = new File(basedir, 'pom.xml') + assert parentOriginalFile.exists() + + final parentOriginal = new XmlSlurper().parse(parentOriginalFile) + + assert '${revision}' == parentOriginal.version.text() + +} + +{ + final File flattenedParentPomFile = new File(basedir, '.flattened-pom.xml') + assert flattenedParentPomFile.exists() + + final flattenedParent = new XmlSlurper().parse(flattenedParentPomFile) + + assert '1.2.3.4' == flattenedParent.version.text() +} + + +{ + final File bomOriginalFile = new File(basedir, 'bom/pom.xml') + assert bomOriginalFile.exists() + + final bomOriginal = new XmlSlurper().parse(bomOriginalFile) + assert 1 == bomOriginal.parent.size() + assert 1 == bomOriginal.dependencyManagement.size() + assert 1 == bomOriginal.dependencyManagement.dependencies.size() + assert 1 == bomOriginal.dependencyManagement.dependencies.dependency.size() + assert '${project.version}' == bomOriginal.properties.'interpolated-project-version'.text() + assert '${project.version}' == bomOriginal.dependencyManagement.dependencies.dependency[0].version.text() + assert '${revision}' == bomOriginal.parent.version.text() + assert 'with-extended_interpolate-parent-version-is-interpolated' == bomOriginal.parent.artifactId.text() + assert 'org.codehaus.mojo.flatten.its' == bomOriginal.parent.groupId.text() +} + +{ + final File flattenedBomPomFile = new File(basedir, 'bom/.flattened-pom.xml') + assert flattenedBomPomFile.exists() + + final flattenedBom = new XmlSlurper().parse(flattenedBomPomFile) + assert '1.2.3.4' == flattenedBom.properties.'interpolated-project-version'.text() + assert '1.2.3.4' == flattenedBom.dependencyManagement.dependencies.dependency[0].version.text() + assert '1.2.3.4' == flattenedBom.parent.version.text() + assert 'with-extended_interpolate-parent-version-is-interpolated' == flattenedBom.parent.artifactId.text() + assert 'org.codehaus.mojo.flatten.its' == flattenedBom.parent.groupId.text() + +} + diff --git a/src/main/java/org/codehaus/mojo/flatten/ElementHandling.java b/src/main/java/org/codehaus/mojo/flatten/ElementHandling.java index cee0c0f6..a09dbdc8 100644 --- a/src/main/java/org/codehaus/mojo/flatten/ElementHandling.java +++ b/src/main/java/org/codehaus/mojo/flatten/ElementHandling.java @@ -41,6 +41,12 @@ public enum ElementHandling { /** Take the element from the interpolated POM (original POM with variables interpolated). */ interpolate, + /** + * Take the element from the interpolated POM, but resolve the variables with the properties from the effective POM.
+ * Don't resolve the following variables "project.basedir", "project.baseUri", "project.build.directory", "project.build.outputDirectory", "project.build.sourceDirectory", "project.build.scriptSourceDirectory", "project.build.testSourceDirectory", "project.reporting.outputDirectory"
+ * Interpolate the parent version + */ + extended_interpolate, /** Take the element untouched from the original POM. */ keep, diff --git a/src/main/java/org/codehaus/mojo/flatten/FlattenDescriptor.java b/src/main/java/org/codehaus/mojo/flatten/FlattenDescriptor.java index af715d41..64abffee 100644 --- a/src/main/java/org/codehaus/mojo/flatten/FlattenDescriptor.java +++ b/src/main/java/org/codehaus/mojo/flatten/FlattenDescriptor.java @@ -19,6 +19,7 @@ * under the License. */ +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -45,6 +46,10 @@ public FlattenDescriptor() { this.name2handlingMap = new HashMap<>(); } + public Map getName2handlingMap() { + return Collections.unmodifiableMap(name2handlingMap); + } + /** * The constructor. * diff --git a/src/main/java/org/codehaus/mojo/flatten/FlattenMojo.java b/src/main/java/org/codehaus/mojo/flatten/FlattenMojo.java index 20342048..6cf7bfc9 100644 --- a/src/main/java/org/codehaus/mojo/flatten/FlattenMojo.java +++ b/src/main/java/org/codehaus/mojo/flatten/FlattenMojo.java @@ -76,6 +76,7 @@ import org.apache.maven.project.MavenProject; import org.apache.maven.settings.Settings; import org.codehaus.mojo.flatten.cifriendly.CiInterpolator; +import org.codehaus.mojo.flatten.extendedinterpolation.ExtendedModelInterpolator; import org.codehaus.mojo.flatten.model.resolution.FlattenModelResolver; import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.xml.Xpp3Dom; @@ -96,7 +97,6 @@ import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; import org.eclipse.aether.util.graph.transformer.ConflictResolver; import org.xml.sax.Attributes; -import org.xml.sax.SAXException; import org.xml.sax.ext.DefaultHandler2; /** @@ -387,7 +387,7 @@ public class FlattenMojo extends AbstractFlattenMojo { * The {@link ModelInterpolator} used to resolve variables. */ @Inject - private ModelInterpolator modelInterpolator; + private ExtendedModelInterpolator extendedModelInterpolator; /** * The {@link ModelInterpolator} used to resolve variables. @@ -569,36 +569,22 @@ protected void writeStringToFile(String data, File file, String encoding) throws */ protected Model createFlattenedPom(File pomFile) throws MojoExecutionException, MojoFailureException { - ModelBuildingRequest buildingRequest = createModelBuildingRequest(pomFile); - Model effectivePom = createEffectivePom(buildingRequest, isEmbedBuildProfileDependencies(), this.flattenMode); + ModelsFactory modelsFactory = new ModelsFactory(pomFile); Model flattenedPom = new Model(); // keep original encoding (we could also normalize to UTF-8 here) - String modelEncoding = effectivePom.getModelEncoding(); + String modelEncoding = modelsFactory.getEffectivePom().getModelEncoding(); if (StringUtils.isEmpty(modelEncoding)) { modelEncoding = "UTF-8"; } flattenedPom.setModelEncoding(modelEncoding); - Model cleanPom; - try { - cleanPom = createCleanPom(effectivePom); - } catch (Exception e) { - throw new MojoExecutionException("failed to create a clean pom", e); - } - FlattenDescriptor descriptor = getFlattenDescriptor(); - Model originalPom = getOriginalModel(); - Model resolvedPom = this.project.getModel(); - Model interpolatedPom = createResolvedPom(buildingRequest); - - // copy the configured additional POM elements... for (PomProperty property : PomProperty.getPomProperties()) { if (property.isElement()) { - Model sourceModel = getSourceModel( - descriptor, property, effectivePom, originalPom, resolvedPom, interpolatedPom, cleanPom); + Model sourceModel = getSourceModel(descriptor, property, modelsFactory); if (sourceModel == null) { if (property.isRequired()) { throw new MojoFailureException( @@ -613,21 +599,55 @@ protected Model createFlattenedPom(File pomFile) throws MojoExecutionException, return flattenedPom; } - private Model createResolvedPom(ModelBuildingRequest buildingRequest) throws MojoExecutionException { + Model createEffectivePom(ModelBuildingRequest buildingRequest) throws MojoExecutionException { + try { + return createEffectivePomImpl(buildingRequest); + } catch (Exception e) { + throw new MojoExecutionException("failed to create the effective pom", e); + } + } + + private Model createCleanPom(Model effectivePom) throws MojoExecutionException { + try { + return createCleanPomImpl(effectivePom); + } catch (Exception e) { + throw new MojoExecutionException("failed to create a clean pom", e); + } + } + + private Model createInterpolatedPom( + ModelBuildingRequest buildingRequest, Model originalPom, File projectDirectory) { LoggingModelProblemCollector problems = new LoggingModelProblemCollector(getLog()); - Model originalModel = getOriginalModel(); if (this.flattenMode == FlattenMode.resolveCiFriendliesOnly) { return this.modelCiFriendlyInterpolator.interpolateModel( - originalModel, this.project.getModel().getProjectDirectory(), buildingRequest, problems); + originalPom, projectDirectory, buildingRequest, problems); } - return this.modelInterpolator.interpolateModel( - originalModel, this.project.getModel().getProjectDirectory(), buildingRequest, problems); + return extendedModelInterpolator.interpolateModel(originalPom, projectDirectory, buildingRequest, problems); } - private Model getOriginalModel() throws MojoExecutionException { + private Model createExtendedInterpolatedPom( + ModelBuildingRequest buildingRequest, Model originalPom, Model effectivePom, File projectDirectory) { + LoggingModelProblemCollector problems = new LoggingModelProblemCollector(getLog()); + if (this.flattenMode == FlattenMode.resolveCiFriendliesOnly) { + return this.modelCiFriendlyInterpolator.interpolateModel( + originalPom, projectDirectory, buildingRequest, problems); + } + final Model extendedInterpolatedPom = extendedModelInterpolator + .interpolateModel(effectivePom, originalPom, projectDirectory, buildingRequest, problems) + .clone(); + + // interpolate parent explicitly because parent is excluded from interpolation + if (effectivePom.getParent() != null) { + extendedInterpolatedPom.setParent(effectivePom.getParent().clone()); + } + + return extendedInterpolatedPom; + } + + private Model createOriginalPom(File pomFile) throws MojoExecutionException { MavenXpp3Reader reader = new MavenXpp3Reader(); try { - return reader.read(Files.newInputStream(this.project.getFile().toPath())); + return reader.read(Files.newInputStream(pomFile.toPath())); } catch (IOException | XmlPullParserException e) { throw new MojoExecutionException("Error reading raw model.", e); } @@ -642,7 +662,7 @@ private Model getOriginalModel() throws MojoExecutionException { * @return the clean POM. * @throws MojoExecutionException if anything goes wrong. */ - protected Model createCleanPom(Model effectivePom) throws MojoExecutionException { + protected Model createCleanPomImpl(Model effectivePom) throws MojoExecutionException { Model cleanPom = new Model(); cleanPom.setGroupId(effectivePom.getGroupId()); @@ -729,33 +749,12 @@ protected Model createCleanPom(Model effectivePom) throws MojoExecutionException return cleanPom; } - private Model getSourceModel( - FlattenDescriptor descriptor, - PomProperty property, - Model effectivePom, - Model originalPom, - Model resolvedPom, - Model interpolatedPom, - Model cleanPom) { + private Model getSourceModel(FlattenDescriptor descriptor, PomProperty property, ModelsFactory modelsFactory) + throws MojoExecutionException { ElementHandling handling = descriptor.getHandling(property); getLog().debug("Property " + property.getName() + " will be handled using " + handling + " in flattened POM."); - switch (handling) { - case expand: - return effectivePom; - case keep: - return originalPom; - case resolve: - return resolvedPom; - case interpolate: - return interpolatedPom; - case flatten: - return cleanPom; - case remove: - return null; - default: - throw new IllegalStateException(handling.toString()); - } + return modelsFactory.getModel(handling); } /** @@ -776,10 +775,10 @@ protected static List createFlattenedRepositories(List r } return flattenedRepositories; } - return repositories; + return null; } - private FlattenDescriptor getFlattenDescriptor() throws MojoFailureException { + private FlattenDescriptor getFlattenDescriptor() { FlattenDescriptor descriptor = this.pomElements; if (descriptor == null) { FlattenMode mode = this.flattenMode; @@ -873,18 +872,11 @@ private List getReactorModelsFromSession() { /** * Creates the effective POM for the given pomFile trying its best to match the core maven behaviour. * - * @param buildingRequest {@link ModelBuildingRequest} - * @param embedBuildProfileDependencies embed build profiles yes/no. - * @param flattenMode the flattening mode + * @param buildingRequest {@link ModelBuildingRequest} * @return the parsed and calculated effective POM. * @throws MojoExecutionException if anything goes wrong. */ - protected Model createEffectivePom( - ModelBuildingRequest buildingRequest, - final boolean embedBuildProfileDependencies, - final FlattenMode flattenMode) - throws MojoExecutionException { - + protected Model createEffectivePomImpl(ModelBuildingRequest buildingRequest) throws MojoExecutionException { ModelBuildingResult buildingResult; try { ProfileInjector customInjector = (model, profile, request, problems) -> { @@ -1270,7 +1262,95 @@ public boolean isUpdatePomFile() { } return !this.project.getPackaging().equals("pom"); } else { - return this.updatePomFile.booleanValue(); + return this.updatePomFile; + } + } + + private class ModelsFactory { + private final File pomFile; + private Model effectivePom; + private Model originalPom; + private Model resolvedPom; + private Model interpolatedPom; + private Model extendedInterpolatedPom; + private Model cleanPom; + + private ModelsFactory(File pomFile) { + this.pomFile = pomFile; + } + + public Model getEffectivePom() throws MojoExecutionException { + if (effectivePom == null) { + this.effectivePom = FlattenMojo.this + .createEffectivePom(createModelBuildingRequest(pomFile)) + .clone(); + } + return this.effectivePom; + } + + public Model getOriginalPom() throws MojoExecutionException { + if (this.originalPom == null) { + this.originalPom = createOriginalPom(this.pomFile); + } + return this.originalPom; + } + + public Model getResolvedPom() { + if (this.resolvedPom == null) { + this.resolvedPom = FlattenMojo.this.project.getModel(); + } + return this.resolvedPom; + } + + public Model getInterpolatedPom() throws MojoExecutionException { + if (this.interpolatedPom == null) { + this.interpolatedPom = createInterpolatedPom( + createModelBuildingRequest(pomFile), + getOriginalPom().clone(), + getResolvedPom().getProjectDirectory()) + .clone(); + } + return this.interpolatedPom; + } + + public Model getExtendedInterpolatedPom() throws MojoExecutionException { + if (this.extendedInterpolatedPom == null) { + this.extendedInterpolatedPom = createExtendedInterpolatedPom( + createModelBuildingRequest(pomFile), + getOriginalPom().clone(), + getEffectivePom().clone(), + getResolvedPom().getProjectDirectory()) + .clone(); + } + return this.extendedInterpolatedPom; + } + + public Model getCleanPom() throws MojoExecutionException { + if (this.cleanPom == null) { + this.cleanPom = createCleanPom(getEffectivePom().clone()).clone(); + } + return this.cleanPom; + } + + public Model getModel(ElementHandling handling) throws MojoExecutionException { + switch (handling) { + case expand: + return this.getEffectivePom(); + case keep: + return this.getOriginalPom(); + case resolve: + return this.getResolvedPom(); + case interpolate: + return this.getInterpolatedPom(); + case extended_interpolate: + return this.getExtendedInterpolatedPom(); + case flatten: + return this.getCleanPom(); + case remove: + return null; + default: + throw new IllegalStateException(handling.toString()); + } } } @@ -1311,7 +1391,7 @@ public String getHeaderComment() { * {@inheritDoc} */ @Override - public void comment(char[] ch, int start, int length) throws SAXException { + public void comment(char[] ch, int start, int length) { if (!this.rootTagSeen) { if (this.headerComment == null) { @@ -1326,7 +1406,7 @@ public void comment(char[] ch, int start, int length) throws SAXException { * {@inheritDoc} */ @Override - public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { + public void startElement(String uri, String localName, String qName, Attributes attrs) { this.rootTagSeen = true; } diff --git a/src/main/java/org/codehaus/mojo/flatten/extendedinterpolation/ExtendedModelInterpolator.java b/src/main/java/org/codehaus/mojo/flatten/extendedinterpolation/ExtendedModelInterpolator.java new file mode 100644 index 00000000..f7d3c2c6 --- /dev/null +++ b/src/main/java/org/codehaus/mojo/flatten/extendedinterpolation/ExtendedModelInterpolator.java @@ -0,0 +1,17 @@ +package org.codehaus.mojo.flatten.extendedinterpolation; + +import java.io.File; + +import org.apache.maven.model.Model; +import org.apache.maven.model.building.ModelBuildingRequest; +import org.apache.maven.model.building.ModelProblemCollector; +import org.apache.maven.model.interpolation.ModelInterpolator; + +public interface ExtendedModelInterpolator extends ModelInterpolator { + Model interpolateModel( + Model effectiveModel, + Model model, + File projectDir, + ModelBuildingRequest config, + ModelProblemCollector problems); +} diff --git a/src/main/java/org/codehaus/mojo/flatten/extendedinterpolation/ExtendedModelInterpolatorException.java b/src/main/java/org/codehaus/mojo/flatten/extendedinterpolation/ExtendedModelInterpolatorException.java new file mode 100644 index 00000000..e2eea829 --- /dev/null +++ b/src/main/java/org/codehaus/mojo/flatten/extendedinterpolation/ExtendedModelInterpolatorException.java @@ -0,0 +1,7 @@ +package org.codehaus.mojo.flatten.extendedinterpolation; + +public class ExtendedModelInterpolatorException extends RuntimeException { + public ExtendedModelInterpolatorException(Throwable cause) { + super(cause.getMessage(), cause); + } +} diff --git a/src/main/java/org/codehaus/mojo/flatten/extendedinterpolation/ExtendedStringSearchModelInterpolator.java b/src/main/java/org/codehaus/mojo/flatten/extendedinterpolation/ExtendedStringSearchModelInterpolator.java new file mode 100644 index 00000000..f733759a --- /dev/null +++ b/src/main/java/org/codehaus/mojo/flatten/extendedinterpolation/ExtendedStringSearchModelInterpolator.java @@ -0,0 +1,79 @@ +package org.codehaus.mojo.flatten.extendedinterpolation; + +import javax.inject.Named; + +import java.io.File; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.apache.maven.model.Model; +import org.apache.maven.model.building.ModelBuildingRequest; +import org.apache.maven.model.building.ModelProblemCollector; +import org.apache.maven.model.interpolation.StringSearchModelInterpolator; +import org.codehaus.plexus.interpolation.ValueSource; + +@Named +public class ExtendedStringSearchModelInterpolator extends StringSearchModelInterpolator + implements ExtendedModelInterpolator { + + private static final List NOT_INTERPOLATABLES = Stream.of( + "basedir", + "baseUri", + "build.directory", + "build.outputDirectory", + "build.sourceDirectory", + "build.scriptSourceDirectory", + "build.testSourceDirectory", + "reporting.outputDirectory") + .flatMap(suffix -> Stream.of(suffix, "pom." + suffix, "project." + suffix)) + .collect(Collectors.toList()); + + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + private Optional valueSourceOriginModel = Optional.empty(); + + public ExtendedStringSearchModelInterpolator() { + FilteringValueSourceWrapper.setClassLoader(getClass().getSuperclass().getClassLoader()); + } + + @Override + protected List createValueSources( + Model model, File projectDir, ModelBuildingRequest config, ModelProblemCollector problems) { + + if (valueSourceOriginModel.isPresent()) { + return FilteringValueSourceWrapper.wrap( + super.createValueSources(this.valueSourceOriginModel.get(), projectDir, config, problems), + this::interpolatable); + } + return super.createValueSources(model, projectDir, config, problems); + } + + private boolean interpolatable(String expression) { + + return !NOT_INTERPOLATABLES.contains(expression); + } + + @Override + public Model interpolateModel( + Model valueSourceOriginModel, + Model model, + File projectDir, + ModelBuildingRequest config, + ModelProblemCollector problems) { + if (valueSourceOriginModel == null) { + throw new IllegalArgumentException("effectiveModel is null"); + } + + if (model == null) { + throw new IllegalArgumentException("model is null"); + } + + this.valueSourceOriginModel = Optional.of(valueSourceOriginModel); + try { + return super.interpolateModel(model, projectDir, config, problems); + } finally { + this.valueSourceOriginModel = Optional.empty(); + } + } +} diff --git a/src/main/java/org/codehaus/mojo/flatten/extendedinterpolation/FilteringValueSourceWrapper.java b/src/main/java/org/codehaus/mojo/flatten/extendedinterpolation/FilteringValueSourceWrapper.java new file mode 100644 index 00000000..6013e110 --- /dev/null +++ b/src/main/java/org/codehaus/mojo/flatten/extendedinterpolation/FilteringValueSourceWrapper.java @@ -0,0 +1,60 @@ +package org.codehaus.mojo.flatten.extendedinterpolation; + +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import org.codehaus.plexus.interpolation.ValueSource; + +public class FilteringValueSourceWrapper { + + private static ClassLoader classLoader; + private final Object delegate; + private final Predicate filter; + private final Class valueSourceClass; + + private FilteringValueSourceWrapper(Object delegate, Predicate expressionFilter) { + this.delegate = delegate; + this.filter = expressionFilter; + try { + this.valueSourceClass = classLoader.loadClass(ValueSource.class.getName()); + } catch (Exception e) { + throw new ExtendedModelInterpolatorException(e); + } + } + + public static void setClassLoader(ClassLoader classLoader) { + FilteringValueSourceWrapper.classLoader = classLoader; + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + public static List wrap(List valueSources, Predicate expressionFilter) { + return (List) new ArrayList(valueSources) + .stream() + .map(vs -> FilteringValueSourceWrapper.wrap(vs, expressionFilter)) + .collect(Collectors.toList()); + } + + public static Object wrap(Object valueSource, Predicate expressionFilter) { + + return new FilteringValueSourceWrapper(valueSource, expressionFilter).asProxy(); + } + + public Object asProxy() { + + return Proxy.newProxyInstance(classLoader, new Class[] {this.valueSourceClass}, (proxy, method, args) -> { + if (method.getName().equals("getValue")) { + if (args.length != 1 || (args[0] != null && !(args[0] instanceof String))) { + throw new InternalError( + "The class " + valueSourceClass.getName() + " got a changed getValue method: " + method); + } + if (!filter.test((String) args[0])) { + return null; + } + } + return method.invoke(this.delegate, args); + }); + } +} diff --git a/src/test/java/org/codehaus/mojo/flatten/CreateEffectivePomTest.java b/src/test/java/org/codehaus/mojo/flatten/CreateEffectivePomTest.java index e7bee870..5e97aa14 100644 --- a/src/test/java/org/codehaus/mojo/flatten/CreateEffectivePomTest.java +++ b/src/test/java/org/codehaus/mojo/flatten/CreateEffectivePomTest.java @@ -80,7 +80,7 @@ public void testCreateEffectivePom() throws Exception { FlattenMojo tested = (FlattenMojo) rule.lookupConfiguredMojo(mavenProject, "flatten"); rule.setVariableValueToObject( tested, "modelBuilderThreadSafetyWorkaround", buildModelBuilderThreadSafetyWorkaroundForTest()); - Model effectivePom = tested.createEffectivePom(buildingRequest, false, FlattenMode.defaults); + Model effectivePom = tested.createEffectivePom(buildingRequest); assertThat(effectivePom.getName()).isEqualTo(magicValue); }