From a256b6e0dc93c897eda43ee2a2f47cc92806eadc Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Sun, 14 Nov 2021 18:43:39 -0500 Subject: [PATCH 001/153] First Version --- .gitignore | 86 +++ .idea/.gitignore | 10 + .idea/codeStyles/Project.xml | 620 ++++++++++++++++++ .idea/codeStyles/codeStyleConfig.xml | 6 + .idea/compiler.xml | 13 + .idea/encodings.xml | 6 + .idea/jarRepositories.xml | 20 + .idea/misc.xml | 12 + .idea/runConfigurations.xml | 10 + README.md | 25 + pom.xml | 171 +++++ .../java/br/com/ingenieux/pom/operator/App.kt | 50 ++ .../com/ingenieux/pom/operator/POMOperator.kt | 113 ++++ .../br/com/ingenieux/pom/operator/BaseTest.kt | 60 ++ .../ingenieux/pom/operator/POMOperatorTest.kt | 61 ++ .../br/com/ingenieux/pom/operator/pom-1.xml | 151 +++++ .../br/com/ingenieux/pom/operator/pom-2.xml | 507 ++++++++++++++ 17 files changed, 1921 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/compiler.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/runConfigurations.xml create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/java/br/com/ingenieux/pom/operator/App.kt create mode 100644 src/main/java/br/com/ingenieux/pom/operator/POMOperator.kt create mode 100644 src/test/java/br/com/ingenieux/pom/operator/BaseTest.kt create mode 100644 src/test/java/br/com/ingenieux/pom/operator/POMOperatorTest.kt create mode 100644 src/test/resources/br/com/ingenieux/pom/operator/pom-1.xml create mode 100644 src/test/resources/br/com/ingenieux/pom/operator/pom-2.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..cdf6b5c3c --- /dev/null +++ b/.gitignore @@ -0,0 +1,86 @@ +### Maven template +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +# https://github.com/takari/maven-wrapper#usage-without-binary-jar +.mvn/wrapper/maven-wrapper.jar + +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 000000000..11bd5c0e3 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Zeppelin ignored files +/ZeppelinRemoteNotebooks/ diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 000000000..66c829eed --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,620 @@ + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 000000000..3c617fb8f --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 000000000..b32030a25 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 000000000..63e900193 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 000000000..712ab9d98 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 000000000..d5cd61439 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 000000000..797acea53 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 000000000..76d84944e --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ + +## Tasks + + * Sample POM files to try out (and use as tests) + * Test Cases + * Docopt-ify + * Mac/Win/Linux utilities?) + +## Goals + +I want to insert a dependency into the pom.xml files in my repositories in my organization. + +I want a Java library that helps me inject this dependency into a repository already-checked out on disk. There are multiple cases that we must account for. + +1. They already have a "dependencies" section with the given dependency in it, so it doesn't have to be inserted. + +2. One of their parent POMs already has the "dependency" and it is inherited in the child POM, so it doesn't have to be inserted. + +3. The POM has the dependency, but the version they have is behind, so it needs to be replaced. + +4. The POM doesn't have a "dependencies" section or inheritance so we need to inject that section as well as the "dependency" section. + +5. The POM doesn't have the dependency or inherit it, so it needs to be inserted. + +I imagine this is mostly XSLT but also need some analysis of the Maven model in order to understand if the dependency is inherited. \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..c3151e819 --- /dev/null +++ b/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + pom-operator + + http://www.example.com + + + UTF-8 + 1.8 + 1.8 + 1.5.31 + + + + + org.apache.commons + commons-lang3 + 3.7 + + + org.dom4j + dom4j + 2.1.3 + + + jaxen + jaxen + 1.2.0 + + + xerces + xercesImpl + 2.12.1 + + + io.github.java-diff-utils + java-diff-utils + 4.9 + test + + + org.xmlunit + xmlunit-core + 2.8.3 + test + + + org.hamcrest + hamcrest-all + 1.3 + test + + + junit + junit + 4.11 + test + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + org.apache.maven.plugins + maven-compiler-plugin + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + + + diff --git a/src/main/java/br/com/ingenieux/pom/operator/App.kt b/src/main/java/br/com/ingenieux/pom/operator/App.kt new file mode 100644 index 000000000..819f0db58 --- /dev/null +++ b/src/main/java/br/com/ingenieux/pom/operator/App.kt @@ -0,0 +1,50 @@ +package br.com.ingenieux.pom.operator + + +/** + * Hello world! + * + */ +object App { + @JvmStatic + fun main(args: Array) { +// val xmlReader = SAXReader() +// +// val file = File("pom.xml") +// +// val originalContent = file.readText() +// +// val doc = xmlReader.read(originalContent.byteInputStream()) +// +// val testNodes = doc.selectNodes("/*[local-name()='project']/*[local-name()='dependencies']/*[local-name()='dependency']") +// +// val nodes = doc.selectNodes("/*[local-name()='project']/*[local-name()='dependencies']/*[local-name()='dependency'][./*[local-name()='groupId'][text()='jaxen'] and ./*[local-name()='artifactId'][text()='jaxen']]/*[local-name()='version']") +// +// nodes[0].text = "1.1.6" +// +// val result = doc.asXML() +// +// val diff = DiffUtils.diff(originalContent, result, null) +// +// println(diff) +// + /* + // TODO: At some point write main flow and CLI App (see docopt) + val registry = DOMImplementationRegistry.newInstance() + val domImplementationLS = registry.getDOMImplementation("LS") as DOMImplementationLS + val builder = domImplementationLS.createLSParser( + DOMImplementationLS.MODE_SYNCHRONOUS, null) + val document = builder.parseURI("pom.xml") + + + + val writer: LSSerializer = domImplementationLS.createLSSerializer() + + val str = writer.writeToString(document) + + println(str) + */ + + + } +} \ No newline at end of file diff --git a/src/main/java/br/com/ingenieux/pom/operator/POMOperator.kt b/src/main/java/br/com/ingenieux/pom/operator/POMOperator.kt new file mode 100644 index 000000000..fed361372 --- /dev/null +++ b/src/main/java/br/com/ingenieux/pom/operator/POMOperator.kt @@ -0,0 +1,113 @@ +package br.com.ingenieux.pom.operator + +import org.apache.commons.lang3.builder.EqualsBuilder +import org.dom4j.Document +import java.lang.IllegalStateException + +data class Dependency( + val groupId: String, + val artifactId: String, + val version: String? = null, + val classifier: String? = null, + val packaging: String? = "jar" +) { + fun matchesOther(dep: Dependency): Boolean { + val equalsBuilder = EqualsBuilder().append(this.groupId, dep.groupId) + .append(this.artifactId, dep.artifactId) + + if (null != classifier) { + equalsBuilder.append(this.classifier, dep.classifier) + } + + if (null != packaging) { + equalsBuilder.append(this.packaging, dep.packaging) + } + + return equalsBuilder.isEquals + } +} + +object POMOperator { + fun upgradePom(pom: Document, dependencyToUpgrade: Dependency): Document { + val doc = pom.clone() as Document + + if (simpleUpgrade(doc, dependencyToUpgrade)) { + return doc + } + + if (simpleDependencyManagementUpgrade(doc, dependencyToUpgrade)) { + return doc + } + + throw IllegalStateException("Unable to upgrade dependency") + } + + private fun simpleUpgrade(doc: Document, dependencyToUpgrade: Dependency): Boolean { + val lookupExpressionForDependency = buildLookupExpressionForDependency(dependencyToUpgrade) + + return upgradeDependency(doc, lookupExpressionForDependency, dependencyToUpgrade) + } + + private fun simpleDependencyManagementUpgrade(doc: Document, dependencyToUpgrade: Dependency): Boolean { + val lookupExpressionForDependency = buildLookupExpressionForDependencyManagement(dependencyToUpgrade) + + return upgradeDependency(doc, lookupExpressionForDependency, dependencyToUpgrade) + } + + private fun upgradeDependency( + doc: Document, + lookupExpression: String, + dep: Dependency + ): Boolean { + val dependencyNodes = doc.selectNodes(lookupExpression) + + if (1 == dependencyNodes.size) { + val versionNodes = dependencyNodes[0]!!.selectNodes("./*[local-name()='version']") + + if (1 == versionNodes.size) { + versionNodes[0].text = dep.version + + return true + } + } + + return false + } + + private fun buildLookupExpressionForDependency(dependency: Dependency) = + "/*[local-name()='project']" + + "/*[local-name()='dependencies']" + + "/*[local-name()='dependency']" + + /* */ "[./*[local-name()='groupId'][text()='${dependency.groupId}'] and " + + /* */ "./*[local-name()='artifactId'][text()='${dependency.artifactId}']" + + "]" + private fun buildLookupExpressionForDependencyManagement(dependency: Dependency) = + "/*[local-name()='project']" + + "/*[local-name()='dependencyManagement']" + + "/*[local-name()='dependencies']" + + "/*[local-name()='dependency']" + + /* */ "[./*[local-name()='groupId'][text()='${dependency.groupId}'] and " + + /* */ "./*[local-name()='artifactId'][text()='${dependency.artifactId}']" + + "]" + +// // "/*[local-name()='project']/*[local-name()='dependencies']/*[local-name()='dependency']" +// private fun selectDependencyNodes(doc: Document, expr: String): List +// { +// val expandedWithNamespaces = expandNS(expr) +// val result = doc.selectNodes(expandedWithNamespaces) +// return result +// } +// +// private fun expandNS(xpathExpr: String): String { +// val exprBuilder = StringBuilder() +// +// for (element: String in xpathExpr.substring(1).split("/")) { +// val whatToAppend = element.replace(Regex("""^(\w+)(.*)""")) { matchResult -> +// "/*[local-name()='${matchResult.groups[1]!!.value}']${matchResult.groups[2]!!.value}" +// } +// exprBuilder.append(whatToAppend) +// } +// +// return exprBuilder.toString() +// } +} \ No newline at end of file diff --git a/src/test/java/br/com/ingenieux/pom/operator/BaseTest.kt b/src/test/java/br/com/ingenieux/pom/operator/BaseTest.kt new file mode 100644 index 000000000..b42328d9e --- /dev/null +++ b/src/test/java/br/com/ingenieux/pom/operator/BaseTest.kt @@ -0,0 +1,60 @@ +package br.com.ingenieux.pom.operator + +import org.dom4j.Document +import org.dom4j.io.SAXReader +import org.xmlunit.builder.DiffBuilder +import org.xmlunit.builder.Input +import org.xmlunit.diff.Diff +import java.io.File +import java.io.FileInputStream +import java.io.InputStreamReader +import java.lang.IllegalStateException +import javax.annotation.processing.ProcessingEnvironment + +open class BaseTest { + protected fun readPom(path: String, effectivePom: Boolean = false): Document { + val pomDoc = if (effectivePom) { + val resourceURI = javaClass.getResource(path).toURI() + + val absPath = File(resourceURI).absolutePath + + val tmpOutputFile = File.createTempFile("tmp-pom", ".xml") + + val psBuilder = ProcessBuilder( + "mvn", + "-N", + "-o", + "-f", + absPath, + "help:effective-pom", + "-Doutput=${tmpOutputFile.absolutePath}" + ).inheritIO() + + psBuilder.environment().putAll(System.getenv()) + + val process = psBuilder.start() + + val retCode = process.waitFor() + + if (0 != retCode) + throw IllegalStateException("Unexpected return code from maven: $retCode") + + InputStreamReader(FileInputStream(tmpOutputFile)) + } else { + InputStreamReader(javaClass.getResourceAsStream(path)) + } + + return SAXReader().read(pomDoc)!! + } + + protected fun getDifferences( + original: Document, + modified: Document + ): Diff? { + val originalDoc = Input.fromString(original.asXML()).build() + val modifiedDoc = Input.fromString(modified.asXML()).build() + + val diff = DiffBuilder.compare(originalDoc).withTest(modifiedDoc).build() + return diff + } +} diff --git a/src/test/java/br/com/ingenieux/pom/operator/POMOperatorTest.kt b/src/test/java/br/com/ingenieux/pom/operator/POMOperatorTest.kt new file mode 100644 index 000000000..0a98d303a --- /dev/null +++ b/src/test/java/br/com/ingenieux/pom/operator/POMOperatorTest.kt @@ -0,0 +1,61 @@ +package br.com.ingenieux.pom.operator + +import org.dom4j.Document +import org.hamcrest.MatcherAssert.assertThat +import org.junit.Test +import org.xmlunit.diff.ComparisonType +import java.lang.IllegalStateException + +/** + * Unit test for simple App. + */ +class POMOperatorTest : BaseTest() { + @Test + fun testSimplePOMUpgrade() { + val pomDocument = readPom("pom-1.xml") + + val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.3") + + pomUpgradeAndAssert(pomDocument, dependencyToUpgrade) + } + + @Test + fun testComplexPOMUpgrade() { + val pomDocument = readPom("pom-2.xml", effectivePom = true) + + val dependencyToUpgrade = Dependency("junit", "junit", version = "4.13") + + pomUpgradeAndAssert(pomDocument, dependencyToUpgrade) + } + + @Test(expected = IllegalStateException::class) + fun testMissingPomChange() { + val pomDocument = readPom("pom-2.xml") + + val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.3") + + POMOperator.upgradePom(pomDocument, dependencyToUpgrade) + } + + private fun pomUpgradeAndAssert( + pomDocument: Document, + dependencyToUpgrade: Dependency + ) { + val changedPom = POMOperator.upgradePom(pomDocument, dependencyToUpgrade) + + val diff = getDifferences(pomDocument, changedPom) + + val oDiff = diff!! + + assertThat("Document has differences", oDiff.hasDifferences()) + assertThat("Document has a single difference", oDiff.differences.toList().size == 1) + assertThat( + "Document has different versions", + oDiff.differences.toList()[0].comparison.type == ComparisonType.TEXT_VALUE + ) + assertThat( + "Document has changed version set to ${dependencyToUpgrade.version}", + oDiff.differences.toList()[0].comparison.testDetails.value == dependencyToUpgrade.version + ) + } +} \ No newline at end of file diff --git a/src/test/resources/br/com/ingenieux/pom/operator/pom-1.xml b/src/test/resources/br/com/ingenieux/pom/operator/pom-1.xml new file mode 100644 index 000000000..a387102e2 --- /dev/null +++ b/src/test/resources/br/com/ingenieux/pom/operator/pom-1.xml @@ -0,0 +1,151 @@ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + pom-operator + + http://www.example.com + + + UTF-8 + 1.8 + 1.8 + 1.5.31 + + + + + org.dom4j + dom4j + 2.1.3 + + + jaxen + jaxen + 1.2.0 + + + xerces + xercesImpl + 2.12.1 + + + io.github.java-diff-utils + java-diff-utils + 4.9 + + + junit + junit + 4.11 + test + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + org.apache.maven.plugins + maven-compiler-plugin + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + + + diff --git a/src/test/resources/br/com/ingenieux/pom/operator/pom-2.xml b/src/test/resources/br/com/ingenieux/pom/operator/pom-2.xml new file mode 100644 index 000000000..5ea271b5f --- /dev/null +++ b/src/test/resources/br/com/ingenieux/pom/operator/pom-2.xml @@ -0,0 +1,507 @@ + + 4.0.0 + + + org.codehaus.mojo + mojo-parent + 63 + + + versions-maven-plugin + 2.9-SNAPSHOT + maven-plugin + + Versions Maven Plugin + http://www.mojohaus.org/versions-maven-plugin/ + + Versions Plugin for Maven. The Versions Plugin updates the versions of components in the POM. + + 2008 + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + Stephen Connolly + stephenconnolly at codehaus + + Lead Developer + + 0 + + + Paul Gier + pgier at redhat + + Developer + + + + Arnaud Heritier + aheritier at apache + + Developer + + +1 + + + + + Benoit Lafontaine + +1 + + + Martin Franklin + + + Tom Folga + + + Eric Pabst + + + Stefan Seelmann + + + Clement Denis + + + Erik Schepers + + + Anton Johansson + antoon.johansson@gmail.com + +1 + + + + + 3.0 + + + + scm:git:https://github.com/mojohaus/versions-maven-plugin.git + scm:git:ssh://git@github.com/mojohaus/versions-maven-plugin.git + https://github.com/mojohaus/versions-maven-plugin/tree/${project.scm.tag} + versions-maven-plugin-2.8.1 + + + github + https://github.com/mojohaus/versions-maven-plugin/issues/ + + + + 1.8 + ${mojo.java.target} + 5.8.1 + 3.0.5 + 3.4.0 + 1.10 + 1.10 + ${project.version} + 3.7 + 2020-08-07T21:31:00Z + + + + + + org.junit + junit-bom + ${junitBomVersion} + pom + import + + + + + + + org.apache.maven.plugin-tools + maven-plugin-annotations + 3.6.1 + provided + + + + org.apache.maven + maven-artifact + ${mavenVersion} + + + org.apache.maven + maven-core + ${mavenVersion} + + + org.apache.maven + maven-compat + ${mavenVersion} + + + org.apache.maven + maven-model + ${mavenVersion} + + + org.apache.maven + maven-plugin-api + ${mavenVersion} + + + org.apache.maven + maven-settings + ${mavenVersion} + + + org.apache.maven.reporting + maven-reporting-api + 3.0 + + + org.apache.maven.reporting + maven-reporting-impl + 3.0.0 + + + org.apache.maven.shared + maven-common-artifact-filters + 3.2.0 + + + org.apache.maven.wagon + wagon-provider-api + ${wagonVersion} + + + org.apache.maven.wagon + wagon-file + ${wagonVersion} + + + + + org.apache.maven.doxia + doxia-core + ${doxiaVersion} + + + org.apache.maven.doxia + doxia-sink-api + ${doxiaVersion} + + + + + org.apache.maven.doxia + doxia-site-renderer + ${doxia-sitetoolsVersion} + + + org.codehaus.plexus + plexus-container-default + + + org.codehaus.plexus + plexus-component-api + + + + + + org.codehaus.plexus + plexus-utils + 3.4.1 + + + org.codehaus.plexus + plexus-container-default + 2.1.0 + + + org.codehaus.plexus + plexus-interactivity-api + 1.1 + + + plexus-container-default + org.codehaus.plexus + + + + + com.fasterxml.woodstox + woodstox-core + 6.2.6 + + + org.apache.commons + commons-lang3 + 3.12.0 + + + org.junit.jupiter + junit-jupiter + test + + + org.junit.vintage + junit-vintage-engine + test + + + org.hamcrest + hamcrest-core + + + + + org.mockito + mockito-core + 3.12.4 + test + + + org.hamcrest + hamcrest + 2.2 + test + + + + + + + + org.codehaus.modello + modello-maven-plugin + 1.11 + + + + + + org.apache.maven.plugins + maven-plugin-plugin + + true + + + + + helpmojo + descriptor + + + + + + org.codehaus.mojo + animal-sniffer-maven-plugin + + + check-java18 + test + + check + + + + org.codehaus.mojo.signature + java18 + 1.0 + + + + + + + org.codehaus.modello + modello-maven-plugin + + + generate-sources + generate-sources + + + xpp3-reader + + xpp3-writer + + java + + + + site-doc + pre-site + + xdoc + + + + site-xsd + pre-site + + xsd + + + ${project.build.directory}/generated-site/resources/xsd + + + + + + src/main/mdo/rule.mdo + + 2.0.0 + true + + + + org.codehaus.mojo + mrm-maven-plugin + 1.2.0 + + + + start + stop + + + + + repository.proxy.url + + + src/it-repo + + + + + + + org.apache.maven.plugins + maven-invoker-plugin + + src/it + ${project.build.directory}/it + ${project.build.directory}/local-repo + src/it/settings.xml + true + true + + 1 + + */pom.xml + + verify + + ${repository.proxy.url} + + -Xmx256m + + + + maven-javadoc-plugin + + + + org.codehaus.mojo.versions.model, + org.codehaus.mojo.versions.model.io.xpp3 + + + + + + + + + + maven-javadoc-plugin + + ${mojo.java.target} + + + + maven-invoker-plugin + + + + report + + + + + + org.codehaus.mojo + versions-maven-plugin + 2.7 + + + + dependency-updates-report + plugin-updates-report + property-updates-report + + + + + + + + + + + run-its + + verify + + + org.apache.maven.plugins + maven-invoker-plugin + + + integration-test + + install + run + + + false + true + + + + + + + + + + org.apache.maven.plugins + maven-invoker-plugin + + + + report + + + + + + + + + From bc26c312063fe18259f71e822c5e5c9a7c51bcc8 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Thu, 18 Nov 2021 10:28:53 -0500 Subject: [PATCH 002/153] Changes --- .idea/vcs.xml | 6 + pom-orig.xml | 439 ++++++++++++++++++ pom.xml | 86 ++++ .../java/br/com/ingenieux/pom/operator/App.kt | 62 ++- .../com/ingenieux/pom/operator/POMOperator.kt | 62 +++ .../br/com/ingenieux/pom/operator/BaseTest.kt | 35 -- .../ingenieux/pom/operator/POMOperatorTest.kt | 9 +- .../br/com/ingenieux/pom/operator/pom-1.xml | 3 +- 8 files changed, 626 insertions(+), 76 deletions(-) create mode 100644 .idea/vcs.xml create mode 100644 pom-orig.xml diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 000000000..94a25f7f4 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/pom-orig.xml b/pom-orig.xml new file mode 100644 index 000000000..f5e1dbd8a --- /dev/null +++ b/pom-orig.xml @@ -0,0 +1,439 @@ + + + 4.0.0 + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + pom-operator + http://www.example.com + + 1.5.31 + 1.8 + 1.8 + UTF-8 + + + + com.offbytwo + docopt + 0.6.0.20150202 + compile + + + org.apache.commons + commons-lang3 + 3.7 + compile + + + org.dom4j + dom4j + 2.1.3 + compile + + + jaxen + jaxen + 1.2.0 + compile + + + xerces + xercesImpl + 2.12.1 + compile + + + io.github.java-diff-utils + java-diff-utils + 4.9 + test + + + org.xmlunit + xmlunit-core + 2.8.3 + test + + + org.hamcrest + hamcrest-all + 1.3 + test + + + junit + junit + 4.11 + test + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + 1.5.31 + compile + + + org.jetbrains.kotlin + kotlin-test + 1.5.31 + test + + + + + + false + + central + Central Repository + https://repo.maven.apache.org/maven2 + + + + + + never + + + false + + central + Central Repository + https://repo.maven.apache.org/maven2 + + + + /home/aldrin/projetos/sources/pom-operator/src/main/java + /home/aldrin/projetos/sources/pom-operator/src/main/scripts + /home/aldrin/projetos/sources/pom-operator/src/test/java + /home/aldrin/projetos/sources/pom-operator/target/classes + /home/aldrin/projetos/sources/pom-operator/target/test-classes + + + /home/aldrin/projetos/sources/pom-operator/src/main/resources + + + + + /home/aldrin/projetos/sources/pom-operator/src/test/resources + + + /home/aldrin/projetos/sources/pom-operator/target + pom-operator-0.0.1-SNAPSHOT + + + + maven-antrun-plugin + 1.3 + + + maven-assembly-plugin + 2.2-beta-5 + + + maven-dependency-plugin + 2.8 + + + maven-release-plugin + 2.5.3 + + + maven-clean-plugin + 3.1.0 + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + 1.5.31 + + + compile + compile + + compile + + + 1.8 + + + + test-compile + test-compile + + test-compile + + + 1.8 + + + + + 1.8 + + + + maven-compiler-plugin + 3.8.0 + + + default-compile + compile + + compile + + + + default-testCompile + test-compile + + testCompile + + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + + maven-clean-plugin + 3.1.0 + + + default-clean + clean + + clean + + + + + + maven-resources-plugin + 3.0.2 + + + default-testResources + process-test-resources + + testResources + + + + default-resources + process-resources + + resources + + + + + + maven-jar-plugin + 3.0.2 + + + default-jar + package + + jar + + + + + + maven-surefire-plugin + 2.22.1 + + + default-test + test + + test + + + + + + maven-install-plugin + 2.5.2 + + + default-install + install + + install + + + + + + maven-deploy-plugin + 2.8.2 + + + default-deploy + deploy + + deploy + + + + + + maven-site-plugin + 3.7.1 + + + default-site + site + + site + + + /home/aldrin/projetos/sources/pom-operator/target/site + + + org.apache.maven.plugins + maven-project-info-reports-plugin + + + + + + default-deploy + site-deploy + + deploy + + + /home/aldrin/projetos/sources/pom-operator/target/site + + + org.apache.maven.plugins + maven-project-info-reports-plugin + + + + + + + /home/aldrin/projetos/sources/pom-operator/target/site + + + org.apache.maven.plugins + maven-project-info-reports-plugin + + + + + + + + /home/aldrin/projetos/sources/pom-operator/target/site + + + + exec-jar + + + + maven-shade-plugin + 2.4.3 + + + package + + shade + + + + + + br.com.ingenieux.pom.operator.App + + + false + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + + org.skife.maven + really-executable-jar-maven-plugin + 1.4.1 + + + package + + really-executable-jar + + + + + -Xmx1G + pom-operator + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index c3151e819..46c1c221a 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,11 @@ + + com.offbytwo + docopt + 0.6.0.20150202 + org.apache.commons commons-lang3 @@ -168,4 +173,85 @@ + + + + exec-jar + + + + + org.apache.maven.plugins + maven-shade-plugin + 2.4.3 + + + package + + shade + + + + + + + + + br.com.ingenieux.pom.operator.App + + + false + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + + + + org.skife.maven + really-executable-jar-maven-plugin + 1.4.1 + + + + -Xmx1G + + + + pom-operator + + + + + + + + + + + + + package + + really-executable-jar + + + + + + + + diff --git a/src/main/java/br/com/ingenieux/pom/operator/App.kt b/src/main/java/br/com/ingenieux/pom/operator/App.kt index 819f0db58..af26cd51a 100644 --- a/src/main/java/br/com/ingenieux/pom/operator/App.kt +++ b/src/main/java/br/com/ingenieux/pom/operator/App.kt @@ -1,5 +1,9 @@ package br.com.ingenieux.pom.operator +import br.com.ingenieux.pom.operator.POMOperator.readPomFile +import org.docopt.Docopt +import java.io.File + /** * Hello world! @@ -8,43 +12,29 @@ package br.com.ingenieux.pom.operator object App { @JvmStatic fun main(args: Array) { -// val xmlReader = SAXReader() -// -// val file = File("pom.xml") -// -// val originalContent = file.readText() -// -// val doc = xmlReader.read(originalContent.byteInputStream()) -// -// val testNodes = doc.selectNodes("/*[local-name()='project']/*[local-name()='dependencies']/*[local-name()='dependency']") -// -// val nodes = doc.selectNodes("/*[local-name()='project']/*[local-name()='dependencies']/*[local-name()='dependency'][./*[local-name()='groupId'][text()='jaxen'] and ./*[local-name()='artifactId'][text()='jaxen']]/*[local-name()='version']") -// -// nodes[0].text = "1.1.6" -// -// val result = doc.asXML() -// -// val diff = DiffUtils.diff(originalContent, result, null) -// -// println(diff) -// - /* - // TODO: At some point write main flow and CLI App (see docopt) - val registry = DOMImplementationRegistry.newInstance() - val domImplementationLS = registry.getDOMImplementation("LS") as DOMImplementationLS - val builder = domImplementationLS.createLSParser( - DOMImplementationLS.MODE_SYNCHRONOUS, null) - val document = builder.parseURI("pom.xml") - - - - val writer: LSSerializer = domImplementationLS.createLSSerializer() - - val str = writer.writeToString(document) - - println(str) - */ + val opts = Docopt("""pom-operator 0.0.1 + + Usage: + pom-operator DEPENDENCY POMFILES... + + """.trimIndent()).withVersion("pom-operator 0.0.1").parse(*args) + + //println(opts) + + val dep = Dependency.fromString(opts["DEPENDENCY"]!! as String) + + val files = opts["POMFILES"]!! as List + + for (path in files) { + val pomFile = readPomFile(File(path)) + + println("Upgrading dependency ($dep) in path $path") + + val newPomFileContents = POMOperator.upgradePom(pomFile, dep) + val xmlContent = newPomFileContents.asXML() + File(path).writeText(xmlContent) + } } } \ No newline at end of file diff --git a/src/main/java/br/com/ingenieux/pom/operator/POMOperator.kt b/src/main/java/br/com/ingenieux/pom/operator/POMOperator.kt index fed361372..cca9f937e 100644 --- a/src/main/java/br/com/ingenieux/pom/operator/POMOperator.kt +++ b/src/main/java/br/com/ingenieux/pom/operator/POMOperator.kt @@ -2,6 +2,10 @@ package br.com.ingenieux.pom.operator import org.apache.commons.lang3.builder.EqualsBuilder import org.dom4j.Document +import org.dom4j.io.SAXReader +import java.io.File +import java.io.FileInputStream +import java.io.InputStreamReader import java.lang.IllegalStateException data class Dependency( @@ -11,6 +15,17 @@ data class Dependency( val classifier: String? = null, val packaging: String? = "jar" ) { + companion object { + fun fromString(str: String): Dependency { + val elements = str.split(":") + + if (elements.size < 3) + throw IllegalStateException("Give me 3 elements") + + return Dependency(elements[0], elements[1], elements[2]) + } + } + fun matchesOther(dep: Dependency): Boolean { val equalsBuilder = EqualsBuilder().append(this.groupId, dep.groupId) .append(this.artifactId, dep.artifactId) @@ -28,6 +43,53 @@ data class Dependency( } object POMOperator { + fun readPomFile(file: File): Document { + val pomDoc = readEffectivePom(file) + + return SAXReader().read(pomDoc)!! + } + + fun readResourcePom(path: String, effectivePom: Boolean = false): Document { + val pomDoc = if (effectivePom) { + val resourceURI = javaClass.getResource(path).toURI() + + val resourceFile = File(resourceURI) + + readEffectivePom(resourceFile) + } else { + InputStreamReader(javaClass.getResourceAsStream(path)) + } + + return SAXReader().read(pomDoc)!! + } + + private fun readEffectivePom(resourceFile: File): InputStreamReader { + val absPath = resourceFile.absolutePath + + val tmpOutputFile = File.createTempFile("tmp-pom", ".xml") + + val psBuilder = ProcessBuilder( + "mvn", + "-N", + "-o", + "-f", + absPath, + "help:effective-pom", + "-Doutput=${tmpOutputFile.absolutePath}" + ).inheritIO() + + psBuilder.environment().putAll(System.getenv()) + + val process = psBuilder.start() + + val retCode = process.waitFor() + + if (0 != retCode) + throw IllegalStateException("Unexpected return code from maven: $retCode") + + return InputStreamReader(FileInputStream(tmpOutputFile)) + } + fun upgradePom(pom: Document, dependencyToUpgrade: Dependency): Document { val doc = pom.clone() as Document diff --git a/src/test/java/br/com/ingenieux/pom/operator/BaseTest.kt b/src/test/java/br/com/ingenieux/pom/operator/BaseTest.kt index b42328d9e..3db801a99 100644 --- a/src/test/java/br/com/ingenieux/pom/operator/BaseTest.kt +++ b/src/test/java/br/com/ingenieux/pom/operator/BaseTest.kt @@ -12,41 +12,6 @@ import java.lang.IllegalStateException import javax.annotation.processing.ProcessingEnvironment open class BaseTest { - protected fun readPom(path: String, effectivePom: Boolean = false): Document { - val pomDoc = if (effectivePom) { - val resourceURI = javaClass.getResource(path).toURI() - - val absPath = File(resourceURI).absolutePath - - val tmpOutputFile = File.createTempFile("tmp-pom", ".xml") - - val psBuilder = ProcessBuilder( - "mvn", - "-N", - "-o", - "-f", - absPath, - "help:effective-pom", - "-Doutput=${tmpOutputFile.absolutePath}" - ).inheritIO() - - psBuilder.environment().putAll(System.getenv()) - - val process = psBuilder.start() - - val retCode = process.waitFor() - - if (0 != retCode) - throw IllegalStateException("Unexpected return code from maven: $retCode") - - InputStreamReader(FileInputStream(tmpOutputFile)) - } else { - InputStreamReader(javaClass.getResourceAsStream(path)) - } - - return SAXReader().read(pomDoc)!! - } - protected fun getDifferences( original: Document, modified: Document diff --git a/src/test/java/br/com/ingenieux/pom/operator/POMOperatorTest.kt b/src/test/java/br/com/ingenieux/pom/operator/POMOperatorTest.kt index 0a98d303a..9d2fea07e 100644 --- a/src/test/java/br/com/ingenieux/pom/operator/POMOperatorTest.kt +++ b/src/test/java/br/com/ingenieux/pom/operator/POMOperatorTest.kt @@ -4,7 +4,6 @@ import org.dom4j.Document import org.hamcrest.MatcherAssert.assertThat import org.junit.Test import org.xmlunit.diff.ComparisonType -import java.lang.IllegalStateException /** * Unit test for simple App. @@ -12,7 +11,7 @@ import java.lang.IllegalStateException class POMOperatorTest : BaseTest() { @Test fun testSimplePOMUpgrade() { - val pomDocument = readPom("pom-1.xml") + val pomDocument = POMOperator.readResourcePom("pom-1.xml") val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.3") @@ -21,7 +20,7 @@ class POMOperatorTest : BaseTest() { @Test fun testComplexPOMUpgrade() { - val pomDocument = readPom("pom-2.xml", effectivePom = true) + val pomDocument = POMOperator.readResourcePom("pom-2.xml", effectivePom = true) val dependencyToUpgrade = Dependency("junit", "junit", version = "4.13") @@ -30,7 +29,7 @@ class POMOperatorTest : BaseTest() { @Test(expected = IllegalStateException::class) fun testMissingPomChange() { - val pomDocument = readPom("pom-2.xml") + val pomDocument = POMOperator.readResourcePom("pom-2.xml") val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.3") @@ -43,6 +42,8 @@ class POMOperatorTest : BaseTest() { ) { val changedPom = POMOperator.upgradePom(pomDocument, dependencyToUpgrade) + println(changedPom.asXML()) + val diff = getDifferences(pomDocument, changedPom) val oDiff = diff!! diff --git a/src/test/resources/br/com/ingenieux/pom/operator/pom-1.xml b/src/test/resources/br/com/ingenieux/pom/operator/pom-1.xml index a387102e2..3c20cbb9c 100644 --- a/src/test/resources/br/com/ingenieux/pom/operator/pom-1.xml +++ b/src/test/resources/br/com/ingenieux/pom/operator/pom-1.xml @@ -1,5 +1,6 @@ - + 4.0.0 br.com.ingenieux From 40eaec0c6c288d8e523eaf5812b489edf44c6562 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 22 Nov 2021 08:41:14 -0500 Subject: [PATCH 003/153] Updating --- pom-orig.xml | 439 ------------------ pom.xml | 8 +- .../java/br/com/ingenieux/pom/operator/App.kt | 15 +- .../br/com/ingenieux/pom/operator/Command.kt | 121 +++++ .../br/com/ingenieux/pom/operator/Context.kt | 59 +++ .../com/ingenieux/pom/operator/Dependency.kt | 23 + .../com/ingenieux/pom/operator/POMOperator.kt | 173 +------ .../com/ingenieux/pom/operator/util/Util.kt | 44 ++ .../br/com/ingenieux/pom/operator/BaseTest.kt | 25 - .../ingenieux/pom/operator/POMOperatorTest.kt | 103 ++-- .../pom/operator/{pom-2.xml => pom-3.xml} | 0 .../com/ingenieux/pom/operator/pom-case-1.xml | 21 + .../com/ingenieux/pom/operator/pom-case-3.xml | 152 ++++++ .../com/ingenieux/pom/operator/pom-case-4.xml | 229 +++++++++ .../ingenieux/pom/operator/webgoat-parent.xml | 291 ++++++++++++ 15 files changed, 1025 insertions(+), 678 deletions(-) delete mode 100644 pom-orig.xml create mode 100644 src/main/java/br/com/ingenieux/pom/operator/Command.kt create mode 100644 src/main/java/br/com/ingenieux/pom/operator/Context.kt create mode 100644 src/main/java/br/com/ingenieux/pom/operator/Dependency.kt create mode 100644 src/main/java/br/com/ingenieux/pom/operator/util/Util.kt delete mode 100644 src/test/java/br/com/ingenieux/pom/operator/BaseTest.kt rename src/test/resources/br/com/ingenieux/pom/operator/{pom-2.xml => pom-3.xml} (100%) create mode 100644 src/test/resources/br/com/ingenieux/pom/operator/pom-case-1.xml create mode 100644 src/test/resources/br/com/ingenieux/pom/operator/pom-case-3.xml create mode 100644 src/test/resources/br/com/ingenieux/pom/operator/pom-case-4.xml create mode 100644 src/test/resources/br/com/ingenieux/pom/operator/webgoat-parent.xml diff --git a/pom-orig.xml b/pom-orig.xml deleted file mode 100644 index f5e1dbd8a..000000000 --- a/pom-orig.xml +++ /dev/null @@ -1,439 +0,0 @@ - - - 4.0.0 - br.com.ingenieux - pom-operator - 0.0.1-SNAPSHOT - pom-operator - http://www.example.com - - 1.5.31 - 1.8 - 1.8 - UTF-8 - - - - com.offbytwo - docopt - 0.6.0.20150202 - compile - - - org.apache.commons - commons-lang3 - 3.7 - compile - - - org.dom4j - dom4j - 2.1.3 - compile - - - jaxen - jaxen - 1.2.0 - compile - - - xerces - xercesImpl - 2.12.1 - compile - - - io.github.java-diff-utils - java-diff-utils - 4.9 - test - - - org.xmlunit - xmlunit-core - 2.8.3 - test - - - org.hamcrest - hamcrest-all - 1.3 - test - - - junit - junit - 4.11 - test - - - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - 1.5.31 - compile - - - org.jetbrains.kotlin - kotlin-test - 1.5.31 - test - - - - - - false - - central - Central Repository - https://repo.maven.apache.org/maven2 - - - - - - never - - - false - - central - Central Repository - https://repo.maven.apache.org/maven2 - - - - /home/aldrin/projetos/sources/pom-operator/src/main/java - /home/aldrin/projetos/sources/pom-operator/src/main/scripts - /home/aldrin/projetos/sources/pom-operator/src/test/java - /home/aldrin/projetos/sources/pom-operator/target/classes - /home/aldrin/projetos/sources/pom-operator/target/test-classes - - - /home/aldrin/projetos/sources/pom-operator/src/main/resources - - - - - /home/aldrin/projetos/sources/pom-operator/src/test/resources - - - /home/aldrin/projetos/sources/pom-operator/target - pom-operator-0.0.1-SNAPSHOT - - - - maven-antrun-plugin - 1.3 - - - maven-assembly-plugin - 2.2-beta-5 - - - maven-dependency-plugin - 2.8 - - - maven-release-plugin - 2.5.3 - - - maven-clean-plugin - 3.1.0 - - - maven-resources-plugin - 3.0.2 - - - maven-compiler-plugin - 3.8.0 - - - maven-surefire-plugin - 2.22.1 - - - maven-jar-plugin - 3.0.2 - - - maven-install-plugin - 2.5.2 - - - maven-deploy-plugin - 2.8.2 - - - maven-site-plugin - 3.7.1 - - - maven-project-info-reports-plugin - 3.0.0 - - - - - - org.jetbrains.kotlin - kotlin-maven-plugin - 1.5.31 - - - compile - compile - - compile - - - 1.8 - - - - test-compile - test-compile - - test-compile - - - 1.8 - - - - - 1.8 - - - - maven-compiler-plugin - 3.8.0 - - - default-compile - compile - - compile - - - - default-testCompile - test-compile - - testCompile - - - - compile - compile - - compile - - - - testCompile - test-compile - - testCompile - - - - - - maven-clean-plugin - 3.1.0 - - - default-clean - clean - - clean - - - - - - maven-resources-plugin - 3.0.2 - - - default-testResources - process-test-resources - - testResources - - - - default-resources - process-resources - - resources - - - - - - maven-jar-plugin - 3.0.2 - - - default-jar - package - - jar - - - - - - maven-surefire-plugin - 2.22.1 - - - default-test - test - - test - - - - - - maven-install-plugin - 2.5.2 - - - default-install - install - - install - - - - - - maven-deploy-plugin - 2.8.2 - - - default-deploy - deploy - - deploy - - - - - - maven-site-plugin - 3.7.1 - - - default-site - site - - site - - - /home/aldrin/projetos/sources/pom-operator/target/site - - - org.apache.maven.plugins - maven-project-info-reports-plugin - - - - - - default-deploy - site-deploy - - deploy - - - /home/aldrin/projetos/sources/pom-operator/target/site - - - org.apache.maven.plugins - maven-project-info-reports-plugin - - - - - - - /home/aldrin/projetos/sources/pom-operator/target/site - - - org.apache.maven.plugins - maven-project-info-reports-plugin - - - - - - - - /home/aldrin/projetos/sources/pom-operator/target/site - - - - exec-jar - - - - maven-shade-plugin - 2.4.3 - - - package - - shade - - - - - - br.com.ingenieux.pom.operator.App - - - false - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - - - org.skife.maven - really-executable-jar-maven-plugin - 1.4.1 - - - package - - really-executable-jar - - - - - -Xmx1G - pom-operator - - - - - - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index 46c1c221a..5be4e5725 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ UTF-8 1.8 1.8 - 1.5.31 + 1.6.0 @@ -28,7 +28,7 @@ org.apache.commons commons-lang3 - 3.7 + 3.12.0 org.dom4j @@ -48,7 +48,7 @@ io.github.java-diff-utils java-diff-utils - 4.9 + 4.11 test @@ -66,7 +66,7 @@ junit junit - 4.11 + 4.13.2 test diff --git a/src/main/java/br/com/ingenieux/pom/operator/App.kt b/src/main/java/br/com/ingenieux/pom/operator/App.kt index af26cd51a..97100393e 100644 --- a/src/main/java/br/com/ingenieux/pom/operator/App.kt +++ b/src/main/java/br/com/ingenieux/pom/operator/App.kt @@ -1,6 +1,5 @@ package br.com.ingenieux.pom.operator -import br.com.ingenieux.pom.operator.POMOperator.readPomFile import org.docopt.Docopt import java.io.File @@ -12,27 +11,27 @@ import java.io.File object App { @JvmStatic fun main(args: Array) { - val opts = Docopt("""pom-operator 0.0.1 + val opts = Docopt( + """pom-operator 0.0.1 Usage: pom-operator DEPENDENCY POMFILES... - """.trimIndent()).withVersion("pom-operator 0.0.1").parse(*args) - - //println(opts) + """.trimIndent() + ).withVersion("pom-operator 0.0.1").parse(*args) val dep = Dependency.fromString(opts["DEPENDENCY"]!! as String) val files = opts["POMFILES"]!! as List for (path in files) { - val pomFile = readPomFile(File(path)) + val ctx = Context.load(File(path), dep) println("Upgrading dependency ($dep) in path $path") - val newPomFileContents = POMOperator.upgradePom(pomFile, dep) + val newPomFileContents = POMOperator.upgradePom(ctx) - val xmlContent = newPomFileContents.asXML() + val xmlContent = ctx.resultPom.asXML() File(path).writeText(xmlContent) } diff --git a/src/main/java/br/com/ingenieux/pom/operator/Command.kt b/src/main/java/br/com/ingenieux/pom/operator/Command.kt new file mode 100644 index 000000000..144e8e7ab --- /dev/null +++ b/src/main/java/br/com/ingenieux/pom/operator/Command.kt @@ -0,0 +1,121 @@ +package br.com.ingenieux.pom.operator + +import br.com.ingenieux.pom.operator.util.Util.buildLookupExpressionForDependency +import br.com.ingenieux.pom.operator.util.Util.buildLookupExpressionForDependencyManagement +import br.com.ingenieux.pom.operator.util.Util.selectXPathNodes +import org.dom4j.Element + + +abstract class Command { + open fun execute(c: Context): Boolean = false + +} + +class SimpleUpgrade : Command() { + override fun execute(c: Context): Boolean { + val lookupExpressionForDependency = buildLookupExpressionForDependency(c.dependencyToInsert) + + val dependencyNodes = c.resultPom.selectXPathNodes(lookupExpressionForDependency) + + if (1 == dependencyNodes.size) { + val versionNodes = dependencyNodes[0]!!.selectXPathNodes("./m:version") + + if (1 == versionNodes.size) { + versionNodes[0].text = c.dependencyToInsert.version + + return true + } + } + + return false + } +} + +class SimpleDependencyManagement : Command() { + override fun execute(c: Context): Boolean { + val lookupExpression = buildLookupExpressionForDependencyManagement(c.dependencyToInsert) + + val dependencyNodes = c.resultPom.selectXPathNodes(lookupExpression) + + if (1 == dependencyNodes.size) { + val versionNodes = dependencyNodes[0]!!.selectXPathNodes("./m:version") + + if (1 == versionNodes.size) { + versionNodes[0].text = c.dependencyToInsert.version + + return true + } + } + + return false + } +} + +class SimpleInsert : Command() { + override fun execute(c: Context): Boolean { + val dependencyManagementNode = c.resultPom.selectXPathNodes("/m:project/m:dependencyManagement") + + if (dependencyManagementNode.isEmpty()) { + val dependencyManagementNode = c.resultPom.rootElement.addElement("dependencyManagement") + + val dependenciesNode = dependencyManagementNode.addElement("dependencies") + + val dependencyNode = appendCoordinates(dependenciesNode, c) + + val versionNode = dependencyNode.addElement("version") + + versionNode.text = c.dependencyToInsert.version + } + + val dependenciesNodeList = c.resultPom.selectXPathNodes("//m:project/m:dependencies") + + val rootDependencyNode: Element = if (dependenciesNodeList.size == 0) { + c.resultPom.rootElement.addElement("dependencies") + } else if (dependenciesNodeList.size == 1){ + dependenciesNodeList[0] as Element + } else { + throw IllegalStateException("More than one dependencies node") + } + + appendCoordinates(rootDependencyNode, c) + + return true + } + + private fun appendCoordinates( + dependenciesNode: Element, + c: Context + ): Element { + val dependencyNode = dependenciesNode.addElement("dependency") + + val groupIdNode = dependencyNode.addElement("groupId") + + groupIdNode.text = c.dependencyToInsert.groupId + + val artifactIdNode = dependencyNode.addElement("artifactId") + + artifactIdNode.text = c.dependencyToInsert.artifactId + return dependencyNode + } +} + +class Chain(c: List) : Command() { + private val commandList = ArrayList(c.toList()) + + override fun execute(c: Context): Boolean { + var done = false + val listIterator = commandList.listIterator() + + while ((!done) && listIterator.hasNext()) { + val nextCommand = listIterator.next() + + done = nextCommand.execute(c) + } + + return done + } + + companion object { + fun create() = Chain(listOf(SimpleUpgrade(), SimpleDependencyManagement(), SimpleInsert())) + } +} \ No newline at end of file diff --git a/src/main/java/br/com/ingenieux/pom/operator/Context.kt b/src/main/java/br/com/ingenieux/pom/operator/Context.kt new file mode 100644 index 000000000..33432293c --- /dev/null +++ b/src/main/java/br/com/ingenieux/pom/operator/Context.kt @@ -0,0 +1,59 @@ +package br.com.ingenieux.pom.operator + +import org.dom4j.Document +import org.dom4j.io.SAXReader +import java.io.File +import java.io.FileInputStream +import java.io.InputStream +import java.lang.IllegalStateException +import java.net.URL + +data class Context( + val pomDocument: Document, + val dependencyToInsert: Dependency, +) { + val resultPom: Document = pomDocument.clone() as Document + + fun getEffectivePom(): Document { + val tmpInputFile = File.createTempFile("tmp-pom-orig", ".xml") + + tmpInputFile.writeText(resultPom.asXML()) + + val tmpOutputFile = File.createTempFile("tmp-pom", ".xml") + + val psBuilder = ProcessBuilder( + "mvn", + "-N", + //"-o", + "-f", + tmpInputFile.absolutePath, + "help:effective-pom", + "-Doutput=${tmpOutputFile.absolutePath}" + ).inheritIO() + + psBuilder.environment().putAll(System.getenv()) + + val process = psBuilder.start() + + val retCode = process.waitFor() + + if (0 != retCode) + throw IllegalStateException("Unexpected return code from maven: $retCode") + + return SAXReader().read(FileInputStream(tmpOutputFile)) + } + + companion object { + fun load(`is`: InputStream, dependencyToInsert: Dependency): Context { + val pomDocument = SAXReader().read(`is`)!! + + return Context(pomDocument, dependencyToInsert) + } + + fun load(f: File, dependencyToInsert: Dependency) = + load(FileInputStream(f), dependencyToInsert) + + fun load(url: URL, dependencyToInsert: Dependency) = + load(url.openStream(), dependencyToInsert) + } +} \ No newline at end of file diff --git a/src/main/java/br/com/ingenieux/pom/operator/Dependency.kt b/src/main/java/br/com/ingenieux/pom/operator/Dependency.kt new file mode 100644 index 000000000..938a82d82 --- /dev/null +++ b/src/main/java/br/com/ingenieux/pom/operator/Dependency.kt @@ -0,0 +1,23 @@ +package br.com.ingenieux.pom.operator + +import org.apache.commons.lang3.builder.EqualsBuilder +import java.lang.IllegalStateException + +data class Dependency( + val groupId: String, + val artifactId: String, + val version: String? = null, + val classifier: String? = null, + val packaging: String? = "jar" +) { + companion object { + fun fromString(str: String): Dependency { + val elements = str.split(":") + + if (elements.size < 3) + throw IllegalStateException("Give me 3 elements") + + return Dependency(elements[0], elements[1], elements[2]) + } + } +} \ No newline at end of file diff --git a/src/main/java/br/com/ingenieux/pom/operator/POMOperator.kt b/src/main/java/br/com/ingenieux/pom/operator/POMOperator.kt index cca9f937e..98c44d8ba 100644 --- a/src/main/java/br/com/ingenieux/pom/operator/POMOperator.kt +++ b/src/main/java/br/com/ingenieux/pom/operator/POMOperator.kt @@ -1,175 +1,6 @@ package br.com.ingenieux.pom.operator -import org.apache.commons.lang3.builder.EqualsBuilder -import org.dom4j.Document -import org.dom4j.io.SAXReader -import java.io.File -import java.io.FileInputStream -import java.io.InputStreamReader -import java.lang.IllegalStateException - -data class Dependency( - val groupId: String, - val artifactId: String, - val version: String? = null, - val classifier: String? = null, - val packaging: String? = "jar" -) { - companion object { - fun fromString(str: String): Dependency { - val elements = str.split(":") - - if (elements.size < 3) - throw IllegalStateException("Give me 3 elements") - - return Dependency(elements[0], elements[1], elements[2]) - } - } - - fun matchesOther(dep: Dependency): Boolean { - val equalsBuilder = EqualsBuilder().append(this.groupId, dep.groupId) - .append(this.artifactId, dep.artifactId) - - if (null != classifier) { - equalsBuilder.append(this.classifier, dep.classifier) - } - - if (null != packaging) { - equalsBuilder.append(this.packaging, dep.packaging) - } - - return equalsBuilder.isEquals - } -} object POMOperator { - fun readPomFile(file: File): Document { - val pomDoc = readEffectivePom(file) - - return SAXReader().read(pomDoc)!! - } - - fun readResourcePom(path: String, effectivePom: Boolean = false): Document { - val pomDoc = if (effectivePom) { - val resourceURI = javaClass.getResource(path).toURI() - - val resourceFile = File(resourceURI) - - readEffectivePom(resourceFile) - } else { - InputStreamReader(javaClass.getResourceAsStream(path)) - } - - return SAXReader().read(pomDoc)!! - } - - private fun readEffectivePom(resourceFile: File): InputStreamReader { - val absPath = resourceFile.absolutePath - - val tmpOutputFile = File.createTempFile("tmp-pom", ".xml") - - val psBuilder = ProcessBuilder( - "mvn", - "-N", - "-o", - "-f", - absPath, - "help:effective-pom", - "-Doutput=${tmpOutputFile.absolutePath}" - ).inheritIO() - - psBuilder.environment().putAll(System.getenv()) - - val process = psBuilder.start() - - val retCode = process.waitFor() - - if (0 != retCode) - throw IllegalStateException("Unexpected return code from maven: $retCode") - - return InputStreamReader(FileInputStream(tmpOutputFile)) - } - - fun upgradePom(pom: Document, dependencyToUpgrade: Dependency): Document { - val doc = pom.clone() as Document - - if (simpleUpgrade(doc, dependencyToUpgrade)) { - return doc - } - - if (simpleDependencyManagementUpgrade(doc, dependencyToUpgrade)) { - return doc - } - - throw IllegalStateException("Unable to upgrade dependency") - } - - private fun simpleUpgrade(doc: Document, dependencyToUpgrade: Dependency): Boolean { - val lookupExpressionForDependency = buildLookupExpressionForDependency(dependencyToUpgrade) - - return upgradeDependency(doc, lookupExpressionForDependency, dependencyToUpgrade) - } - - private fun simpleDependencyManagementUpgrade(doc: Document, dependencyToUpgrade: Dependency): Boolean { - val lookupExpressionForDependency = buildLookupExpressionForDependencyManagement(dependencyToUpgrade) - - return upgradeDependency(doc, lookupExpressionForDependency, dependencyToUpgrade) - } - - private fun upgradeDependency( - doc: Document, - lookupExpression: String, - dep: Dependency - ): Boolean { - val dependencyNodes = doc.selectNodes(lookupExpression) - - if (1 == dependencyNodes.size) { - val versionNodes = dependencyNodes[0]!!.selectNodes("./*[local-name()='version']") - - if (1 == versionNodes.size) { - versionNodes[0].text = dep.version - - return true - } - } - - return false - } - - private fun buildLookupExpressionForDependency(dependency: Dependency) = - "/*[local-name()='project']" + - "/*[local-name()='dependencies']" + - "/*[local-name()='dependency']" + - /* */ "[./*[local-name()='groupId'][text()='${dependency.groupId}'] and " + - /* */ "./*[local-name()='artifactId'][text()='${dependency.artifactId}']" + - "]" - private fun buildLookupExpressionForDependencyManagement(dependency: Dependency) = - "/*[local-name()='project']" + - "/*[local-name()='dependencyManagement']" + - "/*[local-name()='dependencies']" + - "/*[local-name()='dependency']" + - /* */ "[./*[local-name()='groupId'][text()='${dependency.groupId}'] and " + - /* */ "./*[local-name()='artifactId'][text()='${dependency.artifactId}']" + - "]" - -// // "/*[local-name()='project']/*[local-name()='dependencies']/*[local-name()='dependency']" -// private fun selectDependencyNodes(doc: Document, expr: String): List -// { -// val expandedWithNamespaces = expandNS(expr) -// val result = doc.selectNodes(expandedWithNamespaces) -// return result -// } -// -// private fun expandNS(xpathExpr: String): String { -// val exprBuilder = StringBuilder() -// -// for (element: String in xpathExpr.substring(1).split("/")) { -// val whatToAppend = element.replace(Regex("""^(\w+)(.*)""")) { matchResult -> -// "/*[local-name()='${matchResult.groups[1]!!.value}']${matchResult.groups[2]!!.value}" -// } -// exprBuilder.append(whatToAppend) -// } -// -// return exprBuilder.toString() -// } -} \ No newline at end of file + fun upgradePom(context: Context) = Chain.create().execute(context) +} diff --git a/src/main/java/br/com/ingenieux/pom/operator/util/Util.kt b/src/main/java/br/com/ingenieux/pom/operator/util/Util.kt new file mode 100644 index 000000000..b783b06f7 --- /dev/null +++ b/src/main/java/br/com/ingenieux/pom/operator/util/Util.kt @@ -0,0 +1,44 @@ +package br.com.ingenieux.pom.operator.util + +import br.com.ingenieux.pom.operator.Dependency +import org.dom4j.Node +import org.jaxen.SimpleNamespaceContext +import org.jaxen.XPath +import org.jaxen.dom4j.Dom4jXPath + +object Util { + fun buildLookupExpressionForDependency(dependency: Dependency): String = + "/m:project" + + "/m:dependencies" + + "/m:dependency" + + /* */ "[./m:groupId[text()='${dependency.groupId}'] and " + + /* */ "./m:artifactId[text()='${dependency.artifactId}']" + + "]" + + fun buildLookupExpressionForDependencyManagement(dependency: Dependency): String = + "/m:project" + + "/m:dependencyManagement" + + "/m:dependencies" + + "/m:dependency" + + /* */ "[./m:groupId[text()='${dependency.groupId}'] and " + + /* */ "./m:artifactId[text()='${dependency.artifactId}']" + + "]" + + fun Node.selectXPathNodes(expression: String) = + createXPathExpression(expression).selectNodes(this) as List + + fun createXPathExpression(expression: String): XPath { + val xpath = Dom4jXPath(expression) + + xpath.namespaceContext = namespaceContext + + return xpath + } + + internal val namespaceContext = SimpleNamespaceContext( + mapOf( + "m" to "http://maven.apache.org/POM/4.0.0" + ) + ) + +} \ No newline at end of file diff --git a/src/test/java/br/com/ingenieux/pom/operator/BaseTest.kt b/src/test/java/br/com/ingenieux/pom/operator/BaseTest.kt deleted file mode 100644 index 3db801a99..000000000 --- a/src/test/java/br/com/ingenieux/pom/operator/BaseTest.kt +++ /dev/null @@ -1,25 +0,0 @@ -package br.com.ingenieux.pom.operator - -import org.dom4j.Document -import org.dom4j.io.SAXReader -import org.xmlunit.builder.DiffBuilder -import org.xmlunit.builder.Input -import org.xmlunit.diff.Diff -import java.io.File -import java.io.FileInputStream -import java.io.InputStreamReader -import java.lang.IllegalStateException -import javax.annotation.processing.ProcessingEnvironment - -open class BaseTest { - protected fun getDifferences( - original: Document, - modified: Document - ): Diff? { - val originalDoc = Input.fromString(original.asXML()).build() - val modifiedDoc = Input.fromString(modified.asXML()).build() - - val diff = DiffBuilder.compare(originalDoc).withTest(modifiedDoc).build() - return diff - } -} diff --git a/src/test/java/br/com/ingenieux/pom/operator/POMOperatorTest.kt b/src/test/java/br/com/ingenieux/pom/operator/POMOperatorTest.kt index 9d2fea07e..22d618fde 100644 --- a/src/test/java/br/com/ingenieux/pom/operator/POMOperatorTest.kt +++ b/src/test/java/br/com/ingenieux/pom/operator/POMOperatorTest.kt @@ -1,62 +1,103 @@ package br.com.ingenieux.pom.operator +import br.com.ingenieux.pom.operator.util.Util.buildLookupExpressionForDependency +import br.com.ingenieux.pom.operator.util.Util.selectXPathNodes import org.dom4j.Document import org.hamcrest.MatcherAssert.assertThat import org.junit.Test +import org.xmlunit.builder.DiffBuilder +import org.xmlunit.builder.Input import org.xmlunit.diff.ComparisonType +import org.xmlunit.diff.Diff +import java.io.File /** * Unit test for simple App. */ -class POMOperatorTest : BaseTest() { +class POMOperatorTest { @Test - fun testSimplePOMUpgrade() { - val pomDocument = POMOperator.readResourcePom("pom-1.xml") - + fun testCaseOne() { val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.3") - pomUpgradeAndAssert(pomDocument, dependencyToUpgrade) - } + val context = + Context.load(POMOperator::class.java.getResource("pom-case-1.xml"), dependencyToUpgrade) - @Test - fun testComplexPOMUpgrade() { - val pomDocument = POMOperator.readResourcePom("pom-2.xml", effectivePom = true) + POMOperator.upgradePom(context) - val dependencyToUpgrade = Dependency("junit", "junit", version = "4.13") + val diff = getDifferences(context.pomDocument, context.resultPom)!! - pomUpgradeAndAssert(pomDocument, dependencyToUpgrade) - } - - @Test(expected = IllegalStateException::class) - fun testMissingPomChange() { - val pomDocument = POMOperator.readResourcePom("pom-2.xml") - - val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.3") + assertThat("Document has differences", diff.hasDifferences()) + assertThat("Document has three differences", diff.differences.toList().size == 3) - POMOperator.upgradePom(pomDocument, dependencyToUpgrade) + val effectivePom = context.getEffectivePom() } - private fun pomUpgradeAndAssert( - pomDocument: Document, - dependencyToUpgrade: Dependency - ) { - val changedPom = POMOperator.upgradePom(pomDocument, dependencyToUpgrade) + @Test + fun testCaseThree() { + val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.3") - println(changedPom.asXML()) + val context = + Context.load(POMOperator::class.java.getResource("pom-case-3.xml"), dependencyToUpgrade) - val diff = getDifferences(pomDocument, changedPom) + POMOperator.upgradePom(context) - val oDiff = diff!! + val diff = getDifferences(context.pomDocument, context.resultPom)!! - assertThat("Document has differences", oDiff.hasDifferences()) - assertThat("Document has a single difference", oDiff.differences.toList().size == 1) + assertThat("Document has differences", diff.hasDifferences()) + assertThat("Document has a single difference", diff.differences.toList().size == 1) assertThat( "Document has different versions", - oDiff.differences.toList()[0].comparison.type == ComparisonType.TEXT_VALUE + diff.differences.toList()[0].comparison.type == ComparisonType.TEXT_VALUE ) assertThat( "Document has changed version set to ${dependencyToUpgrade.version}", - oDiff.differences.toList()[0].comparison.testDetails.value == dependencyToUpgrade.version + diff.differences.toList()[0].comparison.testDetails.value == dependencyToUpgrade.version ) } + + @Test + fun testCase4() { + val pomPath = File(POMOperator::class.java.getResource("webgoat-parent.xml").toURI()) + + val exitCode = ProcessBuilder( + "mvn", + "-N", + "install:install-file", + "-DgroupId=org.owasp.webgoat", + "-DartifactId=webgoat-parent", + "-Dversion=8.2.3-SNAPSHOT", + "-Dpackaging=pom", + "-Dfile=${pomPath.absolutePath}" + ).start().waitFor() + + assertThat("POM install was successful", 0 == exitCode ) + + val dependencyToUpgrade = + Dependency("org.apache.activemq", "activemq-amqp", version = "5.16.2") + + val context = + Context.load(POMOperator::class.java.getResource("pom-case-4.xml"), dependencyToUpgrade) + + POMOperator.upgradePom(context) + + val diff = getDifferences(context.pomDocument, context.resultPom)!! + + assertThat("Document has differences", diff.hasDifferences()) + + val effectivePom = context.getEffectivePom() + + assertThat("Dependency has been changed", effectivePom.selectXPathNodes(buildLookupExpressionForDependency(dependencyToUpgrade)).isNotEmpty()) + } + + fun getDifferences( + original: Document, + modified: Document + ): Diff? { + val originalDoc = Input.fromString(original.asXML()).build() + val modifiedDoc = Input.fromString(modified.asXML()).build() + + val diff = DiffBuilder.compare(originalDoc).withTest(modifiedDoc).build() + return diff + } + } \ No newline at end of file diff --git a/src/test/resources/br/com/ingenieux/pom/operator/pom-2.xml b/src/test/resources/br/com/ingenieux/pom/operator/pom-3.xml similarity index 100% rename from src/test/resources/br/com/ingenieux/pom/operator/pom-2.xml rename to src/test/resources/br/com/ingenieux/pom/operator/pom-3.xml diff --git a/src/test/resources/br/com/ingenieux/pom/operator/pom-case-1.xml b/src/test/resources/br/com/ingenieux/pom/operator/pom-case-1.xml new file mode 100644 index 000000000..08779506b --- /dev/null +++ b/src/test/resources/br/com/ingenieux/pom/operator/pom-case-1.xml @@ -0,0 +1,21 @@ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + pom-operator + + http://www.example.com + + + UTF-8 + 1.8 + 1.8 + 1.5.31 + + diff --git a/src/test/resources/br/com/ingenieux/pom/operator/pom-case-3.xml b/src/test/resources/br/com/ingenieux/pom/operator/pom-case-3.xml new file mode 100644 index 000000000..3c20cbb9c --- /dev/null +++ b/src/test/resources/br/com/ingenieux/pom/operator/pom-case-3.xml @@ -0,0 +1,152 @@ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + pom-operator + + http://www.example.com + + + UTF-8 + 1.8 + 1.8 + 1.5.31 + + + + + org.dom4j + dom4j + 2.1.3 + + + jaxen + jaxen + 1.2.0 + + + xerces + xercesImpl + 2.12.1 + + + io.github.java-diff-utils + java-diff-utils + 4.9 + + + junit + junit + 4.11 + test + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + org.apache.maven.plugins + maven-compiler-plugin + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + + + diff --git a/src/test/resources/br/com/ingenieux/pom/operator/pom-case-4.xml b/src/test/resources/br/com/ingenieux/pom/operator/pom-case-4.xml new file mode 100644 index 000000000..dec76bfd0 --- /dev/null +++ b/src/test/resources/br/com/ingenieux/pom/operator/pom-case-4.xml @@ -0,0 +1,229 @@ + + 4.0.0 + webgoat-server + jar + + org.owasp.webgoat + webgoat-parent + 8.2.3-SNAPSHOT + + + + org.owasp.webgoat.StartWebGoat + + + + + org.owasp.webgoat + webgoat-container + ${project.version} + + + org.owasp.webgoat.lesson + challenge + ${project.version} + + + org.owasp.webgoat.lesson + bypass-restrictions + ${project.version} + + + org.owasp.webgoat.lesson + client-side-filtering + ${project.version} + + + org.owasp.webgoat.lesson + crypto + ${project.version} + + + org.owasp.webgoat.lesson + cross-site-scripting + ${project.version} + + + org.owasp.webgoat.lesson + html-tampering + ${project.version} + + + org.owasp.webgoat.lesson + http-basics + ${project.version} + + + org.owasp.webgoat.lesson + http-proxies + ${project.version} + + + org.owasp.webgoat.lesson + cia + ${project.version} + + + org.owasp.webgoat.lesson + chrome-dev-tools + ${project.version} + + + org.owasp.webgoat.lesson + idor + ${project.version} + + + org.owasp.webgoat.lesson + csrf + ${project.version} + + + org.owasp.webgoat.lesson + insecure-login + ${project.version} + + + org.owasp.webgoat.lesson + insecure-deserialization + ${project.version} + + + org.owasp.webgoat.lesson + jwt + ${project.version} + + + org.owasp.webgoat.lesson + path-traversal + ${project.version} + + + org.owasp.webgoat.lesson + sql-injection + ${project.version} + + + org.owasp.webgoat.lesson + vulnerable-components + ${project.version} + + + org.owasp.webgoat.lesson + xxe + ${project.version} + + + org.owasp.webgoat.lesson + auth-bypass + ${project.version} + + + org.owasp.webgoat.lesson + webgoat-introduction + ${project.version} + + + org.owasp.webgoat.lesson + webwolf-introduction + ${project.version} + + + org.owasp.webgoat.lesson + missing-function-ac + ${project.version} + + + org.owasp.webgoat.lesson + password-reset + ${project.version} + + + org.owasp.webgoat.lesson + ssrf + ${project.version} + + + org.owasp.webgoat.lesson + secure-passwords + ${project.version} + + + org.owasp.webgoat.lesson + spoof-cookie + ${project.version} + + + org.owasp.webgoat.lesson + hijack-session + ${project.version} + + + org.owasp.webgoat.lesson + webgoat-lesson-template + ${project.version} + + + org.owasp.webgoat.lesson + logging + ${project.version} + + + org.springframework.boot + spring-boot-devtools + true + + + org.postgresql + postgresql + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + org.thymeleaf.extra + thymeleaf-extras-springsecurity5++ + + + org.asciidoctor + asciidoctorj + + + org.jruby + jruby-complete + + + + + + true + + + + org.apache.maven.plugins + maven-jar-plugin + + + test-compile + + jar + + + internal + + + + + + + + diff --git a/src/test/resources/br/com/ingenieux/pom/operator/webgoat-parent.xml b/src/test/resources/br/com/ingenieux/pom/operator/webgoat-parent.xml new file mode 100644 index 000000000..f70b24d70 --- /dev/null +++ b/src/test/resources/br/com/ingenieux/pom/operator/webgoat-parent.xml @@ -0,0 +1,291 @@ + + + + 4.0.0 + org.owasp.webgoat + webgoat-parent + pom + 8.2.3-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 2.5.4 + + + WebGoat Parent Pom + Parent Pom for the WebGoat Project. A deliberately insecure Web Application + 2006 + https://github.com/WebGoat/WebGoat + + + OWASP + https://github.com/WebGoat/WebGoat/ + + + + + GNU General Public License, version 2 + https://www.gnu.org/licenses/gpl-2.0.txt + + + + + + mayhew64 + Bruce Mayhew + webgoat@owasp.org + OWASP + https://github.com/WebGoat/WebGoat + + + nbaars + Nanne Baars + nanne.baars@owasp.org + https://github.com/nbaars + Europe/Amsterdam + + + misfir3 + Jason White + jason.white@owasp.org + + + zubcevic + René Zubcevic + rene.zubcevic@owasp.org + + + aolle + Àngel Ollé Blázquez + angel@olleb.com + + + jwayman + Jeff Wayman + + + + dcowden + Dave Cowden + + + + lawson89 + Richard Lawson + + + + dougmorato + Doug Morato + doug.morato@owasp.org + OWASP + https://github.com/dougmorato + America/New_York + + https://avatars2.githubusercontent.com/u/9654?v=3&s=150 + + + + + + + OWASP WebGoat Mailing List + https://lists.owasp.org/mailman/listinfo/owasp-webgoat + Owasp-webgoat-request@lists.owasp.org + owasp-webgoat@lists.owasp.org + http://lists.owasp.org/pipermail/owasp-webgoat/ + + + + + https://github.com/WebGoat/WebGoat + scm:git:git@github.com:WebGoat/WebGoat.git + scm:git:git@github.com:WebGoat/WebGoat.git + HEAD + + + + Github Issues + https://github.com/WebGoat/WebGoat/issues + + + + + UTF-8 + UTF-8 + 17 + 17 + + + 2.5.2 + 3.2.1 + 3.12.0 + 2.6 + 30.1-jre + 1.18.20 + 2.27.2 + 3.8.0 + 2.22.0 + 3.1.2 + 3.1.1 + 3.1.0 + 3.0.0-M5 + 17 + + + + webgoat-container + webgoat-lessons + webgoat-server + webwolf + webgoat-integration-tests + docker + + + + + org.springframework.boot + spring-boot-starter-validation + + + org.projectlombok + lombok + provided + true + + + org.apache.commons + commons-exec + 1.3 + + + javax.xml.bind + jaxb-api + + + + + + + org.codehaus.mojo + flatten-maven-plugin + 1.2.5 + + + + + flatten + process-resources + + flatten + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 15 + 15 + UTF-8 + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.1.2 + + UTF-8 + true + true + config/checkstyle/checkstyle.xml + config/checkstyle/suppressions.xml + checkstyle.suppressions.file + + + + org.apache.maven.plugins + maven-pmd-plugin + 3.14.0 + + 15 + 1 + + + ${maven.multiModuleProjectDirectory}/config/pmd/pmd-ruleset.xml + + true + true + + + + + check + + + + + + + + + + owasp + + false + + + + + org.owasp + dependency-check-maven + 6.1.3 + + 7 + true + true + + + + ${maven.multiModuleProjectDirectory}/config/dependency-check/project-suppression.xml + + + + + + + check + + + + + + + + + + + + central + https://repo.maven.apache.org/maven2 + + false + + + + + + central + https://repo.maven.apache.org/maven2 + + false + + + + + + From b783f0cf57642deea7eb3e8f9ac7a070426f30db Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 22 Nov 2021 08:53:29 -0500 Subject: [PATCH 004/153] Code Cleanup --- .../java/br/com/ingenieux/pom/operator/App.kt | 8 ++++-- .../br/com/ingenieux/pom/operator/Command.kt | 27 +++++++++---------- .../br/com/ingenieux/pom/operator/Context.kt | 2 +- .../com/ingenieux/pom/operator/Dependency.kt | 3 --- .../com/ingenieux/pom/operator/util/Util.kt | 7 ++--- .../ingenieux/pom/operator/POMOperatorTest.kt | 8 +++--- 6 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/main/java/br/com/ingenieux/pom/operator/App.kt b/src/main/java/br/com/ingenieux/pom/operator/App.kt index 97100393e..53730bd9d 100644 --- a/src/main/java/br/com/ingenieux/pom/operator/App.kt +++ b/src/main/java/br/com/ingenieux/pom/operator/App.kt @@ -2,6 +2,7 @@ package br.com.ingenieux.pom.operator import org.docopt.Docopt import java.io.File +import java.lang.IllegalStateException /** @@ -22,14 +23,17 @@ object App { val dep = Dependency.fromString(opts["DEPENDENCY"]!! as String) - val files = opts["POMFILES"]!! as List + @Suppress("UNCHECKED_CAST") val files = opts["POMFILES"]!! as List for (path in files) { val ctx = Context.load(File(path), dep) println("Upgrading dependency ($dep) in path $path") - val newPomFileContents = POMOperator.upgradePom(ctx) + val upgradeResult = POMOperator.upgradePom(ctx) + + if (!upgradeResult) + throw IllegalStateException("Unexpected failure on upgradeResult") val xmlContent = ctx.resultPom.asXML() diff --git a/src/main/java/br/com/ingenieux/pom/operator/Command.kt b/src/main/java/br/com/ingenieux/pom/operator/Command.kt index 144e8e7ab..933dfa310 100644 --- a/src/main/java/br/com/ingenieux/pom/operator/Command.kt +++ b/src/main/java/br/com/ingenieux/pom/operator/Command.kt @@ -6,19 +6,18 @@ import br.com.ingenieux.pom.operator.util.Util.selectXPathNodes import org.dom4j.Element -abstract class Command { - open fun execute(c: Context): Boolean = false - +fun interface Command { + fun execute(c: Context): Boolean } -class SimpleUpgrade : Command() { +val SimpleUpgrade = object : Command { override fun execute(c: Context): Boolean { val lookupExpressionForDependency = buildLookupExpressionForDependency(c.dependencyToInsert) val dependencyNodes = c.resultPom.selectXPathNodes(lookupExpressionForDependency) if (1 == dependencyNodes.size) { - val versionNodes = dependencyNodes[0]!!.selectXPathNodes("./m:version") + val versionNodes = dependencyNodes[0].selectXPathNodes("./m:version") if (1 == versionNodes.size) { versionNodes[0].text = c.dependencyToInsert.version @@ -31,14 +30,14 @@ class SimpleUpgrade : Command() { } } -class SimpleDependencyManagement : Command() { +val SimpleDependencyManagement = object : Command { override fun execute(c: Context): Boolean { val lookupExpression = buildLookupExpressionForDependencyManagement(c.dependencyToInsert) val dependencyNodes = c.resultPom.selectXPathNodes(lookupExpression) if (1 == dependencyNodes.size) { - val versionNodes = dependencyNodes[0]!!.selectXPathNodes("./m:version") + val versionNodes = dependencyNodes[0].selectXPathNodes("./m:version") if (1 == versionNodes.size) { versionNodes[0].text = c.dependencyToInsert.version @@ -51,14 +50,14 @@ class SimpleDependencyManagement : Command() { } } -class SimpleInsert : Command() { +val SimpleInsert = object : Command { override fun execute(c: Context): Boolean { val dependencyManagementNode = c.resultPom.selectXPathNodes("/m:project/m:dependencyManagement") if (dependencyManagementNode.isEmpty()) { - val dependencyManagementNode = c.resultPom.rootElement.addElement("dependencyManagement") + val newDependencyManagementNode = c.resultPom.rootElement.addElement("dependencyManagement") - val dependenciesNode = dependencyManagementNode.addElement("dependencies") + val dependenciesNode = newDependencyManagementNode.addElement("dependencies") val dependencyNode = appendCoordinates(dependenciesNode, c) @@ -69,7 +68,7 @@ class SimpleInsert : Command() { val dependenciesNodeList = c.resultPom.selectXPathNodes("//m:project/m:dependencies") - val rootDependencyNode: Element = if (dependenciesNodeList.size == 0) { + val rootDependencyNode: Element = if (dependenciesNodeList.isEmpty()) { c.resultPom.rootElement.addElement("dependencies") } else if (dependenciesNodeList.size == 1){ dependenciesNodeList[0] as Element @@ -99,10 +98,10 @@ class SimpleInsert : Command() { } } -class Chain(c: List) : Command() { +class Chain(vararg c: Command) { private val commandList = ArrayList(c.toList()) - override fun execute(c: Context): Boolean { + fun execute(c: Context): Boolean { var done = false val listIterator = commandList.listIterator() @@ -116,6 +115,6 @@ class Chain(c: List) : Command() { } companion object { - fun create() = Chain(listOf(SimpleUpgrade(), SimpleDependencyManagement(), SimpleInsert())) + fun create() = Chain(SimpleUpgrade, SimpleDependencyManagement, SimpleInsert) } } \ No newline at end of file diff --git a/src/main/java/br/com/ingenieux/pom/operator/Context.kt b/src/main/java/br/com/ingenieux/pom/operator/Context.kt index 33432293c..3491e700f 100644 --- a/src/main/java/br/com/ingenieux/pom/operator/Context.kt +++ b/src/main/java/br/com/ingenieux/pom/operator/Context.kt @@ -44,7 +44,7 @@ data class Context( } companion object { - fun load(`is`: InputStream, dependencyToInsert: Dependency): Context { + private fun load(`is`: InputStream, dependencyToInsert: Dependency): Context { val pomDocument = SAXReader().read(`is`)!! return Context(pomDocument, dependencyToInsert) diff --git a/src/main/java/br/com/ingenieux/pom/operator/Dependency.kt b/src/main/java/br/com/ingenieux/pom/operator/Dependency.kt index 938a82d82..a34a8822a 100644 --- a/src/main/java/br/com/ingenieux/pom/operator/Dependency.kt +++ b/src/main/java/br/com/ingenieux/pom/operator/Dependency.kt @@ -1,8 +1,5 @@ package br.com.ingenieux.pom.operator -import org.apache.commons.lang3.builder.EqualsBuilder -import java.lang.IllegalStateException - data class Dependency( val groupId: String, val artifactId: String, diff --git a/src/main/java/br/com/ingenieux/pom/operator/util/Util.kt b/src/main/java/br/com/ingenieux/pom/operator/util/Util.kt index b783b06f7..4b0a0263e 100644 --- a/src/main/java/br/com/ingenieux/pom/operator/util/Util.kt +++ b/src/main/java/br/com/ingenieux/pom/operator/util/Util.kt @@ -24,10 +24,11 @@ object Util { /* */ "./m:artifactId[text()='${dependency.artifactId}']" + "]" + @Suppress("UNCHECKED_CAST") fun Node.selectXPathNodes(expression: String) = - createXPathExpression(expression).selectNodes(this) as List + createXPathExpression(expression).selectNodes(this)!! as List - fun createXPathExpression(expression: String): XPath { + private fun createXPathExpression(expression: String): XPath { val xpath = Dom4jXPath(expression) xpath.namespaceContext = namespaceContext @@ -35,7 +36,7 @@ object Util { return xpath } - internal val namespaceContext = SimpleNamespaceContext( + private val namespaceContext = SimpleNamespaceContext( mapOf( "m" to "http://maven.apache.org/POM/4.0.0" ) diff --git a/src/test/java/br/com/ingenieux/pom/operator/POMOperatorTest.kt b/src/test/java/br/com/ingenieux/pom/operator/POMOperatorTest.kt index 22d618fde..41aa59f02 100644 --- a/src/test/java/br/com/ingenieux/pom/operator/POMOperatorTest.kt +++ b/src/test/java/br/com/ingenieux/pom/operator/POMOperatorTest.kt @@ -20,7 +20,7 @@ class POMOperatorTest { val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.3") val context = - Context.load(POMOperator::class.java.getResource("pom-case-1.xml"), dependencyToUpgrade) + Context.load(POMOperator::class.java.getResource("pom-case-1.xml")!!, dependencyToUpgrade) POMOperator.upgradePom(context) @@ -37,7 +37,7 @@ class POMOperatorTest { val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.3") val context = - Context.load(POMOperator::class.java.getResource("pom-case-3.xml"), dependencyToUpgrade) + Context.load(POMOperator::class.java.getResource("pom-case-3.xml")!!, dependencyToUpgrade) POMOperator.upgradePom(context) @@ -57,7 +57,7 @@ class POMOperatorTest { @Test fun testCase4() { - val pomPath = File(POMOperator::class.java.getResource("webgoat-parent.xml").toURI()) + val pomPath = File(POMOperator::class.java.getResource("webgoat-parent.xml")!!.toURI()) val exitCode = ProcessBuilder( "mvn", @@ -76,7 +76,7 @@ class POMOperatorTest { Dependency("org.apache.activemq", "activemq-amqp", version = "5.16.2") val context = - Context.load(POMOperator::class.java.getResource("pom-case-4.xml"), dependencyToUpgrade) + Context.load(POMOperator::class.java.getResource("pom-case-4.xml")!!, dependencyToUpgrade) POMOperator.upgradePom(context) From 338dcbc7e95f067077f5a4d14b12efed347184d0 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Thu, 25 Aug 2022 12:15:20 -0500 Subject: [PATCH 005/153] Interim Commit --- .idea/codeStyles/Project.xml | 2 +- .idea/dataSources.xml | 15 + .idea/encodings.xml | 1 + .idea/kotlinc.xml | 6 + .idea/runConfigurations.xml | 10 - .../br/com/ingenieux/pom/operator/Command.kt | 101 +- .../pom/operator/diff/DiffMatchPatch.java | 2469 +++++++++++++++++ .../ingenieux/pom/operator/POMOperatorTest.kt | 31 +- 8 files changed, 2613 insertions(+), 22 deletions(-) create mode 100644 .idea/dataSources.xml create mode 100644 .idea/kotlinc.xml delete mode 100644 .idea/runConfigurations.xml create mode 100644 src/main/java/br/com/ingenieux/pom/operator/diff/DiffMatchPatch.java diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 66c829eed..8bc95d2bb 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -241,10 +241,10 @@ + + org.slf4j + slf4j-api + ${slf4j.version} + provided + + + org.slf4j + slf4j-simple + ${slf4j.version} + test + xerces xercesImpl diff --git a/src/main/java/io/openpixee/maven/operator/Command.kt b/src/main/java/io/openpixee/maven/operator/Command.kt index 4292eb048..f65d2cb08 100644 --- a/src/main/java/io/openpixee/maven/operator/Command.kt +++ b/src/main/java/io/openpixee/maven/operator/Command.kt @@ -138,9 +138,7 @@ val SimpleInsert = object : Command { val lastElementText = lastElement?.text ?: "" - val len = lastElementText.trimStart('\n')?.length ?: 0 - - return len + return lastElementText.trimStart('\n').length } return 0 diff --git a/src/main/java/io/openpixee/maven/operator/util/Util.kt b/src/main/java/io/openpixee/maven/operator/util/Util.kt index d84ccd655..29fa3f952 100644 --- a/src/main/java/io/openpixee/maven/operator/util/Util.kt +++ b/src/main/java/io/openpixee/maven/operator/util/Util.kt @@ -43,7 +43,7 @@ object Util { ) ) - public val NAMESPACE_CLEANER = object : VisitorSupport() { + val NAMESPACE_CLEANER = object : VisitorSupport() { override fun visit(document: Document) { (document.getRootElement() as DefaultElement) .setNamespace(Namespace.NO_NAMESPACE) @@ -64,7 +64,7 @@ object Util { override fun visit(node: Element) { if (node is DefaultElement) { - (node as DefaultElement).setNamespace(Namespace.NO_NAMESPACE) + node.setNamespace(Namespace.NO_NAMESPACE) } } } diff --git a/src/main/java/io/openpixee/maven/operator/diff/DiffMatchPatch.java b/src/test/java/io/openpixee/diff/DiffMatchPatch.java similarity index 99% rename from src/main/java/io/openpixee/maven/operator/diff/DiffMatchPatch.java rename to src/test/java/io/openpixee/diff/DiffMatchPatch.java index 032f89f71..ddafe02d7 100644 --- a/src/main/java/io/openpixee/maven/operator/diff/DiffMatchPatch.java +++ b/src/test/java/io/openpixee/diff/DiffMatchPatch.java @@ -1,4 +1,4 @@ -package io.openpixee.maven.operator.diff; +package io.openpixee.diff; /* * Diff Match and Patch diff --git a/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt b/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt index fad658b8b..126249a6d 100644 --- a/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt +++ b/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt @@ -1,21 +1,25 @@ package io.openpixee.maven.operator -import io.openpixee.maven.operator.diff.DiffMatchPatch +import io.openpixee.diff.DiffMatchPatch import io.openpixee.maven.operator.util.Util.buildLookupExpressionForDependency import io.openpixee.maven.operator.util.Util.selectXPathNodes import org.dom4j.Document import org.hamcrest.MatcherAssert.assertThat import org.junit.Test +import org.slf4j.LoggerFactory import org.xmlunit.builder.DiffBuilder import org.xmlunit.builder.Input import org.xmlunit.diff.ComparisonType import org.xmlunit.diff.Diff import java.io.File +import java.net.URLDecoder /** * Unit test for simple App. */ class POMOperatorTest { + val LOGGER = LoggerFactory.getLogger(POMOperatorTest::class.java) + @Test fun testCaseOne() { val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.3") @@ -23,6 +27,8 @@ class POMOperatorTest { val context = Context.load(POMOperator::class.java.getResource("pom-case-1.xml")!!, dependencyToUpgrade) + LOGGER.debug("context: {}", context) + POMOperator.upgradePom(context) val diff = getXmlDifferences(context.pomDocument, context.resultPom)!! @@ -32,8 +38,11 @@ class POMOperatorTest { val textDiff = getTextDifferences(context.pomDocument, context.resultPom)!! + LOGGER.debug("textDiff: {}", textDiff) val effectivePom = context.getEffectivePom() + + LOGGER.debug("effectivePom: {}", effectivePom.asXML()) } fun getTextDifferences(pomDocument: Document, resultPom: Document): Any { @@ -41,9 +50,12 @@ class POMOperatorTest { val resultPomAsString = resultPom.asXML() val dmp = DiffMatchPatch() - val patch = dmp.patch_toText(dmp.patch_make(pomDocumentAsString, resultPomAsString)) - return "" + val diffs = dmp.patch_make(pomDocumentAsString, resultPomAsString) + + val patch = dmp.patch_toText(diffs) + + return URLDecoder.decode(patch, "utf-8") } @Test diff --git a/src/test/resources/simplelogger.properties b/src/test/resources/simplelogger.properties new file mode 100644 index 000000000..eafa2b0f4 --- /dev/null +++ b/src/test/resources/simplelogger.properties @@ -0,0 +1 @@ +org.slf4j.simpleLogger.defaultLogLevel=debug \ No newline at end of file From 74e402e55029b6c6a63b30b631beb6a54b30dd35 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Sun, 4 Sep 2022 18:42:37 -0500 Subject: [PATCH 026/153] Fixing Maven Setup in actions --- .github/workflows/push-test.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/push-test.yml b/.github/workflows/push-test.yml index 1f4f6d591..4d84e1e5c 100644 --- a/.github/workflows/push-test.yml +++ b/.github/workflows/push-test.yml @@ -23,6 +23,10 @@ jobs: server-id: pixee server-username: ARTIFACTORY_USERNAME_REF server-password: ARTIFACTORY_TOKEN_REF + - name: Set up Maven + uses: stCarolas/setup-maven@v4.4 + with: + maven-version: 3.8.2 - name: Build with Maven run: > mvn -B install deploy -DaltDeploymentRepository=pixee::default::https://pixee.jfrog.io/artifactory/mailman-libs-snapshot From 7416c862984d1e946b9f9cded10d0d8da07e0b37 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Tue, 6 Sep 2022 11:02:48 -0500 Subject: [PATCH 027/153] Cleanup --- pom.xml | 8 ++--- .../io/openpixee/maven/operator/Command.kt | 33 ++++++++--------- .../io/openpixee/maven/operator/util/Util.kt | 27 -------------- .../io/openpixee/diff/DiffMatchPatch.java | 1 + .../maven/operator/POMOperatorTest.kt | 36 ++++++++++++++----- src/test/resources/simplelogger.properties | 1 + 6 files changed, 47 insertions(+), 59 deletions(-) diff --git a/pom.xml b/pom.xml index d4083bc9c..0839ca8fb 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ UTF-8 1.8 1.8 - 1.6.0 + 1.7.10 2.0.0 @@ -56,18 +56,18 @@ xerces xercesImpl - 2.12.1 + 2.12.2 io.github.java-diff-utils java-diff-utils - 4.11 + 4.12 test org.xmlunit xmlunit-core - 2.8.3 + 2.9.0 test diff --git a/src/main/java/io/openpixee/maven/operator/Command.kt b/src/main/java/io/openpixee/maven/operator/Command.kt index f65d2cb08..8b297a9e7 100644 --- a/src/main/java/io/openpixee/maven/operator/Command.kt +++ b/src/main/java/io/openpixee/maven/operator/Command.kt @@ -12,17 +12,16 @@ import org.dom4j.io.XMLWriter import org.dom4j.tree.DefaultText import java.io.StringReader import java.io.StringWriter +import kotlin.math.ceil fun interface Command { fun execute(c: Context): Boolean } -val SimpleUpgrade = object : Command { - override fun execute(c: Context): Boolean { - val lookupExpressionForDependency = buildLookupExpressionForDependency(c.dependencyToInsert) - - val dependencyNodes = c.resultPom.selectXPathNodes(lookupExpressionForDependency) +abstract class AbstractSimpleCommand : Command { + protected fun handleDependency(c: Context, lookupExpression: String): Boolean { + val dependencyNodes = c.resultPom.selectXPathNodes(lookupExpression) if (1 == dependencyNodes.size) { val versionNodes = dependencyNodes[0].selectXPathNodes("./m:version") @@ -38,23 +37,19 @@ val SimpleUpgrade = object : Command { } } -val SimpleDependencyManagement = object : Command { +val SimpleUpgrade = object : AbstractSimpleCommand() { override fun execute(c: Context): Boolean { - val lookupExpression = buildLookupExpressionForDependencyManagement(c.dependencyToInsert) - - val dependencyNodes = c.resultPom.selectXPathNodes(lookupExpression) - - if (1 == dependencyNodes.size) { - val versionNodes = dependencyNodes[0].selectXPathNodes("./m:version") + val lookupExpressionForDependency = buildLookupExpressionForDependency(c.dependencyToInsert) - if (1 == versionNodes.size) { - versionNodes[0].text = c.dependencyToInsert.version + return handleDependency(c, lookupExpressionForDependency) + } +} - return true - } - } +val SimpleDependencyManagement = object : AbstractSimpleCommand() { + override fun execute(c: Context): Boolean { + val lookupExpression = buildLookupExpressionForDependencyManagement(c.dependencyToInsert) - return false + return handleDependency(c, lookupExpression) } } @@ -112,7 +107,7 @@ val SimpleInsert = object : Command { val xmlWriter = XMLWriter(out, outputFormat) - xmlWriter.setIndentLevel(Math.ceil(indentLevel.toDouble() / 2).toInt()) + xmlWriter.setIndentLevel(ceil(indentLevel.toDouble() / 2).toInt()) xmlWriter.write(clonedNode) diff --git a/src/main/java/io/openpixee/maven/operator/util/Util.kt b/src/main/java/io/openpixee/maven/operator/util/Util.kt index 29fa3f952..f7abe7424 100644 --- a/src/main/java/io/openpixee/maven/operator/util/Util.kt +++ b/src/main/java/io/openpixee/maven/operator/util/Util.kt @@ -42,31 +42,4 @@ object Util { "m" to "http://maven.apache.org/POM/4.0.0" ) ) - - val NAMESPACE_CLEANER = object : VisitorSupport() { - override fun visit(document: Document) { - (document.getRootElement() as DefaultElement) - .setNamespace(Namespace.NO_NAMESPACE) - document.getRootElement().additionalNamespaces().clear() - } - - override fun visit(namespace: Namespace) { - namespace.detach() - } - - override fun visit(node: Attribute) { - if (node.toString().contains("xmlns") - || node.toString().contains("xsi:") - ) { - node.detach() - } - } - - override fun visit(node: Element) { - if (node is DefaultElement) { - node.setNamespace(Namespace.NO_NAMESPACE) - } - } - } - } \ No newline at end of file diff --git a/src/test/java/io/openpixee/diff/DiffMatchPatch.java b/src/test/java/io/openpixee/diff/DiffMatchPatch.java index ddafe02d7..35de22143 100644 --- a/src/test/java/io/openpixee/diff/DiffMatchPatch.java +++ b/src/test/java/io/openpixee/diff/DiffMatchPatch.java @@ -37,6 +37,7 @@ * Class containing the diff, match and patch methods. * Also contains the behaviour settings. */ +@SuppressWarnings("ALL") public class DiffMatchPatch { // Defaults. diff --git a/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt b/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt index 126249a6d..8959fa51e 100644 --- a/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt +++ b/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt @@ -6,6 +6,7 @@ import io.openpixee.maven.operator.util.Util.selectXPathNodes import org.dom4j.Document import org.hamcrest.MatcherAssert.assertThat import org.junit.Test +import org.slf4j.Logger import org.slf4j.LoggerFactory import org.xmlunit.builder.DiffBuilder import org.xmlunit.builder.Input @@ -18,14 +19,19 @@ import java.net.URLDecoder * Unit test for simple App. */ class POMOperatorTest { - val LOGGER = LoggerFactory.getLogger(POMOperatorTest::class.java) + companion object { + private val LOGGER : Logger = LoggerFactory.getLogger(POMOperatorTest::class.java) + } @Test fun testCaseOne() { val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.3") val context = - Context.load(POMOperator::class.java.getResource("pom-case-1.xml")!!, dependencyToUpgrade) + Context.load( + POMOperator::class.java.getResource("pom-case-1.xml")!!, + dependencyToUpgrade + ) LOGGER.debug("context: {}", context) @@ -36,7 +42,7 @@ class POMOperatorTest { assertThat("Document has differences", diff.hasDifferences()) //assertThat("Document has three differences", diff.differences.toList().size == 3) - val textDiff = getTextDifferences(context.pomDocument, context.resultPom)!! + val textDiff = getTextDifferences(context.pomDocument, context.resultPom) LOGGER.debug("textDiff: {}", textDiff) @@ -45,7 +51,7 @@ class POMOperatorTest { LOGGER.debug("effectivePom: {}", effectivePom.asXML()) } - fun getTextDifferences(pomDocument: Document, resultPom: Document): Any { + private fun getTextDifferences(pomDocument: Document, resultPom: Document): Any { val pomDocumentAsString = pomDocument.asXML() val resultPomAsString = resultPom.asXML() @@ -63,7 +69,10 @@ class POMOperatorTest { val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.3") val context = - Context.load(POMOperator::class.java.getResource("pom-case-3.xml")!!, dependencyToUpgrade) + Context.load( + POMOperator::class.java.getResource("pom-case-3.xml")!!, + dependencyToUpgrade + ) POMOperator.upgradePom(context) @@ -96,13 +105,16 @@ class POMOperatorTest { "-Dfile=${pomPath.absolutePath}" ).start().waitFor() - assertThat("POM install was successful", 0 == exitCode ) + assertThat("POM install was successful", 0 == exitCode) val dependencyToUpgrade = Dependency("org.apache.activemq", "activemq-amqp", version = "5.16.2") val context = - Context.load(POMOperator::class.java.getResource("pom-case-4.xml")!!, dependencyToUpgrade) + Context.load( + POMOperator::class.java.getResource("pom-case-4.xml")!!, + dependencyToUpgrade + ) POMOperator.upgradePom(context) @@ -112,10 +124,14 @@ class POMOperatorTest { val effectivePom = context.getEffectivePom() - assertThat("Dependency has been changed", effectivePom.selectXPathNodes(buildLookupExpressionForDependency(dependencyToUpgrade)).isNotEmpty()) + assertThat( + "Dependency has been changed", + effectivePom.selectXPathNodes(buildLookupExpressionForDependency(dependencyToUpgrade)) + .isNotEmpty() + ) } - fun getXmlDifferences( + private fun getXmlDifferences( original: Document, modified: Document ): Diff? { @@ -124,6 +140,8 @@ class POMOperatorTest { val diff = DiffBuilder.compare(originalDoc).withTest(modifiedDoc).build() + LOGGER.debug("diff: {}", diff) + return diff } } diff --git a/src/test/resources/simplelogger.properties b/src/test/resources/simplelogger.properties index eafa2b0f4..a014e30b5 100644 --- a/src/test/resources/simplelogger.properties +++ b/src/test/resources/simplelogger.properties @@ -1 +1,2 @@ +# suppress inspection "UnusedProperty" org.slf4j.simpleLogger.defaultLogLevel=debug \ No newline at end of file From 981b72109bcadeafb6a3775b738d6aaa4619c2d9 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Tue, 6 Sep 2022 13:37:58 -0500 Subject: [PATCH 028/153] Improving tests a little --- src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt b/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt index 8959fa51e..625313552 100644 --- a/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt +++ b/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt @@ -40,12 +40,14 @@ class POMOperatorTest { val diff = getXmlDifferences(context.pomDocument, context.resultPom)!! assertThat("Document has differences", diff.hasDifferences()) - //assertThat("Document has three differences", diff.differences.toList().size == 3) val textDiff = getTextDifferences(context.pomDocument, context.resultPom) LOGGER.debug("textDiff: {}", textDiff) + assertThat("diff contains a tag", textDiff.toString().contains("")) + assertThat("diff contains a tag", textDiff.toString().contains("")) + val effectivePom = context.getEffectivePom() LOGGER.debug("effectivePom: {}", effectivePom.asXML()) From e4c895e05f614136b8bcdb1979ae576d04a01d18 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Tue, 6 Sep 2022 13:55:29 -0500 Subject: [PATCH 029/153] Adding tests --- .github/workflows/push-test.yml | 4 +- .idea/compiler.xml | 1 + .idea/encodings.xml | 4 + .idea/kotlinc.xml | 2 +- .idea/misc.xml | 1 + it/pom.xml | 86 ++++++++++ .../io/openpixee/it/POMOperatorJavaTest.java | 18 +++ it/src/test/resources/io/openpixee/it/pom.xml | 152 ++++++++++++++++++ 8 files changed, 266 insertions(+), 2 deletions(-) create mode 100644 it/pom.xml create mode 100644 it/src/test/java/io/openpixee/it/POMOperatorJavaTest.java create mode 100644 it/src/test/resources/io/openpixee/it/pom.xml diff --git a/.github/workflows/push-test.yml b/.github/workflows/push-test.yml index 4d84e1e5c..e510d3981 100644 --- a/.github/workflows/push-test.yml +++ b/.github/workflows/push-test.yml @@ -29,5 +29,7 @@ jobs: maven-version: 3.8.2 - name: Build with Maven run: > - mvn -B install deploy -DaltDeploymentRepository=pixee::default::https://pixee.jfrog.io/artifactory/mailman-libs-snapshot + mvn -B install + mvn -f it/pom.xml test + mvn -B deploy -DaltDeploymentRepository=pixee::default::https://pixee.jfrog.io/artifactory/mailman-libs-snapshot diff --git a/.idea/compiler.xml b/.idea/compiler.xml index b32030a25..31fd4523e 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -7,6 +7,7 @@ + diff --git a/.idea/encodings.xml b/.idea/encodings.xml index aa00ffab7..4217ed85b 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -1,6 +1,10 @@ + + + + diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml index 1f711703b..b1077fbd0 100644 --- a/.idea/kotlinc.xml +++ b/.idea/kotlinc.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index d5cd61439..4624648f1 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -5,6 +5,7 @@ diff --git a/it/pom.xml b/it/pom.xml new file mode 100644 index 000000000..d3f611b06 --- /dev/null +++ b/it/pom.xml @@ -0,0 +1,86 @@ + + + + 4.0.0 + + io.openpixee.it + it + 0.0.1-SNAPSHOT + + it + + http://www.example.com + + + UTF-8 + 1.8 + 1.8 + + + + + io.openpixee.maven + pom-operator + 0.0.1-SNAPSHOT + + + org.slf4j + slf4j-api + 2.0.0 + + + junit + junit + 4.13.2 + test + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + diff --git a/it/src/test/java/io/openpixee/it/POMOperatorJavaTest.java b/it/src/test/java/io/openpixee/it/POMOperatorJavaTest.java new file mode 100644 index 000000000..ab15ac99f --- /dev/null +++ b/it/src/test/java/io/openpixee/it/POMOperatorJavaTest.java @@ -0,0 +1,18 @@ +package io.openpixee.it; + +import org.junit.Test; + +import java.io.File; + +import io.openpixee.maven.operator.Context; +import io.openpixee.maven.operator.Dependency; +import io.openpixee.maven.operator.POMOperator; + +public class POMOperatorJavaTest { + @Test + public void testInterop() { + Context ctx = Context.Companion.load(POMOperatorJavaTest.class.getResource("pom.xml"), new Dependency("org.dom4j", "dom4j", "0.0.0", null, "jar")); + + POMOperator.INSTANCE.upgradePom(ctx); + } +} diff --git a/it/src/test/resources/io/openpixee/it/pom.xml b/it/src/test/resources/io/openpixee/it/pom.xml new file mode 100644 index 000000000..014b868fd --- /dev/null +++ b/it/src/test/resources/io/openpixee/it/pom.xml @@ -0,0 +1,152 @@ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + pom-operator + + http://www.example.com + + + UTF-8 + 1.8 + 1.8 + 1.5.31 + + + + + org.dom4j + dom4j + 2.1.3 + + + jaxen + jaxen + 1.2.0 + + + xerces + xercesImpl + 2.12.1 + + + io.github.java-diff-utils + java-diff-utils + 4.9 + + + junit + junit + 4.11 + test + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + org.apache.maven.plugins + maven-compiler-plugin + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + + + From 4d9d3b3446f07750caf88a154258977c229aae6a Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Tue, 6 Sep 2022 13:56:38 -0500 Subject: [PATCH 030/153] Fixing build --- .github/workflows/push-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push-test.yml b/.github/workflows/push-test.yml index e510d3981..8eef26c34 100644 --- a/.github/workflows/push-test.yml +++ b/.github/workflows/push-test.yml @@ -28,7 +28,7 @@ jobs: with: maven-version: 3.8.2 - name: Build with Maven - run: > + run: | mvn -B install mvn -f it/pom.xml test mvn -B deploy -DaltDeploymentRepository=pixee::default::https://pixee.jfrog.io/artifactory/mailman-libs-snapshot From 46f9b38f47289ba4fa84805e41b51121ca4c42ec Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Tue, 6 Sep 2022 17:06:14 -0500 Subject: [PATCH 031/153] Code cleanup + .idea dirs --- .github/workflows/push-test.yml | 2 +- .gitignore | 22 +- .idea/.gitignore | 10 - .idea/codeStyles/Project.xml | 620 ------------------ .idea/codeStyles/codeStyleConfig.xml | 6 - .idea/compiler.xml | 14 - .idea/dataSources.xml | 15 - .idea/encodings.xml | 11 - .idea/jarRepositories.xml | 20 - .idea/kotlinc.xml | 6 - .idea/misc.xml | 13 - .idea/vcs.xml | 6 - README.md | 7 + .../io/openpixee/it/POMOperatorJavaTest.java | 18 - {it => java-test-fixture}/pom.xml | 0 .../io/openpixee/it/POMOperatorJavaTest.java | 17 + .../test/resources/io/openpixee/it/pom.xml | 0 .../java/io/openpixee/maven/operator/App.kt | 2 +- .../io/openpixee/maven/operator/Command.kt | 14 +- .../openpixee/maven/operator/POMOperator.kt | 3 +- .../operator/{Context.kt => ProjectModel.kt} | 24 +- .../maven/operator/POMOperatorTest.kt | 6 +- 22 files changed, 52 insertions(+), 784 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/codeStyles/Project.xml delete mode 100644 .idea/codeStyles/codeStyleConfig.xml delete mode 100644 .idea/compiler.xml delete mode 100644 .idea/dataSources.xml delete mode 100644 .idea/encodings.xml delete mode 100644 .idea/jarRepositories.xml delete mode 100644 .idea/kotlinc.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/vcs.xml delete mode 100644 it/src/test/java/io/openpixee/it/POMOperatorJavaTest.java rename {it => java-test-fixture}/pom.xml (100%) create mode 100644 java-test-fixture/src/test/java/io/openpixee/it/POMOperatorJavaTest.java rename {it => java-test-fixture}/src/test/resources/io/openpixee/it/pom.xml (100%) rename src/main/java/io/openpixee/maven/operator/{Context.kt => ProjectModel.kt} (70%) diff --git a/.github/workflows/push-test.yml b/.github/workflows/push-test.yml index 8eef26c34..6f907b414 100644 --- a/.github/workflows/push-test.yml +++ b/.github/workflows/push-test.yml @@ -30,6 +30,6 @@ jobs: - name: Build with Maven run: | mvn -B install - mvn -f it/pom.xml test + mvn -f java-test-fixture/pom.xml test mvn -B deploy -DaltDeploymentRepository=pixee::default::https://pixee.jfrog.io/artifactory/mailman-libs-snapshot diff --git a/.gitignore b/.gitignore index cdf6b5c3c..8efd9c415 100644 --- a/.gitignore +++ b/.gitignore @@ -16,27 +16,7 @@ buildNumber.properties # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries +.idea/ # Gradle and Maven with auto-import # When using Gradle or Maven with auto-import, you should exclude module files, diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 11bd5c0e3..000000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Zeppelin ignored files -/ZeppelinRemoteNotebooks/ diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 8bc95d2bb..000000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,620 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 3c617fb8f..000000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 31fd4523e..000000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml deleted file mode 100644 index 4b6190a5e..000000000 --- a/.idea/dataSources.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - true - Wrapper For Zeppelin Spark from Big Data Tools plugin - com.dbschema.ZeppelinSparkJdbcDriver - Zeppelin connection@ZeppelinConnections@-3103216562587865833 - - - - $ProjectFileDir$ - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index 4217ed85b..000000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index 712ab9d98..000000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml deleted file mode 100644 index b1077fbd0..000000000 --- a/.idea/kotlinc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 4624648f1..000000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7f4..000000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/README.md b/README.md index f560a1eac..7454d56da 100644 --- a/README.md +++ b/README.md @@ -21,3 +21,10 @@ I want a Java library that helps me inject this dependency into a repository alr 4. The POM doesn't have a "dependencies" section or inheritance so we need to inject that section as well as the "dependency" section. 5. The POM doesn't have the dependency or inherit it, so it needs to be inserted. + +- Make it cleaner +- Folder structure (it) +- better readme +- context -> projectmodel +- companion stuff / instance +- .idea / \ No newline at end of file diff --git a/it/src/test/java/io/openpixee/it/POMOperatorJavaTest.java b/it/src/test/java/io/openpixee/it/POMOperatorJavaTest.java deleted file mode 100644 index ab15ac99f..000000000 --- a/it/src/test/java/io/openpixee/it/POMOperatorJavaTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.openpixee.it; - -import org.junit.Test; - -import java.io.File; - -import io.openpixee.maven.operator.Context; -import io.openpixee.maven.operator.Dependency; -import io.openpixee.maven.operator.POMOperator; - -public class POMOperatorJavaTest { - @Test - public void testInterop() { - Context ctx = Context.Companion.load(POMOperatorJavaTest.class.getResource("pom.xml"), new Dependency("org.dom4j", "dom4j", "0.0.0", null, "jar")); - - POMOperator.INSTANCE.upgradePom(ctx); - } -} diff --git a/it/pom.xml b/java-test-fixture/pom.xml similarity index 100% rename from it/pom.xml rename to java-test-fixture/pom.xml diff --git a/java-test-fixture/src/test/java/io/openpixee/it/POMOperatorJavaTest.java b/java-test-fixture/src/test/java/io/openpixee/it/POMOperatorJavaTest.java new file mode 100644 index 000000000..630083d18 --- /dev/null +++ b/java-test-fixture/src/test/java/io/openpixee/it/POMOperatorJavaTest.java @@ -0,0 +1,17 @@ +package io.openpixee.it; + +import org.junit.Test; + +import io.openpixee.maven.operator.ProjectModel; +import io.openpixee.maven.operator.Dependency; +import io.openpixee.maven.operator.POMOperator; +import io.openpixee.maven.operator.ProjectModelFactory; + +public class POMOperatorJavaTest { + @Test + public void testInterop() { + ProjectModel projectModel = ProjectModelFactory.load(POMOperatorJavaTest.class.getResource("pom.xml"), new Dependency("org.dom4j", "dom4j", "0.0.0", null, "jar")); + + POMOperator.upgradePom(projectModel); + } +} diff --git a/it/src/test/resources/io/openpixee/it/pom.xml b/java-test-fixture/src/test/resources/io/openpixee/it/pom.xml similarity index 100% rename from it/src/test/resources/io/openpixee/it/pom.xml rename to java-test-fixture/src/test/resources/io/openpixee/it/pom.xml diff --git a/src/main/java/io/openpixee/maven/operator/App.kt b/src/main/java/io/openpixee/maven/operator/App.kt index 736e48585..842f68847 100644 --- a/src/main/java/io/openpixee/maven/operator/App.kt +++ b/src/main/java/io/openpixee/maven/operator/App.kt @@ -26,7 +26,7 @@ object App { @Suppress("UNCHECKED_CAST") val files = opts["POMFILES"]!! as List for (path in files) { - val ctx = Context.load(File(path), dep) + val ctx = ProjectModelFactory.load(File(path), dep) println("Upgrading dependency ($dep) in path $path") diff --git a/src/main/java/io/openpixee/maven/operator/Command.kt b/src/main/java/io/openpixee/maven/operator/Command.kt index 8b297a9e7..6085b54a0 100644 --- a/src/main/java/io/openpixee/maven/operator/Command.kt +++ b/src/main/java/io/openpixee/maven/operator/Command.kt @@ -16,11 +16,11 @@ import kotlin.math.ceil fun interface Command { - fun execute(c: Context): Boolean + fun execute(c: ProjectModel): Boolean } abstract class AbstractSimpleCommand : Command { - protected fun handleDependency(c: Context, lookupExpression: String): Boolean { + protected fun handleDependency(c: ProjectModel, lookupExpression: String): Boolean { val dependencyNodes = c.resultPom.selectXPathNodes(lookupExpression) if (1 == dependencyNodes.size) { @@ -38,7 +38,7 @@ abstract class AbstractSimpleCommand : Command { } val SimpleUpgrade = object : AbstractSimpleCommand() { - override fun execute(c: Context): Boolean { + override fun execute(c: ProjectModel): Boolean { val lookupExpressionForDependency = buildLookupExpressionForDependency(c.dependencyToInsert) return handleDependency(c, lookupExpressionForDependency) @@ -46,7 +46,7 @@ val SimpleUpgrade = object : AbstractSimpleCommand() { } val SimpleDependencyManagement = object : AbstractSimpleCommand() { - override fun execute(c: Context): Boolean { + override fun execute(c: ProjectModel): Boolean { val lookupExpression = buildLookupExpressionForDependencyManagement(c.dependencyToInsert) return handleDependency(c, lookupExpression) @@ -54,7 +54,7 @@ val SimpleDependencyManagement = object : AbstractSimpleCommand() { } val SimpleInsert = object : Command { - override fun execute(c: Context): Boolean { + override fun execute(c: ProjectModel): Boolean { val dependencyManagementNode = c.resultPom.selectXPathNodes("/m:project/m:dependencyManagement") val elementsToFormat : MutableList = arrayListOf() @@ -141,7 +141,7 @@ val SimpleInsert = object : Command { private fun appendCoordinates( dependenciesNode: Element, - c: Context + c: ProjectModel ): Element { val dependencyNode = dependenciesNode.addElement("dependency") @@ -159,7 +159,7 @@ val SimpleInsert = object : Command { class Chain(vararg c: Command) { private val commandList = ArrayList(c.toList()) - fun execute(c: Context): Boolean { + fun execute(c: ProjectModel): Boolean { var done = false val listIterator = commandList.listIterator() diff --git a/src/main/java/io/openpixee/maven/operator/POMOperator.kt b/src/main/java/io/openpixee/maven/operator/POMOperator.kt index c29cf703d..acdf93884 100644 --- a/src/main/java/io/openpixee/maven/operator/POMOperator.kt +++ b/src/main/java/io/openpixee/maven/operator/POMOperator.kt @@ -2,5 +2,6 @@ package io.openpixee.maven.operator object POMOperator { - fun upgradePom(context: Context) = Chain.create().execute(context) + @JvmStatic + fun upgradePom(projectModel: ProjectModel) = Chain.create().execute(projectModel) } diff --git a/src/main/java/io/openpixee/maven/operator/Context.kt b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt similarity index 70% rename from src/main/java/io/openpixee/maven/operator/Context.kt rename to src/main/java/io/openpixee/maven/operator/ProjectModel.kt index b1d956c5b..4835f75cf 100644 --- a/src/main/java/io/openpixee/maven/operator/Context.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt @@ -8,7 +8,7 @@ import java.io.InputStream import java.lang.IllegalStateException import java.net.URL -data class Context( +data class ProjectModel( val pomDocument: Document, val dependencyToInsert: Dependency, ) { @@ -42,18 +42,20 @@ data class Context( return SAXReader().read(FileInputStream(tmpOutputFile)) } +} - companion object { - private fun load(`is`: InputStream, dependencyToInsert: Dependency): Context { - val pomDocument = SAXReader().read(`is`)!! +object ProjectModelFactory { + private fun load(`is`: InputStream, dependencyToInsert: Dependency): ProjectModel { + val pomDocument = SAXReader().read(`is`)!! - return Context(pomDocument, dependencyToInsert) - } + return ProjectModel(pomDocument, dependencyToInsert) + } - fun load(f: File, dependencyToInsert: Dependency) = - load(FileInputStream(f), dependencyToInsert) + @JvmStatic + fun load(f: File, dependencyToInsert: Dependency) = + load(FileInputStream(f), dependencyToInsert) - fun load(url: URL, dependencyToInsert: Dependency) = - load(url.openStream(), dependencyToInsert) - } + @JvmStatic + fun load(url: URL, dependencyToInsert: Dependency) = + load(url.openStream(), dependencyToInsert) } \ No newline at end of file diff --git a/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt b/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt index 625313552..1a1ce0765 100644 --- a/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt +++ b/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt @@ -28,7 +28,7 @@ class POMOperatorTest { val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.3") val context = - Context.load( + ProjectModelFactory.load( POMOperator::class.java.getResource("pom-case-1.xml")!!, dependencyToUpgrade ) @@ -71,7 +71,7 @@ class POMOperatorTest { val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.3") val context = - Context.load( + ProjectModelFactory.load( POMOperator::class.java.getResource("pom-case-3.xml")!!, dependencyToUpgrade ) @@ -113,7 +113,7 @@ class POMOperatorTest { Dependency("org.apache.activemq", "activemq-amqp", version = "5.16.2") val context = - Context.load( + ProjectModelFactory.load( POMOperator::class.java.getResource("pom-case-4.xml")!!, dependencyToUpgrade ) From 56860e8fcbfdbd2ed73af1886d3953578e06ec30 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Tue, 6 Sep 2022 19:10:02 -0500 Subject: [PATCH 032/153] Removing D-M-P --- pom.xml | 5 + .../io/openpixee/diff/DiffMatchPatch.java | 2470 ----------------- .../maven/operator/POMOperatorTest.kt | 2 +- 3 files changed, 6 insertions(+), 2471 deletions(-) delete mode 100644 src/test/java/io/openpixee/diff/DiffMatchPatch.java diff --git a/pom.xml b/pom.xml index 0839ca8fb..f757a348e 100644 --- a/pom.xml +++ b/pom.xml @@ -58,6 +58,11 @@ xercesImpl 2.12.2 + + fun.mike + diff-match-patch + 0.0.2 + io.github.java-diff-utils java-diff-utils diff --git a/src/test/java/io/openpixee/diff/DiffMatchPatch.java b/src/test/java/io/openpixee/diff/DiffMatchPatch.java deleted file mode 100644 index 35de22143..000000000 --- a/src/test/java/io/openpixee/diff/DiffMatchPatch.java +++ /dev/null @@ -1,2470 +0,0 @@ -package io.openpixee.diff; - -/* - * Diff Match and Patch - * Copyright 2018 The diff-match-patch Authors. - * https://github.com/google/diff-match-patch - * - * Licensed 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 java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/* - * Functions for diff, match and patch. - * Computes the difference between two texts to create a patch. - * Applies the patch onto another text, allowing for errors. - * - * @author fraser@google.com (Neil Fraser) - */ - -/** - * Class containing the diff, match and patch methods. - * Also contains the behaviour settings. - */ -@SuppressWarnings("ALL") -public class DiffMatchPatch { - - // Defaults. - // Set these on your diff_match_patch instance to override the defaults. - - /** - * Number of seconds to map a diff before giving up (0 for infinity). - */ - public float Diff_Timeout = 1.0f; - /** - * Cost of an empty edit operation in terms of edit characters. - */ - public short Diff_EditCost = 4; - /** - * At what point is no match declared (0.0 = perfection, 1.0 = very loose). - */ - public float Match_Threshold = 0.5f; - /** - * How far to search for a match (0 = exact location, 1000+ = broad match). - * A match this many characters away from the expected location will add - * 1.0 to the score (0.0 is a perfect match). - */ - public int Match_Distance = 1000; - /** - * When deleting a large block of text (over ~64 characters), how close do - * the contents have to be to match the expected contents. (0.0 = perfection, - * 1.0 = very loose). Note that Match_Threshold controls how closely the - * end points of a delete need to match. - */ - public float Patch_DeleteThreshold = 0.5f; - /** - * Chunk size for context length. - */ - public short Patch_Margin = 4; - - /** - * The number of bits in an int. - */ - private final short Match_MaxBits = 32; - - /** - * Internal class for returning results from diff_linesToChars(). - * Other less paranoid languages just use a three-element array. - */ - protected static class LinesToCharsResult { - protected String chars1; - protected String chars2; - protected List lineArray; - - protected LinesToCharsResult(String chars1, String chars2, - List lineArray) { - this.chars1 = chars1; - this.chars2 = chars2; - this.lineArray = lineArray; - } - } - - - // DIFF FUNCTIONS - - - /** - * The data structure representing a diff is a Linked list of Diff objects: - * {Diff(Operation.DELETE, "Hello"), Diff(Operation.INSERT, "Goodbye"), - * Diff(Operation.EQUAL, " world.")} - * which means: delete "Hello", add "Goodbye" and keep " world." - */ - public enum Operation { - DELETE, INSERT, EQUAL - } - - /** - * Find the differences between two texts. - * Run a faster, slightly less optimal diff. - * This method allows the 'checklines' of diff_main() to be optional. - * Most of the time checklines is wanted, so default to true. - * @param text1 Old string to be diffed. - * @param text2 New string to be diffed. - * @return Linked List of Diff objects. - */ - public LinkedList diff_main(String text1, String text2) { - return diff_main(text1, text2, true); - } - - /** - * Find the differences between two texts. - * @param text1 Old string to be diffed. - * @param text2 New string to be diffed. - * @param checklines Speedup flag. If false, then don't run a - * line-level diff first to identify the changed areas. - * If true, then run a faster slightly less optimal diff. - * @return Linked List of Diff objects. - */ - public LinkedList diff_main(String text1, String text2, - boolean checklines) { - // Set a deadline by which time the diff must be complete. - long deadline; - if (Diff_Timeout <= 0) { - deadline = Long.MAX_VALUE; - } else { - deadline = System.currentTimeMillis() + (long) (Diff_Timeout * 1000); - } - return diff_main(text1, text2, checklines, deadline); - } - - /** - * Find the differences between two texts. Simplifies the problem by - * stripping any common prefix or suffix off the texts before diffing. - * @param text1 Old string to be diffed. - * @param text2 New string to be diffed. - * @param checklines Speedup flag. If false, then don't run a - * line-level diff first to identify the changed areas. - * If true, then run a faster slightly less optimal diff. - * @param deadline Time when the diff should be complete by. Used - * internally for recursive calls. Users should set DiffTimeout instead. - * @return Linked List of Diff objects. - */ - private LinkedList diff_main(String text1, String text2, - boolean checklines, long deadline) { - // Check for null inputs. - if (text1 == null || text2 == null) { - throw new IllegalArgumentException("Null inputs. (diff_main)"); - } - - // Check for equality (speedup). - LinkedList diffs; - if (text1.equals(text2)) { - diffs = new LinkedList<>(); - if (text1.length() != 0) { - diffs.add(new Diff(Operation.EQUAL, text1)); - } - return diffs; - } - - // Trim off common prefix (speedup). - int commonlength = diff_commonPrefix(text1, text2); - String commonprefix = text1.substring(0, commonlength); - text1 = text1.substring(commonlength); - text2 = text2.substring(commonlength); - - // Trim off common suffix (speedup). - commonlength = diff_commonSuffix(text1, text2); - String commonsuffix = text1.substring(text1.length() - commonlength); - text1 = text1.substring(0, text1.length() - commonlength); - text2 = text2.substring(0, text2.length() - commonlength); - - // Compute the diff on the middle block. - diffs = diff_compute(text1, text2, checklines, deadline); - - // Restore the prefix and suffix. - if (commonprefix.length() != 0) { - diffs.addFirst(new Diff(Operation.EQUAL, commonprefix)); - } - if (commonsuffix.length() != 0) { - diffs.addLast(new Diff(Operation.EQUAL, commonsuffix)); - } - - diff_cleanupMerge(diffs); - return diffs; - } - - /** - * Find the differences between two texts. Assumes that the texts do not - * have any common prefix or suffix. - * @param text1 Old string to be diffed. - * @param text2 New string to be diffed. - * @param checklines Speedup flag. If false, then don't run a - * line-level diff first to identify the changed areas. - * If true, then run a faster slightly less optimal diff. - * @param deadline Time when the diff should be complete by. - * @return Linked List of Diff objects. - */ - private LinkedList diff_compute(String text1, String text2, - boolean checklines, long deadline) { - LinkedList diffs = new LinkedList<>(); - - if (text1.length() == 0) { - // Just add some text (speedup). - diffs.add(new Diff(Operation.INSERT, text2)); - return diffs; - } - - if (text2.length() == 0) { - // Just delete some text (speedup). - diffs.add(new Diff(Operation.DELETE, text1)); - return diffs; - } - - String longtext = text1.length() > text2.length() ? text1 : text2; - String shorttext = text1.length() > text2.length() ? text2 : text1; - int i = longtext.indexOf(shorttext); - if (i != -1) { - // Shorter text is inside the longer text (speedup). - Operation op = (text1.length() > text2.length()) ? - Operation.DELETE : Operation.INSERT; - diffs.add(new Diff(op, longtext.substring(0, i))); - diffs.add(new Diff(Operation.EQUAL, shorttext)); - diffs.add(new Diff(op, longtext.substring(i + shorttext.length()))); - return diffs; - } - - if (shorttext.length() == 1) { - // Single character string. - // After the previous speedup, the character can't be an equality. - diffs.add(new Diff(Operation.DELETE, text1)); - diffs.add(new Diff(Operation.INSERT, text2)); - return diffs; - } - - // Check to see if the problem can be split in two. - String[] hm = diff_halfMatch(text1, text2); - if (hm != null) { - // A half-match was found, sort out the return data. - String text1_a = hm[0]; - String text1_b = hm[1]; - String text2_a = hm[2]; - String text2_b = hm[3]; - String mid_common = hm[4]; - // Send both pairs off for separate processing. - LinkedList diffs_a = diff_main(text1_a, text2_a, - checklines, deadline); - LinkedList diffs_b = diff_main(text1_b, text2_b, - checklines, deadline); - // Merge the results. - diffs = diffs_a; - diffs.add(new Diff(Operation.EQUAL, mid_common)); - diffs.addAll(diffs_b); - return diffs; - } - - if (checklines && text1.length() > 100 && text2.length() > 100) { - return diff_lineMode(text1, text2, deadline); - } - - return diff_bisect(text1, text2, deadline); - } - - /** - * Do a quick line-level diff on both strings, then rediff the parts for - * greater accuracy. - * This speedup can produce non-minimal diffs. - * @param text1 Old string to be diffed. - * @param text2 New string to be diffed. - * @param deadline Time when the diff should be complete by. - * @return Linked List of Diff objects. - */ - private LinkedList diff_lineMode(String text1, String text2, - long deadline) { - // Scan the text on a line-by-line basis first. - LinesToCharsResult a = diff_linesToChars(text1, text2); - text1 = a.chars1; - text2 = a.chars2; - List linearray = a.lineArray; - - LinkedList diffs = diff_main(text1, text2, false, deadline); - - // Convert the diff back to original text. - diff_charsToLines(diffs, linearray); - // Eliminate freak matches (e.g. blank lines) - diff_cleanupSemantic(diffs); - - // Rediff any replacement blocks, this time character-by-character. - // Add a dummy entry at the end. - diffs.add(new Diff(Operation.EQUAL, "")); - int count_delete = 0; - int count_insert = 0; - StringBuilder text_delete = new StringBuilder(); - StringBuilder text_insert = new StringBuilder(); - ListIterator pointer = diffs.listIterator(); - Diff thisDiff = pointer.next(); - while (thisDiff != null) { - switch (thisDiff.operation) { - case INSERT: - count_insert++; - text_insert.append(thisDiff.text); - break; - case DELETE: - count_delete++; - text_delete.append(thisDiff.text); - break; - case EQUAL: - // Upon reaching an equality, check for prior redundancies. - if (count_delete >= 1 && count_insert >= 1) { - // Delete the offending records and add the merged ones. - pointer.previous(); - for (int j = 0; j < count_delete + count_insert; j++) { - pointer.previous(); - pointer.remove(); - } - for (Diff subDiff : diff_main(text_delete.toString(), text_insert.toString(), false, - deadline)) { - pointer.add(subDiff); - } - } - count_insert = 0; - count_delete = 0; - text_delete = new StringBuilder(); - text_insert = new StringBuilder(); - break; - } - thisDiff = pointer.hasNext() ? pointer.next() : null; - } - diffs.removeLast(); // Remove the dummy entry at the end. - - return diffs; - } - - /** - * Find the 'middle snake' of a diff, split the problem in two - * and return the recursively constructed diff. - * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations. - * @param text1 Old string to be diffed. - * @param text2 New string to be diffed. - * @param deadline Time at which to bail if not yet complete. - * @return LinkedList of Diff objects. - */ - protected LinkedList diff_bisect(String text1, String text2, - long deadline) { - // Cache the text lengths to prevent multiple calls. - int text1_length = text1.length(); - int text2_length = text2.length(); - int max_d = (text1_length + text2_length + 1) / 2; - int v_length = 2 * max_d; - int[] v1 = new int[v_length]; - int[] v2 = new int[v_length]; - for (int x = 0; x < v_length; x++) { - v1[x] = -1; - v2[x] = -1; - } - v1[max_d + 1] = 0; - v2[max_d + 1] = 0; - int delta = text1_length - text2_length; - // If the total number of characters is odd, then the front path will - // collide with the reverse path. - boolean front = (delta % 2 != 0); - // Offsets for start and end of k loop. - // Prevents mapping of space beyond the grid. - int k1start = 0; - int k1end = 0; - int k2start = 0; - int k2end = 0; - for (int d = 0; d < max_d; d++) { - // Bail out if deadline is reached. - if (System.currentTimeMillis() > deadline) { - break; - } - - // Walk the front path one step. - for (int k1 = -d + k1start; k1 <= d - k1end; k1 += 2) { - int k1_offset = max_d + k1; - int x1; - if (k1 == -d || (k1 != d && v1[k1_offset - 1] < v1[k1_offset + 1])) { - x1 = v1[k1_offset + 1]; - } else { - x1 = v1[k1_offset - 1] + 1; - } - int y1 = x1 - k1; - while (x1 < text1_length && y1 < text2_length - && text1.charAt(x1) == text2.charAt(y1)) { - x1++; - y1++; - } - v1[k1_offset] = x1; - if (x1 > text1_length) { - // Ran off the right of the graph. - k1end += 2; - } else if (y1 > text2_length) { - // Ran off the bottom of the graph. - k1start += 2; - } else if (front) { - int k2_offset = max_d + delta - k1; - if (k2_offset >= 0 && k2_offset < v_length && v2[k2_offset] != -1) { - // Mirror x2 onto top-left coordinate system. - int x2 = text1_length - v2[k2_offset]; - if (x1 >= x2) { - // Overlap detected. - return diff_bisectSplit(text1, text2, x1, y1, deadline); - } - } - } - } - - // Walk the reverse path one step. - for (int k2 = -d + k2start; k2 <= d - k2end; k2 += 2) { - int k2_offset = max_d + k2; - int x2; - if (k2 == -d || (k2 != d && v2[k2_offset - 1] < v2[k2_offset + 1])) { - x2 = v2[k2_offset + 1]; - } else { - x2 = v2[k2_offset - 1] + 1; - } - int y2 = x2 - k2; - while (x2 < text1_length && y2 < text2_length - && text1.charAt(text1_length - x2 - 1) - == text2.charAt(text2_length - y2 - 1)) { - x2++; - y2++; - } - v2[k2_offset] = x2; - if (x2 > text1_length) { - // Ran off the left of the graph. - k2end += 2; - } else if (y2 > text2_length) { - // Ran off the top of the graph. - k2start += 2; - } else if (!front) { - int k1_offset = max_d + delta - k2; - if (k1_offset >= 0 && k1_offset < v_length && v1[k1_offset] != -1) { - int x1 = v1[k1_offset]; - int y1 = max_d + x1 - k1_offset; - // Mirror x2 onto top-left coordinate system. - x2 = text1_length - x2; - if (x1 >= x2) { - // Overlap detected. - return diff_bisectSplit(text1, text2, x1, y1, deadline); - } - } - } - } - } - // Diff took too long and hit the deadline or - // number of diffs equals number of characters, no commonality at all. - LinkedList diffs = new LinkedList<>(); - diffs.add(new Diff(Operation.DELETE, text1)); - diffs.add(new Diff(Operation.INSERT, text2)); - return diffs; - } - - /** - * Given the location of the 'middle snake', split the diff in two parts - * and recurse. - * @param text1 Old string to be diffed. - * @param text2 New string to be diffed. - * @param x Index of split point in text1. - * @param y Index of split point in text2. - * @param deadline Time at which to bail if not yet complete. - * @return LinkedList of Diff objects. - */ - private LinkedList diff_bisectSplit(String text1, String text2, - int x, int y, long deadline) { - String text1a = text1.substring(0, x); - String text2a = text2.substring(0, y); - String text1b = text1.substring(x); - String text2b = text2.substring(y); - - // Compute both diffs serially. - LinkedList diffs = diff_main(text1a, text2a, false, deadline); - LinkedList diffsb = diff_main(text1b, text2b, false, deadline); - - diffs.addAll(diffsb); - return diffs; - } - - /** - * Split two texts into a list of strings. Reduce the texts to a string of - * hashes where each Unicode character represents one line. - * @param text1 First string. - * @param text2 Second string. - * @return An object containing the encoded text1, the encoded text2 and - * the List of unique strings. The zeroth element of the List of - * unique strings is intentionally blank. - */ - protected LinesToCharsResult diff_linesToChars(String text1, String text2) { - List lineArray = new ArrayList<>(); - Map lineHash = new HashMap<>(); - // e.g. linearray[4] == "Hello\n" - // e.g. linehash.get("Hello\n") == 4 - - // "\x00" is a valid character, but various debuggers don't like it. - // So we'll insert a junk entry to avoid generating a null character. - lineArray.add(""); - - // Allocate 2/3rds of the space for text1, the rest for text2. - String chars1 = diff_linesToCharsMunge(text1, lineArray, lineHash, 40000); - String chars2 = diff_linesToCharsMunge(text2, lineArray, lineHash, 65535); - return new LinesToCharsResult(chars1, chars2, lineArray); - } - - /** - * Split a text into a list of strings. Reduce the texts to a string of - * hashes where each Unicode character represents one line. - * @param text String to encode. - * @param lineArray List of unique strings. - * @param lineHash Map of strings to indices. - * @param maxLines Maximum length of lineArray. - * @return Encoded string. - */ - private String diff_linesToCharsMunge(String text, List lineArray, - Map lineHash, int maxLines) { - int lineStart = 0; - int lineEnd = -1; - String line; - StringBuilder chars = new StringBuilder(); - // Walk the text, pulling out a substring for each line. - // text.split('\n') would would temporarily double our memory footprint. - // Modifying text would create many large strings to garbage collect. - while (lineEnd < text.length() - 1) { - lineEnd = text.indexOf('\n', lineStart); - if (lineEnd == -1) { - lineEnd = text.length() - 1; - } - line = text.substring(lineStart, lineEnd + 1); - - if (lineHash.containsKey(line)) { - chars.append((char) (int) lineHash.get(line)); - } else { - if (lineArray.size() == maxLines) { - // Bail out at 65535 because - // String.valueOf((char) 65536).equals(String.valueOf(((char) 0))) - line = text.substring(lineStart); - lineEnd = text.length(); - } - lineArray.add(line); - lineHash.put(line, lineArray.size() - 1); - chars.append((char) (lineArray.size() - 1)); - } - lineStart = lineEnd + 1; - } - return chars.toString(); - } - - /** - * Rehydrate the text in a diff from a string of line hashes to real lines of - * text. - * @param diffs List of Diff objects. - * @param lineArray List of unique strings. - */ - protected void diff_charsToLines(List diffs, - List lineArray) { - StringBuilder text; - for (Diff diff : diffs) { - text = new StringBuilder(); - for (int j = 0; j < diff.text.length(); j++) { - text.append(lineArray.get(diff.text.charAt(j))); - } - diff.text = text.toString(); - } - } - - /** - * Determine the common prefix of two strings - * @param text1 First string. - * @param text2 Second string. - * @return The number of characters common to the start of each string. - */ - public int diff_commonPrefix(String text1, String text2) { - // Performance analysis: https://neil.fraser.name/news/2007/10/09/ - int n = Math.min(text1.length(), text2.length()); - for (int i = 0; i < n; i++) { - if (text1.charAt(i) != text2.charAt(i)) { - return i; - } - } - return n; - } - - /** - * Determine the common suffix of two strings - * @param text1 First string. - * @param text2 Second string. - * @return The number of characters common to the end of each string. - */ - public int diff_commonSuffix(String text1, String text2) { - // Performance analysis: https://neil.fraser.name/news/2007/10/09/ - int text1_length = text1.length(); - int text2_length = text2.length(); - int n = Math.min(text1_length, text2_length); - for (int i = 1; i <= n; i++) { - if (text1.charAt(text1_length - i) != text2.charAt(text2_length - i)) { - return i - 1; - } - } - return n; - } - - /** - * Determine if the suffix of one string is the prefix of another. - * @param text1 First string. - * @param text2 Second string. - * @return The number of characters common to the end of the first - * string and the start of the second string. - */ - protected int diff_commonOverlap(String text1, String text2) { - // Cache the text lengths to prevent multiple calls. - int text1_length = text1.length(); - int text2_length = text2.length(); - // Eliminate the null case. - if (text1_length == 0 || text2_length == 0) { - return 0; - } - // Truncate the longer string. - if (text1_length > text2_length) { - text1 = text1.substring(text1_length - text2_length); - } else if (text1_length < text2_length) { - text2 = text2.substring(0, text1_length); - } - int text_length = Math.min(text1_length, text2_length); - // Quick check for the worst case. - if (text1.equals(text2)) { - return text_length; - } - - // Start by looking for a single character match - // and increase length until no match is found. - // Performance analysis: https://neil.fraser.name/news/2010/11/04/ - int best = 0; - int length = 1; - while (true) { - String pattern = text1.substring(text_length - length); - int found = text2.indexOf(pattern); - if (found == -1) { - return best; - } - length += found; - if (found == 0 || text1.substring(text_length - length).equals( - text2.substring(0, length))) { - best = length; - length++; - } - } - } - - /** - * Do the two texts share a substring which is at least half the length of - * the longer text? - * This speedup can produce non-minimal diffs. - * @param text1 First string. - * @param text2 Second string. - * @return Five element String array, containing the prefix of text1, the - * suffix of text1, the prefix of text2, the suffix of text2 and the - * common middle. Or null if there was no match. - */ - protected String[] diff_halfMatch(String text1, String text2) { - if (Diff_Timeout <= 0) { - // Don't risk returning a non-optimal diff if we have unlimited time. - return null; - } - String longtext = text1.length() > text2.length() ? text1 : text2; - String shorttext = text1.length() > text2.length() ? text2 : text1; - if (longtext.length() < 4 || shorttext.length() * 2 < longtext.length()) { - return null; // Pointless. - } - - // First check if the second quarter is the seed for a half-match. - String[] hm1 = diff_halfMatchI(longtext, shorttext, - (longtext.length() + 3) / 4); - // Check again based on the third quarter. - String[] hm2 = diff_halfMatchI(longtext, shorttext, - (longtext.length() + 1) / 2); - String[] hm; - if (hm1 == null && hm2 == null) { - return null; - } else if (hm2 == null) { - hm = hm1; - } else if (hm1 == null) { - hm = hm2; - } else { - // Both matched. Select the longest. - hm = hm1[4].length() > hm2[4].length() ? hm1 : hm2; - } - - // A half-match was found, sort out the return data. - if (text1.length() > text2.length()) { - return hm; - //return new String[]{hm[0], hm[1], hm[2], hm[3], hm[4]}; - } else { - return new String[]{hm[2], hm[3], hm[0], hm[1], hm[4]}; - } - } - - /** - * Does a substring of shorttext exist within longtext such that the - * substring is at least half the length of longtext? - * @param longtext Longer string. - * @param shorttext Shorter string. - * @param i Start index of quarter length substring within longtext. - * @return Five element String array, containing the prefix of longtext, the - * suffix of longtext, the prefix of shorttext, the suffix of shorttext - * and the common middle. Or null if there was no match. - */ - private String[] diff_halfMatchI(String longtext, String shorttext, int i) { - // Start with a 1/4 length substring at position i as a seed. - String seed = longtext.substring(i, i + longtext.length() / 4); - int j = -1; - String best_common = ""; - String best_longtext_a = "", best_longtext_b = ""; - String best_shorttext_a = "", best_shorttext_b = ""; - while ((j = shorttext.indexOf(seed, j + 1)) != -1) { - int prefixLength = diff_commonPrefix(longtext.substring(i), - shorttext.substring(j)); - int suffixLength = diff_commonSuffix(longtext.substring(0, i), - shorttext.substring(0, j)); - if (best_common.length() < suffixLength + prefixLength) { - best_common = shorttext.substring(j - suffixLength, j) - + shorttext.substring(j, j + prefixLength); - best_longtext_a = longtext.substring(0, i - suffixLength); - best_longtext_b = longtext.substring(i + prefixLength); - best_shorttext_a = shorttext.substring(0, j - suffixLength); - best_shorttext_b = shorttext.substring(j + prefixLength); - } - } - if (best_common.length() * 2 >= longtext.length()) { - return new String[]{best_longtext_a, best_longtext_b, - best_shorttext_a, best_shorttext_b, best_common}; - } else { - return null; - } - } - - /** - * Reduce the number of edits by eliminating semantically trivial equalities. - * @param diffs LinkedList of Diff objects. - */ - public void diff_cleanupSemantic(LinkedList diffs) { - if (diffs.isEmpty()) { - return; - } - boolean changes = false; - Deque equalities = new ArrayDeque<>(); // Double-ended queue of qualities. - String lastEquality = null; // Always equal to equalities.peek().text - ListIterator pointer = diffs.listIterator(); - // Number of characters that changed prior to the equality. - int length_insertions1 = 0; - int length_deletions1 = 0; - // Number of characters that changed after the equality. - int length_insertions2 = 0; - int length_deletions2 = 0; - Diff thisDiff = pointer.next(); - while (thisDiff != null) { - if (thisDiff.operation == Operation.EQUAL) { - // Equality found. - equalities.push(thisDiff); - length_insertions1 = length_insertions2; - length_deletions1 = length_deletions2; - length_insertions2 = 0; - length_deletions2 = 0; - lastEquality = thisDiff.text; - } else { - // An insertion or deletion. - if (thisDiff.operation == Operation.INSERT) { - length_insertions2 += thisDiff.text.length(); - } else { - length_deletions2 += thisDiff.text.length(); - } - // Eliminate an equality that is smaller or equal to the edits on both - // sides of it. - if (lastEquality != null && (lastEquality.length() - <= Math.max(length_insertions1, length_deletions1)) - && (lastEquality.length() - <= Math.max(length_insertions2, length_deletions2))) { - //System.out.println("Splitting: '" + lastEquality + "'"); - // Walk back to offending equality. - while (thisDiff != equalities.peek()) { - thisDiff = pointer.previous(); - } - pointer.next(); - - // Replace equality with a delete. - pointer.set(new Diff(Operation.DELETE, lastEquality)); - // Insert a corresponding an insert. - pointer.add(new Diff(Operation.INSERT, lastEquality)); - - equalities.pop(); // Throw away the equality we just deleted. - if (!equalities.isEmpty()) { - // Throw away the previous equality (it needs to be reevaluated). - equalities.pop(); - } - if (equalities.isEmpty()) { - // There are no previous equalities, walk back to the start. - while (pointer.hasPrevious()) { - pointer.previous(); - } - } else { - // There is a safe equality we can fall back to. - thisDiff = equalities.peek(); - while (thisDiff != pointer.previous()) { - // Intentionally empty loop. - } - } - - length_insertions1 = 0; // Reset the counters. - length_insertions2 = 0; - length_deletions1 = 0; - length_deletions2 = 0; - lastEquality = null; - changes = true; - } - } - thisDiff = pointer.hasNext() ? pointer.next() : null; - } - - // Normalize the diff. - if (changes) { - diff_cleanupMerge(diffs); - } - diff_cleanupSemanticLossless(diffs); - - // Find any overlaps between deletions and insertions. - // e.g: abcxxxxxxdef - // -> abcxxxdef - // e.g: xxxabcdefxxx - // -> defxxxabc - // Only extract an overlap if it is as big as the edit ahead or behind it. - pointer = diffs.listIterator(); - Diff prevDiff = null; - if (pointer.hasNext()) { - prevDiff = pointer.next(); - if (pointer.hasNext()) { - thisDiff = pointer.next(); - } - } - while (thisDiff != null) { - if (prevDiff.operation == Operation.DELETE && - thisDiff.operation == Operation.INSERT) { - String deletion = prevDiff.text; - String insertion = thisDiff.text; - int overlap_length1 = this.diff_commonOverlap(deletion, insertion); - int overlap_length2 = this.diff_commonOverlap(insertion, deletion); - if (overlap_length1 >= overlap_length2) { - if (overlap_length1 >= deletion.length() / 2.0 || - overlap_length1 >= insertion.length() / 2.0) { - // Overlap found. Insert an equality and trim the surrounding edits. - pointer.previous(); - pointer.add(new Diff(Operation.EQUAL, - insertion.substring(0, overlap_length1))); - prevDiff.text = - deletion.substring(0, deletion.length() - overlap_length1); - thisDiff.text = insertion.substring(overlap_length1); - // pointer.add inserts the element before the cursor, so there is - // no need to step past the new element. - } - } else { - if (overlap_length2 >= deletion.length() / 2.0 || - overlap_length2 >= insertion.length() / 2.0) { - // Reverse overlap found. - // Insert an equality and swap and trim the surrounding edits. - pointer.previous(); - pointer.add(new Diff(Operation.EQUAL, - deletion.substring(0, overlap_length2))); - prevDiff.operation = Operation.INSERT; - prevDiff.text = - insertion.substring(0, insertion.length() - overlap_length2); - thisDiff.operation = Operation.DELETE; - thisDiff.text = deletion.substring(overlap_length2); - // pointer.add inserts the element before the cursor, so there is - // no need to step past the new element. - } - } - thisDiff = pointer.hasNext() ? pointer.next() : null; - } - prevDiff = thisDiff; - thisDiff = pointer.hasNext() ? pointer.next() : null; - } - } - - /** - * Look for single edits surrounded on both sides by equalities - * which can be shifted sideways to align the edit to a word boundary. - * e.g: The cat came. -> The cat came. - * @param diffs LinkedList of Diff objects. - */ - public void diff_cleanupSemanticLossless(LinkedList diffs) { - String equality1, edit, equality2; - String commonString; - int commonOffset; - int score, bestScore; - String bestEquality1, bestEdit, bestEquality2; - // Create a new iterator at the start. - ListIterator pointer = diffs.listIterator(); - Diff prevDiff = pointer.hasNext() ? pointer.next() : null; - Diff thisDiff = pointer.hasNext() ? pointer.next() : null; - Diff nextDiff = pointer.hasNext() ? pointer.next() : null; - // Intentionally ignore the first and last element (don't need checking). - while (nextDiff != null) { - if (prevDiff.operation == Operation.EQUAL && - nextDiff.operation == Operation.EQUAL) { - // This is a single edit surrounded by equalities. - equality1 = prevDiff.text; - edit = thisDiff.text; - equality2 = nextDiff.text; - - // First, shift the edit as far left as possible. - commonOffset = diff_commonSuffix(equality1, edit); - if (commonOffset != 0) { - commonString = edit.substring(edit.length() - commonOffset); - equality1 = equality1.substring(0, equality1.length() - commonOffset); - edit = commonString + edit.substring(0, edit.length() - commonOffset); - equality2 = commonString + equality2; - } - - // Second, step character by character right, looking for the best fit. - bestEquality1 = equality1; - bestEdit = edit; - bestEquality2 = equality2; - bestScore = diff_cleanupSemanticScore(equality1, edit) - + diff_cleanupSemanticScore(edit, equality2); - while (edit.length() != 0 && equality2.length() != 0 - && edit.charAt(0) == equality2.charAt(0)) { - equality1 += edit.charAt(0); - edit = edit.substring(1) + equality2.charAt(0); - equality2 = equality2.substring(1); - score = diff_cleanupSemanticScore(equality1, edit) - + diff_cleanupSemanticScore(edit, equality2); - // The >= encourages trailing rather than leading whitespace on edits. - if (score >= bestScore) { - bestScore = score; - bestEquality1 = equality1; - bestEdit = edit; - bestEquality2 = equality2; - } - } - - if (!prevDiff.text.equals(bestEquality1)) { - // We have an improvement, save it back to the diff. - if (bestEquality1.length() != 0) { - prevDiff.text = bestEquality1; - } else { - pointer.previous(); // Walk past nextDiff. - pointer.previous(); // Walk past thisDiff. - pointer.previous(); // Walk past prevDiff. - pointer.remove(); // Delete prevDiff. - pointer.next(); // Walk past thisDiff. - pointer.next(); // Walk past nextDiff. - } - thisDiff.text = bestEdit; - if (bestEquality2.length() != 0) { - nextDiff.text = bestEquality2; - } else { - pointer.remove(); // Delete nextDiff. - nextDiff = thisDiff; - thisDiff = prevDiff; - } - } - } - prevDiff = thisDiff; - thisDiff = nextDiff; - nextDiff = pointer.hasNext() ? pointer.next() : null; - } - } - - /** - * Given two strings, compute a score representing whether the internal - * boundary falls on logical boundaries. - * Scores range from 6 (best) to 0 (worst). - * @param one First string. - * @param two Second string. - * @return The score. - */ - private int diff_cleanupSemanticScore(String one, String two) { - if (one.length() == 0 || two.length() == 0) { - // Edges are the best. - return 6; - } - - // Each port of this function behaves slightly differently due to - // subtle differences in each language's definition of things like - // 'whitespace'. Since this function's purpose is largely cosmetic, - // the choice has been made to use each language's native features - // rather than force total conformity. - char char1 = one.charAt(one.length() - 1); - char char2 = two.charAt(0); - boolean nonAlphaNumeric1 = !Character.isLetterOrDigit(char1); - boolean nonAlphaNumeric2 = !Character.isLetterOrDigit(char2); - boolean whitespace1 = nonAlphaNumeric1 && Character.isWhitespace(char1); - boolean whitespace2 = nonAlphaNumeric2 && Character.isWhitespace(char2); - boolean lineBreak1 = whitespace1 - && Character.getType(char1) == Character.CONTROL; - boolean lineBreak2 = whitespace2 - && Character.getType(char2) == Character.CONTROL; - boolean blankLine1 = lineBreak1 && BLANKLINEEND.matcher(one).find(); - boolean blankLine2 = lineBreak2 && BLANKLINESTART.matcher(two).find(); - - if (blankLine1 || blankLine2) { - // Five points for blank lines. - return 5; - } else if (lineBreak1 || lineBreak2) { - // Four points for line breaks. - return 4; - } else if (nonAlphaNumeric1 && !whitespace1 && whitespace2) { - // Three points for end of sentences. - return 3; - } else if (whitespace1 || whitespace2) { - // Two points for whitespace. - return 2; - } else if (nonAlphaNumeric1 || nonAlphaNumeric2) { - // One point for non-alphanumeric. - return 1; - } - return 0; - } - - // Define some regex patterns for matching boundaries. - private final Pattern BLANKLINEEND - = Pattern.compile("\\n\\r?\\n\\Z", Pattern.DOTALL); - private final Pattern BLANKLINESTART - = Pattern.compile("\\A\\r?\\n\\r?\\n", Pattern.DOTALL); - - /** - * Reduce the number of edits by eliminating operationally trivial equalities. - * @param diffs LinkedList of Diff objects. - */ - public void diff_cleanupEfficiency(LinkedList diffs) { - if (diffs.isEmpty()) { - return; - } - boolean changes = false; - Deque equalities = new ArrayDeque<>(); // Double-ended queue of equalities. - String lastEquality = null; // Always equal to equalities.peek().text - ListIterator pointer = diffs.listIterator(); - // Is there an insertion operation before the last equality. - boolean pre_ins = false; - // Is there a deletion operation before the last equality. - boolean pre_del = false; - // Is there an insertion operation after the last equality. - boolean post_ins = false; - // Is there a deletion operation after the last equality. - boolean post_del = false; - Diff thisDiff = pointer.next(); - Diff safeDiff = thisDiff; // The last Diff that is known to be unsplittable. - while (thisDiff != null) { - if (thisDiff.operation == Operation.EQUAL) { - // Equality found. - if (thisDiff.text.length() < Diff_EditCost && (post_ins || post_del)) { - // Candidate found. - equalities.push(thisDiff); - pre_ins = post_ins; - pre_del = post_del; - lastEquality = thisDiff.text; - } else { - // Not a candidate, and can never become one. - equalities.clear(); - lastEquality = null; - safeDiff = thisDiff; - } - post_ins = post_del = false; - } else { - // An insertion or deletion. - if (thisDiff.operation == Operation.DELETE) { - post_del = true; - } else { - post_ins = true; - } - /* - * Five types to be split: - * ABXYCD - * AXCD - * ABXC - * AXCD - * ABXC - */ - if (lastEquality != null - && ((pre_ins && pre_del && post_ins && post_del) - || ((lastEquality.length() < Diff_EditCost / 2) - && ((pre_ins ? 1 : 0) + (pre_del ? 1 : 0) - + (post_ins ? 1 : 0) + (post_del ? 1 : 0)) == 3))) { - //System.out.println("Splitting: '" + lastEquality + "'"); - // Walk back to offending equality. - while (thisDiff != equalities.peek()) { - thisDiff = pointer.previous(); - } - pointer.next(); - - // Replace equality with a delete. - pointer.set(new Diff(Operation.DELETE, lastEquality)); - // Insert a corresponding an insert. - pointer.add(thisDiff = new Diff(Operation.INSERT, lastEquality)); - - equalities.pop(); // Throw away the equality we just deleted. - lastEquality = null; - if (pre_ins && pre_del) { - // No changes made which could affect previous entry, keep going. - post_ins = post_del = true; - equalities.clear(); - safeDiff = thisDiff; - } else { - if (!equalities.isEmpty()) { - // Throw away the previous equality (it needs to be reevaluated). - equalities.pop(); - } - if (equalities.isEmpty()) { - // There are no previous questionable equalities, - // walk back to the last known safe diff. - thisDiff = safeDiff; - } else { - // There is an equality we can fall back to. - thisDiff = equalities.peek(); - } - while (thisDiff != pointer.previous()) { - // Intentionally empty loop. - } - post_ins = post_del = false; - } - - changes = true; - } - } - thisDiff = pointer.hasNext() ? pointer.next() : null; - } - - if (changes) { - diff_cleanupMerge(diffs); - } - } - - /** - * Reorder and merge like edit sections. Merge equalities. - * Any edit section can move as long as it doesn't cross an equality. - * @param diffs LinkedList of Diff objects. - */ - public void diff_cleanupMerge(LinkedList diffs) { - diffs.add(new Diff(Operation.EQUAL, "")); // Add a dummy entry at the end. - ListIterator pointer = diffs.listIterator(); - int count_delete = 0; - int count_insert = 0; - String text_delete = ""; - String text_insert = ""; - Diff thisDiff = pointer.next(); - Diff prevEqual = null; - int commonlength; - while (thisDiff != null) { - switch (thisDiff.operation) { - case INSERT: - count_insert++; - text_insert += thisDiff.text; - prevEqual = null; - break; - case DELETE: - count_delete++; - text_delete += thisDiff.text; - prevEqual = null; - break; - case EQUAL: - if (count_delete + count_insert > 1) { - boolean both_types = count_delete != 0 && count_insert != 0; - // Delete the offending records. - pointer.previous(); // Reverse direction. - while (count_delete-- > 0) { - pointer.previous(); - pointer.remove(); - } - while (count_insert-- > 0) { - pointer.previous(); - pointer.remove(); - } - if (both_types) { - // Factor out any common prefixies. - commonlength = diff_commonPrefix(text_insert, text_delete); - if (commonlength != 0) { - if (pointer.hasPrevious()) { - thisDiff = pointer.previous(); - assert thisDiff.operation == Operation.EQUAL - : "Previous diff should have been an equality."; - thisDiff.text += text_insert.substring(0, commonlength); - pointer.next(); - } else { - pointer.add(new Diff(Operation.EQUAL, - text_insert.substring(0, commonlength))); - } - text_insert = text_insert.substring(commonlength); - text_delete = text_delete.substring(commonlength); - } - // Factor out any common suffixies. - commonlength = diff_commonSuffix(text_insert, text_delete); - if (commonlength != 0) { - thisDiff = pointer.next(); - thisDiff.text = text_insert.substring(text_insert.length() - - commonlength) + thisDiff.text; - text_insert = text_insert.substring(0, text_insert.length() - - commonlength); - text_delete = text_delete.substring(0, text_delete.length() - - commonlength); - pointer.previous(); - } - } - // Insert the merged records. - if (text_delete.length() != 0) { - pointer.add(new Diff(Operation.DELETE, text_delete)); - } - if (text_insert.length() != 0) { - pointer.add(new Diff(Operation.INSERT, text_insert)); - } - // Step forward to the equality. - thisDiff = pointer.hasNext() ? pointer.next() : null; - } else if (prevEqual != null) { - // Merge this equality with the previous one. - prevEqual.text += thisDiff.text; - pointer.remove(); - thisDiff = pointer.previous(); - pointer.next(); // Forward direction - } - count_insert = 0; - count_delete = 0; - text_delete = ""; - text_insert = ""; - prevEqual = thisDiff; - break; - } - thisDiff = pointer.hasNext() ? pointer.next() : null; - } - if (diffs.getLast().text.length() == 0) { - diffs.removeLast(); // Remove the dummy entry at the end. - } - - /* - * Second pass: look for single edits surrounded on both sides by equalities - * which can be shifted sideways to eliminate an equality. - * e.g: ABAC -> ABAC - */ - boolean changes = false; - // Create a new iterator at the start. - // (As opposed to walking the current one back.) - pointer = diffs.listIterator(); - Diff prevDiff = pointer.hasNext() ? pointer.next() : null; - thisDiff = pointer.hasNext() ? pointer.next() : null; - Diff nextDiff = pointer.hasNext() ? pointer.next() : null; - // Intentionally ignore the first and last element (don't need checking). - while (nextDiff != null) { - if (prevDiff.operation == Operation.EQUAL && - nextDiff.operation == Operation.EQUAL) { - // This is a single edit surrounded by equalities. - if (thisDiff.text.endsWith(prevDiff.text)) { - // Shift the edit over the previous equality. - thisDiff.text = prevDiff.text - + thisDiff.text.substring(0, thisDiff.text.length() - - prevDiff.text.length()); - nextDiff.text = prevDiff.text + nextDiff.text; - pointer.previous(); // Walk past nextDiff. - pointer.previous(); // Walk past thisDiff. - pointer.previous(); // Walk past prevDiff. - pointer.remove(); // Delete prevDiff. - pointer.next(); // Walk past thisDiff. - thisDiff = pointer.next(); // Walk past nextDiff. - nextDiff = pointer.hasNext() ? pointer.next() : null; - changes = true; - } else if (thisDiff.text.startsWith(nextDiff.text)) { - // Shift the edit over the next equality. - prevDiff.text += nextDiff.text; - thisDiff.text = thisDiff.text.substring(nextDiff.text.length()) - + nextDiff.text; - pointer.remove(); // Delete nextDiff. - nextDiff = pointer.hasNext() ? pointer.next() : null; - changes = true; - } - } - prevDiff = thisDiff; - thisDiff = nextDiff; - nextDiff = pointer.hasNext() ? pointer.next() : null; - } - // If shifts were made, the diff needs reordering and another shift sweep. - if (changes) { - diff_cleanupMerge(diffs); - } - } - - /** - * loc is a location in text1, compute and return the equivalent location in - * text2. - * e.g. "The cat" vs "The big cat", 1->1, 5->8 - * @param diffs List of Diff objects. - * @param loc Location within text1. - * @return Location within text2. - */ - public int diff_xIndex(List diffs, int loc) { - int chars1 = 0; - int chars2 = 0; - int last_chars1 = 0; - int last_chars2 = 0; - Diff lastDiff = null; - for (Diff aDiff : diffs) { - if (aDiff.operation != Operation.INSERT) { - // Equality or deletion. - chars1 += aDiff.text.length(); - } - if (aDiff.operation != Operation.DELETE) { - // Equality or insertion. - chars2 += aDiff.text.length(); - } - if (chars1 > loc) { - // Overshot the location. - lastDiff = aDiff; - break; - } - last_chars1 = chars1; - last_chars2 = chars2; - } - if (lastDiff != null && lastDiff.operation == Operation.DELETE) { - // The location was deleted. - return last_chars2; - } - // Add the remaining character length. - return last_chars2 + (loc - last_chars1); - } - -// /** -// * Convert a Diff list into a pretty HTML report. -// * @param diffs List of Diff objects. -// * @return HTML representation. -// */ -// public String diff_prettyHtml(List diffs) { -// StringBuilder html = new StringBuilder(); -// for (Diff aDiff : diffs) { -// String text = aDiff.text.replace("&", "&").replace("<", "<") -// .replace(">", ">").replace("\n", "¶
"); -// switch (aDiff.operation) { -// case INSERT: -// html.append("").append(text) -// .append(""); -// break; -// case DELETE: -// html.append("").append(text) -// .append(""); -// break; -// case EQUAL: -// html.append("").append(text).append(""); -// break; -// } -// } -// return html.toString(); -// } - - /** - * Compute and return the source text (all equalities and deletions). - * @param diffs List of Diff objects. - * @return Source text. - */ - public String diff_text1(List diffs) { - StringBuilder text = new StringBuilder(); - for (Diff aDiff : diffs) { - if (aDiff.operation != Operation.INSERT) { - text.append(aDiff.text); - } - } - return text.toString(); - } - - /** - * Compute and return the destination text (all equalities and insertions). - * @param diffs List of Diff objects. - * @return Destination text. - */ - public String diff_text2(List diffs) { - StringBuilder text = new StringBuilder(); - for (Diff aDiff : diffs) { - if (aDiff.operation != Operation.DELETE) { - text.append(aDiff.text); - } - } - return text.toString(); - } - - /** - * Compute the Levenshtein distance; the number of inserted, deleted or - * substituted characters. - * @param diffs List of Diff objects. - * @return Number of changes. - */ - public int diff_levenshtein(List diffs) { - int levenshtein = 0; - int insertions = 0; - int deletions = 0; - for (Diff aDiff : diffs) { - switch (aDiff.operation) { - case INSERT: - insertions += aDiff.text.length(); - break; - case DELETE: - deletions += aDiff.text.length(); - break; - case EQUAL: - // A deletion and an insertion is one substitution. - levenshtein += Math.max(insertions, deletions); - insertions = 0; - deletions = 0; - break; - } - } - levenshtein += Math.max(insertions, deletions); - return levenshtein; - } - - /** - * Crush the diff into an encoded string which describes the operations - * required to transform text1 into text2. - * E.g. =3\t-2\t+ing -> Keep 3 chars, delete 2 chars, insert 'ing'. - * Operations are tab-separated. Inserted text is escaped using %xx notation. - * @param diffs List of Diff objects. - * @return Delta text. - */ - public String diff_toDelta(List diffs) { - StringBuilder text = new StringBuilder(); - for (Diff aDiff : diffs) { - switch (aDiff.operation) { - case INSERT: - try { - text.append("+").append(URLEncoder.encode(aDiff.text, "UTF-8") - .replace('+', ' ')).append("\t"); - } catch (UnsupportedEncodingException e) { - // Not likely on modern system. - throw new Error("This system does not support UTF-8.", e); - } - break; - case DELETE: - text.append("-").append(aDiff.text.length()).append("\t"); - break; - case EQUAL: - text.append("=").append(aDiff.text.length()).append("\t"); - break; - } - } - String delta = text.toString(); - if (delta.length() != 0) { - // Strip off trailing tab character. - delta = delta.substring(0, delta.length() - 1); - delta = unescapeForEncodeUriCompatability(delta); - } - return delta; - } - - /** - * Given the original text1, and an encoded string which describes the - * operations required to transform text1 into text2, compute the full diff. - * @param text1 Source string for the diff. - * @param delta Delta text. - * @return Array of Diff objects or null if invalid. - * @throws IllegalArgumentException If invalid input. - */ - public LinkedList diff_fromDelta(String text1, String delta) - throws IllegalArgumentException { - LinkedList diffs = new LinkedList(); - int pointer = 0; // Cursor in text1 - String[] tokens = delta.split("\t"); - for (String token : tokens) { - if (token.length() == 0) { - // Blank tokens are ok (from a trailing \t). - continue; - } - // Each token begins with a one character parameter which specifies the - // operation of this token (delete, insert, equality). - String param = token.substring(1); - switch (token.charAt(0)) { - case '+': - // decode would change all "+" to " " - param = param.replace("+", "%2B"); - try { - param = URLDecoder.decode(param, "UTF-8"); - } catch (UnsupportedEncodingException e) { - // Not likely on modern system. - throw new Error("This system does not support UTF-8.", e); - } catch (IllegalArgumentException e) { - // Malformed URI sequence. - throw new IllegalArgumentException( - "Illegal escape in diff_fromDelta: " + param, e); - } - diffs.add(new Diff(Operation.INSERT, param)); - break; - case '-': - // Fall through. - case '=': - int n; - try { - n = Integer.parseInt(param); - } catch (NumberFormatException e) { - throw new IllegalArgumentException( - "Invalid number in diff_fromDelta: " + param, e); - } - if (n < 0) { - throw new IllegalArgumentException( - "Negative number in diff_fromDelta: " + param); - } - String text; - try { - text = text1.substring(pointer, pointer += n); - } catch (StringIndexOutOfBoundsException e) { - throw new IllegalArgumentException("Delta length (" + pointer - + ") larger than source text length (" + text1.length() - + ").", e); - } - if (token.charAt(0) == '=') { - diffs.add(new Diff(Operation.EQUAL, text)); - } else { - diffs.add(new Diff(Operation.DELETE, text)); - } - break; - default: - // Anything else is an error. - throw new IllegalArgumentException( - "Invalid diff operation in diff_fromDelta: " + token.charAt(0)); - } - } - if (pointer != text1.length()) { - throw new IllegalArgumentException("Delta length (" + pointer - + ") smaller than source text length (" + text1.length() + ")."); - } - return diffs; - } - - - // MATCH FUNCTIONS - - - /** - * Locate the best instance of 'pattern' in 'text' near 'loc'. - * Returns -1 if no match found. - * @param text The text to search. - * @param pattern The pattern to search for. - * @param loc The location to search around. - * @return Best match index or -1. - */ - public int match_main(String text, String pattern, int loc) { - // Check for null inputs. - if (text == null || pattern == null) { - throw new IllegalArgumentException("Null inputs. (match_main)"); - } - - loc = Math.max(0, Math.min(loc, text.length())); - if (text.equals(pattern)) { - // Shortcut (potentially not guaranteed by the algorithm) - return 0; - } else if (text.length() == 0) { - // Nothing to match. - return -1; - } else if (loc + pattern.length() <= text.length() - && text.substring(loc, loc + pattern.length()).equals(pattern)) { - // Perfect match at the perfect spot! (Includes case of null pattern) - return loc; - } else { - // Do a fuzzy compare. - return match_bitap(text, pattern, loc); - } - } - - /** - * Locate the best instance of 'pattern' in 'text' near 'loc' using the - * Bitap algorithm. Returns -1 if no match found. - * @param text The text to search. - * @param pattern The pattern to search for. - * @param loc The location to search around. - * @return Best match index or -1. - */ - protected int match_bitap(String text, String pattern, int loc) { - assert (Match_MaxBits == 0 || pattern.length() <= Match_MaxBits) - : "Pattern too long for this application."; - - // Initialise the alphabet. - Map s = match_alphabet(pattern); - - // Highest score beyond which we give up. - double score_threshold = Match_Threshold; - // Is there a nearby exact match? (speedup) - int best_loc = text.indexOf(pattern, loc); - if (best_loc != -1) { - score_threshold = Math.min(match_bitapScore(0, best_loc, loc, pattern), - score_threshold); - // What about in the other direction? (speedup) - best_loc = text.lastIndexOf(pattern, loc + pattern.length()); - if (best_loc != -1) { - score_threshold = Math.min(match_bitapScore(0, best_loc, loc, pattern), - score_threshold); - } - } - - // Initialise the bit arrays. - int matchmask = 1 << (pattern.length() - 1); - best_loc = -1; - - int bin_min, bin_mid; - int bin_max = pattern.length() + text.length(); - // Empty initialization added to appease Java compiler. - int[] last_rd = new int[0]; - for (int d = 0; d < pattern.length(); d++) { - // Scan for the best match; each iteration allows for one more error. - // Run a binary search to determine how far from 'loc' we can stray at - // this error level. - bin_min = 0; - bin_mid = bin_max; - while (bin_min < bin_mid) { - if (match_bitapScore(d, loc + bin_mid, loc, pattern) - <= score_threshold) { - bin_min = bin_mid; - } else { - bin_max = bin_mid; - } - bin_mid = (bin_max - bin_min) / 2 + bin_min; - } - // Use the result from this iteration as the maximum for the next. - bin_max = bin_mid; - int start = Math.max(1, loc - bin_mid + 1); - int finish = Math.min(loc + bin_mid, text.length()) + pattern.length(); - - int[] rd = new int[finish + 2]; - rd[finish + 1] = (1 << d) - 1; - for (int j = finish; j >= start; j--) { - int charMatch; - if (text.length() <= j - 1 || !s.containsKey(text.charAt(j - 1))) { - // Out of range. - charMatch = 0; - } else { - charMatch = s.get(text.charAt(j - 1)); - } - if (d == 0) { - // First pass: exact match. - rd[j] = ((rd[j + 1] << 1) | 1) & charMatch; - } else { - // Subsequent passes: fuzzy match. - rd[j] = (((rd[j + 1] << 1) | 1) & charMatch) - | (((last_rd[j + 1] | last_rd[j]) << 1) | 1) | last_rd[j + 1]; - } - if ((rd[j] & matchmask) != 0) { - double score = match_bitapScore(d, j - 1, loc, pattern); - // This match will almost certainly be better than any existing - // match. But check anyway. - if (score <= score_threshold) { - // Told you so. - score_threshold = score; - best_loc = j - 1; - if (best_loc > loc) { - // When passing loc, don't exceed our current distance from loc. - start = Math.max(1, 2 * loc - best_loc); - } else { - // Already passed loc, downhill from here on in. - break; - } - } - } - } - if (match_bitapScore(d + 1, loc, loc, pattern) > score_threshold) { - // No hope for a (better) match at greater error levels. - break; - } - last_rd = rd; - } - return best_loc; - } - - /** - * Compute and return the score for a match with e errors and x location. - * @param e Number of errors in match. - * @param x Location of match. - * @param loc Expected location of match. - * @param pattern Pattern being sought. - * @return Overall score for match (0.0 = good, 1.0 = bad). - */ - private double match_bitapScore(int e, int x, int loc, String pattern) { - float accuracy = (float) e / pattern.length(); - int proximity = Math.abs(loc - x); - if (Match_Distance == 0) { - // Dodge divide by zero error. - return proximity == 0 ? accuracy : 1.0; - } - return accuracy + (proximity / (float) Match_Distance); - } - - /** - * Initialise the alphabet for the Bitap algorithm. - * @param pattern The text to encode. - * @return Hash of character locations. - */ - protected Map match_alphabet(String pattern) { - Map s = new HashMap(); - char[] char_pattern = pattern.toCharArray(); - for (char c : char_pattern) { - s.put(c, 0); - } - int i = 0; - for (char c : char_pattern) { - s.put(c, s.get(c) | (1 << (pattern.length() - i - 1))); - i++; - } - return s; - } - - - // PATCH FUNCTIONS - - - /** - * Increase the context until it is unique, - * but don't let the pattern expand beyond Match_MaxBits. - * @param patch The patch to grow. - * @param text Source text. - */ - protected void patch_addContext(Patch patch, String text) { - if (text.length() == 0) { - return; - } - String pattern = text.substring(patch.start2, patch.start2 + patch.length1); - int padding = 0; - - // Look for the first and last matches of pattern in text. If two different - // matches are found, increase the pattern length. - while (text.indexOf(pattern) != text.lastIndexOf(pattern) - && pattern.length() < Match_MaxBits - Patch_Margin - Patch_Margin) { - padding += Patch_Margin; - pattern = text.substring(Math.max(0, patch.start2 - padding), - Math.min(text.length(), patch.start2 + patch.length1 + padding)); - } - // Add one chunk for good luck. - padding += Patch_Margin; - - // Add the prefix. - String prefix = text.substring(Math.max(0, patch.start2 - padding), - patch.start2); - if (prefix.length() != 0) { - patch.diffs.addFirst(new Diff(Operation.EQUAL, prefix)); - } - // Add the suffix. - String suffix = text.substring(patch.start2 + patch.length1, - Math.min(text.length(), patch.start2 + patch.length1 + padding)); - if (suffix.length() != 0) { - patch.diffs.addLast(new Diff(Operation.EQUAL, suffix)); - } - - // Roll back the start points. - patch.start1 -= prefix.length(); - patch.start2 -= prefix.length(); - // Extend the lengths. - patch.length1 += prefix.length() + suffix.length(); - patch.length2 += prefix.length() + suffix.length(); - } - - /** - * Compute a list of patches to turn text1 into text2. - * A set of diffs will be computed. - * @param text1 Old text. - * @param text2 New text. - * @return LinkedList of Patch objects. - */ - public LinkedList patch_make(String text1, String text2) { - if (text1 == null || text2 == null) { - throw new IllegalArgumentException("Null inputs. (patch_make)"); - } - // No diffs provided, compute our own. - LinkedList diffs = diff_main(text1, text2, true); - if (diffs.size() > 2) { - diff_cleanupSemantic(diffs); - diff_cleanupEfficiency(diffs); - } - return patch_make(text1, diffs); - } - - /** - * Compute a list of patches to turn text1 into text2. - * text1 will be derived from the provided diffs. - * @param diffs Array of Diff objects for text1 to text2. - * @return LinkedList of Patch objects. - */ - public LinkedList patch_make(LinkedList diffs) { - if (diffs == null) { - throw new IllegalArgumentException("Null inputs. (patch_make)"); - } - // No origin string provided, compute our own. - String text1 = diff_text1(diffs); - return patch_make(text1, diffs); - } - - /** - * Compute a list of patches to turn text1 into text2. - * text2 is ignored, diffs are the delta between text1 and text2. - * @param text1 Old text - * @param text2 Ignored. - * @param diffs Array of Diff objects for text1 to text2. - * @return LinkedList of Patch objects. - * @deprecated Prefer patch_make(String text1, LinkedList diffs). - */ - @Deprecated public LinkedList patch_make(String text1, String text2, - LinkedList diffs) { - return patch_make(text1, diffs); - } - - /** - * Compute a list of patches to turn text1 into text2. - * text2 is not provided, diffs are the delta between text1 and text2. - * @param text1 Old text. - * @param diffs Array of Diff objects for text1 to text2. - * @return LinkedList of Patch objects. - */ - public LinkedList patch_make(String text1, LinkedList diffs) { - if (text1 == null || diffs == null) { - throw new IllegalArgumentException("Null inputs. (patch_make)"); - } - - LinkedList patches = new LinkedList(); - if (diffs.isEmpty()) { - return patches; // Get rid of the null case. - } - Patch patch = new Patch(); - int char_count1 = 0; // Number of characters into the text1 string. - int char_count2 = 0; // Number of characters into the text2 string. - // Start with text1 (prepatch_text) and apply the diffs until we arrive at - // text2 (postpatch_text). We recreate the patches one by one to determine - // context info. - String prepatch_text = text1; - String postpatch_text = text1; - for (Diff aDiff : diffs) { - if (patch.diffs.isEmpty() && aDiff.operation != Operation.EQUAL) { - // A new patch starts here. - patch.start1 = char_count1; - patch.start2 = char_count2; - } - - switch (aDiff.operation) { - case INSERT: - patch.diffs.add(aDiff); - patch.length2 += aDiff.text.length(); - postpatch_text = postpatch_text.substring(0, char_count2) - + aDiff.text + postpatch_text.substring(char_count2); - break; - case DELETE: - patch.length1 += aDiff.text.length(); - patch.diffs.add(aDiff); - postpatch_text = postpatch_text.substring(0, char_count2) - + postpatch_text.substring(char_count2 + aDiff.text.length()); - break; - case EQUAL: - if (aDiff.text.length() <= 2 * Patch_Margin - && !patch.diffs.isEmpty() && aDiff != diffs.getLast()) { - // Small equality inside a patch. - patch.diffs.add(aDiff); - patch.length1 += aDiff.text.length(); - patch.length2 += aDiff.text.length(); - } - - if (aDiff.text.length() >= 2 * Patch_Margin && !patch.diffs.isEmpty()) { - // Time for a new patch. - if (!patch.diffs.isEmpty()) { - patch_addContext(patch, prepatch_text); - patches.add(patch); - patch = new Patch(); - // Unlike Unidiff, our patch lists have a rolling context. - // https://github.com/google/diff-match-patch/wiki/Unidiff - // Update prepatch text & pos to reflect the application of the - // just completed patch. - prepatch_text = postpatch_text; - char_count1 = char_count2; - } - } - break; - } - - // Update the current character count. - if (aDiff.operation != Operation.INSERT) { - char_count1 += aDiff.text.length(); - } - if (aDiff.operation != Operation.DELETE) { - char_count2 += aDiff.text.length(); - } - } - // Pick up the leftover patch if not empty. - if (!patch.diffs.isEmpty()) { - patch_addContext(patch, prepatch_text); - patches.add(patch); - } - - return patches; - } - - /** - * Given an array of patches, return another array that is identical. - * @param patches Array of Patch objects. - * @return Array of Patch objects. - */ - public LinkedList patch_deepCopy(LinkedList patches) { - LinkedList patchesCopy = new LinkedList(); - for (Patch aPatch : patches) { - Patch patchCopy = new Patch(); - for (Diff aDiff : aPatch.diffs) { - Diff diffCopy = new Diff(aDiff.operation, aDiff.text); - patchCopy.diffs.add(diffCopy); - } - patchCopy.start1 = aPatch.start1; - patchCopy.start2 = aPatch.start2; - patchCopy.length1 = aPatch.length1; - patchCopy.length2 = aPatch.length2; - patchesCopy.add(patchCopy); - } - return patchesCopy; - } - - /** - * Merge a set of patches onto the text. Return a patched text, as well - * as an array of true/false values indicating which patches were applied. - * @param patches Array of Patch objects - * @param text Old text. - * @return Two element Object array, containing the new text and an array of - * boolean values. - */ - public Object[] patch_apply(LinkedList patches, String text) { - if (patches.isEmpty()) { - return new Object[]{text, new boolean[0]}; - } - - // Deep copy the patches so that no changes are made to originals. - patches = patch_deepCopy(patches); - - String nullPadding = patch_addPadding(patches); - text = nullPadding + text + nullPadding; - patch_splitMax(patches); - - int x = 0; - // delta keeps track of the offset between the expected and actual location - // of the previous patch. If there are patches expected at positions 10 and - // 20, but the first patch was found at 12, delta is 2 and the second patch - // has an effective expected position of 22. - int delta = 0; - boolean[] results = new boolean[patches.size()]; - for (Patch aPatch : patches) { - int expected_loc = aPatch.start2 + delta; - String text1 = diff_text1(aPatch.diffs); - int start_loc; - int end_loc = -1; - if (text1.length() > this.Match_MaxBits) { - // patch_splitMax will only provide an oversized pattern in the case of - // a monster delete. - start_loc = match_main(text, - text1.substring(0, this.Match_MaxBits), expected_loc); - if (start_loc != -1) { - end_loc = match_main(text, - text1.substring(text1.length() - this.Match_MaxBits), - expected_loc + text1.length() - this.Match_MaxBits); - if (end_loc == -1 || start_loc >= end_loc) { - // Can't find valid trailing context. Drop this patch. - start_loc = -1; - } - } - } else { - start_loc = match_main(text, text1, expected_loc); - } - if (start_loc == -1) { - // No match found. :( - results[x] = false; - // Subtract the delta for this failed patch from subsequent patches. - delta -= aPatch.length2 - aPatch.length1; - } else { - // Found a match. :) - results[x] = true; - delta = start_loc - expected_loc; - String text2; - if (end_loc == -1) { - text2 = text.substring(start_loc, - Math.min(start_loc + text1.length(), text.length())); - } else { - text2 = text.substring(start_loc, - Math.min(end_loc + this.Match_MaxBits, text.length())); - } - if (text1.equals(text2)) { - // Perfect match, just shove the replacement text in. - text = text.substring(0, start_loc) + diff_text2(aPatch.diffs) - + text.substring(start_loc + text1.length()); - } else { - // Imperfect match. Run a diff to get a framework of equivalent - // indices. - LinkedList diffs = diff_main(text1, text2, false); - if (text1.length() > this.Match_MaxBits - && diff_levenshtein(diffs) / (float) text1.length() - > this.Patch_DeleteThreshold) { - // The end points match, but the content is unacceptably bad. - results[x] = false; - } else { - diff_cleanupSemanticLossless(diffs); - int index1 = 0; - for (Diff aDiff : aPatch.diffs) { - if (aDiff.operation != Operation.EQUAL) { - int index2 = diff_xIndex(diffs, index1); - if (aDiff.operation == Operation.INSERT) { - // Insertion - text = text.substring(0, start_loc + index2) + aDiff.text - + text.substring(start_loc + index2); - } else if (aDiff.operation == Operation.DELETE) { - // Deletion - text = text.substring(0, start_loc + index2) - + text.substring(start_loc + diff_xIndex(diffs, - index1 + aDiff.text.length())); - } - } - if (aDiff.operation != Operation.DELETE) { - index1 += aDiff.text.length(); - } - } - } - } - } - x++; - } - // Strip the padding off. - text = text.substring(nullPadding.length(), text.length() - - nullPadding.length()); - return new Object[]{text, results}; - } - - /** - * Add some padding on text start and end so that edges can match something. - * Intended to be called only from within patch_apply. - * @param patches Array of Patch objects. - * @return The padding string added to each side. - */ - public String patch_addPadding(LinkedList patches) { - short paddingLength = this.Patch_Margin; - String nullPadding = ""; - for (short x = 1; x <= paddingLength; x++) { - nullPadding += String.valueOf((char) x); - } - - // Bump all the patches forward. - for (Patch aPatch : patches) { - aPatch.start1 += paddingLength; - aPatch.start2 += paddingLength; - } - - // Add some padding on start of first diff. - Patch patch = patches.getFirst(); - LinkedList diffs = patch.diffs; - if (diffs.isEmpty() || diffs.getFirst().operation != Operation.EQUAL) { - // Add nullPadding equality. - diffs.addFirst(new Diff(Operation.EQUAL, nullPadding)); - patch.start1 -= paddingLength; // Should be 0. - patch.start2 -= paddingLength; // Should be 0. - patch.length1 += paddingLength; - patch.length2 += paddingLength; - } else if (paddingLength > diffs.getFirst().text.length()) { - // Grow first equality. - Diff firstDiff = diffs.getFirst(); - int extraLength = paddingLength - firstDiff.text.length(); - firstDiff.text = nullPadding.substring(firstDiff.text.length()) - + firstDiff.text; - patch.start1 -= extraLength; - patch.start2 -= extraLength; - patch.length1 += extraLength; - patch.length2 += extraLength; - } - - // Add some padding on end of last diff. - patch = patches.getLast(); - diffs = patch.diffs; - if (diffs.isEmpty() || diffs.getLast().operation != Operation.EQUAL) { - // Add nullPadding equality. - diffs.addLast(new Diff(Operation.EQUAL, nullPadding)); - patch.length1 += paddingLength; - patch.length2 += paddingLength; - } else if (paddingLength > diffs.getLast().text.length()) { - // Grow last equality. - Diff lastDiff = diffs.getLast(); - int extraLength = paddingLength - lastDiff.text.length(); - lastDiff.text += nullPadding.substring(0, extraLength); - patch.length1 += extraLength; - patch.length2 += extraLength; - } - - return nullPadding; - } - - /** - * Look through the patches and break up any which are longer than the - * maximum limit of the match algorithm. - * Intended to be called only from within patch_apply. - * @param patches LinkedList of Patch objects. - */ - public void patch_splitMax(LinkedList patches) { - short patch_size = Match_MaxBits; - String precontext, postcontext; - Patch patch; - int start1, start2; - boolean empty; - Operation diff_type; - String diff_text; - ListIterator pointer = patches.listIterator(); - Patch bigpatch = pointer.hasNext() ? pointer.next() : null; - while (bigpatch != null) { - if (bigpatch.length1 <= Match_MaxBits) { - bigpatch = pointer.hasNext() ? pointer.next() : null; - continue; - } - // Remove the big old patch. - pointer.remove(); - start1 = bigpatch.start1; - start2 = bigpatch.start2; - precontext = ""; - while (!bigpatch.diffs.isEmpty()) { - // Create one of several smaller patches. - patch = new Patch(); - empty = true; - patch.start1 = start1 - precontext.length(); - patch.start2 = start2 - precontext.length(); - if (precontext.length() != 0) { - patch.length1 = patch.length2 = precontext.length(); - patch.diffs.add(new Diff(Operation.EQUAL, precontext)); - } - while (!bigpatch.diffs.isEmpty() - && patch.length1 < patch_size - Patch_Margin) { - diff_type = bigpatch.diffs.getFirst().operation; - diff_text = bigpatch.diffs.getFirst().text; - if (diff_type == Operation.INSERT) { - // Insertions are harmless. - patch.length2 += diff_text.length(); - start2 += diff_text.length(); - patch.diffs.addLast(bigpatch.diffs.removeFirst()); - empty = false; - } else if (diff_type == Operation.DELETE && patch.diffs.size() == 1 - && patch.diffs.getFirst().operation == Operation.EQUAL - && diff_text.length() > 2 * patch_size) { - // This is a large deletion. Let it pass in one chunk. - patch.length1 += diff_text.length(); - start1 += diff_text.length(); - empty = false; - patch.diffs.add(new Diff(diff_type, diff_text)); - bigpatch.diffs.removeFirst(); - } else { - // Deletion or equality. Only take as much as we can stomach. - diff_text = diff_text.substring(0, Math.min(diff_text.length(), - patch_size - patch.length1 - Patch_Margin)); - patch.length1 += diff_text.length(); - start1 += diff_text.length(); - if (diff_type == Operation.EQUAL) { - patch.length2 += diff_text.length(); - start2 += diff_text.length(); - } else { - empty = false; - } - patch.diffs.add(new Diff(diff_type, diff_text)); - if (diff_text.equals(bigpatch.diffs.getFirst().text)) { - bigpatch.diffs.removeFirst(); - } else { - bigpatch.diffs.getFirst().text = bigpatch.diffs.getFirst().text - .substring(diff_text.length()); - } - } - } - // Compute the head context for the next patch. - precontext = diff_text2(patch.diffs); - precontext = precontext.substring(Math.max(0, precontext.length() - - Patch_Margin)); - // Append the end context for this patch. - if (diff_text1(bigpatch.diffs).length() > Patch_Margin) { - postcontext = diff_text1(bigpatch.diffs).substring(0, Patch_Margin); - } else { - postcontext = diff_text1(bigpatch.diffs); - } - if (postcontext.length() != 0) { - patch.length1 += postcontext.length(); - patch.length2 += postcontext.length(); - if (!patch.diffs.isEmpty() - && patch.diffs.getLast().operation == Operation.EQUAL) { - patch.diffs.getLast().text += postcontext; - } else { - patch.diffs.add(new Diff(Operation.EQUAL, postcontext)); - } - } - if (!empty) { - pointer.add(patch); - } - } - bigpatch = pointer.hasNext() ? pointer.next() : null; - } - } - - /** - * Take a list of patches and return a textual representation. - * @param patches List of Patch objects. - * @return Text representation of patches. - */ - public String patch_toText(List patches) { - StringBuilder text = new StringBuilder(); - for (Patch aPatch : patches) { - text.append(aPatch); - } - return text.toString(); - } - - /** - * Parse a textual representation of patches and return a List of Patch - * objects. - * @param textline Text representation of patches. - * @return List of Patch objects. - * @throws IllegalArgumentException If invalid input. - */ - public List patch_fromText(String textline) - throws IllegalArgumentException { - List patches = new LinkedList(); - if (textline.length() == 0) { - return patches; - } - List textList = Arrays.asList(textline.split("\n")); - LinkedList text = new LinkedList(textList); - Patch patch; - Pattern patchHeader - = Pattern.compile("^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@$"); - Matcher m; - char sign; - String line; - while (!text.isEmpty()) { - m = patchHeader.matcher(text.getFirst()); - if (!m.matches()) { - throw new IllegalArgumentException( - "Invalid patch string: " + text.getFirst()); - } - patch = new Patch(); - patches.add(patch); - patch.start1 = Integer.parseInt(m.group(1)); - if (m.group(2).length() == 0) { - patch.start1--; - patch.length1 = 1; - } else if (m.group(2).equals("0")) { - patch.length1 = 0; - } else { - patch.start1--; - patch.length1 = Integer.parseInt(m.group(2)); - } - - patch.start2 = Integer.parseInt(m.group(3)); - if (m.group(4).length() == 0) { - patch.start2--; - patch.length2 = 1; - } else if (m.group(4).equals("0")) { - patch.length2 = 0; - } else { - patch.start2--; - patch.length2 = Integer.parseInt(m.group(4)); - } - text.removeFirst(); - - while (!text.isEmpty()) { - try { - sign = text.getFirst().charAt(0); - } catch (IndexOutOfBoundsException e) { - // Blank line? Whatever. - text.removeFirst(); - continue; - } - line = text.getFirst().substring(1); - line = line.replace("+", "%2B"); // decode would change all "+" to " " - try { - line = URLDecoder.decode(line, "UTF-8"); - } catch (UnsupportedEncodingException e) { - // Not likely on modern system. - throw new Error("This system does not support UTF-8.", e); - } catch (IllegalArgumentException e) { - // Malformed URI sequence. - throw new IllegalArgumentException( - "Illegal escape in patch_fromText: " + line, e); - } - if (sign == '-') { - // Deletion. - patch.diffs.add(new Diff(Operation.DELETE, line)); - } else if (sign == '+') { - // Insertion. - patch.diffs.add(new Diff(Operation.INSERT, line)); - } else if (sign == ' ') { - // Minor equality. - patch.diffs.add(new Diff(Operation.EQUAL, line)); - } else if (sign == '@') { - // Start of next patch. - break; - } else { - // WTF? - throw new IllegalArgumentException( - "Invalid patch mode '" + sign + "' in: " + line); - } - text.removeFirst(); - } - } - return patches; - } - - - /** - * Class representing one diff operation. - */ - public static class Diff { - /** - * One of: INSERT, DELETE or EQUAL. - */ - public Operation operation; - /** - * The text associated with this diff operation. - */ - public String text; - - /** - * Constructor. Initializes the diff with the provided values. - * @param operation One of INSERT, DELETE or EQUAL. - * @param text The text being applied. - */ - public Diff(Operation operation, String text) { - // Construct a diff with the specified operation and text. - this.operation = operation; - this.text = text; - } - - /** - * Display a human-readable version of this Diff. - * @return text version. - */ - public String toString() { - String prettyText = this.text.replace('\n', '\u00b6'); - return "Diff(" + this.operation + ",\"" + prettyText + "\")"; - } - - /** - * Create a numeric hash value for a Diff. - * This function is not used by DMP. - * @return Hash value. - */ - @Override - public int hashCode() { - final int prime = 31; - int result = (operation == null) ? 0 : operation.hashCode(); - result += prime * ((text == null) ? 0 : text.hashCode()); - return result; - } - - /** - * Is this Diff equivalent to another Diff? - * @param obj Another Diff to compare against. - * @return true or false. - */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Diff other = (Diff) obj; - if (operation != other.operation) { - return false; - } - if (text == null) { - if (other.text != null) { - return false; - } - } else if (!text.equals(other.text)) { - return false; - } - return true; - } - } - - - /** - * Class representing one patch operation. - */ - public static class Patch { - public LinkedList diffs; - public int start1; - public int start2; - public int length1; - public int length2; - - /** - * Constructor. Initializes with an empty list of diffs. - */ - public Patch() { - this.diffs = new LinkedList(); - } - - /** - * Emulate GNU diff's format. - * Header: @@ -382,8 +481,9 @@ - * Indices are printed as 1-based, not 0-based. - * @return The GNU diff string. - */ - public String toString() { - String coords1, coords2; - if (this.length1 == 0) { - coords1 = this.start1 + ",0"; - } else if (this.length1 == 1) { - coords1 = Integer.toString(this.start1 + 1); - } else { - coords1 = (this.start1 + 1) + "," + this.length1; - } - if (this.length2 == 0) { - coords2 = this.start2 + ",0"; - } else if (this.length2 == 1) { - coords2 = Integer.toString(this.start2 + 1); - } else { - coords2 = (this.start2 + 1) + "," + this.length2; - } - StringBuilder text = new StringBuilder(); - text.append("@@ -").append(coords1).append(" +").append(coords2) - .append(" @@\n"); - // Escape the body of the patch with %xx notation. - for (Diff aDiff : this.diffs) { - switch (aDiff.operation) { - case INSERT: - text.append('+'); - break; - case DELETE: - text.append('-'); - break; - case EQUAL: - text.append(' '); - break; - } - try { - text.append(URLEncoder.encode(aDiff.text, "UTF-8").replace('+', ' ')) - .append("\n"); - } catch (UnsupportedEncodingException e) { - // Not likely on modern system. - throw new Error("This system does not support UTF-8.", e); - } - } - return unescapeForEncodeUriCompatability(text.toString()); - } - } - - /** - * Unescape selected chars for compatability with JavaScript's encodeURI. - * In speed critical applications this could be dropped since the - * receiving application will certainly decode these fine. - * Note that this function is case-sensitive. Thus "%3f" would not be - * unescaped. But this is ok because it is only called with the output of - * URLEncoder.encode which returns uppercase hex. - * - * Example: "%3F" -> "?", "%24" -> "$", etc. - * - * @param str The string to escape. - * @return The escaped string. - */ - private static String unescapeForEncodeUriCompatability(String str) { - return str.replace("%21", "!").replace("%7E", "~") - .replace("%27", "'").replace("%28", "(").replace("%29", ")") - .replace("%3B", ";").replace("%2F", "/").replace("%3F", "?") - .replace("%3A", ":").replace("%40", "@").replace("%26", "&") - .replace("%3D", "=").replace("%2B", "+").replace("%24", "$") - .replace("%2C", ",").replace("%23", "#"); - } -} \ No newline at end of file diff --git a/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt b/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt index 1a1ce0765..2fc5a1a11 100644 --- a/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt +++ b/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt @@ -1,6 +1,6 @@ package io.openpixee.maven.operator -import io.openpixee.diff.DiffMatchPatch +import `fun`.mike.dmp.DiffMatchPatch import io.openpixee.maven.operator.util.Util.buildLookupExpressionForDependency import io.openpixee.maven.operator.util.Util.selectXPathNodes import org.dom4j.Document From 4148b6ff188681d3a96fb7fe18b939ee75df657f Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Tue, 6 Sep 2022 19:10:36 -0500 Subject: [PATCH 033/153] Fixing scope --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index f757a348e..e223c1bae 100644 --- a/pom.xml +++ b/pom.xml @@ -62,6 +62,7 @@ fun.mike diff-match-patch 0.0.2 + test
io.github.java-diff-utils From b8b9b316bda794bd0b04747e1166c0d7f92f6eb5 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 7 Sep 2022 13:02:55 -0500 Subject: [PATCH 034/153] Updates --- .github/workflows/push-test.yml | 6 +-- README.md | 24 ++--------- {java-test-fixture => java-sample}/pom.xml | 4 +- .../io/openpixee/it/POMOperatorJavaTest.java | 0 .../test/resources/io/openpixee/it/pom.xml | 0 pom.xml | 40 +++++++++++++++++++ .../maven/operator/POMOperatorJavaIT.java | 27 +++++++++++++ 7 files changed, 75 insertions(+), 26 deletions(-) rename {java-test-fixture => java-sample}/pom.xml (97%) rename {java-test-fixture => java-sample}/src/test/java/io/openpixee/it/POMOperatorJavaTest.java (100%) rename {java-test-fixture => java-sample}/src/test/resources/io/openpixee/it/pom.xml (100%) create mode 100644 src/test/java/io/openpixee/maven/operator/POMOperatorJavaIT.java diff --git a/.github/workflows/push-test.yml b/.github/workflows/push-test.yml index 6f907b414..bb6543f36 100644 --- a/.github/workflows/push-test.yml +++ b/.github/workflows/push-test.yml @@ -29,7 +29,7 @@ jobs: maven-version: 3.8.2 - name: Build with Maven run: | - mvn -B install - mvn -f java-test-fixture/pom.xml test - mvn -B deploy -DaltDeploymentRepository=pixee::default::https://pixee.jfrog.io/artifactory/mailman-libs-snapshot + mvn -N -B install + mvn -N -B -P integration-testing verify + mvn -N -B deploy -DaltDeploymentRepository=pixee::default::https://pixee.jfrog.io/artifactory/mailman-libs-snapshot diff --git a/README.md b/README.md index 7454d56da..a1c86dd88 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,12 @@ +# pom-operator -## Tasks - * Sample POM files to try out (and use as tests) - * Test Cases - * Docopt-ify - * Mac/Win/Linux utilities?) -## Goals +## TODO: -I want to insert a dependency into the pom.xml files in my repositories in my organization. - -I want a Java library that helps me inject this dependency into a repository already-checked out on disk. There are multiple cases that we must account for. - -1. They already have a "dependencies" section with the given dependency in it, so it doesn't have to be inserted. - -2. One of their parent POMs already has the "dependency" and it is inherited in the child POM, so it doesn't have to be inserted. - -3. The POM has the dependency, but the version they have is behind, so it needs to be replaced. - -4. The POM doesn't have a "dependencies" section or inheritance so we need to inject that section as well as the "dependency" section. - -5. The POM doesn't have the dependency or inherit it, so it needs to be inserted. - -- Make it cleaner - Folder structure (it) - better readme +- Make it cleaner - context -> projectmodel - companion stuff / instance - .idea / \ No newline at end of file diff --git a/java-test-fixture/pom.xml b/java-sample/pom.xml similarity index 97% rename from java-test-fixture/pom.xml rename to java-sample/pom.xml index d3f611b06..243248862 100644 --- a/java-test-fixture/pom.xml +++ b/java-sample/pom.xml @@ -5,8 +5,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - io.openpixee.it - it + io.openpixee.pom + java-sample 0.0.1-SNAPSHOT it diff --git a/java-test-fixture/src/test/java/io/openpixee/it/POMOperatorJavaTest.java b/java-sample/src/test/java/io/openpixee/it/POMOperatorJavaTest.java similarity index 100% rename from java-test-fixture/src/test/java/io/openpixee/it/POMOperatorJavaTest.java rename to java-sample/src/test/java/io/openpixee/it/POMOperatorJavaTest.java diff --git a/java-test-fixture/src/test/resources/io/openpixee/it/pom.xml b/java-sample/src/test/resources/io/openpixee/it/pom.xml similarity index 100% rename from java-test-fixture/src/test/resources/io/openpixee/it/pom.xml rename to java-sample/src/test/resources/io/openpixee/it/pom.xml diff --git a/pom.xml b/pom.xml index e223c1bae..6f23c7e3c 100644 --- a/pom.xml +++ b/pom.xml @@ -272,5 +272,45 @@ + + integration-testing + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + + org.apache.maven.plugins + maven-failsafe-plugin + 3.0.0-M7 + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + + + +
diff --git a/src/test/java/io/openpixee/maven/operator/POMOperatorJavaIT.java b/src/test/java/io/openpixee/maven/operator/POMOperatorJavaIT.java new file mode 100644 index 000000000..62b6e7754 --- /dev/null +++ b/src/test/java/io/openpixee/maven/operator/POMOperatorJavaIT.java @@ -0,0 +1,27 @@ +package io.openpixee.maven.operator; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class POMOperatorJavaIT { + @Test + public void testJavaSample() throws Exception { + ProcessBuilder psBuilder = new ProcessBuilder( + "mvn", + "-B", + "-N", + "-f", + "java-sample/pom.xml", + "verify" + ).inheritIO(); + + psBuilder.environment().putAll(System.getenv()); + + Process process = psBuilder.start(); + + int retCode = process.waitFor(); + + assertEquals("Embedded execution must return zero", 0, retCode); + } +} From 55692f8078282dc72bf449c1b79965ffa3dc5aaa Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Thu, 8 Sep 2022 10:18:41 -0500 Subject: [PATCH 035/153] Updating README --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a1c86dd88..cd6ac218a 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,10 @@ # pom-operator +POM Operator is a Library responsible for maintaining POMS +There's a sample of usage from Java on the `java-sample` directory ## TODO: -- Folder structure (it) - better readme -- Make it cleaner -- context -> projectmodel -- companion stuff / instance -- .idea / \ No newline at end of file +- be able to guess formatting for existing documents From 09ffb323c42cb97300a0d486c11faa8105cea815 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Thu, 8 Sep 2022 10:48:27 -0500 Subject: [PATCH 036/153] Updating README --- README.md | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cd6ac218a..40a3d96dc 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,43 @@ POM Operator is a Library responsible for maintaining POMS -There's a sample of usage from Java on the `java-sample` directory +## Building it -## TODO: +Use Maven: -- better readme -- be able to guess formatting for existing documents +``` +$ mvn clean install +``` + +## How to Use It? + +There's a sample of usage from Java on the `java-sample` directory - of look under the `src/test` directory as well. TL;DR: + +```java +import org.junit.Test; + +import io.openpixee.maven.operator.ProjectModel; +import io.openpixee.maven.operator.Dependency; +import io.openpixee.maven.operator.POMOperator; +import io.openpixee.maven.operator.ProjectModelFactory; + +public class POMOperatorJavaTest { + @Test + public void testInterop() { + ProjectModel projectModel = ProjectModelFactory.load(POMOperatorJavaTest.class.getResource("pom.xml"), new Dependency("org.dom4j", "dom4j", "0.0.0", null, "jar")); + + POMOperator.upgradePom(projectModel); + } +} + +``` + +## How it works? + +It implements a Chain of Responsibility strategy - each `Command` class attempts a different way of fixing a POM, based around a Context (in this case, a `ProjectModel`) + + +# TODO: + +- ~~better readme~~ +- be able to guess existing indenting for existing documents From d67a5ed26c592a597eae83d2283efa2d154e0864 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Thu, 8 Sep 2022 10:49:02 -0500 Subject: [PATCH 037/153] Updating README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 40a3d96dc..1b5173418 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,10 @@ POM Operator is a Library responsible for maintaining POMS ## Building it -Use Maven: +Use [Maven](https://maven.apache.org): ``` +$ git clone git@github.com:openpixee/pom-operator.git && cd pom-operator $ mvn clean install ``` From e01ba26d86ff53c5112598a5c8b3cbdfd2625735 Mon Sep 17 00:00:00 2001 From: Arshan Dabirsiaghi Date: Thu, 8 Sep 2022 15:49:35 -0400 Subject: [PATCH 038/153] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1b5173418..cd70a92bf 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # pom-operator -POM Operator is a Library responsible for maintaining POMS +POM Operator is a library responsible for injecting dependencies into POM files programatically. -## Building it +## Building Use [Maven](https://maven.apache.org): @@ -11,7 +11,7 @@ $ git clone git@github.com:openpixee/pom-operator.git && cd pom-operator $ mvn clean install ``` -## How to Use It? +## Using There's a sample of usage from Java on the `java-sample` directory - of look under the `src/test` directory as well. TL;DR: From babaa22d51f290458931c1cd2c57bbc3c5b67cca Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 9 Sep 2022 09:00:23 -0500 Subject: [PATCH 039/153] Implementing Builder Pattern + Conditional Upgrade --- README.md | 2 +- .../io/openpixee/it/POMOperatorJavaTest.java | 6 ++- pom.xml | 6 ++- .../java/io/openpixee/maven/operator/App.kt | 4 +- .../io/openpixee/maven/operator/Command.kt | 17 +++++++- .../openpixee/maven/operator/POMOperator.kt | 2 +- .../openpixee/maven/operator/ProjectModel.kt | 38 ++++++++++++++--- .../maven/operator/POMOperatorTest.kt | 42 +++++++++++++------ 8 files changed, 91 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index cd70a92bf..974c4596d 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ public class POMOperatorJavaTest { public void testInterop() { ProjectModel projectModel = ProjectModelFactory.load(POMOperatorJavaTest.class.getResource("pom.xml"), new Dependency("org.dom4j", "dom4j", "0.0.0", null, "jar")); - POMOperator.upgradePom(projectModel); + POMOperator.modify(projectModel); } } diff --git a/java-sample/src/test/java/io/openpixee/it/POMOperatorJavaTest.java b/java-sample/src/test/java/io/openpixee/it/POMOperatorJavaTest.java index 630083d18..0b6175e5b 100644 --- a/java-sample/src/test/java/io/openpixee/it/POMOperatorJavaTest.java +++ b/java-sample/src/test/java/io/openpixee/it/POMOperatorJavaTest.java @@ -10,8 +10,10 @@ public class POMOperatorJavaTest { @Test public void testInterop() { - ProjectModel projectModel = ProjectModelFactory.load(POMOperatorJavaTest.class.getResource("pom.xml"), new Dependency("org.dom4j", "dom4j", "0.0.0", null, "jar")); + ProjectModel projectModel = ProjectModelFactory.load(POMOperatorJavaTest.class.getResource("pom.xml")) + .withDependency(new Dependency("org.dom4j", "dom4j", "0.0.0", null, "jar")) + .build(); - POMOperator.upgradePom(projectModel); + POMOperator.modify(projectModel); } } diff --git a/pom.xml b/pom.xml index 6f23c7e3c..9c90a5ec1 100644 --- a/pom.xml +++ b/pom.xml @@ -99,8 +99,12 @@ ${kotlin.version} test
+ + com.github.zafarkhaja + java-semver + 0.9.0 +
- diff --git a/src/main/java/io/openpixee/maven/operator/App.kt b/src/main/java/io/openpixee/maven/operator/App.kt index 842f68847..0ec14f082 100644 --- a/src/main/java/io/openpixee/maven/operator/App.kt +++ b/src/main/java/io/openpixee/maven/operator/App.kt @@ -26,11 +26,11 @@ object App { @Suppress("UNCHECKED_CAST") val files = opts["POMFILES"]!! as List for (path in files) { - val ctx = ProjectModelFactory.load(File(path), dep) + val ctx = ProjectModelFactory.load(File(path)).withDependency(dep).build() println("Upgrading dependency ($dep) in path $path") - val upgradeResult = POMOperator.upgradePom(ctx) + val upgradeResult = POMOperator.modify(ctx) if (!upgradeResult) throw IllegalStateException("Unexpected failure on upgradeResult") diff --git a/src/main/java/io/openpixee/maven/operator/Command.kt b/src/main/java/io/openpixee/maven/operator/Command.kt index 6085b54a0..1efb20ada 100644 --- a/src/main/java/io/openpixee/maven/operator/Command.kt +++ b/src/main/java/io/openpixee/maven/operator/Command.kt @@ -1,5 +1,6 @@ package io.openpixee.maven.operator +import com.github.zafarkhaja.semver.Version import io.openpixee.maven.operator.util.Util.buildLookupExpressionForDependency import io.openpixee.maven.operator.util.Util.buildLookupExpressionForDependencyManagement import io.openpixee.maven.operator.util.Util.selectXPathNodes @@ -27,7 +28,21 @@ abstract class AbstractSimpleCommand : Command { val versionNodes = dependencyNodes[0].selectXPathNodes("./m:version") if (1 == versionNodes.size) { - versionNodes[0].text = c.dependencyToInsert.version + var mustUpgrade = true + + if (c.skipIfNewer) { + // TODO: Handle Properties + val currentVersion = Version.valueOf(versionNodes[0].text) + val newVersion = Version.valueOf(c.dependencyToInsert.version) + + val versionsAreIncreasing = newVersion.greaterThan(currentVersion) + + mustUpgrade = versionsAreIncreasing + } + + if (mustUpgrade) { + versionNodes[0].text = c.dependencyToInsert.version + } return true } diff --git a/src/main/java/io/openpixee/maven/operator/POMOperator.kt b/src/main/java/io/openpixee/maven/operator/POMOperator.kt index acdf93884..d1eb75548 100644 --- a/src/main/java/io/openpixee/maven/operator/POMOperator.kt +++ b/src/main/java/io/openpixee/maven/operator/POMOperator.kt @@ -3,5 +3,5 @@ package io.openpixee.maven.operator object POMOperator { @JvmStatic - fun upgradePom(projectModel: ProjectModel) = Chain.create().execute(projectModel) + fun modify(projectModel: ProjectModel) = Chain.create().execute(projectModel) } diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt index 4835f75cf..99d3e435e 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt @@ -11,6 +11,7 @@ import java.net.URL data class ProjectModel( val pomDocument: Document, val dependencyToInsert: Dependency, + val skipIfNewer: Boolean, ) { val resultPom: Document = pomDocument.clone() as Document @@ -45,17 +46,42 @@ data class ProjectModel( } object ProjectModelFactory { - private fun load(`is`: InputStream, dependencyToInsert: Dependency): ProjectModel { + var pomDocument: Document? = null + + var dependency: Dependency? = null + + var skipIfNewer: Boolean = false + + private fun load(`is`: InputStream): ProjectModelFactory { val pomDocument = SAXReader().read(`is`)!! - return ProjectModel(pomDocument, dependencyToInsert) + return this.apply { + this.pomDocument = pomDocument + } + } + + fun withDependency(dep: Dependency): ProjectModelFactory { + return this.apply { + this.dependency = dep + } + } + + fun withSkipIfNewer(skipIfNewer: Boolean): ProjectModelFactory { + return this.apply { + this.skipIfNewer = skipIfNewer + } + } + + + public fun build(): ProjectModel { + return ProjectModel(pomDocument!!, dependency!!, skipIfNewer) } @JvmStatic - fun load(f: File, dependencyToInsert: Dependency) = - load(FileInputStream(f), dependencyToInsert) + fun load(f: File) = + load(FileInputStream(f)) @JvmStatic - fun load(url: URL, dependencyToInsert: Dependency) = - load(url.openStream(), dependencyToInsert) + fun load(url: URL) = + load(url.openStream()) } \ No newline at end of file diff --git a/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt b/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt index 2fc5a1a11..2b9b82fdd 100644 --- a/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt +++ b/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt @@ -20,7 +20,7 @@ import java.net.URLDecoder */ class POMOperatorTest { companion object { - private val LOGGER : Logger = LoggerFactory.getLogger(POMOperatorTest::class.java) + private val LOGGER: Logger = LoggerFactory.getLogger(POMOperatorTest::class.java) } @Test @@ -30,12 +30,11 @@ class POMOperatorTest { val context = ProjectModelFactory.load( POMOperator::class.java.getResource("pom-case-1.xml")!!, - dependencyToUpgrade - ) + ).withDependency(dependencyToUpgrade).build() LOGGER.debug("context: {}", context) - POMOperator.upgradePom(context) + POMOperator.modify(context) val diff = getXmlDifferences(context.pomDocument, context.resultPom)!! @@ -45,7 +44,10 @@ class POMOperatorTest { LOGGER.debug("textDiff: {}", textDiff) - assertThat("diff contains a tag", textDiff.toString().contains("")) + assertThat( + "diff contains a tag", + textDiff.toString().contains("") + ) assertThat("diff contains a tag", textDiff.toString().contains("")) val effectivePom = context.getEffectivePom() @@ -68,15 +70,15 @@ class POMOperatorTest { @Test fun testCaseThree() { - val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.3") + val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.2") val context = ProjectModelFactory.load( POMOperator::class.java.getResource("pom-case-3.xml")!!, - dependencyToUpgrade - ) + ).withDependency(dependencyToUpgrade).withSkipIfNewer(false).build() + - POMOperator.upgradePom(context) + POMOperator.modify(context) val diff = getXmlDifferences(context.pomDocument, context.resultPom)!! @@ -92,6 +94,23 @@ class POMOperatorTest { ) } + @Test + fun testCaseThreeButWithLowerVersion() { + val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.2") + + val context = + ProjectModelFactory.load( + POMOperator::class.java.getResource("pom-case-3.xml")!!, + ).withDependency(dependencyToUpgrade).withSkipIfNewer(true).build() + + + POMOperator.modify(context) + + val diff = getXmlDifferences(context.pomDocument, context.resultPom)!! + + assertThat("Document has no differences", !diff.hasDifferences()) + } + @Test fun testCase4() { val pomPath = File(POMOperator::class.java.getResource("webgoat-parent.xml")!!.toURI()) @@ -115,10 +134,9 @@ class POMOperatorTest { val context = ProjectModelFactory.load( POMOperator::class.java.getResource("pom-case-4.xml")!!, - dependencyToUpgrade - ) + ).withDependency(dependencyToUpgrade).build() - POMOperator.upgradePom(context) + POMOperator.modify(context) val diff = getXmlDifferences(context.pomDocument, context.resultPom)!! From ba7a1411ffe3f543f338450914310eecb757ab61 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 9 Sep 2022 09:08:58 -0500 Subject: [PATCH 040/153] README --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 974c4596d..4e5a1d51c 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,11 @@ import io.openpixee.maven.operator.ProjectModelFactory; public class POMOperatorJavaTest { @Test public void testInterop() { - ProjectModel projectModel = ProjectModelFactory.load(POMOperatorJavaTest.class.getResource("pom.xml"), new Dependency("org.dom4j", "dom4j", "0.0.0", null, "jar")); + ProjectModel projectModel = ProjectModelFactory + .load(POMOperatorJavaTest.class.getResource("pom.xml")) + .withDependency( + new Dependency("org.dom4j", "dom4j", "0.0.0", null, "jar") + ); POMOperator.modify(projectModel); } From 13be9d96d93981c2a5d6e21c76b882a12588a109 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 14 Sep 2022 15:27:05 -0500 Subject: [PATCH 041/153] Minor reorg + Beginnings of Version Property --- .github/workflows/push-test.yml | 13 +- README.md | 1 + .../maven/operator/AbstractSimpleCommand.kt | 36 +++ .../java/io/openpixee/maven/operator/Chain.kt | 22 ++ .../io/openpixee/maven/operator/Command.kt | 188 ----------- .../openpixee/maven/operator/ProjectModel.kt | 81 ++--- .../maven/operator/ProjectModelFactory.kt | 58 ++++ .../operator/SimpleDependencyManagement.kt | 12 + .../openpixee/maven/operator/SimpleInsert.kt | 62 ++++ .../openpixee/maven/operator/SimpleUpgrade.kt | 12 + .../io/openpixee/maven/operator/format.kt | 58 ++++ .../io/openpixee/maven/operator/util/Util.kt | 3 +- .../{ => test}/POMOperatorJavaIT.java | 2 +- .../operator/{ => test}/POMOperatorTest.kt | 5 +- .../operator/test/PropertyResolutionTest.kt | 43 +++ .../io/openpixee/maven/operator/pom-1.xml | 299 +++++++++--------- 16 files changed, 504 insertions(+), 391 deletions(-) create mode 100644 src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt create mode 100644 src/main/java/io/openpixee/maven/operator/Chain.kt create mode 100644 src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt create mode 100644 src/main/java/io/openpixee/maven/operator/SimpleDependencyManagement.kt create mode 100644 src/main/java/io/openpixee/maven/operator/SimpleInsert.kt create mode 100644 src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt create mode 100644 src/main/java/io/openpixee/maven/operator/format.kt rename src/test/java/io/openpixee/maven/operator/{ => test}/POMOperatorJavaIT.java (92%) rename src/test/java/io/openpixee/maven/operator/{ => test}/POMOperatorTest.kt (96%) create mode 100644 src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt diff --git a/.github/workflows/push-test.yml b/.github/workflows/push-test.yml index bb6543f36..eee4c5fad 100644 --- a/.github/workflows/push-test.yml +++ b/.github/workflows/push-test.yml @@ -1,8 +1,4 @@ -on: - push: - branches: [ "master" ] - pull_request: - branches: [ "master" ] +on: [push] jobs: build: @@ -27,9 +23,14 @@ jobs: uses: stCarolas/setup-maven@v4.4 with: maven-version: 3.8.2 + - name: Resolve all Dependencies + run: | + mvn -N -B dependency:go-offline - name: Build with Maven run: | mvn -N -B install mvn -N -B -P integration-testing verify + - name: Deploy + if: ${{ github.ref_name == 'master' }} + run: | mvn -N -B deploy -DaltDeploymentRepository=pixee::default::https://pixee.jfrog.io/artifactory/mailman-libs-snapshot - diff --git a/README.md b/README.md index 4e5a1d51c..d78b687ba 100644 --- a/README.md +++ b/README.md @@ -47,3 +47,4 @@ It implements a Chain of Responsibility strategy - each `Command` class attempts - ~~better readme~~ - be able to guess existing indenting for existing documents +- investigate leverage whats on [versions-maven-plugin](https://github.com/mojohaus/versions-maven-plugin) diff --git a/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt b/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt new file mode 100644 index 000000000..dbd6481c2 --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt @@ -0,0 +1,36 @@ +package io.openpixee.maven.operator + +import com.github.zafarkhaja.semver.Version +import io.openpixee.maven.operator.util.Util.selectXPathNodes + +abstract class AbstractSimpleCommand : Command { + protected fun handleDependency(c: ProjectModel, lookupExpression: String): Boolean { + val dependencyNodes = c.resultPom.selectXPathNodes(lookupExpression) + + if (1 == dependencyNodes.size) { + val versionNodes = dependencyNodes[0].selectXPathNodes("./m:version") + + if (1 == versionNodes.size) { + var mustUpgrade = true + + if (c.skipIfNewer) { + // TODO: Handle Properties + val currentVersion = Version.valueOf(versionNodes[0].text) + val newVersion = Version.valueOf(c.dependency.version) + + val versionsAreIncreasing = newVersion.greaterThan(currentVersion) + + mustUpgrade = versionsAreIncreasing + } + + if (mustUpgrade) { + versionNodes[0].text = c.dependency.version + } + + return true + } + } + + return false + } +} \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/Chain.kt b/src/main/java/io/openpixee/maven/operator/Chain.kt new file mode 100644 index 000000000..05ac2b483 --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/Chain.kt @@ -0,0 +1,22 @@ +package io.openpixee.maven.operator + +class Chain(vararg c: Command) { + private val commandList = ArrayList(c.toList()) + + fun execute(c: ProjectModel): Boolean { + var done = false + val listIterator = commandList.listIterator() + + while ((!done) && listIterator.hasNext()) { + val nextCommand = listIterator.next() + + done = nextCommand.execute(c) + } + + return done + } + + companion object { + fun create() = Chain(SimpleUpgrade, SimpleDependencyManagement, SimpleInsert) + } +} \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/Command.kt b/src/main/java/io/openpixee/maven/operator/Command.kt index 1efb20ada..9e19188ba 100644 --- a/src/main/java/io/openpixee/maven/operator/Command.kt +++ b/src/main/java/io/openpixee/maven/operator/Command.kt @@ -1,193 +1,5 @@ package io.openpixee.maven.operator -import com.github.zafarkhaja.semver.Version -import io.openpixee.maven.operator.util.Util.buildLookupExpressionForDependency -import io.openpixee.maven.operator.util.Util.buildLookupExpressionForDependencyManagement -import io.openpixee.maven.operator.util.Util.selectXPathNodes -import org.apache.commons.lang3.StringUtils -import org.dom4j.Element -import org.dom4j.Text -import org.dom4j.io.OutputFormat -import org.dom4j.io.SAXReader -import org.dom4j.io.XMLWriter -import org.dom4j.tree.DefaultText -import java.io.StringReader -import java.io.StringWriter -import kotlin.math.ceil - - fun interface Command { fun execute(c: ProjectModel): Boolean -} - -abstract class AbstractSimpleCommand : Command { - protected fun handleDependency(c: ProjectModel, lookupExpression: String): Boolean { - val dependencyNodes = c.resultPom.selectXPathNodes(lookupExpression) - - if (1 == dependencyNodes.size) { - val versionNodes = dependencyNodes[0].selectXPathNodes("./m:version") - - if (1 == versionNodes.size) { - var mustUpgrade = true - - if (c.skipIfNewer) { - // TODO: Handle Properties - val currentVersion = Version.valueOf(versionNodes[0].text) - val newVersion = Version.valueOf(c.dependencyToInsert.version) - - val versionsAreIncreasing = newVersion.greaterThan(currentVersion) - - mustUpgrade = versionsAreIncreasing - } - - if (mustUpgrade) { - versionNodes[0].text = c.dependencyToInsert.version - } - - return true - } - } - - return false - } -} - -val SimpleUpgrade = object : AbstractSimpleCommand() { - override fun execute(c: ProjectModel): Boolean { - val lookupExpressionForDependency = buildLookupExpressionForDependency(c.dependencyToInsert) - - return handleDependency(c, lookupExpressionForDependency) - } -} - -val SimpleDependencyManagement = object : AbstractSimpleCommand() { - override fun execute(c: ProjectModel): Boolean { - val lookupExpression = buildLookupExpressionForDependencyManagement(c.dependencyToInsert) - - return handleDependency(c, lookupExpression) - } -} - -val SimpleInsert = object : Command { - override fun execute(c: ProjectModel): Boolean { - val dependencyManagementNode = - c.resultPom.selectXPathNodes("/m:project/m:dependencyManagement") - val elementsToFormat : MutableList = arrayListOf() - - if (dependencyManagementNode.isEmpty()) { - val newDependencyManagementNode = - c.resultPom.rootElement.addElement("dependencyManagement") - - val dependenciesNode = newDependencyManagementNode.addElement("dependencies") - - val dependencyNode = appendCoordinates(dependenciesNode, c) - - val versionNode = dependencyNode.addElement("version") - - versionNode.text = c.dependencyToInsert.version - - elementsToFormat.add(newDependencyManagementNode) - } - - val dependenciesNodeList = c.resultPom.selectXPathNodes("//m:project/m:dependencies") - - val rootDependencyNode: Element = if (dependenciesNodeList.isEmpty()) { - c.resultPom.rootElement.addElement("dependencies") - } else if (dependenciesNodeList.size == 1) { - dependenciesNodeList[0] as Element - } else { - throw IllegalStateException("More than one dependencies node") - } - - elementsToFormat.add(rootDependencyNode) - - appendCoordinates(rootDependencyNode, c) - - elementsToFormat.forEach { formatNode(it) } - - return true - } - - private fun formatNode(node: Element) { - val parent = node.parent - val siblings = parent.content() - - val indentLevel = findIndentLevel(node) - - val clonedNode = node.clone() as Element - - val out = StringWriter() - - val outputFormat = OutputFormat.createPrettyPrint() - - val xmlWriter = XMLWriter(out, outputFormat) - - xmlWriter.setIndentLevel(ceil(indentLevel.toDouble() / 2).toInt()) - - xmlWriter.write(clonedNode) - - val content = out.toString() - - val newElement = SAXReader().read(StringReader(content)).rootElement.clone() as Element - - parent.remove(node) - - parent.add(DefaultText("\n" + StringUtils.repeat(" ", indentLevel))) - parent.add(newElement) - parent.add(DefaultText("\n" + StringUtils.repeat(" ", ((indentLevel-1) / 2)))) - } - - private fun findIndentLevel(node: Element): Int { - val siblings = node.parent.content() - val myIndex = siblings.indexOf(node) - - if (myIndex > 0) { - val lastElement = siblings.subList(0, myIndex).findLast { - (it is Text) && it.text.matches(Regex("\\n+\\s+")) - } - - val lastElementText = lastElement?.text ?: "" - - return lastElementText.trimStart('\n').length - } - - return 0 - } - - private fun appendCoordinates( - dependenciesNode: Element, - c: ProjectModel - ): Element { - val dependencyNode = dependenciesNode.addElement("dependency") - - val groupIdNode = dependencyNode.addElement("groupId") - - groupIdNode.text = c.dependencyToInsert.groupId - - val artifactIdNode = dependencyNode.addElement("artifactId") - - artifactIdNode.text = c.dependencyToInsert.artifactId - return dependencyNode - } -} - -class Chain(vararg c: Command) { - private val commandList = ArrayList(c.toList()) - - fun execute(c: ProjectModel): Boolean { - var done = false - val listIterator = commandList.listIterator() - - while ((!done) && listIterator.hasNext()) { - val nextCommand = listIterator.next() - - done = nextCommand.execute(c) - } - - return done - } - - companion object { - fun create() = Chain(SimpleUpgrade, SimpleDependencyManagement, SimpleInsert) - } } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt index 99d3e435e..7ab11198c 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt @@ -1,20 +1,32 @@ package io.openpixee.maven.operator import org.dom4j.Document +import org.dom4j.Element import org.dom4j.io.SAXReader import java.io.File import java.io.FileInputStream -import java.io.InputStream import java.lang.IllegalStateException -import java.net.URL -data class ProjectModel( +/** + * ProjectModel represents the input parameters for the chain + * + * @todo Wrap it into a
Context
interface + */ +class ProjectModel internal constructor( val pomDocument: Document, - val dependencyToInsert: Dependency, + val dependency: Dependency, val skipIfNewer: Boolean, + val useProperties: Boolean, + val activeProfiles: Set ) { val resultPom: Document = pomDocument.clone() as Document + internal fun getResolvedProperties(): Map = + getEffectivePom().rootElement.elements("properties").flatMap { it.elements() } + .associate { + it.name to it.text + } + fun getEffectivePom(): Document { val tmpInputFile = File.createTempFile("tmp-pom-orig", ".xml") @@ -22,15 +34,26 @@ data class ProjectModel( val tmpOutputFile = File.createTempFile("tmp-pom", ".xml") - val psBuilder = ProcessBuilder( + val processArgs = mutableListOf( "mvn", + "-B", "-N", - //"-o", "-f", tmpInputFile.absolutePath, - "help:effective-pom", - "-Doutput=${tmpOutputFile.absolutePath}" - ).inheritIO() + ) + + if (this.activeProfiles.isNotEmpty()) { + processArgs.addAll(listOf("-P", "'${this.activeProfiles.joinToString(",")}'")) + } + + processArgs.addAll( + listOf( + "help:effective-pom", + "-Doutput=${tmpOutputFile.absolutePath}" + ) + ) + + val psBuilder = ProcessBuilder(processArgs).inheritIO() psBuilder.environment().putAll(System.getenv()) @@ -45,43 +68,3 @@ data class ProjectModel( } } -object ProjectModelFactory { - var pomDocument: Document? = null - - var dependency: Dependency? = null - - var skipIfNewer: Boolean = false - - private fun load(`is`: InputStream): ProjectModelFactory { - val pomDocument = SAXReader().read(`is`)!! - - return this.apply { - this.pomDocument = pomDocument - } - } - - fun withDependency(dep: Dependency): ProjectModelFactory { - return this.apply { - this.dependency = dep - } - } - - fun withSkipIfNewer(skipIfNewer: Boolean): ProjectModelFactory { - return this.apply { - this.skipIfNewer = skipIfNewer - } - } - - - public fun build(): ProjectModel { - return ProjectModel(pomDocument!!, dependency!!, skipIfNewer) - } - - @JvmStatic - fun load(f: File) = - load(FileInputStream(f)) - - @JvmStatic - fun load(url: URL) = - load(url.openStream()) -} \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt new file mode 100644 index 000000000..0e6be2430 --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt @@ -0,0 +1,58 @@ +package io.openpixee.maven.operator + +import org.dom4j.Document +import org.dom4j.io.SAXReader +import java.io.File +import java.io.FileInputStream +import java.io.InputStream +import java.net.URL + +class ProjectModelFactory private constructor( + private var pomDocument: Document, + private var dependency: Dependency? = null, + private var skipIfNewer: Boolean = false, + private var useProperties: Boolean = false, + private var activeProfiles: Set = emptySet(), +) { + fun withDependency(dep: Dependency): ProjectModelFactory = this.apply { + this.dependency = dep + } + + fun withSkipIfNewer(skipIfNewer: Boolean): ProjectModelFactory = this.apply { + this.skipIfNewer = skipIfNewer + } + + fun withUseProperties(useProperties: Boolean): ProjectModelFactory = this.apply { + this.useProperties = useProperties + } + + fun withActiveProfiles(activeProfiles: Set): ProjectModelFactory = this.apply { + this.activeProfiles = activeProfiles.toCollection(LinkedHashSet()) + } + + fun build(): ProjectModel { + return ProjectModel( + pomDocument = pomDocument, + dependency = dependency!!, + skipIfNewer = skipIfNewer, + useProperties = useProperties, + activeProfiles = activeProfiles + ) + } + + companion object { + private fun load(`is`: InputStream): ProjectModelFactory { + val pomDocument = SAXReader().read(`is`)!! + + return ProjectModelFactory(pomDocument) + } + + @JvmStatic + fun load(f: File) = + load(FileInputStream(f)) + + @JvmStatic + fun load(url: URL) = + load(url.openStream()) + } +} \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/SimpleDependencyManagement.kt b/src/main/java/io/openpixee/maven/operator/SimpleDependencyManagement.kt new file mode 100644 index 000000000..96af0cae0 --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/SimpleDependencyManagement.kt @@ -0,0 +1,12 @@ +package io.openpixee.maven.operator + +import io.openpixee.maven.operator.util.Util + +val SimpleDependencyManagement = object : AbstractSimpleCommand() { + override fun execute(c: ProjectModel): Boolean { + val lookupExpression = + Util.buildLookupExpressionForDependencyManagement(c.dependency) + + return handleDependency(c, lookupExpression) + } +} \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt b/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt new file mode 100644 index 000000000..b0b9dbfdb --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt @@ -0,0 +1,62 @@ +package io.openpixee.maven.operator + +import io.openpixee.maven.operator.util.Util.selectXPathNodes +import org.dom4j.Element + +val SimpleInsert = object : Command { + override fun execute(c: ProjectModel): Boolean { + val dependencyManagementNode = + c.resultPom.selectXPathNodes("/m:project/m:dependencyManagement") + val elementsToFormat : MutableList = arrayListOf() + + if (dependencyManagementNode.isEmpty()) { + val newDependencyManagementNode = + c.resultPom.rootElement.addElement("dependencyManagement") + + val dependenciesNode = newDependencyManagementNode.addElement("dependencies") + + val dependencyNode = appendCoordinates(dependenciesNode, c) + + val versionNode = dependencyNode.addElement("version") + + versionNode.text = c.dependency.version + + elementsToFormat.add(newDependencyManagementNode) + } + + val dependenciesNodeList = c.resultPom.selectXPathNodes("//m:project/m:dependencies") + + val rootDependencyNode: Element = if (dependenciesNodeList.isEmpty()) { + c.resultPom.rootElement.addElement("dependencies") + } else if (dependenciesNodeList.size == 1) { + dependenciesNodeList[0] as Element + } else { + throw IllegalStateException("More than one dependencies node") + } + + elementsToFormat.add(rootDependencyNode) + + appendCoordinates(rootDependencyNode, c) + + elementsToFormat.forEach { formatNode(it) } + + return true + } + + + private fun appendCoordinates( + dependenciesNode: Element, + c: ProjectModel + ): Element { + val dependencyNode = dependenciesNode.addElement("dependency") + + val groupIdNode = dependencyNode.addElement("groupId") + + groupIdNode.text = c.dependency.groupId + + val artifactIdNode = dependencyNode.addElement("artifactId") + + artifactIdNode.text = c.dependency.artifactId + return dependencyNode + } +} \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt b/src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt new file mode 100644 index 000000000..882b60c80 --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt @@ -0,0 +1,12 @@ +package io.openpixee.maven.operator + +import io.openpixee.maven.operator.util.Util + +val SimpleUpgrade = object : AbstractSimpleCommand() { + override fun execute(c: ProjectModel): Boolean { + val lookupExpressionForDependency = + Util.buildLookupExpressionForDependency(c.dependency) + + return handleDependency(c, lookupExpressionForDependency) + } +} \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/format.kt b/src/main/java/io/openpixee/maven/operator/format.kt new file mode 100644 index 000000000..583c82605 --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/format.kt @@ -0,0 +1,58 @@ +package io.openpixee.maven.operator + +import org.apache.commons.lang3.StringUtils +import org.dom4j.Element +import org.dom4j.Text +import org.dom4j.io.OutputFormat +import org.dom4j.io.SAXReader +import org.dom4j.io.XMLWriter +import org.dom4j.tree.DefaultText +import java.io.StringReader +import java.io.StringWriter +import kotlin.math.ceil + +internal fun formatNode(node: Element) { + val parent = node.parent + val siblings = parent.content() + + val indentLevel = findIndentLevel(node) + + val clonedNode = node.clone() as Element + + val out = StringWriter() + + val outputFormat = OutputFormat.createPrettyPrint() + + val xmlWriter = XMLWriter(out, outputFormat) + + xmlWriter.setIndentLevel(ceil(indentLevel.toDouble() / 2).toInt()) + + xmlWriter.write(clonedNode) + + val content = out.toString() + + val newElement = SAXReader().read(StringReader(content)).rootElement.clone() as Element + + parent.remove(node) + + parent.add(DefaultText("\n" + StringUtils.repeat(" ", indentLevel))) + parent.add(newElement) + parent.add(DefaultText("\n" + StringUtils.repeat(" ", ((indentLevel - 1) / 2)))) +} + +internal fun findIndentLevel(node: Element): Int { + val siblings = node.parent.content() + val myIndex = siblings.indexOf(node) + + if (myIndex > 0) { + val lastElement = siblings.subList(0, myIndex).findLast { + (it is Text) && it.text.matches(Regex("\\n+\\s+")) + } + + val lastElementText = lastElement?.text ?: "" + + return lastElementText.trimStart('\n').length + } + + return 0 +} diff --git a/src/main/java/io/openpixee/maven/operator/util/Util.kt b/src/main/java/io/openpixee/maven/operator/util/Util.kt index f7abe7424..be2b96bd7 100644 --- a/src/main/java/io/openpixee/maven/operator/util/Util.kt +++ b/src/main/java/io/openpixee/maven/operator/util/Util.kt @@ -1,8 +1,7 @@ package io.openpixee.maven.operator.util import io.openpixee.maven.operator.Dependency -import org.dom4j.* -import org.dom4j.tree.DefaultElement +import org.dom4j.Node import org.jaxen.SimpleNamespaceContext import org.jaxen.XPath import org.jaxen.dom4j.Dom4jXPath diff --git a/src/test/java/io/openpixee/maven/operator/POMOperatorJavaIT.java b/src/test/java/io/openpixee/maven/operator/test/POMOperatorJavaIT.java similarity index 92% rename from src/test/java/io/openpixee/maven/operator/POMOperatorJavaIT.java rename to src/test/java/io/openpixee/maven/operator/test/POMOperatorJavaIT.java index 62b6e7754..8057a913f 100644 --- a/src/test/java/io/openpixee/maven/operator/POMOperatorJavaIT.java +++ b/src/test/java/io/openpixee/maven/operator/test/POMOperatorJavaIT.java @@ -1,4 +1,4 @@ -package io.openpixee.maven.operator; +package io.openpixee.maven.operator.test; import org.junit.Test; diff --git a/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt similarity index 96% rename from src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt rename to src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt index 2b9b82fdd..5dfa8e028 100644 --- a/src/test/java/io/openpixee/maven/operator/POMOperatorTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt @@ -1,6 +1,9 @@ -package io.openpixee.maven.operator +package io.openpixee.maven.operator.test import `fun`.mike.dmp.DiffMatchPatch +import io.openpixee.maven.operator.Dependency +import io.openpixee.maven.operator.POMOperator +import io.openpixee.maven.operator.ProjectModelFactory import io.openpixee.maven.operator.util.Util.buildLookupExpressionForDependency import io.openpixee.maven.operator.util.Util.selectXPathNodes import org.dom4j.Document diff --git a/src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt b/src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt new file mode 100644 index 000000000..52ebcaed1 --- /dev/null +++ b/src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt @@ -0,0 +1,43 @@ +package io.openpixee.maven.operator.test + +import io.openpixee.maven.operator.Dependency +import io.openpixee.maven.operator.POMOperator +import io.openpixee.maven.operator.ProjectModelFactory +import junit.framework.TestCase.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test + +class PropertyResolutionTest { + @Test + fun testPropertyResolutionWhenProfileIsDeactivatedForcefully() { + val resolvedProperties = resolveWithProfiles("!test-profile") + + assertFalse("foo property must not be there", resolvedProperties.contains("foo")) + } + + @Test + fun testPropertyResolutionWhenProfileIsMissing() { + val resolvedProperties = resolveWithProfiles() + + assertFalse("foo property must not be there", resolvedProperties.contains("foo")) + } + + @Test + fun testPropertyResolutionWhenProfileIsActivated() { + val resolvedProperties = resolveWithProfiles("test-profile") + + assertTrue("foo property must be there", resolvedProperties.contains("foo")) + assertEquals("foo property must be equal to 'bar'", resolvedProperties["foo"], "bar") + } + + private fun resolveWithProfiles(vararg profilesToUse: String): Map { + val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.2") + val context = + ProjectModelFactory.load( + POMOperator::class.java.getResource("pom-1.xml")!!, + ).withDependency(dependencyToUpgrade).withActiveProfiles(setOf(*profilesToUse)).build() + + return context.getResolvedProperties() + } +} \ No newline at end of file diff --git a/src/test/resources/io/openpixee/maven/operator/pom-1.xml b/src/test/resources/io/openpixee/maven/operator/pom-1.xml index 3c20cbb9c..7ba609cf4 100644 --- a/src/test/resources/io/openpixee/maven/operator/pom-1.xml +++ b/src/test/resources/io/openpixee/maven/operator/pom-1.xml @@ -1,152 +1,163 @@ - 4.0.0 + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - br.com.ingenieux - pom-operator - 0.0.1-SNAPSHOT + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT - pom-operator - - http://www.example.com + pom-operator + + http://www.example.com - - UTF-8 - 1.8 - 1.8 - 1.5.31 - + + UTF-8 + 1.8 + 1.8 + 1.5.31 + - - - org.dom4j - dom4j - 2.1.3 - - - jaxen - jaxen - 1.2.0 - - - xerces - xercesImpl - 2.12.1 - - - io.github.java-diff-utils - java-diff-utils - 4.9 - - - junit - junit - 4.11 - test - - - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - ${kotlin.version} - - - org.jetbrains.kotlin - kotlin-test - ${kotlin.version} - test - - + + + test-profile + + bar + + + - - - - - - maven-clean-plugin - 3.1.0 - - - - maven-resources-plugin - 3.0.2 - - - maven-compiler-plugin - 3.8.0 - - - maven-surefire-plugin - 2.22.1 - - - maven-jar-plugin - 3.0.2 - - - maven-install-plugin - 2.5.2 - - - maven-deploy-plugin - 2.8.2 - - - - maven-site-plugin - 3.7.1 - - - maven-project-info-reports-plugin - 3.0.0 - - - - - - org.jetbrains.kotlin - kotlin-maven-plugin - ${kotlin.version} - - - compile - compile - - compile - - - - test-compile - test-compile - - test-compile - - - - - 1.8 - - - - org.apache.maven.plugins - maven-compiler-plugin - - - compile - compile - - compile - - - - testCompile - test-compile - - testCompile - - - - - - + + + org.dom4j + dom4j + 2.1.3 + + + jaxen + jaxen + 1.2.0 + + + xerces + xercesImpl + 2.12.1 + + + io.github.java-diff-utils + java-diff-utils + 4.9 + + + junit + junit + 4.11 + test + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + org.apache.maven.plugins + maven-compiler-plugin + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + + From 36211fa302c225f82d3b06f67fe4701941299677 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 14 Sep 2022 15:43:40 -0500 Subject: [PATCH 042/153] Adding Logging - Disabling extra quoting --- .../io/openpixee/maven/operator/ProjectModel.kt | 4 +++- .../maven/operator/ProjectModelFactory.kt | 4 ++-- .../operator/test/PropertyResolutionTest.kt | 16 ++++++++++++++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt index 7ab11198c..ac68242ac 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt @@ -43,7 +43,9 @@ class ProjectModel internal constructor( ) if (this.activeProfiles.isNotEmpty()) { - processArgs.addAll(listOf("-P", "'${this.activeProfiles.joinToString(",")}'")) + // TODO Aldrin: How safe is not to escape those things? My concern is that deactivating a profile uses '!', + // and I'm not sure how shell escaping rules play a part on that + processArgs.addAll(listOf("-P", this.activeProfiles.joinToString(","))) } processArgs.addAll( diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt index 0e6be2430..04de29c15 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt @@ -26,8 +26,8 @@ class ProjectModelFactory private constructor( this.useProperties = useProperties } - fun withActiveProfiles(activeProfiles: Set): ProjectModelFactory = this.apply { - this.activeProfiles = activeProfiles.toCollection(LinkedHashSet()) + fun withActiveProfiles(vararg activeProfiles: String): ProjectModelFactory = this.apply { + this.activeProfiles = setOf(*activeProfiles) } fun build(): ProjectModel { diff --git a/src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt b/src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt index 52ebcaed1..9251472b6 100644 --- a/src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt @@ -7,6 +7,8 @@ import junit.framework.TestCase.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test +import org.slf4j.Logger +import org.slf4j.LoggerFactory class PropertyResolutionTest { @Test @@ -32,12 +34,22 @@ class PropertyResolutionTest { } private fun resolveWithProfiles(vararg profilesToUse: String): Map { + LOGGER.debug("resolving with profiles: {}", profilesToUse) + val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.2") val context = ProjectModelFactory.load( POMOperator::class.java.getResource("pom-1.xml")!!, - ).withDependency(dependencyToUpgrade).withActiveProfiles(setOf(*profilesToUse)).build() + ).withDependency(dependencyToUpgrade).withActiveProfiles(*profilesToUse).build() + + val resolvedProperties = context.getResolvedProperties() + + LOGGER.debug("Resolved Properties: {}", resolvedProperties) + + return resolvedProperties + } - return context.getResolvedProperties() + companion object { + private val LOGGER: Logger = LoggerFactory.getLogger(POMOperatorTest::class.java) } } \ No newline at end of file From ba20872805342573e217c71cdfe495719d0975ec Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Thu, 15 Sep 2022 01:46:47 -0500 Subject: [PATCH 043/153] * Cleaning TODOS * Property Resolution and Handling --- java-sample/pom.xml | 4 - .../test/resources/io/openpixee/it/pom.xml | 4 - pom.xml | 4 - .../maven/operator/AbstractSimpleCommand.kt | 77 +++++++++++++++++-- .../openpixee/maven/operator/ProjectModel.kt | 5 +- .../maven/operator/test/POMOperatorTest.kt | 22 ++++++ .../operator/test/PropertyResolutionTest.kt | 6 +- .../io/openpixee/maven/operator/pom-1.xml | 4 - .../openpixee/maven/operator/pom-case-1.xml | 4 - .../openpixee/maven/operator/pom-case-3.xml | 4 - .../operator/pom-with-property-simple.xml | 32 ++++++++ 11 files changed, 127 insertions(+), 39 deletions(-) create mode 100644 src/test/resources/io/openpixee/maven/operator/pom-with-property-simple.xml diff --git a/java-sample/pom.xml b/java-sample/pom.xml index 243248862..ca3afcc77 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -9,10 +9,6 @@ java-sample 0.0.1-SNAPSHOT - it - - http://www.example.com - UTF-8 1.8 diff --git a/java-sample/src/test/resources/io/openpixee/it/pom.xml b/java-sample/src/test/resources/io/openpixee/it/pom.xml index 014b868fd..b653bbdf6 100644 --- a/java-sample/src/test/resources/io/openpixee/it/pom.xml +++ b/java-sample/src/test/resources/io/openpixee/it/pom.xml @@ -7,10 +7,6 @@ pom-operator 0.0.1-SNAPSHOT - pom-operator - - http://www.example.com - UTF-8 1.8 diff --git a/pom.xml b/pom.xml index 9c90a5ec1..74502e635 100644 --- a/pom.xml +++ b/pom.xml @@ -8,10 +8,6 @@ pom-operator 0.0.1-SNAPSHOT - pom-operator - - http://www.example.com - UTF-8 1.8 diff --git a/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt b/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt index dbd6481c2..b5e6e185b 100644 --- a/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt +++ b/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt @@ -2,8 +2,14 @@ package io.openpixee.maven.operator import com.github.zafarkhaja.semver.Version import io.openpixee.maven.operator.util.Util.selectXPathNodes +import org.apache.commons.lang3.text.StrSubstitutor +import org.dom4j.Element abstract class AbstractSimpleCommand : Command { + companion object { + val PROPERTY_REFERENCE_REGEX = Regex("^\\\$\\{(.*)}$") + } + protected fun handleDependency(c: ProjectModel, lookupExpression: String): Boolean { val dependencyNodes = c.resultPom.selectXPathNodes(lookupExpression) @@ -11,20 +17,25 @@ abstract class AbstractSimpleCommand : Command { val versionNodes = dependencyNodes[0].selectXPathNodes("./m:version") if (1 == versionNodes.size) { + val versionNode = versionNodes[0] as Element + var mustUpgrade = true if (c.skipIfNewer) { - // TODO: Handle Properties - val currentVersion = Version.valueOf(versionNodes[0].text) - val newVersion = Version.valueOf(c.dependency.version) - - val versionsAreIncreasing = newVersion.greaterThan(currentVersion) - - mustUpgrade = versionsAreIncreasing + mustUpgrade = findOutIfUpgradeIsNeeded(c, versionNode) } if (mustUpgrade) { - versionNodes[0].text = c.dependency.version + if (c.useProperties) { + val propertyName = propertyName(c, versionNode) + + // define property + upgradeProperty(c, propertyName) + + versionNodes[0].text = "\${$propertyName}" + } else { + versionNodes[0].text = c.dependency.version + } } return true @@ -33,4 +44,54 @@ abstract class AbstractSimpleCommand : Command { return false } + + private fun upgradeProperty(c: ProjectModel, propertyName: String) { + // TODO: Handle Profiles + + val propertyElement = c.resultPom.rootElement.element("properties") + + if (null == propertyElement.element(propertyName)) { + val newElement = propertyElement.addElement(propertyName) + + formatNode(newElement) + } + + propertyElement.element(propertyName).text = c.dependency.version + } + + private fun propertyName(c: ProjectModel, versionNode: Element): String { + val version = versionNode.textTrim + + if (PROPERTY_REFERENCE_REGEX.matches(version)) { + val match = PROPERTY_REFERENCE_REGEX.find(version) + + val firstMatch = match!!.groups[1]!! + + return firstMatch.value + } + + // TODO: Escaping + + return c.dependency.artifactId + ".version" + } + + private fun findOutIfUpgradeIsNeeded(c: ProjectModel, versionNode: Element): Boolean { + val currentVersionNodeText = resolveVersion(c, versionNode.text!!) + + val currentVersion = Version.valueOf(currentVersionNodeText) + val newVersion = Version.valueOf(c.dependency.version) + + val versionsAreIncreasing = newVersion.greaterThan(currentVersion) + + return versionsAreIncreasing + } + + private fun resolveVersion(c: ProjectModel, versionText: String): String = + if (versionText.contains("\${")) { + @Suppress("DEPRECATION") + StrSubstitutor(c.resolvedProperties).replace(versionText) + } else { + versionText + } + } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt index ac68242ac..f512aabb8 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt @@ -1,11 +1,9 @@ package io.openpixee.maven.operator import org.dom4j.Document -import org.dom4j.Element import org.dom4j.io.SAXReader import java.io.File import java.io.FileInputStream -import java.lang.IllegalStateException /** * ProjectModel represents the input parameters for the chain @@ -21,11 +19,12 @@ class ProjectModel internal constructor( ) { val resultPom: Document = pomDocument.clone() as Document - internal fun getResolvedProperties(): Map = + internal val resolvedProperties: Map by lazy { getEffectivePom().rootElement.elements("properties").flatMap { it.elements() } .associate { it.name to it.text } + } fun getEffectivePom(): Document { val tmpInputFile = File.createTempFile("tmp-pom-orig", ".xml") diff --git a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt index 5dfa8e028..21c86b8e9 100644 --- a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt @@ -154,6 +154,28 @@ class POMOperatorTest { ) } + @Test + fun testCaseWithProperty() { + val dependencyToUpgrade = + Dependency("org.dom4j", "dom4j", version = "1.0.0") + + val context = + ProjectModelFactory.load( + POMOperator::class.java.getResource("pom-with-property-simple.xml")!!, + ).withDependency(dependencyToUpgrade).withUseProperties(true).withSkipIfNewer(true) + .build() + + POMOperator.modify(context) + + val diff = getXmlDifferences(context.pomDocument, context.resultPom)!! + + assertThat("Document has differences", diff.hasDifferences()) + + assertThat("Document has one difference", 1 == listOf(diff.differences).size) + + assertThat("Document changes a single version", diff.differences.first().toString().startsWith("Expected text value '0.0.1-SNAPSHOT' but was '1.0.0'")) + } + private fun getXmlDifferences( original: Document, modified: Document diff --git a/src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt b/src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt index 9251472b6..1df60ebdc 100644 --- a/src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt @@ -42,11 +42,9 @@ class PropertyResolutionTest { POMOperator::class.java.getResource("pom-1.xml")!!, ).withDependency(dependencyToUpgrade).withActiveProfiles(*profilesToUse).build() - val resolvedProperties = context.getResolvedProperties() + LOGGER.debug("Resolved Properties: {}", context.resolvedProperties) - LOGGER.debug("Resolved Properties: {}", resolvedProperties) - - return resolvedProperties + return context.resolvedProperties } companion object { diff --git a/src/test/resources/io/openpixee/maven/operator/pom-1.xml b/src/test/resources/io/openpixee/maven/operator/pom-1.xml index 7ba609cf4..cc3ff40c0 100644 --- a/src/test/resources/io/openpixee/maven/operator/pom-1.xml +++ b/src/test/resources/io/openpixee/maven/operator/pom-1.xml @@ -9,10 +9,6 @@ pom-operator 0.0.1-SNAPSHOT - pom-operator - - http://www.example.com - UTF-8 1.8 diff --git a/src/test/resources/io/openpixee/maven/operator/pom-case-1.xml b/src/test/resources/io/openpixee/maven/operator/pom-case-1.xml index 08779506b..28d291308 100644 --- a/src/test/resources/io/openpixee/maven/operator/pom-case-1.xml +++ b/src/test/resources/io/openpixee/maven/operator/pom-case-1.xml @@ -8,10 +8,6 @@ pom-operator 0.0.1-SNAPSHOT - pom-operator - - http://www.example.com - UTF-8 1.8 diff --git a/src/test/resources/io/openpixee/maven/operator/pom-case-3.xml b/src/test/resources/io/openpixee/maven/operator/pom-case-3.xml index 3c20cbb9c..e9149e701 100644 --- a/src/test/resources/io/openpixee/maven/operator/pom-case-3.xml +++ b/src/test/resources/io/openpixee/maven/operator/pom-case-3.xml @@ -7,10 +7,6 @@ pom-operator 0.0.1-SNAPSHOT - pom-operator - - http://www.example.com - UTF-8 1.8 diff --git a/src/test/resources/io/openpixee/maven/operator/pom-with-property-simple.xml b/src/test/resources/io/openpixee/maven/operator/pom-with-property-simple.xml new file mode 100644 index 000000000..fb7d9824f --- /dev/null +++ b/src/test/resources/io/openpixee/maven/operator/pom-with-property-simple.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + + + + test-profile + + 1.0.1 + + + + + + + org.dom4j + dom4j + ${sample.version} + + + From e7b27c8221dd8f3548eeeb40ba7c69c033e1c32c Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Thu, 15 Sep 2022 02:39:20 -0500 Subject: [PATCH 044/153] Minor reorg + versioning on nodes --- .../maven/operator/AbstractSimpleCommand.kt | 64 +-------- .../openpixee/maven/operator/SimpleInsert.kt | 3 +- .../io/openpixee/maven/operator/format.kt | 58 -------- .../java/io/openpixee/maven/operator/misc.kt | 128 ++++++++++++++++++ 4 files changed, 131 insertions(+), 122 deletions(-) delete mode 100644 src/main/java/io/openpixee/maven/operator/format.kt create mode 100644 src/main/java/io/openpixee/maven/operator/misc.kt diff --git a/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt b/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt index b5e6e185b..10533c59f 100644 --- a/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt +++ b/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt @@ -6,10 +6,6 @@ import org.apache.commons.lang3.text.StrSubstitutor import org.dom4j.Element abstract class AbstractSimpleCommand : Command { - companion object { - val PROPERTY_REFERENCE_REGEX = Regex("^\\\$\\{(.*)}$") - } - protected fun handleDependency(c: ProjectModel, lookupExpression: String): Boolean { val dependencyNodes = c.resultPom.selectXPathNodes(lookupExpression) @@ -26,16 +22,7 @@ abstract class AbstractSimpleCommand : Command { } if (mustUpgrade) { - if (c.useProperties) { - val propertyName = propertyName(c, versionNode) - - // define property - upgradeProperty(c, propertyName) - - versionNodes[0].text = "\${$propertyName}" - } else { - versionNodes[0].text = c.dependency.version - } + upgradeVersionNode(c, versionNode) } return true @@ -45,53 +32,4 @@ abstract class AbstractSimpleCommand : Command { return false } - private fun upgradeProperty(c: ProjectModel, propertyName: String) { - // TODO: Handle Profiles - - val propertyElement = c.resultPom.rootElement.element("properties") - - if (null == propertyElement.element(propertyName)) { - val newElement = propertyElement.addElement(propertyName) - - formatNode(newElement) - } - - propertyElement.element(propertyName).text = c.dependency.version - } - - private fun propertyName(c: ProjectModel, versionNode: Element): String { - val version = versionNode.textTrim - - if (PROPERTY_REFERENCE_REGEX.matches(version)) { - val match = PROPERTY_REFERENCE_REGEX.find(version) - - val firstMatch = match!!.groups[1]!! - - return firstMatch.value - } - - // TODO: Escaping - - return c.dependency.artifactId + ".version" - } - - private fun findOutIfUpgradeIsNeeded(c: ProjectModel, versionNode: Element): Boolean { - val currentVersionNodeText = resolveVersion(c, versionNode.text!!) - - val currentVersion = Version.valueOf(currentVersionNodeText) - val newVersion = Version.valueOf(c.dependency.version) - - val versionsAreIncreasing = newVersion.greaterThan(currentVersion) - - return versionsAreIncreasing - } - - private fun resolveVersion(c: ProjectModel, versionText: String): String = - if (versionText.contains("\${")) { - @Suppress("DEPRECATION") - StrSubstitutor(c.resolvedProperties).replace(versionText) - } else { - versionText - } - } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt b/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt index b0b9dbfdb..709cf8546 100644 --- a/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt +++ b/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt @@ -19,7 +19,7 @@ val SimpleInsert = object : Command { val versionNode = dependencyNode.addElement("version") - versionNode.text = c.dependency.version + upgradeVersionNode(c, versionNode) elementsToFormat.add(newDependencyManagementNode) } @@ -57,6 +57,7 @@ val SimpleInsert = object : Command { val artifactIdNode = dependencyNode.addElement("artifactId") artifactIdNode.text = c.dependency.artifactId + return dependencyNode } } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/format.kt b/src/main/java/io/openpixee/maven/operator/format.kt deleted file mode 100644 index 583c82605..000000000 --- a/src/main/java/io/openpixee/maven/operator/format.kt +++ /dev/null @@ -1,58 +0,0 @@ -package io.openpixee.maven.operator - -import org.apache.commons.lang3.StringUtils -import org.dom4j.Element -import org.dom4j.Text -import org.dom4j.io.OutputFormat -import org.dom4j.io.SAXReader -import org.dom4j.io.XMLWriter -import org.dom4j.tree.DefaultText -import java.io.StringReader -import java.io.StringWriter -import kotlin.math.ceil - -internal fun formatNode(node: Element) { - val parent = node.parent - val siblings = parent.content() - - val indentLevel = findIndentLevel(node) - - val clonedNode = node.clone() as Element - - val out = StringWriter() - - val outputFormat = OutputFormat.createPrettyPrint() - - val xmlWriter = XMLWriter(out, outputFormat) - - xmlWriter.setIndentLevel(ceil(indentLevel.toDouble() / 2).toInt()) - - xmlWriter.write(clonedNode) - - val content = out.toString() - - val newElement = SAXReader().read(StringReader(content)).rootElement.clone() as Element - - parent.remove(node) - - parent.add(DefaultText("\n" + StringUtils.repeat(" ", indentLevel))) - parent.add(newElement) - parent.add(DefaultText("\n" + StringUtils.repeat(" ", ((indentLevel - 1) / 2)))) -} - -internal fun findIndentLevel(node: Element): Int { - val siblings = node.parent.content() - val myIndex = siblings.indexOf(node) - - if (myIndex > 0) { - val lastElement = siblings.subList(0, myIndex).findLast { - (it is Text) && it.text.matches(Regex("\\n+\\s+")) - } - - val lastElementText = lastElement?.text ?: "" - - return lastElementText.trimStart('\n').length - } - - return 0 -} diff --git a/src/main/java/io/openpixee/maven/operator/misc.kt b/src/main/java/io/openpixee/maven/operator/misc.kt new file mode 100644 index 000000000..12a2482bc --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/misc.kt @@ -0,0 +1,128 @@ +package io.openpixee.maven.operator + +import com.github.zafarkhaja.semver.Version +import org.apache.commons.lang3.StringUtils +import org.apache.commons.lang3.text.StrSubstitutor +import org.dom4j.Element +import org.dom4j.Text +import org.dom4j.io.OutputFormat +import org.dom4j.io.SAXReader +import org.dom4j.io.XMLWriter +import org.dom4j.tree.DefaultText +import java.io.StringReader +import java.io.StringWriter +import kotlin.math.ceil + +internal fun formatNode(node: Element) { + val parent = node.parent + val siblings = parent.content() + + val indentLevel = findIndentLevel(node) + + val clonedNode = node.clone() as Element + + val out = StringWriter() + + val outputFormat = OutputFormat.createPrettyPrint() + + val xmlWriter = XMLWriter(out, outputFormat) + + xmlWriter.setIndentLevel(ceil(indentLevel.toDouble() / 2).toInt()) + + xmlWriter.write(clonedNode) + + val content = out.toString() + + val newElement = SAXReader().read(StringReader(content)).rootElement.clone() as Element + + parent.remove(node) + + parent.add(DefaultText("\n" + StringUtils.repeat(" ", indentLevel))) + parent.add(newElement) + parent.add(DefaultText("\n" + StringUtils.repeat(" ", ((indentLevel - 1) / 2)))) +} + +internal fun findIndentLevel(node: Element): Int { + val siblings = node.parent.content() + val myIndex = siblings.indexOf(node) + + if (myIndex > 0) { + val lastElement = siblings.subList(0, myIndex).findLast { + (it is Text) && it.text.matches(Regex("\\n+\\s+")) + } + + val lastElementText = lastElement?.text ?: "" + + return lastElementText.trimStart('\n').length + } + + return 0 +} + +internal val PROPERTY_REFERENCE_REGEX = Regex("^\\\$\\{(.*)}$") +internal fun upgradeProperty(c: ProjectModel, propertyName: String) { + // TODO: Handle Profiles + + val propertyElement = c.resultPom.rootElement.element("properties") + + if (null == propertyElement.element(propertyName)) { + val newElement = propertyElement.addElement(propertyName) + + formatNode(newElement) + } + + propertyElement.element(propertyName).text = c.dependency.version +} + +internal fun propertyName(c: ProjectModel, versionNode: Element): String { + val version = versionNode.textTrim + + if (PROPERTY_REFERENCE_REGEX.matches(version)) { + val match = PROPERTY_REFERENCE_REGEX.find(version) + + val firstMatch = match!!.groups[1]!! + + return firstMatch.value + } + + // TODO: Escaping + + return c.dependency.artifactId + ".version" +} + +internal fun findOutIfUpgradeIsNeeded(c: ProjectModel, versionNode: Element): Boolean { + val currentVersionNodeText = resolveVersion(c, versionNode.text!!) + + val currentVersion = Version.valueOf(currentVersionNodeText) + val newVersion = Version.valueOf(c.dependency.version) + + val versionsAreIncreasing = newVersion.greaterThan(currentVersion) + + return versionsAreIncreasing +} + +internal fun resolveVersion(c: ProjectModel, versionText: String): String = + if (PROPERTY_REFERENCE_REGEX.matches(versionText)) { + @Suppress("DEPRECATION") + StrSubstitutor(c.resolvedProperties).replace(versionText) + } else { + versionText + } + +internal fun escapedPropertyName(propertyName: String): String = + "\${$propertyName}" + +internal fun upgradeVersionNode(c: ProjectModel, versionNode: Element) { + if (c.useProperties) { + val propertyName = propertyName(c, versionNode) + + // define property + upgradeProperty(c, propertyName) + + versionNode.text = escapedPropertyName(propertyName) + } else { + versionNode.text = c.dependency.version + } +} + + From 8f556ef81b26c6e4b020e68373aeba83254020f8 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 16 Sep 2022 13:57:42 -0500 Subject: [PATCH 045/153] Adding Jacoco + Versions Formatting --- .github/workflows/push-test.yml | 24 +++++++++++++++++++ pom.xml | 23 ++++++++++++++++++ .../java/io/openpixee/maven/operator/misc.kt | 3 ++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/.github/workflows/push-test.yml b/.github/workflows/push-test.yml index eee4c5fad..72ac74e11 100644 --- a/.github/workflows/push-test.yml +++ b/.github/workflows/push-test.yml @@ -30,6 +30,30 @@ jobs: run: | mvn -N -B install mvn -N -B -P integration-testing verify + - name: Generate Coverage Badge + id: jacoco + uses: cicirello/jacoco-badge-generator@v2 + with: + generate-branches-badge: true + - name: Log coverage percentage + run: | + echo "coverage = ${{ steps.jacoco.outputs.coverage }}" + echo "branch coverage = ${{ steps.jacoco.outputs.branches }}" + - name: Commit the JaCoCo badge (if it changed) + run: | + if [[ `git status --porcelain` ]]; then + git config --global user.name 'Jacoco Coverage Update Action' + git config --global user.email 'pixee@users.noreply.github.com' + git add -A + git commit -m "Autogenerated JaCoCo coverage badge" + git push + fi + - name: Upload JaCoCo coverage report + uses: actions/upload-artifact@v2 + with: + name: jacoco-report + path: target/site/jacoco/ + - name: Deploy if: ${{ github.ref_name == 'master' }} run: | diff --git a/pom.xml b/pom.xml index 74502e635..71cbd8e31 100644 --- a/pom.xml +++ b/pom.xml @@ -143,6 +143,25 @@ maven-project-info-reports-plugin 3.0.0 + + org.jacoco + jacoco-maven-plugin + 0.8.7 + + + + prepare-agent + + + + generate-code-coverage-report + test + + report + + + +
@@ -190,6 +209,10 @@ + + org.jacoco + jacoco-maven-plugin +
diff --git a/src/main/java/io/openpixee/maven/operator/misc.kt b/src/main/java/io/openpixee/maven/operator/misc.kt index 12a2482bc..cee1ca835 100644 --- a/src/main/java/io/openpixee/maven/operator/misc.kt +++ b/src/main/java/io/openpixee/maven/operator/misc.kt @@ -86,8 +86,9 @@ internal fun propertyName(c: ProjectModel, versionNode: Element): String { } // TODO: Escaping + // TODO: Template Format (suffix / preffix)? - return c.dependency.artifactId + ".version" + return "versions." + c.dependency.artifactId } internal fun findOutIfUpgradeIsNeeded(c: ProjectModel, versionNode: Element): Boolean { From 9b808b0244c7839f316aace225df0006521dd916 Mon Sep 17 00:00:00 2001 From: Jacoco Coverage Update Action Date: Fri, 16 Sep 2022 18:59:31 +0000 Subject: [PATCH 046/153] Autogenerated JaCoCo coverage badge --- .github/badges/branches.svg | 1 + .github/badges/jacoco.svg | 1 + 2 files changed, 2 insertions(+) create mode 100644 .github/badges/branches.svg create mode 100644 .github/badges/jacoco.svg diff --git a/.github/badges/branches.svg b/.github/badges/branches.svg new file mode 100644 index 000000000..e40f012b0 --- /dev/null +++ b/.github/badges/branches.svg @@ -0,0 +1 @@ +branches67.3% \ No newline at end of file diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg new file mode 100644 index 000000000..8b60e9f5e --- /dev/null +++ b/.github/badges/jacoco.svg @@ -0,0 +1 @@ +coverage85.1% \ No newline at end of file From 91bf6f01a7f8dc4ea36625a51dba446120853b01 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 16 Sep 2022 14:09:53 -0500 Subject: [PATCH 047/153] README fixes --- .github/workflows/push-test.yml | 2 ++ README.md | 3 +++ 2 files changed, 5 insertions(+) diff --git a/.github/workflows/push-test.yml b/.github/workflows/push-test.yml index 72ac74e11..39ca3248a 100644 --- a/.github/workflows/push-test.yml +++ b/.github/workflows/push-test.yml @@ -1,3 +1,5 @@ +name: Java CI + on: [push] jobs: diff --git a/README.md b/README.md index d78b687ba..6132368f5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +[![Actions Status](https://github.com/openpixee/pom-operator/workflows/Java%20CI/badge.svg)](https://github.com/openpixee/pom-operator/actions) +![Coverage](.github/badges/jacoco.svg) + # pom-operator POM Operator is a library responsible for injecting dependencies into POM files programatically. From 45479b5cb7a363b7a587d9e03fb9d5b233d56207 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 16 Sep 2022 15:05:44 -0500 Subject: [PATCH 048/153] Cleanup / Logging / Tests --- .github/workflows/push-test.yml | 2 +- .../maven/operator/ProjectModelFactory.kt | 3 +- .../java/io/openpixee/maven/operator/misc.kt | 20 ++++-- .../maven/operator/test/POMOperatorTest.kt | 69 ++++++++++++++++++- 4 files changed, 84 insertions(+), 10 deletions(-) diff --git a/.github/workflows/push-test.yml b/.github/workflows/push-test.yml index 39ca3248a..220947e2e 100644 --- a/.github/workflows/push-test.yml +++ b/.github/workflows/push-test.yml @@ -56,7 +56,7 @@ jobs: name: jacoco-report path: target/site/jacoco/ - - name: Deploy + - name: Deploy (only if on master) if: ${{ github.ref_name == 'master' }} run: | mvn -N -B deploy -DaltDeploymentRepository=pixee::default::https://pixee.jfrog.io/artifactory/mailman-libs-snapshot diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt index 04de29c15..04bb62739 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt @@ -41,7 +41,8 @@ class ProjectModelFactory private constructor( } companion object { - private fun load(`is`: InputStream): ProjectModelFactory { + @JvmStatic + fun load(`is`: InputStream): ProjectModelFactory { val pomDocument = SAXReader().read(`is`)!! return ProjectModelFactory(pomDocument) diff --git a/src/main/java/io/openpixee/maven/operator/misc.kt b/src/main/java/io/openpixee/maven/operator/misc.kt index cee1ca835..932e1da88 100644 --- a/src/main/java/io/openpixee/maven/operator/misc.kt +++ b/src/main/java/io/openpixee/maven/operator/misc.kt @@ -15,7 +15,7 @@ import kotlin.math.ceil internal fun formatNode(node: Element) { val parent = node.parent - val siblings = parent.content() + //val siblings = parent.content() val indentLevel = findIndentLevel(node) @@ -63,15 +63,25 @@ internal val PROPERTY_REFERENCE_REGEX = Regex("^\\\$\\{(.*)}$") internal fun upgradeProperty(c: ProjectModel, propertyName: String) { // TODO: Handle Profiles - val propertyElement = c.resultPom.rootElement.element("properties") + if (null == c.resultPom.rootElement.element("properties")) { + val propertyElement = c.resultPom.rootElement.addElement("properties") - if (null == propertyElement.element(propertyName)) { - val newElement = propertyElement.addElement(propertyName) + formatNode(propertyElement) + } + + val parentPropertyElement = c.resultPom.rootElement.element("properties") + + if (null == parentPropertyElement.element(propertyName)) { + val newElement = parentPropertyElement.addElement(propertyName) formatNode(newElement) } - propertyElement.element(propertyName).text = c.dependency.version + val propertyElement = parentPropertyElement.element(propertyName) + + propertyElement.text = c.dependency.version + + formatNode(propertyElement) } internal fun propertyName(c: ProjectModel, versionNode: Element): String { diff --git a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt index 21c86b8e9..46f3d9a35 100644 --- a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt @@ -8,6 +8,7 @@ import io.openpixee.maven.operator.util.Util.buildLookupExpressionForDependency import io.openpixee.maven.operator.util.Util.selectXPathNodes import org.dom4j.Document import org.hamcrest.MatcherAssert.assertThat +import org.junit.Assert.assertEquals import org.junit.Test import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -167,13 +168,74 @@ class POMOperatorTest { POMOperator.modify(context) + LOGGER.debug("original pom: {}", context.pomDocument.asXML()) + LOGGER.debug("resulting pom: {}", context.resultPom.asXML()) + + val diff = getXmlDifferences(context.pomDocument, context.resultPom)!! + + assertThat("Document has differences", diff.hasDifferences()) + + val differenceList = diff.differences.toList() + + assertThat("Document has one difference", 1 == differenceList.size) + + assertThat( + "Document changes a single version", + differenceList.first().toString() + .startsWith("Expected text value '0.0.1-SNAPSHOT' but was '1.0.0'") + ) + + assertEquals( + "Document changes a property called 'sample.version'", + differenceList.first().comparison.testDetails.xPath, + "/project[1]/properties[1]/sample.version[1]/text()[1]" + ) + } + + @Test + fun testCaseWithoutPropertyButDefiningOne() { + val dependencyToUpgrade = + Dependency("org.dom4j", "dom4j", version = "1.0.0") + + val originalPom = """ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + + + org.dom4j + dom4j + 0.0.1-SNAPSHOT + + + + """.trim() + val context = + ProjectModelFactory.load( + originalPom.byteInputStream(), + ).withDependency(dependencyToUpgrade).withUseProperties(true).withSkipIfNewer(true) + .build() + + POMOperator.modify(context) + + LOGGER.debug("original pom: {}", context.pomDocument.asXML()) + LOGGER.debug("resulting pom: {}", context.resultPom.asXML()) + val diff = getXmlDifferences(context.pomDocument, context.resultPom)!! assertThat("Document has differences", diff.hasDifferences()) - assertThat("Document has one difference", 1 == listOf(diff.differences).size) + val differencesAsList = diff.differences.toList() - assertThat("Document changes a single version", diff.differences.first().toString().startsWith("Expected text value '0.0.1-SNAPSHOT' but was '1.0.0'")) + assertThat("Document has several differences", differencesAsList.size > 1) } private fun getXmlDifferences( @@ -183,7 +245,8 @@ class POMOperatorTest { val originalDoc = Input.fromString(original.asXML()).build() val modifiedDoc = Input.fromString(modified.asXML()).build() - val diff = DiffBuilder.compare(originalDoc).withTest(modifiedDoc).build() + val diff = DiffBuilder.compare(originalDoc).withTest(modifiedDoc).ignoreWhitespace() + .checkForSimilar().build() LOGGER.debug("diff: {}", diff) From c566f0823a42a844ef46c6ca8533228c1aad405e Mon Sep 17 00:00:00 2001 From: Jacoco Coverage Update Action Date: Fri, 16 Sep 2022 20:07:09 +0000 Subject: [PATCH 049/153] Autogenerated JaCoCo coverage badge --- .github/badges/branches.svg | 2 +- .github/badges/jacoco.svg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/badges/branches.svg b/.github/badges/branches.svg index e40f012b0..f754b46b2 100644 --- a/.github/badges/branches.svg +++ b/.github/badges/branches.svg @@ -1 +1 @@ -branches67.3% \ No newline at end of file +branches77.7% \ No newline at end of file diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index 8b60e9f5e..ac6096f32 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage85.1% \ No newline at end of file +coverage87.1% \ No newline at end of file From a2e620a7f327987835809cf6186ea5c2f6fd8dc5 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 23 Sep 2022 16:58:34 -0500 Subject: [PATCH 050/153] Handling when version already exists --- README.md | 1 + .../openpixee/maven/operator/ProjectModel.kt | 3 +- .../maven/operator/ProjectModelFactory.kt | 8 +++- .../java/io/openpixee/maven/operator/misc.kt | 11 +++++ .../maven/operator/test/POMOperatorTest.kt | 45 +++++++++++++++++++ 5 files changed, 66 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6132368f5..31d90ede1 100644 --- a/README.md +++ b/README.md @@ -51,3 +51,4 @@ It implements a Chain of Responsibility strategy - each `Command` class attempts - ~~better readme~~ - be able to guess existing indenting for existing documents - investigate leverage whats on [versions-maven-plugin](https://github.com/mojohaus/versions-maven-plugin) +- consider fuzzying when testing \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt index f512aabb8..9c8541df3 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt @@ -15,7 +15,8 @@ class ProjectModel internal constructor( val dependency: Dependency, val skipIfNewer: Boolean, val useProperties: Boolean, - val activeProfiles: Set + val activeProfiles: Set, + val overrideIfAlreadyExists: Boolean, ) { val resultPom: Document = pomDocument.clone() as Document diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt index 04bb62739..f7029fdd9 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt @@ -13,6 +13,7 @@ class ProjectModelFactory private constructor( private var skipIfNewer: Boolean = false, private var useProperties: Boolean = false, private var activeProfiles: Set = emptySet(), + private var overrideIfAlreadyExists: Boolean = false, ) { fun withDependency(dep: Dependency): ProjectModelFactory = this.apply { this.dependency = dep @@ -30,13 +31,18 @@ class ProjectModelFactory private constructor( this.activeProfiles = setOf(*activeProfiles) } + fun withOverrideIfAlreadyExists(overrideIfAlreadyExists: Boolean) = this.apply { + this.overrideIfAlreadyExists = overrideIfAlreadyExists + } + fun build(): ProjectModel { return ProjectModel( pomDocument = pomDocument, dependency = dependency!!, skipIfNewer = skipIfNewer, useProperties = useProperties, - activeProfiles = activeProfiles + activeProfiles = activeProfiles, + overrideIfAlreadyExists = overrideIfAlreadyExists ) } diff --git a/src/main/java/io/openpixee/maven/operator/misc.kt b/src/main/java/io/openpixee/maven/operator/misc.kt index 932e1da88..f8cad965b 100644 --- a/src/main/java/io/openpixee/maven/operator/misc.kt +++ b/src/main/java/io/openpixee/maven/operator/misc.kt @@ -11,6 +11,7 @@ import org.dom4j.io.XMLWriter import org.dom4j.tree.DefaultText import java.io.StringReader import java.io.StringWriter +import java.lang.IllegalStateException import kotlin.math.ceil internal fun formatNode(node: Element) { @@ -75,6 +76,16 @@ internal fun upgradeProperty(c: ProjectModel, propertyName: String) { val newElement = parentPropertyElement.addElement(propertyName) formatNode(newElement) + } else { + if (!c.overrideIfAlreadyExists) { + val propertyReferenceRE = Regex.fromLiteral("\${$propertyName}") + + val numberOfAllCurrentMatches = propertyReferenceRE.findAll(c.pomDocument.asXML()).toList().size + + if (numberOfAllCurrentMatches > 1) { + throw IllegalStateException("Property ${propertyName} is already defined - and used more than once.") + } + } } val propertyElement = parentPropertyElement.element(propertyName) diff --git a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt index 46f3d9a35..e6d76319b 100644 --- a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt @@ -17,6 +17,7 @@ import org.xmlunit.builder.Input import org.xmlunit.diff.ComparisonType import org.xmlunit.diff.Diff import java.io.File +import java.lang.IllegalStateException import java.net.URLDecoder /** @@ -192,6 +193,50 @@ class POMOperatorTest { ) } + @Test(expected = IllegalStateException::class) + fun testCaseWithPropertyDefinedTwice() { + val dependencyToUpgrade = + Dependency("org.dom4j", "dom4j", version = "1.0.0") + + val originalPom = """ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + + 0.0.1 + + + + + org.dom4j + dom4j + ${'$'}{dom4j.version} + + + org.dom4j + dom4j-other + ${'$'}{dom4j.version} + + + + """.trimIndent() + val context = + ProjectModelFactory.load( + originalPom.byteInputStream(), + ).withDependency(dependencyToUpgrade).withUseProperties(true).withOverrideIfAlreadyExists(false) + .build() + + POMOperator.modify(context) + } + @Test fun testCaseWithoutPropertyButDefiningOne() { val dependencyToUpgrade = From c6103e0b362c8f57890abba5cd9654c9d3d68192 Mon Sep 17 00:00:00 2001 From: Jacoco Coverage Update Action Date: Fri, 23 Sep 2022 22:00:13 +0000 Subject: [PATCH 051/153] Autogenerated JaCoCo coverage badge --- .github/badges/branches.svg | 2 +- .github/badges/jacoco.svg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/badges/branches.svg b/.github/badges/branches.svg index f754b46b2..dac76e5af 100644 --- a/.github/badges/branches.svg +++ b/.github/badges/branches.svg @@ -1 +1 @@ -branches77.7% \ No newline at end of file +branches77.5% \ No newline at end of file diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index ac6096f32..0824fec9c 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage87.1% \ No newline at end of file +coverage87.8% \ No newline at end of file From b512b4a25afabed13d199b06126784dfe9f5153f Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Sun, 16 Oct 2022 16:59:11 -0500 Subject: [PATCH 052/153] Code Cleanup + Moving effective Pom to tests --- .../maven/operator/AbstractSimpleCommand.kt | 3 + .../java/io/openpixee/maven/operator/App.kt | 3 +- .../java/io/openpixee/maven/operator/Chain.kt | 21 ++++- .../io/openpixee/maven/operator/Command.kt | 9 +++ .../io/openpixee/maven/operator/Dependency.kt | 6 ++ .../openpixee/maven/operator/POMOperator.kt | 3 + .../openpixee/maven/operator/ProjectModel.kt | 76 +++++++------------ .../maven/operator/ProjectModelFactory.kt | 23 ++++++ .../openpixee/maven/operator/SimpleInsert.kt | 8 +- .../openpixee/maven/operator/SimpleUpgrade.kt | 3 + .../java/io/openpixee/maven/operator/misc.kt | 28 ++++++- .../io/openpixee/maven/operator/util/Util.kt | 26 +++++++ .../io/openpixee/maven/operator/test/util.kt | 56 ++++++++++++++ .../io/openpixee/maven/operator/pom-3.xml | 6 +- 14 files changed, 209 insertions(+), 62 deletions(-) create mode 100644 src/test/java/io/openpixee/maven/operator/test/util.kt diff --git a/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt b/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt index 10533c59f..f9e30a270 100644 --- a/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt +++ b/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt @@ -5,6 +5,9 @@ import io.openpixee.maven.operator.util.Util.selectXPathNodes import org.apache.commons.lang3.text.StrSubstitutor import org.dom4j.Element +/** + * Base implementation of Command - used by SimpleDependency and SimpleInsert + */ abstract class AbstractSimpleCommand : Command { protected fun handleDependency(c: ProjectModel, lookupExpression: String): Boolean { val dependencyNodes = c.resultPom.selectXPathNodes(lookupExpression) diff --git a/src/main/java/io/openpixee/maven/operator/App.kt b/src/main/java/io/openpixee/maven/operator/App.kt index 0ec14f082..72b5d0176 100644 --- a/src/main/java/io/openpixee/maven/operator/App.kt +++ b/src/main/java/io/openpixee/maven/operator/App.kt @@ -6,8 +6,7 @@ import java.lang.IllegalStateException /** - * Hello world! - * + * Sample CLI Modification App */ object App { @JvmStatic diff --git a/src/main/java/io/openpixee/maven/operator/Chain.kt b/src/main/java/io/openpixee/maven/operator/Chain.kt index 05ac2b483..d99da1b87 100644 --- a/src/main/java/io/openpixee/maven/operator/Chain.kt +++ b/src/main/java/io/openpixee/maven/operator/Chain.kt @@ -1,8 +1,22 @@ package io.openpixee.maven.operator -class Chain(vararg c: Command) { - private val commandList = ArrayList(c.toList()) +/** + * Implements a Chain of Responsibility Pattern + * + * @constructor commands: Commands to Use + */ +class Chain(vararg commands: Command) { + /** + * Internal ArrayList of the Commands + */ + private val commandList = ArrayList(commands.toList()) + /** + * Executes the Commands in the Chain of Responsibility + * + * @param c ProjectModel (context) + * @return Boolean if successful + */ fun execute(c: ProjectModel): Boolean { var done = false val listIterator = commandList.listIterator() @@ -17,6 +31,9 @@ class Chain(vararg c: Command) { } companion object { + /** + * Returns a Pre-Configured Chain with the Defaults + */ fun create() = Chain(SimpleUpgrade, SimpleDependencyManagement, SimpleInsert) } } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/Command.kt b/src/main/java/io/openpixee/maven/operator/Command.kt index 9e19188ba..c0423c48d 100644 --- a/src/main/java/io/openpixee/maven/operator/Command.kt +++ b/src/main/java/io/openpixee/maven/operator/Command.kt @@ -1,5 +1,14 @@ package io.openpixee.maven.operator +/** + * Represents a Command in a Chain of Responsibility Pattern + */ fun interface Command { + /** + * Given a context, performs an operation + * + * @param c Context (Project Model) to use + * @return true if the execution was successful *AND* the chain must end + */ fun execute(c: ProjectModel): Boolean } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/Dependency.kt b/src/main/java/io/openpixee/maven/operator/Dependency.kt index 12943c9aa..21ba74d73 100644 --- a/src/main/java/io/openpixee/maven/operator/Dependency.kt +++ b/src/main/java/io/openpixee/maven/operator/Dependency.kt @@ -1,5 +1,8 @@ package io.openpixee.maven.operator +/** + * Represents a Dependency + */ data class Dependency( val groupId: String, val artifactId: String, @@ -7,6 +10,9 @@ data class Dependency( val classifier: String? = null, val packaging: String? = "jar" ) { + /** + * Given a string, parses - and creates - a new dependency Object + */ companion object { fun fromString(str: String): Dependency { val elements = str.split(":") diff --git a/src/main/java/io/openpixee/maven/operator/POMOperator.kt b/src/main/java/io/openpixee/maven/operator/POMOperator.kt index d1eb75548..13edef745 100644 --- a/src/main/java/io/openpixee/maven/operator/POMOperator.kt +++ b/src/main/java/io/openpixee/maven/operator/POMOperator.kt @@ -1,6 +1,9 @@ package io.openpixee.maven.operator +/** + * Façade for the POM Upgrader + */ object POMOperator { @JvmStatic fun modify(projectModel: ProjectModel) = Chain.create().execute(projectModel) diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt index 9c8541df3..9c252ebc6 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt @@ -1,9 +1,8 @@ package io.openpixee.maven.operator +import io.openpixee.maven.operator.util.Util.selectXPathNodes import org.dom4j.Document -import org.dom4j.io.SAXReader -import java.io.File -import java.io.FileInputStream +import org.dom4j.Element /** * ProjectModel represents the input parameters for the chain @@ -20,53 +19,32 @@ class ProjectModel internal constructor( ) { val resultPom: Document = pomDocument.clone() as Document - internal val resolvedProperties: Map by lazy { - getEffectivePom().rootElement.elements("properties").flatMap { it.elements() } - .associate { - it.name to it.text + val resolvedProperties: Map = + run { + val rootProperties = + pomDocument.rootElement.elements("properties").flatMap { it.elements() } + .associate { + it.name to it.text + } + val result: MutableMap = LinkedHashMap() + result.putAll(rootProperties) + val activatedProfiles = activeProfiles.filterNot { it.startsWith("!") } + activatedProfiles.forEach { profileName -> + val expression = + "/m:project/m:profiles/m:profile[./m:id[text()='${profileName}']]/m:properties" + val propertiesElements = + pomDocument.selectXPathNodes(expression) + + val newPropertiesToAppend = + propertiesElements.filter { it is Element }.map { it as Element } + .flatMap { it.elements() } + .associate { + it.name to it.text + } + + result.putAll(newPropertiesToAppend) } - } - - fun getEffectivePom(): Document { - val tmpInputFile = File.createTempFile("tmp-pom-orig", ".xml") - - tmpInputFile.writeText(resultPom.asXML()) - - val tmpOutputFile = File.createTempFile("tmp-pom", ".xml") - - val processArgs = mutableListOf( - "mvn", - "-B", - "-N", - "-f", - tmpInputFile.absolutePath, - ) - - if (this.activeProfiles.isNotEmpty()) { - // TODO Aldrin: How safe is not to escape those things? My concern is that deactivating a profile uses '!', - // and I'm not sure how shell escaping rules play a part on that - processArgs.addAll(listOf("-P", this.activeProfiles.joinToString(","))) + result.toMap() } - - processArgs.addAll( - listOf( - "help:effective-pom", - "-Doutput=${tmpOutputFile.absolutePath}" - ) - ) - - val psBuilder = ProcessBuilder(processArgs).inheritIO() - - psBuilder.environment().putAll(System.getenv()) - - val process = psBuilder.start() - - val retCode = process.waitFor() - - if (0 != retCode) - throw IllegalStateException("Unexpected return code from maven: $retCode") - - return SAXReader().read(FileInputStream(tmpOutputFile)) - } } diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt index f7029fdd9..1b42d4ffe 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt @@ -7,6 +7,9 @@ import java.io.FileInputStream import java.io.InputStream import java.net.URL +/** + * Builder Object for ProjectModel instances + */ class ProjectModelFactory private constructor( private var pomDocument: Document, private var dependency: Dependency? = null, @@ -15,26 +18,46 @@ class ProjectModelFactory private constructor( private var activeProfiles: Set = emptySet(), private var overrideIfAlreadyExists: Boolean = false, ) { + /** + * Fluent Setter + * + * @param dep dependency + */ fun withDependency(dep: Dependency): ProjectModelFactory = this.apply { this.dependency = dep } + /** + * Fluent Setter + */ fun withSkipIfNewer(skipIfNewer: Boolean): ProjectModelFactory = this.apply { this.skipIfNewer = skipIfNewer } + /** + * Fluent Setter + */ fun withUseProperties(useProperties: Boolean): ProjectModelFactory = this.apply { this.useProperties = useProperties } + /** + * Fluent Setter + */ fun withActiveProfiles(vararg activeProfiles: String): ProjectModelFactory = this.apply { this.activeProfiles = setOf(*activeProfiles) } + /** + * Fluent Setter + */ fun withOverrideIfAlreadyExists(overrideIfAlreadyExists: Boolean) = this.apply { this.overrideIfAlreadyExists = overrideIfAlreadyExists } + /** + * Fluent Setter + */ fun build(): ProjectModel { return ProjectModel( pomDocument = pomDocument, diff --git a/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt b/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt index 709cf8546..69aec7df2 100644 --- a/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt +++ b/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt @@ -3,11 +3,14 @@ package io.openpixee.maven.operator import io.openpixee.maven.operator.util.Util.selectXPathNodes import org.dom4j.Element +/** + * Represents a POM Upgrade Strategy implicying simply adding a dependency/ section (and optionally a dependencyManagement/ section as well) + */ val SimpleInsert = object : Command { override fun execute(c: ProjectModel): Boolean { val dependencyManagementNode = c.resultPom.selectXPathNodes("/m:project/m:dependencyManagement") - val elementsToFormat : MutableList = arrayListOf() + val elementsToFormat: MutableList = arrayListOf() if (dependencyManagementNode.isEmpty()) { val newDependencyManagementNode = @@ -44,6 +47,9 @@ val SimpleInsert = object : Command { } + /** + * Creates the XML Elements for a given dependency + */ private fun appendCoordinates( dependenciesNode: Element, c: ProjectModel diff --git a/src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt b/src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt index 882b60c80..d3e63c567 100644 --- a/src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt +++ b/src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt @@ -2,6 +2,9 @@ package io.openpixee.maven.operator import io.openpixee.maven.operator.util.Util +/** + * Represents bumping an existing dependency/ + */ val SimpleUpgrade = object : AbstractSimpleCommand() { override fun execute(c: ProjectModel): Boolean { val lookupExpressionForDependency = diff --git a/src/main/java/io/openpixee/maven/operator/misc.kt b/src/main/java/io/openpixee/maven/operator/misc.kt index f8cad965b..eb124f97f 100644 --- a/src/main/java/io/openpixee/maven/operator/misc.kt +++ b/src/main/java/io/openpixee/maven/operator/misc.kt @@ -14,6 +14,9 @@ import java.io.StringWriter import java.lang.IllegalStateException import kotlin.math.ceil +/** + * Formats a XML Element Node + */ internal fun formatNode(node: Element) { val parent = node.parent //val siblings = parent.content() @@ -43,6 +46,9 @@ internal fun formatNode(node: Element) { parent.add(DefaultText("\n" + StringUtils.repeat(" ", ((indentLevel - 1) / 2)))) } +/** + * Guesses the current indent level of the nearest nodes + */ internal fun findIndentLevel(node: Element): Int { val siblings = node.parent.content() val myIndex = siblings.indexOf(node) @@ -60,7 +66,14 @@ internal fun findIndentLevel(node: Element): Int { return 0 } +/** + * Represents a Property Reference - as a regex + */ internal val PROPERTY_REFERENCE_REGEX = Regex("^\\\$\\{(.*)}$") + +/** + * Upserts a given property + */ internal fun upgradeProperty(c: ProjectModel, propertyName: String) { // TODO: Handle Profiles @@ -95,6 +108,9 @@ internal fun upgradeProperty(c: ProjectModel, propertyName: String) { formatNode(propertyElement) } +/** + * Creates a property Name + */ internal fun propertyName(c: ProjectModel, versionNode: Element): String { val version = versionNode.textTrim @@ -106,12 +122,12 @@ internal fun propertyName(c: ProjectModel, versionNode: Element): String { return firstMatch.value } - // TODO: Escaping - // TODO: Template Format (suffix / preffix)? - return "versions." + c.dependency.artifactId } +/** + * Identifies if an upgrade is needed + */ internal fun findOutIfUpgradeIsNeeded(c: ProjectModel, versionNode: Element): Boolean { val currentVersionNodeText = resolveVersion(c, versionNode.text!!) @@ -131,9 +147,15 @@ internal fun resolveVersion(c: ProjectModel, versionText: String): String = versionText } +/** + * Escapes a Property Name + */ internal fun escapedPropertyName(propertyName: String): String = "\${$propertyName}" +/** + * Given a Version Node, upgrades a resulting POM + */ internal fun upgradeVersionNode(c: ProjectModel, versionNode: Element) { if (c.useProperties) { val propertyName = propertyName(c, versionNode) diff --git a/src/main/java/io/openpixee/maven/operator/util/Util.kt b/src/main/java/io/openpixee/maven/operator/util/Util.kt index be2b96bd7..83db8d58c 100644 --- a/src/main/java/io/openpixee/maven/operator/util/Util.kt +++ b/src/main/java/io/openpixee/maven/operator/util/Util.kt @@ -6,7 +6,15 @@ import org.jaxen.SimpleNamespaceContext import org.jaxen.XPath import org.jaxen.dom4j.Dom4jXPath +/** + * Common Utilities + */ object Util { + /** + * Builds a Lookup Expression String for a given dependency + * + * @param dependency Dependency + */ fun buildLookupExpressionForDependency(dependency: Dependency): String = "/m:project" + "/m:dependencies" + @@ -15,6 +23,11 @@ object Util { /* */ "./m:artifactId[text()='${dependency.artifactId}']" + "]" + /** + * Builds a Lookup Expression String for a given dependency, but under the >dependencyManagement> section + * + * @param dependency Dependency + */ fun buildLookupExpressionForDependencyManagement(dependency: Dependency): String = "/m:project" + "/m:dependencyManagement" + @@ -24,10 +37,20 @@ object Util { /* */ "./m:artifactId[text()='${dependency.artifactId}']" + "]" + /** + * Extension Function to Select the XPath Nodes + * + * @param expression expression to use + */ @Suppress("UNCHECKED_CAST") fun Node.selectXPathNodes(expression: String) = createXPathExpression(expression).selectNodes(this)!! as List + /** + * Creates a XPath Expression from a given expression string + * + * @param expression expression to create xpath from + */ private fun createXPathExpression(expression: String): XPath { val xpath = Dom4jXPath(expression) @@ -36,6 +59,9 @@ object Util { return xpath } + /** + * Hard-Coded POM Namespace Map + */ private val namespaceContext = SimpleNamespaceContext( mapOf( "m" to "http://maven.apache.org/POM/4.0.0" diff --git a/src/test/java/io/openpixee/maven/operator/test/util.kt b/src/test/java/io/openpixee/maven/operator/test/util.kt new file mode 100644 index 000000000..cd45fc554 --- /dev/null +++ b/src/test/java/io/openpixee/maven/operator/test/util.kt @@ -0,0 +1,56 @@ +package io.openpixee.maven.operator.test + +import io.openpixee.maven.operator.ProjectModel +import org.dom4j.Document +import org.dom4j.io.SAXReader +import java.io.File +import java.io.FileInputStream + + +internal fun ProjectModel.getRuntimeResolvedProperties(): Map = + this.getEffectivePom().rootElement.elements("properties").flatMap { it.elements() } + .associate { + it.name to it.text + } + +internal fun ProjectModel.getEffectivePom(): Document { + val tmpInputFile = File.createTempFile("tmp-pom-orig", ".xml") + + tmpInputFile.writeText(this.resultPom.asXML()) + + val tmpOutputFile = File.createTempFile("tmp-pom", ".xml") + + val processArgs = mutableListOf( + "mvn", + "-B", + "-N", + "-f", + tmpInputFile.absolutePath, + ) + + if (this.activeProfiles.isNotEmpty()) { + // TODO Aldrin: How safe is not to escape those things? My concern is that deactivating a profile uses '!', + // and I'm not sure how shell escaping rules play a part on that + processArgs.addAll(listOf("-P", this.activeProfiles.joinToString(","))) + } + + processArgs.addAll( + listOf( + "help:effective-pom", + "-Doutput=${tmpOutputFile.absolutePath}" + ) + ) + + val psBuilder = ProcessBuilder(processArgs).inheritIO() + + psBuilder.environment().putAll(System.getenv()) + + val process = psBuilder.start() + + val retCode = process.waitFor() + + if (0 != retCode) + throw IllegalStateException("Unexpected return code from maven: $retCode") + + return SAXReader().read(FileInputStream(tmpOutputFile)) +} \ No newline at end of file diff --git a/src/test/resources/io/openpixee/maven/operator/pom-3.xml b/src/test/resources/io/openpixee/maven/operator/pom-3.xml index 5ea271b5f..0d3cdf584 100644 --- a/src/test/resources/io/openpixee/maven/operator/pom-3.xml +++ b/src/test/resources/io/openpixee/maven/operator/pom-3.xml @@ -394,11 +394,7 @@ src/it/settings.xml true true - + 1 */pom.xml From 484a19b7b322f22895b54be0cc17e41c09a26fea Mon Sep 17 00:00:00 2001 From: Jacoco Coverage Update Action Date: Sun, 16 Oct 2022 22:01:36 +0000 Subject: [PATCH 053/153] Autogenerated JaCoCo coverage badge --- .github/badges/branches.svg | 2 +- .github/badges/jacoco.svg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/badges/branches.svg b/.github/badges/branches.svg index dac76e5af..694138638 100644 --- a/.github/badges/branches.svg +++ b/.github/badges/branches.svg @@ -1 +1 @@ -branches77.5% \ No newline at end of file +branches76.7% \ No newline at end of file diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index 0824fec9c..5f4004e7f 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage87.8% \ No newline at end of file +coverage88.4% \ No newline at end of file From c7f7404cabc282c0130dac8bf5fc09e43d844a6e Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Sun, 23 Oct 2022 17:25:48 -0500 Subject: [PATCH 054/153] Refactoring --- pom.xml | 6 + .../maven/operator/AbstractSimpleCommand.kt | 2 - .../operator/SimpleDependencyManagement.kt | 5 +- .../openpixee/maven/operator/SimpleUpgrade.kt | 5 +- .../maven/operator/util/{Util.kt => Utils.kt} | 2 +- .../maven/operator/test/AbstractTestBase.kt | 106 ++++++++ .../maven/operator/test/POMOperatorTest.kt | 119 +++------ .../operator/test/PropertyResolutionTest.kt | 3 +- .../openpixee/maven/operator/pom-case-1.xml | 17 -- .../openpixee/maven/operator/pom-case-3.xml | 148 ----------- .../maven/operator/{ => test}/pom-1.xml | 2 +- .../maven/operator/{ => test}/pom-3.xml | 14 +- .../maven/operator/test/pom-case-1-result.xml | 32 +++ .../maven/operator/test/pom-case-1.xml | 17 ++ .../maven/operator/test/pom-case-3-result.xml | 147 +++++++++++ .../maven/operator/test/pom-case-3.xml | 150 +++++++++++ .../maven/operator/test/pom-case-4-result.xml | 245 ++++++++++++++++++ .../maven/operator/{ => test}/pom-case-4.xml | 3 +- .../test/pom-case-with-property-result.xml | 31 +++ ...m-case-three-with-lower-version-result.xml | 147 +++++++++++ .../{ => test}/pom-with-property-simple.xml | 2 +- .../operator/{ => test}/webgoat-parent.xml | 15 +- 22 files changed, 950 insertions(+), 268 deletions(-) rename src/main/java/io/openpixee/maven/operator/util/{Util.kt => Utils.kt} (99%) create mode 100644 src/test/java/io/openpixee/maven/operator/test/AbstractTestBase.kt delete mode 100644 src/test/resources/io/openpixee/maven/operator/pom-case-1.xml delete mode 100644 src/test/resources/io/openpixee/maven/operator/pom-case-3.xml rename src/test/resources/io/openpixee/maven/operator/{ => test}/pom-1.xml (100%) rename src/test/resources/io/openpixee/maven/operator/{ => test}/pom-3.xml (97%) create mode 100644 src/test/resources/io/openpixee/maven/operator/test/pom-case-1-result.xml create mode 100644 src/test/resources/io/openpixee/maven/operator/test/pom-case-1.xml create mode 100644 src/test/resources/io/openpixee/maven/operator/test/pom-case-3-result.xml create mode 100644 src/test/resources/io/openpixee/maven/operator/test/pom-case-3.xml create mode 100644 src/test/resources/io/openpixee/maven/operator/test/pom-case-4-result.xml rename src/test/resources/io/openpixee/maven/operator/{ => test}/pom-case-4.xml (98%) create mode 100644 src/test/resources/io/openpixee/maven/operator/test/pom-case-with-property-result.xml create mode 100644 src/test/resources/io/openpixee/maven/operator/test/pom-pom-case-three-with-lower-version-result.xml rename src/test/resources/io/openpixee/maven/operator/{ => test}/pom-with-property-simple.xml (100%) rename src/test/resources/io/openpixee/maven/operator/{ => test}/webgoat-parent.xml (96%) diff --git a/pom.xml b/pom.xml index 71cbd8e31..5e1b00603 100644 --- a/pom.xml +++ b/pom.xml @@ -72,6 +72,12 @@ 2.9.0 test + + org.xmlunit + xmlunit-assertj3 + 2.9.0 + test + org.hamcrest hamcrest-all diff --git a/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt b/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt index f9e30a270..9fc8eda2b 100644 --- a/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt +++ b/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt @@ -1,8 +1,6 @@ package io.openpixee.maven.operator -import com.github.zafarkhaja.semver.Version import io.openpixee.maven.operator.util.Util.selectXPathNodes -import org.apache.commons.lang3.text.StrSubstitutor import org.dom4j.Element /** diff --git a/src/main/java/io/openpixee/maven/operator/SimpleDependencyManagement.kt b/src/main/java/io/openpixee/maven/operator/SimpleDependencyManagement.kt index 96af0cae0..3a42a759f 100644 --- a/src/main/java/io/openpixee/maven/operator/SimpleDependencyManagement.kt +++ b/src/main/java/io/openpixee/maven/operator/SimpleDependencyManagement.kt @@ -1,11 +1,12 @@ package io.openpixee.maven.operator -import io.openpixee.maven.operator.util.Util +import io.openpixee.maven.operator.util.Util.buildLookupExpressionForDependencyManagement + val SimpleDependencyManagement = object : AbstractSimpleCommand() { override fun execute(c: ProjectModel): Boolean { val lookupExpression = - Util.buildLookupExpressionForDependencyManagement(c.dependency) + buildLookupExpressionForDependencyManagement(c.dependency) return handleDependency(c, lookupExpression) } diff --git a/src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt b/src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt index d3e63c567..9f1370998 100644 --- a/src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt +++ b/src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt @@ -1,6 +1,7 @@ package io.openpixee.maven.operator -import io.openpixee.maven.operator.util.Util +import io.openpixee.maven.operator.util.Util.buildLookupExpressionForDependency + /** * Represents bumping an existing dependency/ @@ -8,7 +9,7 @@ import io.openpixee.maven.operator.util.Util val SimpleUpgrade = object : AbstractSimpleCommand() { override fun execute(c: ProjectModel): Boolean { val lookupExpressionForDependency = - Util.buildLookupExpressionForDependency(c.dependency) + buildLookupExpressionForDependency(c.dependency) return handleDependency(c, lookupExpressionForDependency) } diff --git a/src/main/java/io/openpixee/maven/operator/util/Util.kt b/src/main/java/io/openpixee/maven/operator/util/Utils.kt similarity index 99% rename from src/main/java/io/openpixee/maven/operator/util/Util.kt rename to src/main/java/io/openpixee/maven/operator/util/Utils.kt index 83db8d58c..9be3a9067 100644 --- a/src/main/java/io/openpixee/maven/operator/util/Util.kt +++ b/src/main/java/io/openpixee/maven/operator/util/Utils.kt @@ -67,4 +67,4 @@ object Util { "m" to "http://maven.apache.org/POM/4.0.0" ) ) -} \ No newline at end of file +} diff --git a/src/test/java/io/openpixee/maven/operator/test/AbstractTestBase.kt b/src/test/java/io/openpixee/maven/operator/test/AbstractTestBase.kt new file mode 100644 index 000000000..29465ad60 --- /dev/null +++ b/src/test/java/io/openpixee/maven/operator/test/AbstractTestBase.kt @@ -0,0 +1,106 @@ +package io.openpixee.maven.operator.test + +import `fun`.mike.dmp.DiffMatchPatch +import io.openpixee.maven.operator.POMOperator +import io.openpixee.maven.operator.ProjectModel +import io.openpixee.maven.operator.ProjectModelFactory +import org.dom4j.Document +import org.dom4j.io.SAXReader +import org.junit.Assert.assertFalse +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import org.xmlunit.builder.DiffBuilder +import org.xmlunit.builder.Input +import org.xmlunit.diff.Diff +import java.io.File +import java.net.URLDecoder + +open class AbstractTestBase { + protected val LOGGER: Logger = LoggerFactory.getLogger(POMOperatorTest::class.java) + + /** + * Implements a Given-When-Then idiom + * + * @param g: Given - returns a context + * @param t: Then - validates given a context/ProjectModel + */ + protected fun gwt(g: () -> ProjectModel, t: (p: ProjectModel) -> Unit) { + val context = g() + + LOGGER.debug("context: {}", context) + + POMOperator.modify(context) + + LOGGER.debug("context after: {}", context) + + t(context) + } + + protected fun gwt(name: String, pmf: ProjectModelFactory): ProjectModel = + gwt(name, pmf.build()) + + protected fun gwt(testName: String, context: ProjectModel): ProjectModel { + val resultFile = "pom-$testName-result.xml" + val resource = this.javaClass.javaClass.getResource(resultFile) + + if (resource != null) { + val outcome = SAXReader().read(resource) + + LOGGER.debug("context: {}", context) + + POMOperator.modify(context) + + LOGGER.debug("context after: {}", context) + + assertFalse( + "Expected and outcome have differences", + getXmlDifferences(context.resultPom, outcome).hasDifferences() + ) + } else { + val resultFilePath = "src/test/resources/" + this.javaClass.`package`.name.replace( + ".", + "/" + ) + "/" + resultFile + + LOGGER.debug("context: {}", context) + + POMOperator.modify(context) + + LOGGER.debug("context after: {}", context) + + LOGGER.warn("File $resultFilePath not found - writing results instead and ignorning assertions at all") + + File(resultFilePath).writeText(context.resultPom.asXML()) + } + + return context + } + + protected fun getXmlDifferences( + original: Document, + modified: Document + ): Diff { + val originalDoc = Input.fromString(original.asXML()).build() + val modifiedDoc = Input.fromString(modified.asXML()).build() + + val diff = DiffBuilder.compare(originalDoc).withTest(modifiedDoc).ignoreWhitespace() + .checkForSimilar().build() + + LOGGER.debug("diff: {}", diff) + + return diff + } + + protected fun getTextDifferences(pomDocument: Document, resultPom: Document): Any { + val pomDocumentAsString = pomDocument.asXML() + val resultPomAsString = resultPom.asXML() + + val dmp = DiffMatchPatch() + + val diffs = dmp.patch_make(pomDocumentAsString, resultPomAsString) + + val patch = dmp.patch_toText(diffs) + + return URLDecoder.decode(patch, "utf-8") + } +} diff --git a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt index e6d76319b..6658bad49 100644 --- a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt @@ -1,47 +1,31 @@ package io.openpixee.maven.operator.test -import `fun`.mike.dmp.DiffMatchPatch import io.openpixee.maven.operator.Dependency import io.openpixee.maven.operator.POMOperator import io.openpixee.maven.operator.ProjectModelFactory import io.openpixee.maven.operator.util.Util.buildLookupExpressionForDependency import io.openpixee.maven.operator.util.Util.selectXPathNodes -import org.dom4j.Document import org.hamcrest.MatcherAssert.assertThat import org.junit.Assert.assertEquals import org.junit.Test -import org.slf4j.Logger -import org.slf4j.LoggerFactory -import org.xmlunit.builder.DiffBuilder -import org.xmlunit.builder.Input import org.xmlunit.diff.ComparisonType -import org.xmlunit.diff.Diff import java.io.File -import java.lang.IllegalStateException -import java.net.URLDecoder /** * Unit test for simple App. */ -class POMOperatorTest { - companion object { - private val LOGGER: Logger = LoggerFactory.getLogger(POMOperatorTest::class.java) - } +class POMOperatorTest : AbstractTestBase() { @Test fun testCaseOne() { - val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.3") - - val context = + val context = gwt( + "case-1", ProjectModelFactory.load( - POMOperator::class.java.getResource("pom-case-1.xml")!!, - ).withDependency(dependencyToUpgrade).build() - - LOGGER.debug("context: {}", context) - - POMOperator.modify(context) + POMOperatorTest::class.java.getResource("pom-case-1.xml")!!, + ).withDependency(Dependency.fromString("org.dom4j:dom4j:2.0.3")) + ) - val diff = getXmlDifferences(context.pomDocument, context.resultPom)!! + val diff = getXmlDifferences(context.pomDocument, context.resultPom) assertThat("Document has differences", diff.hasDifferences()) @@ -60,32 +44,18 @@ class POMOperatorTest { LOGGER.debug("effectivePom: {}", effectivePom.asXML()) } - private fun getTextDifferences(pomDocument: Document, resultPom: Document): Any { - val pomDocumentAsString = pomDocument.asXML() - val resultPomAsString = resultPom.asXML() - - val dmp = DiffMatchPatch() - - val diffs = dmp.patch_make(pomDocumentAsString, resultPomAsString) - - val patch = dmp.patch_toText(diffs) - - return URLDecoder.decode(patch, "utf-8") - } - @Test fun testCaseThree() { - val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.2") + val dependencyToUpgradeOnCaseThree = Dependency("org.dom4j", "dom4j", version = "2.0.2") - val context = + val context = gwt( + "case-3", ProjectModelFactory.load( - POMOperator::class.java.getResource("pom-case-3.xml")!!, - ).withDependency(dependencyToUpgrade).withSkipIfNewer(false).build() - - - POMOperator.modify(context) + POMOperatorTest::class.java.getResource("pom-case-3.xml")!!, + ).withDependency(dependencyToUpgradeOnCaseThree).withSkipIfNewer(false) + ) - val diff = getXmlDifferences(context.pomDocument, context.resultPom)!! + val diff = getXmlDifferences(context.pomDocument, context.resultPom) assertThat("Document has differences", diff.hasDifferences()) assertThat("Document has a single difference", diff.differences.toList().size == 1) @@ -94,8 +64,8 @@ class POMOperatorTest { diff.differences.toList()[0].comparison.type == ComparisonType.TEXT_VALUE ) assertThat( - "Document has changed version set to ${dependencyToUpgrade.version}", - diff.differences.toList()[0].comparison.testDetails.value == dependencyToUpgrade.version + "Document has changed version set to ${dependencyToUpgradeOnCaseThree.version}", + diff.differences.toList()[0].comparison.testDetails.value == dependencyToUpgradeOnCaseThree.version ) } @@ -103,22 +73,21 @@ class POMOperatorTest { fun testCaseThreeButWithLowerVersion() { val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.2") - val context = + val context = gwt( + "pom-case-three-with-lower-version", ProjectModelFactory.load( - POMOperator::class.java.getResource("pom-case-3.xml")!!, - ).withDependency(dependencyToUpgrade).withSkipIfNewer(true).build() - - - POMOperator.modify(context) + POMOperatorTest::class.java.getResource("pom-case-3.xml")!!, + ).withDependency(dependencyToUpgrade).withSkipIfNewer(true) + ) - val diff = getXmlDifferences(context.pomDocument, context.resultPom)!! + val diff = getXmlDifferences(context.pomDocument, context.resultPom) assertThat("Document has no differences", !diff.hasDifferences()) } @Test fun testCase4() { - val pomPath = File(POMOperator::class.java.getResource("webgoat-parent.xml")!!.toURI()) + val pomPath = File(POMOperatorTest::class.java.getResource("webgoat-parent.xml")!!.toURI()) val exitCode = ProcessBuilder( "mvn", @@ -136,14 +105,14 @@ class POMOperatorTest { val dependencyToUpgrade = Dependency("org.apache.activemq", "activemq-amqp", version = "5.16.2") - val context = + val context = gwt( + "case-4", ProjectModelFactory.load( - POMOperator::class.java.getResource("pom-case-4.xml")!!, - ).withDependency(dependencyToUpgrade).build() - - POMOperator.modify(context) + POMOperatorTest::class.java.getResource("pom-case-4.xml")!!, + ).withDependency(dependencyToUpgrade) + ) - val diff = getXmlDifferences(context.pomDocument, context.resultPom)!! + val diff = getXmlDifferences(context.pomDocument, context.resultPom) assertThat("Document has differences", diff.hasDifferences()) @@ -161,18 +130,17 @@ class POMOperatorTest { val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "1.0.0") - val context = + val context = gwt( + "case-with-property", ProjectModelFactory.load( - POMOperator::class.java.getResource("pom-with-property-simple.xml")!!, + POMOperatorTest::class.java.getResource("pom-with-property-simple.xml")!!, ).withDependency(dependencyToUpgrade).withUseProperties(true).withSkipIfNewer(true) - .build() - - POMOperator.modify(context) + ) LOGGER.debug("original pom: {}", context.pomDocument.asXML()) LOGGER.debug("resulting pom: {}", context.resultPom.asXML()) - val diff = getXmlDifferences(context.pomDocument, context.resultPom)!! + val diff = getXmlDifferences(context.pomDocument, context.resultPom) assertThat("Document has differences", diff.hasDifferences()) @@ -231,7 +199,8 @@ class POMOperatorTest { val context = ProjectModelFactory.load( originalPom.byteInputStream(), - ).withDependency(dependencyToUpgrade).withUseProperties(true).withOverrideIfAlreadyExists(false) + ).withDependency(dependencyToUpgrade).withUseProperties(true) + .withOverrideIfAlreadyExists(false) .build() POMOperator.modify(context) @@ -274,7 +243,7 @@ class POMOperatorTest { LOGGER.debug("original pom: {}", context.pomDocument.asXML()) LOGGER.debug("resulting pom: {}", context.resultPom.asXML()) - val diff = getXmlDifferences(context.pomDocument, context.resultPom)!! + val diff = getXmlDifferences(context.pomDocument, context.resultPom) assertThat("Document has differences", diff.hasDifferences()) @@ -283,18 +252,4 @@ class POMOperatorTest { assertThat("Document has several differences", differencesAsList.size > 1) } - private fun getXmlDifferences( - original: Document, - modified: Document - ): Diff? { - val originalDoc = Input.fromString(original.asXML()).build() - val modifiedDoc = Input.fromString(modified.asXML()).build() - - val diff = DiffBuilder.compare(originalDoc).withTest(modifiedDoc).ignoreWhitespace() - .checkForSimilar().build() - - LOGGER.debug("diff: {}", diff) - - return diff - } } diff --git a/src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt b/src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt index 1df60ebdc..bb9b26bf7 100644 --- a/src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt @@ -1,7 +1,6 @@ package io.openpixee.maven.operator.test import io.openpixee.maven.operator.Dependency -import io.openpixee.maven.operator.POMOperator import io.openpixee.maven.operator.ProjectModelFactory import junit.framework.TestCase.assertEquals import org.junit.Assert.assertFalse @@ -39,7 +38,7 @@ class PropertyResolutionTest { val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.2") val context = ProjectModelFactory.load( - POMOperator::class.java.getResource("pom-1.xml")!!, + POMOperatorTest::class.java.getResource("pom-1.xml")!!, ).withDependency(dependencyToUpgrade).withActiveProfiles(*profilesToUse).build() LOGGER.debug("Resolved Properties: {}", context.resolvedProperties) diff --git a/src/test/resources/io/openpixee/maven/operator/pom-case-1.xml b/src/test/resources/io/openpixee/maven/operator/pom-case-1.xml deleted file mode 100644 index 28d291308..000000000 --- a/src/test/resources/io/openpixee/maven/operator/pom-case-1.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - 4.0.0 - - br.com.ingenieux - pom-operator - 0.0.1-SNAPSHOT - - - UTF-8 - 1.8 - 1.8 - 1.5.31 - - diff --git a/src/test/resources/io/openpixee/maven/operator/pom-case-3.xml b/src/test/resources/io/openpixee/maven/operator/pom-case-3.xml deleted file mode 100644 index e9149e701..000000000 --- a/src/test/resources/io/openpixee/maven/operator/pom-case-3.xml +++ /dev/null @@ -1,148 +0,0 @@ - - - 4.0.0 - - br.com.ingenieux - pom-operator - 0.0.1-SNAPSHOT - - - UTF-8 - 1.8 - 1.8 - 1.5.31 - - - - - org.dom4j - dom4j - 2.1.3 - - - jaxen - jaxen - 1.2.0 - - - xerces - xercesImpl - 2.12.1 - - - io.github.java-diff-utils - java-diff-utils - 4.9 - - - junit - junit - 4.11 - test - - - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - ${kotlin.version} - - - org.jetbrains.kotlin - kotlin-test - ${kotlin.version} - test - - - - - - - - - maven-clean-plugin - 3.1.0 - - - - maven-resources-plugin - 3.0.2 - - - maven-compiler-plugin - 3.8.0 - - - maven-surefire-plugin - 2.22.1 - - - maven-jar-plugin - 3.0.2 - - - maven-install-plugin - 2.5.2 - - - maven-deploy-plugin - 2.8.2 - - - - maven-site-plugin - 3.7.1 - - - maven-project-info-reports-plugin - 3.0.0 - - - - - - org.jetbrains.kotlin - kotlin-maven-plugin - ${kotlin.version} - - - compile - compile - - compile - - - - test-compile - test-compile - - test-compile - - - - - 1.8 - - - - org.apache.maven.plugins - maven-compiler-plugin - - - compile - compile - - compile - - - - testCompile - test-compile - - testCompile - - - - - - - diff --git a/src/test/resources/io/openpixee/maven/operator/pom-1.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-1.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/pom-1.xml rename to src/test/resources/io/openpixee/maven/operator/test/pom-1.xml index cc3ff40c0..7b8471751 100644 --- a/src/test/resources/io/openpixee/maven/operator/pom-1.xml +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-1.xml @@ -1,7 +1,7 @@ 4.0.0 diff --git a/src/test/resources/io/openpixee/maven/operator/pom-3.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-3.xml similarity index 97% rename from src/test/resources/io/openpixee/maven/operator/pom-3.xml rename to src/test/resources/io/openpixee/maven/operator/test/pom-3.xml index 0d3cdf584..80ded0522 100644 --- a/src/test/resources/io/openpixee/maven/operator/pom-3.xml +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-3.xml @@ -1,4 +1,6 @@ - + 4.0.0 @@ -14,7 +16,8 @@ Versions Maven Plugin http://www.mojohaus.org/versions-maven-plugin/ - Versions Plugin for Maven. The Versions Plugin updates the versions of components in the POM. + Versions Plugin for Maven. The Versions Plugin updates the versions of components in the + POM. 2008 @@ -86,7 +89,8 @@ scm:git:https://github.com/mojohaus/versions-maven-plugin.git - scm:git:ssh://git@github.com/mojohaus/versions-maven-plugin.git + scm:git:ssh://git@github.com/mojohaus/versions-maven-plugin.git + https://github.com/mojohaus/versions-maven-plugin/tree/${project.scm.tag} versions-maven-plugin-2.8.1 @@ -350,7 +354,9 @@ xsd - ${project.build.directory}/generated-site/resources/xsd + + ${project.build.directory}/generated-site/resources/xsd + diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-1-result.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-case-1-result.xml new file mode 100644 index 000000000..a1e82e0ae --- /dev/null +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-case-1-result.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + + UTF-8 + 1.8 + 1.8 + 1.5.31 + + + + + + org.dom4j + dom4j + 2.0.3 + + + + + + + org.dom4j + dom4j + + + \ No newline at end of file diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-1.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-case-1.xml new file mode 100644 index 000000000..2d3c8a59c --- /dev/null +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-case-1.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + + UTF-8 + 1.8 + 1.8 + 1.5.31 + + diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-3-result.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-case-3-result.xml new file mode 100644 index 000000000..99b59658b --- /dev/null +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-case-3-result.xml @@ -0,0 +1,147 @@ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + + UTF-8 + 1.8 + 1.8 + 1.5.31 + + + + + org.dom4j + dom4j + 2.0.2 + + + jaxen + jaxen + 1.2.0 + + + xerces + xercesImpl + 2.12.1 + + + io.github.java-diff-utils + java-diff-utils + 4.9 + + + junit + junit + 4.11 + test + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + org.apache.maven.plugins + maven-compiler-plugin + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + + + \ No newline at end of file diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-3.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-case-3.xml new file mode 100644 index 000000000..6de228aa5 --- /dev/null +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-case-3.xml @@ -0,0 +1,150 @@ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + + UTF-8 + 1.8 + 1.8 + 1.5.31 + + + + + org.dom4j + dom4j + 2.1.3 + + + jaxen + jaxen + 1.2.0 + + + xerces + xercesImpl + 2.12.1 + + + io.github.java-diff-utils + java-diff-utils + 4.9 + + + junit + junit + 4.11 + test + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + org.apache.maven.plugins + maven-compiler-plugin + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + + + diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-4-result.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-case-4-result.xml new file mode 100644 index 000000000..331f5b870 --- /dev/null +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-case-4-result.xml @@ -0,0 +1,245 @@ + + + 4.0.0 + webgoat-server + jar + + org.owasp.webgoat + webgoat-parent + 8.2.3-SNAPSHOT + + + + org.owasp.webgoat.StartWebGoat + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + org.thymeleaf.extra + thymeleaf-extras-springsecurity5++ + + + org.asciidoctor + asciidoctorj + + + org.jruby + jruby-complete + + + + + + true + + + + org.apache.maven.plugins + maven-jar-plugin + + + test-compile + + jar + + + internal + + + + + + + + + + + + org.apache.activemq + activemq-amqp + 5.16.2 + + + + + + + org.owasp.webgoat + webgoat-container + ${project.version} + + + org.owasp.webgoat.lesson + challenge + ${project.version} + + + org.owasp.webgoat.lesson + bypass-restrictions + ${project.version} + + + org.owasp.webgoat.lesson + client-side-filtering + ${project.version} + + + org.owasp.webgoat.lesson + crypto + ${project.version} + + + org.owasp.webgoat.lesson + cross-site-scripting + ${project.version} + + + org.owasp.webgoat.lesson + html-tampering + ${project.version} + + + org.owasp.webgoat.lesson + http-basics + ${project.version} + + + org.owasp.webgoat.lesson + http-proxies + ${project.version} + + + org.owasp.webgoat.lesson + cia + ${project.version} + + + org.owasp.webgoat.lesson + chrome-dev-tools + ${project.version} + + + org.owasp.webgoat.lesson + idor + ${project.version} + + + org.owasp.webgoat.lesson + csrf + ${project.version} + + + org.owasp.webgoat.lesson + insecure-login + ${project.version} + + + org.owasp.webgoat.lesson + insecure-deserialization + ${project.version} + + + org.owasp.webgoat.lesson + jwt + ${project.version} + + + org.owasp.webgoat.lesson + path-traversal + ${project.version} + + + org.owasp.webgoat.lesson + sql-injection + ${project.version} + + + org.owasp.webgoat.lesson + vulnerable-components + ${project.version} + + + org.owasp.webgoat.lesson + xxe + ${project.version} + + + org.owasp.webgoat.lesson + auth-bypass + ${project.version} + + + org.owasp.webgoat.lesson + webgoat-introduction + ${project.version} + + + org.owasp.webgoat.lesson + webwolf-introduction + ${project.version} + + + org.owasp.webgoat.lesson + missing-function-ac + ${project.version} + + + org.owasp.webgoat.lesson + password-reset + ${project.version} + + + org.owasp.webgoat.lesson + ssrf + ${project.version} + + + org.owasp.webgoat.lesson + secure-passwords + ${project.version} + + + org.owasp.webgoat.lesson + spoof-cookie + ${project.version} + + + org.owasp.webgoat.lesson + hijack-session + ${project.version} + + + org.owasp.webgoat.lesson + webgoat-lesson-template + ${project.version} + + + org.owasp.webgoat.lesson + logging + ${project.version} + + + org.springframework.boot + spring-boot-devtools + true + + + org.postgresql + postgresql + + + org.apache.activemq + activemq-amqp + + + \ No newline at end of file diff --git a/src/test/resources/io/openpixee/maven/operator/pom-case-4.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-case-4.xml similarity index 98% rename from src/test/resources/io/openpixee/maven/operator/pom-case-4.xml rename to src/test/resources/io/openpixee/maven/operator/test/pom-case-4.xml index dec76bfd0..2b6f8f8a4 100644 --- a/src/test/resources/io/openpixee/maven/operator/pom-case-4.xml +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-case-4.xml @@ -1,4 +1,5 @@ - 4.0.0 webgoat-server diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-with-property-result.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-case-with-property-result.xml new file mode 100644 index 000000000..acf877958 --- /dev/null +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-case-with-property-result.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + + + + 1.0.0 + + + + + test-profile + + 1.0.1 + + + + + + + org.dom4j + dom4j + ${sample.version} + + + \ No newline at end of file diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-pom-case-three-with-lower-version-result.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-pom-case-three-with-lower-version-result.xml new file mode 100644 index 000000000..1b992ed0e --- /dev/null +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-pom-case-three-with-lower-version-result.xml @@ -0,0 +1,147 @@ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + + UTF-8 + 1.8 + 1.8 + 1.5.31 + + + + + org.dom4j + dom4j + 2.1.3 + + + jaxen + jaxen + 1.2.0 + + + xerces + xercesImpl + 2.12.1 + + + io.github.java-diff-utils + java-diff-utils + 4.9 + + + junit + junit + 4.11 + test + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + org.apache.maven.plugins + maven-compiler-plugin + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + + + \ No newline at end of file diff --git a/src/test/resources/io/openpixee/maven/operator/pom-with-property-simple.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-with-property-simple.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/pom-with-property-simple.xml rename to src/test/resources/io/openpixee/maven/operator/test/pom-with-property-simple.xml index fb7d9824f..d2f9f3b26 100644 --- a/src/test/resources/io/openpixee/maven/operator/pom-with-property-simple.xml +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-with-property-simple.xml @@ -1,7 +1,7 @@ 4.0.0 diff --git a/src/test/resources/io/openpixee/maven/operator/webgoat-parent.xml b/src/test/resources/io/openpixee/maven/operator/test/webgoat-parent.xml similarity index 96% rename from src/test/resources/io/openpixee/maven/operator/webgoat-parent.xml rename to src/test/resources/io/openpixee/maven/operator/test/webgoat-parent.xml index f70b24d70..4e8ab5de9 100644 --- a/src/test/resources/io/openpixee/maven/operator/webgoat-parent.xml +++ b/src/test/resources/io/openpixee/maven/operator/test/webgoat-parent.xml @@ -1,5 +1,6 @@ - 4.0.0 @@ -15,7 +16,8 @@ WebGoat Parent Pom - Parent Pom for the WebGoat Project. A deliberately insecure Web Application + Parent Pom for the WebGoat Project. A deliberately insecure Web Application + 2006 https://github.com/WebGoat/WebGoat @@ -204,7 +206,8 @@ true config/checkstyle/checkstyle.xml config/checkstyle/suppressions.xml - checkstyle.suppressions.file + checkstyle.suppressions.file + @@ -213,10 +216,12 @@ 3.14.0 15 - 1 + 1 + - ${maven.multiModuleProjectDirectory}/config/pmd/pmd-ruleset.xml + ${maven.multiModuleProjectDirectory}/config/pmd/pmd-ruleset.xml + true true From 6390c53b99dcfac837da104c5e8a7983ccd9bf92 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Sun, 6 Nov 2022 18:07:26 -0500 Subject: [PATCH 055/153] Adding Mass Repo Tests --- .gitignore | 2 + .../io/openpixee/maven/operator/Dependency.kt | 3 + .../maven/operator/test/MassRepoTest.kt | 228 ++++++++++++++++++ 3 files changed, 233 insertions(+) create mode 100644 src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt diff --git a/.gitignore b/.gitignore index 8efd9c415..1621d5fe2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ ### Maven template +.cache/ + target/ pom.xml.tag pom.xml.releaseBackup diff --git a/src/main/java/io/openpixee/maven/operator/Dependency.kt b/src/main/java/io/openpixee/maven/operator/Dependency.kt index 21ba74d73..d642ce353 100644 --- a/src/main/java/io/openpixee/maven/operator/Dependency.kt +++ b/src/main/java/io/openpixee/maven/operator/Dependency.kt @@ -10,6 +10,9 @@ data class Dependency( val classifier: String? = null, val packaging: String? = "jar" ) { + override fun toString(): String { + return listOf(groupId, artifactId, packaging, version).joinToString(":") + } /** * Given a string, parses - and creates - a new dependency Object */ diff --git a/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt b/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt new file mode 100644 index 000000000..e0bbe9881 --- /dev/null +++ b/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt @@ -0,0 +1,228 @@ +package io.openpixee.maven.operator.test + +import io.openpixee.maven.operator.Dependency +import io.openpixee.maven.operator.POMOperator +import io.openpixee.maven.operator.ProjectModelFactory +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test +import org.slf4j.LoggerFactory +import java.io.File + +data class TestRepo( + val slug: String, + val branch: String = "master", + val pomPath: String = "pom.xml" +) { + fun cacheDir() = BASE_CACHE_DIR.resolve("repo-%08X".format(slug.hashCode())) + + companion object { + val BASE_CACHE_DIR = File(System.getProperty("user.dir") + "/.cache").absoluteFile + } +} + +/** + * This test actually picks up several github repos and apply the POM Operator and checks for a runtime dependency change + */ +class MassRepoIT { + /* + https://github.com/trending/java?since=daily + + apache/pulsar + metersphere/metersphere + apache/rocketmq + OpenAPITools/openapi-generator + casbin/jcasbin + trinodb/trino + bytedeco/javacv + flowable/flowable-engine + + Azure/azure-sdk-for-java + questdb/questdb + */ + + val repos = listOf( + TestRepo( + "apache/pulsar", + pomPath = "pulsar-broker/pom.xml" + ) to "commons-codec:commons-codec:1.14", + TestRepo( + "metersphere/metersphere", + branch = "main", + pomPath = "framework/eureka/pom.xml" + ) to "commons-lang3:commons-lang3:3.6", + TestRepo( + "apache/rocketmq", + pomPath = "common/pom.xml" + ) to "commons-codec:commons-codec:1.15", + TestRepo( + "OpenAPITools/openapi-generator", + pomPath = "modules/openapi-generator-core/pom.xml" + ) to "com.google.guava:guava:31.0-jre", + TestRepo( + "casbin/jcasbin", + ) to "com.google.code.gson:gson:2.8.0", + TestRepo( + "trinodb/trino", + pomPath = "core/trino-main/pom.xml" + ) to "org.apache.commons:commons-math3:3.6.0", + TestRepo( + "bytedeco/javacv" + ) to "org.jogamp.jocl:jocl-main:2.3.1", + TestRepo( + "flowable/flowable-engine", + branch = "main", + pomPath = "modules/flowable-engine-common-api/pom.xml" + ) to "org.apache.commons:commons-lang3:3.11", + ) + + /** + * Checks out - or resets - a stored github repo + */ + private fun checkoutOrResetCachedRepo(repo: TestRepo) { + if (!repo.cacheDir().exists()) { + // git clone -b branch github.com/slug/ dir + val command = arrayOf( + "git", + "clone", + "-b", + repo.branch, + "https://github.com/${repo.slug}.git", + repo.cacheDir().canonicalPath + ) + + LOGGER.debug("Running command: ${command.joinToString(" ")}") + + val process = ProcessBuilder(*command) + .directory(TestRepo.BASE_CACHE_DIR.canonicalFile) + .inheritIO() + .start() + + process.waitFor() + } else { + val command = arrayOf("git", "reset", "--hard", "HEAD") + + LOGGER.debug("Running command: ${command.joinToString(" ")}") + + val process = ProcessBuilder(*command) + .directory(repo.cacheDir()) + .inheritIO() + .start() + + process.waitFor() + } + } + + /** + * Sanity Test on a single repo + */ + @Test + fun testBasic() { + val firstCase = repos.first() + + testOnRepo(firstCase.first, firstCase.second) + } + + /** + * THATS THE FULL TEST + */ + @Test + fun testAllOthers() { + repos.forEach { testOnRepo(it.first, it.second) } + } + + private fun testOnRepo( + sampleRepo: TestRepo, + dependencyToUpgradeString: String + ) { + LOGGER.info( + "Testing on repo {}, branch {} with dependency {}", + sampleRepo.slug, + sampleRepo.branch, + dependencyToUpgradeString + ) + + checkoutOrResetCachedRepo(sampleRepo) + + val originalDependencies = getDepedenciesFrom(sampleRepo) + + LOGGER.info("dependencies: {}", originalDependencies) + + val dependencyToUpgrade = Dependency.fromString(dependencyToUpgradeString) + val context = ProjectModelFactory.load(File(sampleRepo.cacheDir(), sampleRepo.pomPath)) + .withDependency(dependencyToUpgrade) + .withSkipIfNewer(false) + .build() + + POMOperator.modify(context) + + val alternatePomFile = + File(File(sampleRepo.cacheDir(), sampleRepo.pomPath).parent, "pom-modified.xml") + + alternatePomFile.writeText(context.resultPom.asXML()) + + val finalDependencies = + getDepedenciesFrom(alternatePomFile.canonicalPath, sampleRepo.cacheDir()) + + LOGGER.info("dependencies: {}", finalDependencies) + + val dependencyAsStringWithPackaging = dependencyToUpgrade.toString() + + assertFalse( + "Dependency should be originally missing", originalDependencies.contains( + dependencyAsStringWithPackaging + ) + ) + assertTrue( + "New Dependency should be appearing", finalDependencies.contains( + dependencyAsStringWithPackaging + ) + ) + } + + private fun getDepedenciesFrom(repo: TestRepo): String = + getDepedenciesFrom(repo.pomPath, repo.cacheDir()) + + private fun getDepedenciesFrom(pomPath: String, dir: File): String { + val outputFile = File.createTempFile("tmp-pom", ".txt") + + if (outputFile.exists()) { + outputFile.delete() + } + + val command = arrayOf( + "mvn", + "-B", + "-f", + pomPath, + "dependency:tree", + "-Dscope=runtime", + "-DoutputFile=${outputFile.canonicalPath}" + ) + + val process = ProcessBuilder(*command) + .directory(dir) + .inheritIO() + .start() + + process.waitFor() + + val result = outputFile.readText() + + outputFile.delete() + + return result + } + + companion object { + val LOGGER = LoggerFactory.getLogger(MassRepoIT::class.java) + } + + init { + /** + * Creates the Cache Directory + */ + if (!TestRepo.BASE_CACHE_DIR.exists()) + TestRepo.BASE_CACHE_DIR.mkdirs() + } +} \ No newline at end of file From 8f38110f845d7f36b8c765b49b0af09dd2425e05 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Sun, 6 Nov 2022 18:13:32 -0500 Subject: [PATCH 056/153] Removing trinodb --- src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt b/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt index e0bbe9881..fab596cf6 100644 --- a/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt @@ -62,10 +62,12 @@ class MassRepoIT { TestRepo( "casbin/jcasbin", ) to "com.google.code.gson:gson:2.8.0", + /* TestRepo( "trinodb/trino", pomPath = "core/trino-main/pom.xml" ) to "org.apache.commons:commons-math3:3.6.0", + */ TestRepo( "bytedeco/javacv" ) to "org.jogamp.jocl:jocl-main:2.3.1", From 2c9eba783dbf1c48a26b70a69403aa6febb10036 Mon Sep 17 00:00:00 2001 From: Jacoco Coverage Update Action Date: Sun, 6 Nov 2022 23:19:56 +0000 Subject: [PATCH 057/153] Autogenerated JaCoCo coverage badge --- .github/badges/branches.svg | 2 +- .github/badges/jacoco.svg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/badges/branches.svg b/.github/badges/branches.svg index 694138638..0e4f034f3 100644 --- a/.github/badges/branches.svg +++ b/.github/badges/branches.svg @@ -1 +1 @@ -branches76.7% \ No newline at end of file +branches78.5% \ No newline at end of file diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index 5f4004e7f..7bbf58b53 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage88.4% \ No newline at end of file +coverage89.1% \ No newline at end of file From 013977160d111a9934fa97f2793c70258496f1f9 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Sun, 6 Nov 2022 18:46:54 -0500 Subject: [PATCH 058/153] Typo --- .../io/openpixee/maven/operator/test/MassRepoTest.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt b/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt index fab596cf6..caced350d 100644 --- a/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt @@ -146,7 +146,7 @@ class MassRepoIT { checkoutOrResetCachedRepo(sampleRepo) - val originalDependencies = getDepedenciesFrom(sampleRepo) + val originalDependencies = getDependenciesFrom(sampleRepo) LOGGER.info("dependencies: {}", originalDependencies) @@ -164,7 +164,7 @@ class MassRepoIT { alternatePomFile.writeText(context.resultPom.asXML()) val finalDependencies = - getDepedenciesFrom(alternatePomFile.canonicalPath, sampleRepo.cacheDir()) + getDependenciesFrom(alternatePomFile.canonicalPath, sampleRepo.cacheDir()) LOGGER.info("dependencies: {}", finalDependencies) @@ -182,10 +182,10 @@ class MassRepoIT { ) } - private fun getDepedenciesFrom(repo: TestRepo): String = - getDepedenciesFrom(repo.pomPath, repo.cacheDir()) + private fun getDependenciesFrom(repo: TestRepo): String = + getDependenciesFrom(repo.pomPath, repo.cacheDir()) - private fun getDepedenciesFrom(pomPath: String, dir: File): String { + private fun getDependenciesFrom(pomPath: String, dir: File): String { val outputFile = File.createTempFile("tmp-pom", ".txt") if (outputFile.exists()) { From 1f78b5a4904a00da9ad95e4886b948936f91524f Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 4 Jan 2023 13:46:16 -0500 Subject: [PATCH 059/153] Feature/query versions (#7) * Minor refactoring * Interim Commit * Autogenerated JaCoCo coverage badge * Interim Commit * Interim Commit * Autogenerated JaCoCo coverage badge * Fixing Warning * Autogenerated JaCoCo coverage badge * Making Invoker Explicit * Autogenerated JaCoCo coverage badge * Improving path - and using several environments * Windows fixes * Autogenerated JaCoCo coverage badge * Cross OS Changes * Windows exec lookup * Autogenerated JaCoCo coverage badge * Workflow Changes * Workflow fixes * Workflow fixes * Workflow fixes * Tests * Windows Fixes * Windows Fixes * CI Skip * Addressing Comments + Improving Coverage * [no ci] Autogenerated JaCoCo coverage badge * Interim Commit - adding resolution * [no ci] Autogenerated JaCoCo coverage badge * Interim Commit - Last cleanup * [no ci] Autogenerated JaCoCo coverage badge Co-authored-by: Jacoco Coverage Update Action --- .github/badges/branches.svg | 2 +- .github/badges/jacoco.svg | 2 +- .github/pull_request_template.md | 15 + .github/workflows/push-test.yml | 20 +- java-sample/pom.xml | 6 + .../io/openpixee/it/POMOperatorJavaTest.java | 2 +- pom.xml | 156 +++++----- .../maven/operator/AbstractSimpleCommand.kt | 7 +- .../operator/AbstractSimpleQueryCommand.kt | 199 +++++++++++++ .../java/io/openpixee/maven/operator/App.kt | 42 --- .../java/io/openpixee/maven/operator/Chain.kt | 46 ++- .../maven/operator/CheckDependencyPresent.kt | 16 + .../io/openpixee/maven/operator/Dependency.kt | 5 +- .../maven/operator/InvalidContextException.kt | 6 + .../operator/MissingDependencyException.kt | 3 + .../openpixee/maven/operator/POMOperator.kt | 37 ++- .../openpixee/maven/operator/ProjectModel.kt | 11 +- .../maven/operator/ProjectModelFactory.kt | 37 ++- .../maven/operator/QueryByEmbedder.kt | 80 +++++ .../maven/operator/QueryByInvoker.kt | 31 ++ .../maven/operator/QueryByResolver.kt | 198 +++++++++++++ .../io/openpixee/maven/operator/QueryType.kt | 6 + .../operator/SimpleDependencyManagement.kt | 4 +- .../openpixee/maven/operator/SimpleInsert.kt | 14 +- .../openpixee/maven/operator/SimpleUpgrade.kt | 4 +- .../java/io/openpixee/maven/operator/Util.kt | 276 ++++++++++++++++++ .../java/io/openpixee/maven/operator/misc.kt | 172 ----------- .../io/openpixee/maven/operator/util/Utils.kt | 70 ----- .../maven/operator/test/MassRepoTest.kt | 19 +- .../operator/test/POMOperatorJavaIT.java | 28 +- .../operator/test/POMOperatorQueryTest.kt | 75 +++++ .../maven/operator/test/POMOperatorTest.kt | 42 ++- .../io/openpixee/maven/operator/test/util.kt | 21 +- .../maven/operator/test/pom-broken.xml | 5 + 34 files changed, 1233 insertions(+), 424 deletions(-) create mode 100644 .github/pull_request_template.md create mode 100644 src/main/java/io/openpixee/maven/operator/AbstractSimpleQueryCommand.kt delete mode 100644 src/main/java/io/openpixee/maven/operator/App.kt create mode 100644 src/main/java/io/openpixee/maven/operator/CheckDependencyPresent.kt create mode 100644 src/main/java/io/openpixee/maven/operator/InvalidContextException.kt create mode 100644 src/main/java/io/openpixee/maven/operator/MissingDependencyException.kt create mode 100644 src/main/java/io/openpixee/maven/operator/QueryByEmbedder.kt create mode 100644 src/main/java/io/openpixee/maven/operator/QueryByInvoker.kt create mode 100644 src/main/java/io/openpixee/maven/operator/QueryByResolver.kt create mode 100644 src/main/java/io/openpixee/maven/operator/QueryType.kt create mode 100644 src/main/java/io/openpixee/maven/operator/Util.kt delete mode 100644 src/main/java/io/openpixee/maven/operator/misc.kt delete mode 100644 src/main/java/io/openpixee/maven/operator/util/Utils.kt create mode 100644 src/test/java/io/openpixee/maven/operator/test/POMOperatorQueryTest.kt create mode 100644 src/test/resources/io/openpixee/maven/operator/test/pom-broken.xml diff --git a/.github/badges/branches.svg b/.github/badges/branches.svg index 0e4f034f3..0687eb350 100644 --- a/.github/badges/branches.svg +++ b/.github/badges/branches.svg @@ -1 +1 @@ -branches78.5% \ No newline at end of file +branches73.1% \ No newline at end of file diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index 7bbf58b53..78372f5a0 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage89.1% \ No newline at end of file +coverage90.2% \ No newline at end of file diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..647353c41 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,15 @@ +# Description + +# Checklist: + +- [ ] I did my own review +- [ ] Commented Code - particularly in hard sections +- [ ] Docs (Javadocs) +- [ ] No TODOs / Issues on Code +- [ ] Tests: Unit Testing +- [ ] Tests: Assertions Look Good and Sane +- [ ] Tests: Coverage +- [ ] Integration Testing +- [ ] Java Test Fixtures +- [ ] Security Risks Considered and Addressed / Mitigated + \ No newline at end of file diff --git a/.github/workflows/push-test.yml b/.github/workflows/push-test.yml index 220947e2e..bbd82a9ea 100644 --- a/.github/workflows/push-test.yml +++ b/.github/workflows/push-test.yml @@ -4,7 +4,10 @@ on: [push] jobs: build: - runs-on: ubuntu-latest + strategy: + matrix: + platform: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.platform }} environment: name: default env: @@ -31,32 +34,41 @@ jobs: - name: Build with Maven run: | mvn -N -B install + - name: Integration Testing (Linux Only) + if: matrix.platform == 'ubuntu-latest' + run: | mvn -N -B -P integration-testing verify - name: Generate Coverage Badge id: jacoco uses: cicirello/jacoco-badge-generator@v2 + if: ${{ matrix.platform == 'ubuntu-latest' }} with: generate-branches-badge: true - name: Log coverage percentage + if: ${{ matrix.platform == 'ubuntu-latest' }} run: | echo "coverage = ${{ steps.jacoco.outputs.coverage }}" echo "branch coverage = ${{ steps.jacoco.outputs.branches }}" - - name: Commit the JaCoCo badge (if it changed) + - # When using "Act", disable certain actions, starting with this one + # See https://github.com/nektos/act#skipping-steps for more details + name: Commit the JaCoCo badge (if it changed) + if: ${{ matrix.platform == 'ubuntu-latest' && !env.ACT }} run: | if [[ `git status --porcelain` ]]; then git config --global user.name 'Jacoco Coverage Update Action' git config --global user.email 'pixee@users.noreply.github.com' git add -A - git commit -m "Autogenerated JaCoCo coverage badge" + git commit -m "[no ci] Autogenerated JaCoCo coverage badge" git push fi - name: Upload JaCoCo coverage report + if: ${{ matrix.platform == 'ubuntu-latest' && !env.ACT }} uses: actions/upload-artifact@v2 with: name: jacoco-report path: target/site/jacoco/ - name: Deploy (only if on master) - if: ${{ github.ref_name == 'master' }} + if: ${{ github.ref_name == 'master' && matrix.platform == 'ubuntu-latest' && !env.ACT }} run: | mvn -N -B deploy -DaltDeploymentRepository=pixee::default::https://pixee.jfrog.io/artifactory/mailman-libs-snapshot diff --git a/java-sample/pom.xml b/java-sample/pom.xml index ca3afcc77..7844749ca 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -32,6 +32,12 @@ 4.13.2 test + + org.apache.maven + maven-embedder + 3.8.6 + provided + diff --git a/java-sample/src/test/java/io/openpixee/it/POMOperatorJavaTest.java b/java-sample/src/test/java/io/openpixee/it/POMOperatorJavaTest.java index 0b6175e5b..9be326dfb 100644 --- a/java-sample/src/test/java/io/openpixee/it/POMOperatorJavaTest.java +++ b/java-sample/src/test/java/io/openpixee/it/POMOperatorJavaTest.java @@ -11,7 +11,7 @@ public class POMOperatorJavaTest { @Test public void testInterop() { ProjectModel projectModel = ProjectModelFactory.load(POMOperatorJavaTest.class.getResource("pom.xml")) - .withDependency(new Dependency("org.dom4j", "dom4j", "0.0.0", null, "jar")) + .withDependency(new Dependency("org.dom4j", "dom4j", "0.0.0", null, "jar", null)) .build(); POMOperator.modify(projectModel); diff --git a/pom.xml b/pom.xml index 5e1b00603..5dafd0a02 100644 --- a/pom.xml +++ b/pom.xml @@ -106,6 +106,84 @@ java-semver 0.9.0 + + + commons-io + commons-io + 2.11.0 + + + org.apache.maven.shared + maven-invoker + 3.2.0 + compile + + + org.apache.maven + maven-embedder + 3.8.6 + compile + + + org.apache.maven + maven-compat + 3.8.6 + compile + + + org.apache.maven.resolver + maven-resolver-api + 1.9.2 + provided + + + org.apache.maven.resolver + maven-resolver-spi + 1.9.2 + provided + + + org.apache.maven.resolver + maven-resolver-util + 1.9.2 + provided + + + org.apache.maven.resolver + maven-resolver-impl + 1.9.2 + provided + + + org.apache.maven.resolver + maven-resolver-transport-file + 1.9.2 + provided + + + org.apache.maven.resolver + maven-resolver-transport-http + 1.9.2 + provided + + + org.apache.maven.resolver + maven-resolver-connector-basic + 1.9.2 + provided + + + org.apache.maven + maven-resolver-provider + 3.8.6 + provided + + + org.apache.maven + maven-model-builder + 3.8.6 + provided + @@ -223,84 +301,6 @@ - - exec-jar - - - - - org.apache.maven.plugins - maven-shade-plugin - 2.4.3 - - - package - - shade - - - - - - - - - io.openpixee.maven.operator.App - - - false - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - - - - - org.skife.maven - really-executable-jar-maven-plugin - 1.4.1 - - - - -Xmx1G - - - - pom-operator - - - - - - - - - - - - - package - - really-executable-jar - - - - - - - integration-testing diff --git a/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt b/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt index 9fc8eda2b..d47e3f0de 100644 --- a/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt +++ b/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt @@ -1,12 +1,17 @@ package io.openpixee.maven.operator -import io.openpixee.maven.operator.util.Util.selectXPathNodes +import io.openpixee.maven.operator.Util.findOutIfUpgradeIsNeeded +import io.openpixee.maven.operator.Util.selectXPathNodes +import io.openpixee.maven.operator.Util.upgradeVersionNode import org.dom4j.Element /** * Base implementation of Command - used by SimpleDependency and SimpleInsert */ abstract class AbstractSimpleCommand : Command { + /** + * Given a POM, locate its coordinates for a given dependency based on lookupExpression and figures out the upgrade + */ protected fun handleDependency(c: ProjectModel, lookupExpression: String): Boolean { val dependencyNodes = c.resultPom.selectXPathNodes(lookupExpression) diff --git a/src/main/java/io/openpixee/maven/operator/AbstractSimpleQueryCommand.kt b/src/main/java/io/openpixee/maven/operator/AbstractSimpleQueryCommand.kt new file mode 100644 index 000000000..cf7a22e9f --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/AbstractSimpleQueryCommand.kt @@ -0,0 +1,199 @@ +package io.openpixee.maven.operator + +import io.openpixee.maven.operator.Util.which +import org.apache.commons.lang3.SystemUtils +import org.apache.maven.shared.invoker.DefaultInvocationRequest +import org.apache.maven.shared.invoker.InvocationRequest +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import java.io.File +import java.nio.file.Paths +import java.util.* + +/** + * Common Base Class - Meant to be used by Simple Queries using either Invoker and/or Embedder, thus + * relying on dependency:tree mojo outputting into a text file - which might be cached. + * + */ +abstract class AbstractSimpleQueryCommand : AbstractSimpleCommand() { + /** + * Generates a temporary file path used to store the output of the
dependency:tree
mojo + * + * @param pomFilePath POM Original File Path + */ + protected fun getOutputPath(pomFilePath: File): File { + val basePath = pomFilePath.parentFile + + val outputBasename = "output-%08X.txt".format(pomFilePath.hashCode()) + + val outputPath = File(basePath, outputBasename) + + return outputPath + } + + /** + * Given a POM URI, returns a File Object + * + * @param c ProjectModel + */ + protected fun getPomFilePath(c: ProjectModel): File = Paths.get(c.pomPath!!.toURI()).toFile() + + /** + * Abstract Method to extract dependencies + * + * @param outputPath Output Path to where to store the content + * @param pomFilePath Input Pom Path + * @param c Project Model + */ + abstract fun extractDependencyTree(outputPath: File, pomFilePath: File, c: ProjectModel) + + /** + * Internal Holder Variable + * + * Todo: OF COURSE IT BREAKS THE PROTOCOL + */ + internal var result: Collection? = null + + /** + * We declare the main logic here - details are made in the child classes for now + */ + override fun execute(c: ProjectModel): Boolean { + val pomFilePath = getPomFilePath(c) + + val outputPath = getOutputPath(pomFilePath) + + if (outputPath.exists()) { + outputPath.delete() + } + + try { + extractDependencyTree(outputPath, pomFilePath, c) + } catch (e: InvalidContextException) { + return false + } + + this.result = extractDependencies(outputPath).values + + return true + } + + /** + * Given a File containing the output of the dependency:tree mojo, read its contents and parse, creating an array of dependencies + * + * About the file contents: We receive something such as this, then filter it out: + * + *
+     *     br.com.ingenieux:pom-operator:jar:0.0.1-SNAPSHOT
+     *     +- xerces:xercesImpl:jar:2.12.1:compile
+     *     |  \- xml-apis:xml-apis:jar:1.4.01:compile
+     *     \- org.jetbrains.kotlin:kotlin-test:jar:1.5.31:test
+     * 
+ * + * @param outputPath file to read + */ + protected fun extractDependencies(outputPath: File) = outputPath.readLines().drop(1).map { + it.trim(*"+-|\\ ".toCharArray()) + }.map { + it to it.split(':') + }.associate { (line, elements) -> + val (groupId, artifactId, packaging, version, scope) = elements + + line to Dependency( + groupId = groupId, + artifactId = artifactId, + version = version, + packaging = packaging, + scope = scope + ) + } + + protected fun buildInvocationRequest( + outputPath: File, + pomFilePath: File, + c: ProjectModel + ): InvocationRequest { + val props = Properties(System.getProperties()).apply { + //System.getProperties().forEach { t, u -> setProperty(t as String, u as String) } + setProperty("outputFile", outputPath.absolutePath) + } + + val request: InvocationRequest = DefaultInvocationRequest().apply { + findMaven(this) + + pomFile = pomFilePath + + isShellEnvironmentInherited = true + + isNoTransferProgress = true + isBatchMode = true + isRecursive = false + profiles = c.activeProfiles.toList() + isDebug = true + + properties = props + + goals = listOf(DEPENDENCY_TREE_MOJO_REFERENCE) + } + + return request + } + + /** + * Locates where Maven is at - HOME var and main launcher script. + * + * @param invocationRequest InvocationRequest to be filled up + */ + private fun findMaven(invocationRequest: InvocationRequest) { + /* + * Step 1: Locate Maven Home + */ + val m2homeEnvVar = System.getenv("M2_HOME") + + if (null != m2homeEnvVar) { + val m2HomeDir = File(m2homeEnvVar) + + if (m2HomeDir.isDirectory) + invocationRequest.mavenHome = m2HomeDir + } + + /** + * Step 1.1: Try to guess if thats the case + */ + if (invocationRequest.mavenHome == null) { + val inferredHome = File(SystemUtils.getUserHome(), ".m2") + + if (!(inferredHome.exists() && inferredHome.isDirectory)) { + LOGGER.warn( + "Inferred User Home - which does not exist or not a directory: {}", + inferredHome + ) + } + + invocationRequest.mavenHome = inferredHome + } + + /** + * Step 2: Find Maven Executable given the operating system and PATH variable contents + */ + val foundExecutable = listOf("mvn", "mvnw").map { which(it) }.firstOrNull() + + if (null != foundExecutable) { + invocationRequest.mavenExecutable = foundExecutable + + return + } + + throw IllegalStateException("Missing Maven Home / Executable") + } + + companion object { + /** + * Mojo Reference + */ + const val DEPENDENCY_TREE_MOJO_REFERENCE = + "org.apache.maven.plugins:maven-dependency-plugin:3.3.0:tree" + + val LOGGER: Logger = LoggerFactory.getLogger(AbstractSimpleQueryCommand::class.java) + } + +} \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/App.kt b/src/main/java/io/openpixee/maven/operator/App.kt deleted file mode 100644 index 72b5d0176..000000000 --- a/src/main/java/io/openpixee/maven/operator/App.kt +++ /dev/null @@ -1,42 +0,0 @@ -package io.openpixee.maven.operator - -import org.docopt.Docopt -import java.io.File -import java.lang.IllegalStateException - - -/** - * Sample CLI Modification App - */ -object App { - @JvmStatic - fun main(args: Array) { - val opts = Docopt( - """pom-operator 0.0.1 - - Usage: - pom-operator DEPENDENCY POMFILES... - - """.trimIndent() - ).withVersion("pom-operator 0.0.1").parse(*args) - - val dep = Dependency.fromString(opts["DEPENDENCY"]!! as String) - - @Suppress("UNCHECKED_CAST") val files = opts["POMFILES"]!! as List - - for (path in files) { - val ctx = ProjectModelFactory.load(File(path)).withDependency(dep).build() - - println("Upgrading dependency ($dep) in path $path") - - val upgradeResult = POMOperator.modify(ctx) - - if (!upgradeResult) - throw IllegalStateException("Unexpected failure on upgradeResult") - - val xmlContent = ctx.resultPom.asXML() - - File(path).writeText(xmlContent) - } - } -} \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/Chain.kt b/src/main/java/io/openpixee/maven/operator/Chain.kt index d99da1b87..e41624297 100644 --- a/src/main/java/io/openpixee/maven/operator/Chain.kt +++ b/src/main/java/io/openpixee/maven/operator/Chain.kt @@ -1,5 +1,8 @@ package io.openpixee.maven.operator +import org.slf4j.Logger +import org.slf4j.LoggerFactory + /** * Implements a Chain of Responsibility Pattern * @@ -9,7 +12,7 @@ class Chain(vararg commands: Command) { /** * Internal ArrayList of the Commands */ - private val commandList = ArrayList(commands.toList()) + internal val commandList : MutableList = ArrayList(commands.toList()) /** * Executes the Commands in the Chain of Responsibility @@ -31,9 +34,46 @@ class Chain(vararg commands: Command) { } companion object { + private val LOGGER: Logger = LoggerFactory.getLogger(Chain::class.java) + /** - * Returns a Pre-Configured Chain with the Defaults + * Some classes won't have all available dependencies on the classpath during runtime + * for this reason we'll use
Class.forName
and report issues creating */ - fun create() = Chain(SimpleUpgrade, SimpleDependencyManagement, SimpleInsert) + val AVAILABLE_QUERY_COMMANDS = listOf( + QueryType.SAFE to "QueryByResolver", + QueryType.SAFE to "QueryByEmbedder", + QueryType.UNSAFE to "QueryByInvoker", + ) + + /** + * Returns a Pre-Configured Chain with the Defaults for Modifying a POM + */ + fun createForModify() = + Chain(CheckDependencyPresent, SimpleUpgrade, SimpleDependencyManagement, SimpleInsert) + + /** + * returns a pre-configured chain with the defaults for Querying + */ + fun createForQuery(queryType: QueryType = QueryType.SAFE): Chain { + val commands: List = AVAILABLE_QUERY_COMMANDS + .filter { it.first == queryType }.mapNotNull { + val commandClassName = "io.openpixee.maven.operator.${it.second}" + + try { + Class.forName(commandClassName).newInstance() as Command + } catch (e: Throwable) { + LOGGER.warn("Creating class '{}': ", commandClassName, e) + + null + } + } + .toList() + + if (commands.isEmpty()) + throw IllegalStateException("Unable to load any available strategy for ${queryType.name}") + + return Chain(*commands.toTypedArray()) + } } } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/CheckDependencyPresent.kt b/src/main/java/io/openpixee/maven/operator/CheckDependencyPresent.kt new file mode 100644 index 000000000..eb552c6dc --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/CheckDependencyPresent.kt @@ -0,0 +1,16 @@ +package io.openpixee.maven.operator + +/** + * Guard Command Singleton use to validate required parameters + */ +val CheckDependencyPresent = object : AbstractSimpleCommand() { + override fun execute(c: ProjectModel): Boolean { + /** + * CheckDependencyPresent requires a Dependency to be Present + */ + if (null == c.dependency) + throw MissingDependencyException("Dependency must be present for modify") + + return false + } +} \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/Dependency.kt b/src/main/java/io/openpixee/maven/operator/Dependency.kt index d642ce353..9ab5a2292 100644 --- a/src/main/java/io/openpixee/maven/operator/Dependency.kt +++ b/src/main/java/io/openpixee/maven/operator/Dependency.kt @@ -8,7 +8,8 @@ data class Dependency( val artifactId: String, val version: String? = null, val classifier: String? = null, - val packaging: String? = "jar" + val packaging: String? = "jar", + val scope: String? = "compile", ) { override fun toString(): String { return listOf(groupId, artifactId, packaging, version).joinToString(":") @@ -21,7 +22,7 @@ data class Dependency( val elements = str.split(":") if (elements.size < 3) - throw IllegalStateException("Give me 3 elements") + throw IllegalStateException("Give me at least 3 elements") return Dependency(elements[0], elements[1], elements[2]) } diff --git a/src/main/java/io/openpixee/maven/operator/InvalidContextException.kt b/src/main/java/io/openpixee/maven/operator/InvalidContextException.kt new file mode 100644 index 000000000..987aa1362 --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/InvalidContextException.kt @@ -0,0 +1,6 @@ +package io.openpixee.maven.operator + +/** + * This is an exception to tag when the output file couldn't be generated - perhaps due a missing or incompatible maven installation + */ +internal class InvalidContextException : RuntimeException() \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/MissingDependencyException.kt b/src/main/java/io/openpixee/maven/operator/MissingDependencyException.kt new file mode 100644 index 000000000..cd6ded0c1 --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/MissingDependencyException.kt @@ -0,0 +1,3 @@ +package io.openpixee.maven.operator + +class MissingDependencyException(message: String?) : RuntimeException(message) \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/POMOperator.kt b/src/main/java/io/openpixee/maven/operator/POMOperator.kt index 13edef745..b2a28b86c 100644 --- a/src/main/java/io/openpixee/maven/operator/POMOperator.kt +++ b/src/main/java/io/openpixee/maven/operator/POMOperator.kt @@ -2,9 +2,42 @@ package io.openpixee.maven.operator /** - * Façade for the POM Upgrader + * Façade for the POM Operator */ object POMOperator { + /** + * Bump a Dependency Version on a POM + * + * @param projectModel Project Model (Context) class + */ @JvmStatic - fun modify(projectModel: ProjectModel) = Chain.create().execute(projectModel) + fun modify(projectModel: ProjectModel) = Chain.createForModify().execute(projectModel) + + + /** + * Query for all the artifacts mentioned on a POM + * + * @param projectModel Project Model (Context) class + * @param commandList do not use (required for tests) + */ + @JvmStatic + fun queryDependency( + projectModel: ProjectModel, + commandList: List = emptyList() + ): Collection { + val chain = Chain.createForQuery(projectModel.queryType) + + if (commandList.isNotEmpty()) { + chain.commandList.clear() + chain.commandList.addAll(commandList) + } + + chain.execute(projectModel) + + val lastCommand = chain.commandList.filterIsInstance() + .lastOrNull { it.result != null } + ?: return emptyList() + + return lastCommand.result!! + } } diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt index 9c252ebc6..43a8b3bd1 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt @@ -1,21 +1,24 @@ package io.openpixee.maven.operator -import io.openpixee.maven.operator.util.Util.selectXPathNodes +import io.openpixee.maven.operator.Util.selectXPathNodes import org.dom4j.Document import org.dom4j.Element +import java.net.URL /** * ProjectModel represents the input parameters for the chain * - * @todo Wrap it into a
Context
interface + * @todo consider resolution and also Topological Sort of Properties for cross-property reference */ class ProjectModel internal constructor( + val pomPath: URL?, val pomDocument: Document, - val dependency: Dependency, + var dependency: Dependency?, val skipIfNewer: Boolean, val useProperties: Boolean, val activeProfiles: Set, val overrideIfAlreadyExists: Boolean, + val queryType: QueryType = QueryType.SAFE, ) { val resultPom: Document = pomDocument.clone() as Document @@ -36,7 +39,7 @@ class ProjectModel internal constructor( pomDocument.selectXPathNodes(expression) val newPropertiesToAppend = - propertiesElements.filter { it is Element }.map { it as Element } + propertiesElements.filterIsInstance() .flatMap { it.elements() } .associate { it.name to it.text diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt index 1b42d4ffe..55a9d2fec 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt @@ -3,7 +3,6 @@ package io.openpixee.maven.operator import org.dom4j.Document import org.dom4j.io.SAXReader import java.io.File -import java.io.FileInputStream import java.io.InputStream import java.net.URL @@ -11,13 +10,23 @@ import java.net.URL * Builder Object for ProjectModel instances */ class ProjectModelFactory private constructor( + private var pomPath: URL?, private var pomDocument: Document, private var dependency: Dependency? = null, private var skipIfNewer: Boolean = false, private var useProperties: Boolean = false, private var activeProfiles: Set = emptySet(), private var overrideIfAlreadyExists: Boolean = false, + private var queryType: QueryType = QueryType.SAFE, ) { + /** + * Fluent Setter + * @param pomPath pomPath + */ + fun withPomPath(pomPath: URL): ProjectModelFactory = this.apply { + this.pomPath = pomPath + } + /** * Fluent Setter * @@ -55,17 +64,28 @@ class ProjectModelFactory private constructor( this.overrideIfAlreadyExists = overrideIfAlreadyExists } + /** + * Fluent Setter + * + * @param queryType query type + */ + fun withQueryType(queryType: QueryType) = this.apply { + this.queryType = queryType + } + /** * Fluent Setter */ fun build(): ProjectModel { return ProjectModel( + pomPath = pomPath, pomDocument = pomDocument, - dependency = dependency!!, + dependency = dependency, skipIfNewer = skipIfNewer, useProperties = useProperties, activeProfiles = activeProfiles, - overrideIfAlreadyExists = overrideIfAlreadyExists + overrideIfAlreadyExists = overrideIfAlreadyExists, + queryType = queryType, ) } @@ -74,15 +94,18 @@ class ProjectModelFactory private constructor( fun load(`is`: InputStream): ProjectModelFactory { val pomDocument = SAXReader().read(`is`)!! - return ProjectModelFactory(pomDocument) + return ProjectModelFactory(pomPath = null, pomDocument = pomDocument) } @JvmStatic fun load(f: File) = - load(FileInputStream(f)) + load(f.toURI().toURL()) @JvmStatic - fun load(url: URL) = - load(url.openStream()) + fun load(url: URL): ProjectModelFactory { + val pomDocument = SAXReader().read(url.openStream()) + + return ProjectModelFactory(pomPath = url, pomDocument = pomDocument) + } } } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/QueryByEmbedder.kt b/src/main/java/io/openpixee/maven/operator/QueryByEmbedder.kt new file mode 100644 index 000000000..3e30e4cff --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/QueryByEmbedder.kt @@ -0,0 +1,80 @@ +package io.openpixee.maven.operator + +import org.apache.commons.io.output.NullOutputStream +import org.apache.maven.cli.MavenCli +import org.apache.maven.shared.invoker.InvocationRequest +import org.apache.maven.shared.invoker.MavenCommandLineBuilder +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import java.io.ByteArrayOutputStream +import java.io.File +import java.io.PrintStream + +/** + * Uses Maven Embedder to Implement + */ +class QueryByEmbedder : AbstractSimpleQueryCommand() { + /** + * Runs the "dependency:tree" mojo - but using Embedder instead. + */ + override fun extractDependencyTree(outputPath: File, pomFilePath: File, c: ProjectModel) { + val mavenCli = MavenCli() + + val cliBuilder = MavenCommandLineBuilder() + + val invocationRequest: InvocationRequest = + buildInvocationRequest(outputPath, pomFilePath, c) + + val oldMultimoduleValue = System.getProperty(MAVEN_MULTIMODULE_PROJECT_DIRECTORY) + + System.setProperty(MAVEN_MULTIMODULE_PROJECT_DIRECTORY, pomFilePath.parent) + + try { + val cliBuilderResult = cliBuilder.build(invocationRequest) + + val cliArgs = cliBuilderResult.commandline.toList().drop(1).toTypedArray() + + val baosOut = + if (LOGGER.isDebugEnabled) ByteArrayOutputStream() else NullOutputStream.NULL_OUTPUT_STREAM + + val baosErr = + if (LOGGER.isDebugEnabled) ByteArrayOutputStream() else NullOutputStream.NULL_OUTPUT_STREAM + + val result: Int = mavenCli.doMain( + cliArgs, + pomFilePath.parent, + PrintStream(baosOut, true), + PrintStream(baosErr, true) + ) + + if (LOGGER.isDebugEnabled) { + LOGGER.debug("baosOut: {}", baosOut.toString()) + LOGGER.debug("baosErr: {}", baosErr.toString()) + } + + /** + * Sometimes the Embedder will fail - it will return this specific exit code (1) as well as + * not generate this file + * + * If that happens, we'll move to the next strategy (Invoker-based likely) by throwing a + * custom exception which is caught inside the Chain#execute method + * + * @see Chain#execute + */ + if (1 == result && (!outputPath.exists())) + throw InvalidContextException() + + if (0 != result) + throw IllegalStateException("Unexpected status code: %02d".format(result)) + } finally { + if (null != oldMultimoduleValue) + System.setProperty(MAVEN_MULTIMODULE_PROJECT_DIRECTORY, oldMultimoduleValue) + } + } + + companion object { + const val MAVEN_MULTIMODULE_PROJECT_DIRECTORY = "maven.multiModuleProjectDirectory" + + private val LOGGER: Logger = LoggerFactory.getLogger(QueryByEmbedder::class.java) + } +} \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/QueryByInvoker.kt b/src/main/java/io/openpixee/maven/operator/QueryByInvoker.kt new file mode 100644 index 000000000..ac4a71cb0 --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/QueryByInvoker.kt @@ -0,0 +1,31 @@ +package io.openpixee.maven.operator + +import org.apache.maven.shared.invoker.DefaultInvoker +import org.apache.maven.shared.invoker.InvocationRequest +import java.io.File + +class QueryByInvoker : AbstractSimpleQueryCommand() { + + override fun extractDependencyTree( + outputPath: File, + pomFilePath: File, + c: ProjectModel + ) { + val invoker = DefaultInvoker() + + val invocationRequest: InvocationRequest = buildInvocationRequest(outputPath, pomFilePath, c) + + val invocationResult = invoker.execute(invocationRequest) + + val exitCode = invocationResult.exitCode + + if (0 != exitCode) { + throw IllegalStateException( + "Unexpected Status Code from Invoker: %02d".format( + exitCode + ) + ) + } + } + +} \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/QueryByResolver.kt b/src/main/java/io/openpixee/maven/operator/QueryByResolver.kt new file mode 100644 index 000000000..63a3408d3 --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/QueryByResolver.kt @@ -0,0 +1,198 @@ +package io.openpixee.maven.operator + +import org.apache.maven.model.building.DefaultModelBuilderFactory +import org.apache.maven.model.building.DefaultModelBuildingRequest +import org.apache.maven.model.building.FileModelSource +import org.apache.maven.model.building.ModelBuildingException +import org.apache.maven.project.ProjectModelResolver +import org.apache.maven.repository.internal.MavenRepositorySystemUtils +import org.eclipse.aether.DefaultRepositorySystemSession +import org.eclipse.aether.RepositorySystem +import org.eclipse.aether.artifact.DefaultArtifact +import org.eclipse.aether.collection.CollectRequest +import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory +import org.eclipse.aether.graph.DependencyNode +import org.eclipse.aether.graph.DependencyVisitor +import org.eclipse.aether.internal.impl.DefaultRemoteRepositoryManager +import org.eclipse.aether.repository.LocalRepository +import org.eclipse.aether.repository.RemoteRepository +import org.eclipse.aether.transport.file.FileTransporterFactory +import org.eclipse.aether.transport.http.HttpTransporterFactory +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import java.io.File +import kotlin.io.path.toPath + +/** + * This is a resolver that actually embeds much of Maven Logic into that. + * + * TODO: Support Profiles / Environment Variables + * Support Third Party / User-Supplied Repositories (right now it only supports central) + */ +class QueryByResolver : AbstractSimpleQueryCommand() { + private val localRepo = LocalRepository( + File( + System.getProperty("user.home"), + ".m2/repository" + ).absolutePath + ) // "target/local-repo") + + private fun newRepositorySystemSession(system: RepositorySystem): DefaultRepositorySystemSession? { + val session = MavenRepositorySystemUtils.newSession() + + session.localRepositoryManager = system.newLocalRepositoryManager(session, localRepo) + + return session + } + + + companion object { + private val LOGGER: Logger = LoggerFactory.getLogger(QueryByResolver::class.java) + } + + override fun extractDependencyTree(outputPath: File, pomFilePath: File, c: ProjectModel) { + TODO("Not yet implemented") + } + + override fun execute(c: ProjectModel): Boolean { + /* + * Aether's components implement org.eclipse.aether.spi.locator.Service to ease manual wiring and using the + * prepopulated DefaultServiceLocator, we only need to register the repository connector and transporter + * factories. + */ + val locator: org.eclipse.aether.impl.DefaultServiceLocator = + MavenRepositorySystemUtils.newServiceLocator() + locator.addService( + org.eclipse.aether.spi.connector.RepositoryConnectorFactory::class.java, + BasicRepositoryConnectorFactory::class.java + ) + locator.addService( + org.eclipse.aether.spi.connector.transport.TransporterFactory::class.java, + FileTransporterFactory::class.java + ) + locator.addService( + org.eclipse.aether.spi.connector.transport.TransporterFactory::class.java, + HttpTransporterFactory::class.java + ) + + locator.setErrorHandler(object : + org.eclipse.aether.impl.DefaultServiceLocator.ErrorHandler() { + override fun serviceCreationFailed( + type: Class<*>?, + impl: Class<*>?, + exception: Throwable + ) { + LOGGER.error( + "Service creation failed for {} with implementation {}", + type, impl, exception + ) + } + }) + + val remoteRepository = + RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2/") + .build() + + val remoteRepositories = listOf(remoteRepository) + + val repositorySystem = + locator.getService(org.eclipse.aether.RepositorySystem::class.java) + + val session = newRepositorySystemSession(repositorySystem) + + val modelBuilder = DefaultModelBuilderFactory().newInstance() + + val repositoryManager = DefaultRemoteRepositoryManager() + + val modelBuildingRequest = DefaultModelBuildingRequest().apply { + val pomFile = c.pomPath!!.toURI().toPath().toFile() + + this.activeProfileIds = c.activeProfiles.filterNot { it.startsWith("!") }.toList() + this.inactiveProfileIds = + c.activeProfiles.filter { it.startsWith("!") }.map { it.substring(1) }.toList() + + this.userProperties = System.getProperties() + this.systemProperties = System.getProperties() + this.pomFile = pomFile + + this.isProcessPlugins = false + + this.modelSource = FileModelSource(pomFile) + + val modelResolver = ProjectModelResolver( + session, + null, + repositorySystem, + repositoryManager, + remoteRepositories, + null, + null + ) + + this.modelResolver = modelResolver + } + + val res = try { + modelBuilder.build(modelBuildingRequest) + } catch (e: ModelBuildingException) { + LOGGER.warn("Oops: ", e) + + return false + } + + val dependencyToArtifact: (org.apache.maven.model.Dependency) -> org.eclipse.aether.graph.Dependency = + { + org.eclipse.aether.graph.Dependency( + DefaultArtifact( + it.groupId, + it.artifactId, + it.classifier, + null, + it.version + ), + it.scope, + ) + } + + val deps: List = + res.effectiveModel.dependencies?.map(dependencyToArtifact)?.toList() ?: emptyList() + + val managedDeps: List = + res.effectiveModel.dependencyManagement?.dependencies?.map(dependencyToArtifact) + ?.toList() ?: emptyList() + + val collectRequest = CollectRequest(deps, managedDeps, remoteRepositories) + + val collectResult = repositorySystem.collectDependencies(session, collectRequest) + + val returnList: MutableList = mutableListOf() + + collectResult.root.accept(object : DependencyVisitor { + override fun visitEnter(node: DependencyNode?): Boolean { + node?.dependency?.apply { + returnList.add( + Dependency( + groupId = this.artifact.groupId, + artifactId = this.artifact.artifactId, + version = this.artifact.version, + classifier = this.artifact.classifier, + packaging = this.artifact.extension, + scope = this.scope, + ) + ) + } + + return true + } + + override fun visitLeave(node: DependencyNode?): Boolean { + return true + } + }) + + this.result = returnList.toList() + + return true + } + +} \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/QueryType.kt b/src/main/java/io/openpixee/maven/operator/QueryType.kt new file mode 100644 index 000000000..1f84f546a --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/QueryType.kt @@ -0,0 +1,6 @@ +package io.openpixee.maven.operator + +enum class QueryType { + SAFE, + UNSAFE, +} \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/SimpleDependencyManagement.kt b/src/main/java/io/openpixee/maven/operator/SimpleDependencyManagement.kt index 3a42a759f..7d6f7643a 100644 --- a/src/main/java/io/openpixee/maven/operator/SimpleDependencyManagement.kt +++ b/src/main/java/io/openpixee/maven/operator/SimpleDependencyManagement.kt @@ -1,12 +1,12 @@ package io.openpixee.maven.operator -import io.openpixee.maven.operator.util.Util.buildLookupExpressionForDependencyManagement +import io.openpixee.maven.operator.Util.buildLookupExpressionForDependencyManagement val SimpleDependencyManagement = object : AbstractSimpleCommand() { override fun execute(c: ProjectModel): Boolean { val lookupExpression = - buildLookupExpressionForDependencyManagement(c.dependency) + buildLookupExpressionForDependencyManagement(c.dependency!!) return handleDependency(c, lookupExpression) } diff --git a/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt b/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt index 69aec7df2..3e8e5006a 100644 --- a/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt +++ b/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt @@ -1,15 +1,18 @@ package io.openpixee.maven.operator -import io.openpixee.maven.operator.util.Util.selectXPathNodes +import io.openpixee.maven.operator.Util.formatNode +import io.openpixee.maven.operator.Util.selectXPathNodes +import io.openpixee.maven.operator.Util.upgradeVersionNode import org.dom4j.Element /** - * Represents a POM Upgrade Strategy implicying simply adding a dependency/ section (and optionally a dependencyManagement/ section as well) + * Represents a POM Upgrade Strategy by simply adding a dependency/ section (and optionally a dependencyManagement/ section as well) */ val SimpleInsert = object : Command { override fun execute(c: ProjectModel): Boolean { val dependencyManagementNode = c.resultPom.selectXPathNodes("/m:project/m:dependencyManagement") + val elementsToFormat: MutableList = arrayListOf() if (dependencyManagementNode.isEmpty()) { @@ -46,7 +49,6 @@ val SimpleInsert = object : Command { return true } - /** * Creates the XML Elements for a given dependency */ @@ -58,11 +60,13 @@ val SimpleInsert = object : Command { val groupIdNode = dependencyNode.addElement("groupId") - groupIdNode.text = c.dependency.groupId + val dep = c.dependency!! + + groupIdNode.text = dep.groupId val artifactIdNode = dependencyNode.addElement("artifactId") - artifactIdNode.text = c.dependency.artifactId + artifactIdNode.text = dep.artifactId return dependencyNode } diff --git a/src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt b/src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt index 9f1370998..fd8e751b3 100644 --- a/src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt +++ b/src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt @@ -1,6 +1,6 @@ package io.openpixee.maven.operator -import io.openpixee.maven.operator.util.Util.buildLookupExpressionForDependency +import io.openpixee.maven.operator.Util.buildLookupExpressionForDependency /** @@ -9,7 +9,7 @@ import io.openpixee.maven.operator.util.Util.buildLookupExpressionForDependency val SimpleUpgrade = object : AbstractSimpleCommand() { override fun execute(c: ProjectModel): Boolean { val lookupExpressionForDependency = - buildLookupExpressionForDependency(c.dependency) + buildLookupExpressionForDependency(c.dependency!!) return handleDependency(c, lookupExpressionForDependency) } diff --git a/src/main/java/io/openpixee/maven/operator/Util.kt b/src/main/java/io/openpixee/maven/operator/Util.kt new file mode 100644 index 000000000..b7624561e --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/Util.kt @@ -0,0 +1,276 @@ +@file:Suppress("DEPRECATION") + +package io.openpixee.maven.operator + +import com.github.zafarkhaja.semver.Version +import org.apache.commons.lang3.StringUtils +import org.apache.commons.lang3.SystemUtils +import org.apache.commons.lang3.text.StrSubstitutor +import org.dom4j.Element +import org.dom4j.Node +import org.dom4j.Text +import org.dom4j.io.OutputFormat +import org.dom4j.io.SAXReader +import org.dom4j.io.XMLWriter +import org.dom4j.tree.DefaultText +import org.jaxen.SimpleNamespaceContext +import org.jaxen.XPath +import org.jaxen.dom4j.Dom4jXPath +import java.io.File +import java.io.StringReader +import java.io.StringWriter +import kotlin.math.ceil + +/** + * Common Utilities + */ +object Util { + /** + * Formats a XML Element Node + */ + internal fun formatNode(node: Element) { + val parent = node.parent + //val siblings = parent.content() + + val indentLevel = findIndentLevel(node) + + val clonedNode = node.clone() as Element + + val out = StringWriter() + + val outputFormat = OutputFormat.createPrettyPrint() + + val xmlWriter = XMLWriter(out, outputFormat) + + xmlWriter.setIndentLevel(ceil(indentLevel.toDouble() / 2).toInt()) + + xmlWriter.write(clonedNode) + + val content = out.toString() + + val newElement = SAXReader().read(StringReader(content)).rootElement.clone() as Element + + parent.remove(node) + + parent.add(DefaultText("\n" + StringUtils.repeat(" ", indentLevel))) + parent.add(newElement) + parent.add(DefaultText("\n" + StringUtils.repeat(" ", ((indentLevel - 1) / 2)))) + } + + /** + * Guesses the current indent level of the nearest nodes + */ + internal fun findIndentLevel(node: Element): Int { + val siblings = node.parent.content() + val myIndex = siblings.indexOf(node) + + if (myIndex > 0) { + val lastElement = siblings.subList(0, myIndex).findLast { + (it is Text) && it.text.matches(Regex("\\n+\\s+")) + } + + val lastElementText = lastElement?.text ?: "" + + return lastElementText.trimStart('\n').length + } + + return 0 + } + + /** + * Represents a Property Reference - as a regex + */ + internal val PROPERTY_REFERENCE_REGEX = Regex("^\\\$\\{(.*)}$") + + /** + * Upserts a given property + */ + internal fun upgradeProperty(c: ProjectModel, propertyName: String) { + if (null == c.resultPom.rootElement.element("properties")) { + val propertyElement = c.resultPom.rootElement.addElement("properties") + + formatNode(propertyElement) + } + + val parentPropertyElement = c.resultPom.rootElement.element("properties") + + if (null == parentPropertyElement.element(propertyName)) { + val newElement = parentPropertyElement.addElement(propertyName) + + formatNode(newElement) + } else { + if (!c.overrideIfAlreadyExists) { + val propertyReferenceRE = Regex.fromLiteral("\${$propertyName}") + + val numberOfAllCurrentMatches = propertyReferenceRE.findAll(c.pomDocument.asXML()).toList().size + + if (numberOfAllCurrentMatches > 1) { + throw IllegalStateException("Property $propertyName is already defined - and used more than once.") + } + } + } + + val propertyElement = parentPropertyElement.element(propertyName) + + propertyElement.text = c.dependency!!.version + + formatNode(propertyElement) + } + + /** + * Creates a property Name + */ + internal fun propertyName(c: ProjectModel, versionNode: Element): String { + val version = versionNode.textTrim + + if (PROPERTY_REFERENCE_REGEX.matches(version)) { + val match = PROPERTY_REFERENCE_REGEX.find(version) + + val firstMatch = match!!.groups[1]!! + + return firstMatch.value + } + + return "versions." + c.dependency!!.artifactId + } + + /** + * Identifies if an upgrade is needed + */ + internal fun findOutIfUpgradeIsNeeded(c: ProjectModel, versionNode: Element): Boolean { + val currentVersionNodeText = resolveVersion(c, versionNode.text!!) + + val currentVersion = Version.valueOf(currentVersionNodeText) + val newVersion = Version.valueOf(c.dependency!!.version) + + @Suppress("UnnecessaryVariable") val versionsAreIncreasing = newVersion.greaterThan(currentVersion) + + return versionsAreIncreasing + } + + internal fun resolveVersion(c: ProjectModel, versionText: String): String = + if (PROPERTY_REFERENCE_REGEX.matches(versionText)) { + @Suppress("DEPRECATION") + StrSubstitutor(c.resolvedProperties).replace(versionText) + } else { + versionText + } + + /** + * Escapes a Property Name + */ + internal fun escapedPropertyName(propertyName: String): String = + "\${$propertyName}" + + /** + * Given a Version Node, upgrades a resulting POM + */ + internal fun upgradeVersionNode(c: ProjectModel, versionNode: Element) { + if (c.useProperties) { + val propertyName = propertyName(c, versionNode) + + // define property + upgradeProperty(c, propertyName) + + versionNode.text = escapedPropertyName(propertyName) + } else { + versionNode.text = c.dependency!!.version + } + } + + /** + * Builds a Lookup Expression String for a given dependency + * + * @param dependency Dependency + */ + fun buildLookupExpressionForDependency(dependency: Dependency): String = + "/m:project" + + "/m:dependencies" + + "/m:dependency" + + /* */ "[./m:groupId[text()='${dependency.groupId}'] and " + + /* */ "./m:artifactId[text()='${dependency.artifactId}']" + + "]" + + /** + * Builds a Lookup Expression String for a given dependency, but under the >dependencyManagement> section + * + * @param dependency Dependency + */ + fun buildLookupExpressionForDependencyManagement(dependency: Dependency): String = + "/m:project" + + "/m:dependencyManagement" + + "/m:dependencies" + + "/m:dependency" + + /* */ "[./m:groupId[text()='${dependency.groupId}'] and " + + /* */ "./m:artifactId[text()='${dependency.artifactId}']" + + "]" + + /** + * Extension Function to Select the XPath Nodes + * + * @param expression expression to use + */ + @Suppress("UNCHECKED_CAST") + fun Node.selectXPathNodes(expression: String) = + createXPathExpression(expression).selectNodes(this)!! as List + + /** + * Creates a XPath Expression from a given expression string + * + * @param expression expression to create xpath from + */ + private fun createXPathExpression(expression: String): XPath { + val xpath = Dom4jXPath(expression) + + xpath.namespaceContext = namespaceContext + + return xpath + } + + /** + * Hard-Coded POM Namespace Map + */ + private val namespaceContext = SimpleNamespaceContext( + mapOf( + "m" to "http://maven.apache.org/POM/4.0.0" + ) + ) + + + internal fun which(path: String): File? { + val nativeExecutables: List = if (SystemUtils.IS_OS_WINDOWS) { + listOf("", ".exe", ".bat", ".cmd").map { path + it }.toList() + } else { + listOf(path) + } + + val pathContentString = System.getenv("PATH") + + val pathElements = pathContentString.split(File.pathSeparatorChar) + + val possiblePaths = nativeExecutables.flatMap { executable -> + pathElements.map { pathElement -> + File(File(pathElement), executable) + } + } + + val isCliCallable: (File) -> Boolean = if (SystemUtils.IS_OS_WINDOWS) { it -> + it.exists() && it.isFile + } else { it -> + it.exists() && it.isFile && it.canExecute() + } + + val result = possiblePaths.findLast(isCliCallable) + + if (null == result) { + AbstractSimpleQueryCommand.LOGGER.warn( + "Unable to find mvn executable (execs: {}, path: {})", + nativeExecutables.joinToString("/"), + pathContentString + ) + } + + return result + } + +} diff --git a/src/main/java/io/openpixee/maven/operator/misc.kt b/src/main/java/io/openpixee/maven/operator/misc.kt deleted file mode 100644 index eb124f97f..000000000 --- a/src/main/java/io/openpixee/maven/operator/misc.kt +++ /dev/null @@ -1,172 +0,0 @@ -package io.openpixee.maven.operator - -import com.github.zafarkhaja.semver.Version -import org.apache.commons.lang3.StringUtils -import org.apache.commons.lang3.text.StrSubstitutor -import org.dom4j.Element -import org.dom4j.Text -import org.dom4j.io.OutputFormat -import org.dom4j.io.SAXReader -import org.dom4j.io.XMLWriter -import org.dom4j.tree.DefaultText -import java.io.StringReader -import java.io.StringWriter -import java.lang.IllegalStateException -import kotlin.math.ceil - -/** - * Formats a XML Element Node - */ -internal fun formatNode(node: Element) { - val parent = node.parent - //val siblings = parent.content() - - val indentLevel = findIndentLevel(node) - - val clonedNode = node.clone() as Element - - val out = StringWriter() - - val outputFormat = OutputFormat.createPrettyPrint() - - val xmlWriter = XMLWriter(out, outputFormat) - - xmlWriter.setIndentLevel(ceil(indentLevel.toDouble() / 2).toInt()) - - xmlWriter.write(clonedNode) - - val content = out.toString() - - val newElement = SAXReader().read(StringReader(content)).rootElement.clone() as Element - - parent.remove(node) - - parent.add(DefaultText("\n" + StringUtils.repeat(" ", indentLevel))) - parent.add(newElement) - parent.add(DefaultText("\n" + StringUtils.repeat(" ", ((indentLevel - 1) / 2)))) -} - -/** - * Guesses the current indent level of the nearest nodes - */ -internal fun findIndentLevel(node: Element): Int { - val siblings = node.parent.content() - val myIndex = siblings.indexOf(node) - - if (myIndex > 0) { - val lastElement = siblings.subList(0, myIndex).findLast { - (it is Text) && it.text.matches(Regex("\\n+\\s+")) - } - - val lastElementText = lastElement?.text ?: "" - - return lastElementText.trimStart('\n').length - } - - return 0 -} - -/** - * Represents a Property Reference - as a regex - */ -internal val PROPERTY_REFERENCE_REGEX = Regex("^\\\$\\{(.*)}$") - -/** - * Upserts a given property - */ -internal fun upgradeProperty(c: ProjectModel, propertyName: String) { - // TODO: Handle Profiles - - if (null == c.resultPom.rootElement.element("properties")) { - val propertyElement = c.resultPom.rootElement.addElement("properties") - - formatNode(propertyElement) - } - - val parentPropertyElement = c.resultPom.rootElement.element("properties") - - if (null == parentPropertyElement.element(propertyName)) { - val newElement = parentPropertyElement.addElement(propertyName) - - formatNode(newElement) - } else { - if (!c.overrideIfAlreadyExists) { - val propertyReferenceRE = Regex.fromLiteral("\${$propertyName}") - - val numberOfAllCurrentMatches = propertyReferenceRE.findAll(c.pomDocument.asXML()).toList().size - - if (numberOfAllCurrentMatches > 1) { - throw IllegalStateException("Property ${propertyName} is already defined - and used more than once.") - } - } - } - - val propertyElement = parentPropertyElement.element(propertyName) - - propertyElement.text = c.dependency.version - - formatNode(propertyElement) -} - -/** - * Creates a property Name - */ -internal fun propertyName(c: ProjectModel, versionNode: Element): String { - val version = versionNode.textTrim - - if (PROPERTY_REFERENCE_REGEX.matches(version)) { - val match = PROPERTY_REFERENCE_REGEX.find(version) - - val firstMatch = match!!.groups[1]!! - - return firstMatch.value - } - - return "versions." + c.dependency.artifactId -} - -/** - * Identifies if an upgrade is needed - */ -internal fun findOutIfUpgradeIsNeeded(c: ProjectModel, versionNode: Element): Boolean { - val currentVersionNodeText = resolveVersion(c, versionNode.text!!) - - val currentVersion = Version.valueOf(currentVersionNodeText) - val newVersion = Version.valueOf(c.dependency.version) - - val versionsAreIncreasing = newVersion.greaterThan(currentVersion) - - return versionsAreIncreasing -} - -internal fun resolveVersion(c: ProjectModel, versionText: String): String = - if (PROPERTY_REFERENCE_REGEX.matches(versionText)) { - @Suppress("DEPRECATION") - StrSubstitutor(c.resolvedProperties).replace(versionText) - } else { - versionText - } - -/** - * Escapes a Property Name - */ -internal fun escapedPropertyName(propertyName: String): String = - "\${$propertyName}" - -/** - * Given a Version Node, upgrades a resulting POM - */ -internal fun upgradeVersionNode(c: ProjectModel, versionNode: Element) { - if (c.useProperties) { - val propertyName = propertyName(c, versionNode) - - // define property - upgradeProperty(c, propertyName) - - versionNode.text = escapedPropertyName(propertyName) - } else { - versionNode.text = c.dependency.version - } -} - - diff --git a/src/main/java/io/openpixee/maven/operator/util/Utils.kt b/src/main/java/io/openpixee/maven/operator/util/Utils.kt deleted file mode 100644 index 9be3a9067..000000000 --- a/src/main/java/io/openpixee/maven/operator/util/Utils.kt +++ /dev/null @@ -1,70 +0,0 @@ -package io.openpixee.maven.operator.util - -import io.openpixee.maven.operator.Dependency -import org.dom4j.Node -import org.jaxen.SimpleNamespaceContext -import org.jaxen.XPath -import org.jaxen.dom4j.Dom4jXPath - -/** - * Common Utilities - */ -object Util { - /** - * Builds a Lookup Expression String for a given dependency - * - * @param dependency Dependency - */ - fun buildLookupExpressionForDependency(dependency: Dependency): String = - "/m:project" + - "/m:dependencies" + - "/m:dependency" + - /* */ "[./m:groupId[text()='${dependency.groupId}'] and " + - /* */ "./m:artifactId[text()='${dependency.artifactId}']" + - "]" - - /** - * Builds a Lookup Expression String for a given dependency, but under the >dependencyManagement> section - * - * @param dependency Dependency - */ - fun buildLookupExpressionForDependencyManagement(dependency: Dependency): String = - "/m:project" + - "/m:dependencyManagement" + - "/m:dependencies" + - "/m:dependency" + - /* */ "[./m:groupId[text()='${dependency.groupId}'] and " + - /* */ "./m:artifactId[text()='${dependency.artifactId}']" + - "]" - - /** - * Extension Function to Select the XPath Nodes - * - * @param expression expression to use - */ - @Suppress("UNCHECKED_CAST") - fun Node.selectXPathNodes(expression: String) = - createXPathExpression(expression).selectNodes(this)!! as List - - /** - * Creates a XPath Expression from a given expression string - * - * @param expression expression to create xpath from - */ - private fun createXPathExpression(expression: String): XPath { - val xpath = Dom4jXPath(expression) - - xpath.namespaceContext = namespaceContext - - return xpath - } - - /** - * Hard-Coded POM Namespace Map - */ - private val namespaceContext = SimpleNamespaceContext( - mapOf( - "m" to "http://maven.apache.org/POM/4.0.0" - ) - ) -} diff --git a/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt b/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt index caced350d..bfdfd567d 100644 --- a/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt @@ -3,9 +3,12 @@ package io.openpixee.maven.operator.test import io.openpixee.maven.operator.Dependency import io.openpixee.maven.operator.POMOperator import io.openpixee.maven.operator.ProjectModelFactory +import io.openpixee.maven.operator.Util.which +import org.apache.commons.lang3.SystemUtils import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test +import org.slf4j.Logger import org.slf4j.LoggerFactory import java.io.File @@ -17,7 +20,7 @@ data class TestRepo( fun cacheDir() = BASE_CACHE_DIR.resolve("repo-%08X".format(slug.hashCode())) companion object { - val BASE_CACHE_DIR = File(System.getProperty("user.dir") + "/.cache").absoluteFile + val BASE_CACHE_DIR: File = File(System.getProperty("user.dir") + "/.cache").absoluteFile } } @@ -41,7 +44,7 @@ class MassRepoIT { questdb/questdb */ - val repos = listOf( + private val repos = listOf( TestRepo( "apache/pulsar", pomPath = "pulsar-broker/pom.xml" @@ -192,8 +195,12 @@ class MassRepoIT { outputFile.delete() } - val command = arrayOf( - "mvn", + val command = if (SystemUtils.IS_OS_WINDOWS) { + listOf(which("cmd")!!.canonicalPath, "/c") + } else { + emptyList() + } + listOf( + which("mvn")!!.canonicalPath, "-B", "-f", pomPath, @@ -202,7 +209,7 @@ class MassRepoIT { "-DoutputFile=${outputFile.canonicalPath}" ) - val process = ProcessBuilder(*command) + val process = ProcessBuilder(*command.toTypedArray()) .directory(dir) .inheritIO() .start() @@ -217,7 +224,7 @@ class MassRepoIT { } companion object { - val LOGGER = LoggerFactory.getLogger(MassRepoIT::class.java) + val LOGGER: Logger = LoggerFactory.getLogger(MassRepoIT::class.java) } init { diff --git a/src/test/java/io/openpixee/maven/operator/test/POMOperatorJavaIT.java b/src/test/java/io/openpixee/maven/operator/test/POMOperatorJavaIT.java index 8057a913f..8f9354c21 100644 --- a/src/test/java/io/openpixee/maven/operator/test/POMOperatorJavaIT.java +++ b/src/test/java/io/openpixee/maven/operator/test/POMOperatorJavaIT.java @@ -1,20 +1,40 @@ package io.openpixee.maven.operator.test; +import org.apache.commons.lang3.SystemUtils; import org.junit.Test; -import static org.junit.Assert.*; +import java.util.Arrays; +import java.util.List; + +import io.openpixee.maven.operator.Util; + +import static org.junit.Assert.assertEquals; public class POMOperatorJavaIT { @Test public void testJavaSample() throws Exception { - ProcessBuilder psBuilder = new ProcessBuilder( - "mvn", + String mvnAbsPath = Util.INSTANCE.which$pom_operator("mvn").getAbsolutePath(); + + List argList = Arrays.asList( + mvnAbsPath, "-B", "-N", "-f", "java-sample/pom.xml", "verify" - ).inheritIO(); + ); + + if (SystemUtils.IS_OS_WINDOWS) { + List newArgList = Arrays.asList(Util.INSTANCE.which$pom_operator("cmd").getAbsolutePath(), "/c"); + + newArgList.addAll(argList); + + argList = newArgList; + } + + String[] args = argList.toArray(new String[0]); + + ProcessBuilder psBuilder = new ProcessBuilder(args).inheritIO(); psBuilder.environment().putAll(System.getenv()); diff --git a/src/test/java/io/openpixee/maven/operator/test/POMOperatorQueryTest.kt b/src/test/java/io/openpixee/maven/operator/test/POMOperatorQueryTest.kt new file mode 100644 index 000000000..b2df0b54e --- /dev/null +++ b/src/test/java/io/openpixee/maven/operator/test/POMOperatorQueryTest.kt @@ -0,0 +1,75 @@ +package io.openpixee.maven.operator.test + +import io.openpixee.maven.operator.* +import org.junit.Test +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import kotlin.test.assertTrue + +class POMOperatorQueryTest { + private val LOGGER: Logger = LoggerFactory.getLogger(POMOperatorTest::class.java) + + @Test + fun testBasicQuery() { + QueryType.values().forEach { queryType -> + val context = + ProjectModelFactory + .load(this.javaClass.getResource("pom-1.xml")!!) + .withQueryType(queryType) + .build() + + val dependencies = POMOperator.queryDependency(context) + + LOGGER.debug("Dependencies found: {}", dependencies) + + assertTrue(dependencies.isNotEmpty(), "Dependencies are not empty") + } + } + + @Test + fun testFailedSafeQuery() { + val context = + ProjectModelFactory + .load(this.javaClass.getResource("pom-broken.xml")!!) + .withQueryType(QueryType.SAFE) + .build() + + val dependencies = POMOperator.queryDependency(context) + + assertTrue(dependencies.isEmpty(), "Dependencies are empty") + } + + @Test(expected = IllegalStateException::class) + fun testFailedUnsafeQuery() { + val context = + ProjectModelFactory + .load(this.javaClass.getResource("pom-broken.xml")!!) + .withQueryType(QueryType.UNSAFE) + .build() + + val dependencies = POMOperator.queryDependency(context) + + assertTrue(dependencies.isEmpty(), "Dependencies are empty") + } + + @Test + fun testAllQueryTypes() { + listOf("pom-1.xml", "pom-3.xml").forEach { pomFile -> + Chain.AVAILABLE_QUERY_COMMANDS.forEach { + val commandClassName = "io.openpixee.maven.operator.${it.second}" + + val commandListOverride = listOf(Class.forName(commandClassName).newInstance() as Command) + + val context = + ProjectModelFactory + .load(this.javaClass.getResource(pomFile)!!) + .withQueryType(QueryType.UNSAFE) + .build() + + val dependencies = POMOperator.queryDependency(context, commandList = commandListOverride) + + assertTrue(dependencies.isNotEmpty(), "Dependencies are not empty") + } + } + } +} \ No newline at end of file diff --git a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt index 6658bad49..3286c5f3e 100644 --- a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt @@ -1,10 +1,13 @@ package io.openpixee.maven.operator.test import io.openpixee.maven.operator.Dependency +import io.openpixee.maven.operator.MissingDependencyException import io.openpixee.maven.operator.POMOperator import io.openpixee.maven.operator.ProjectModelFactory -import io.openpixee.maven.operator.util.Util.buildLookupExpressionForDependency -import io.openpixee.maven.operator.util.Util.selectXPathNodes +import io.openpixee.maven.operator.Util.buildLookupExpressionForDependency +import io.openpixee.maven.operator.Util.selectXPathNodes +import io.openpixee.maven.operator.Util.which +import org.apache.commons.lang3.SystemUtils import org.hamcrest.MatcherAssert.assertThat import org.junit.Assert.assertEquals import org.junit.Test @@ -15,6 +18,15 @@ import java.io.File * Unit test for simple App. */ class POMOperatorTest : AbstractTestBase() { + @Test(expected = MissingDependencyException::class) + fun testWithDependencyMissing() { + gwt( + "case-dependency-missing", + ProjectModelFactory.load( + POMOperatorTest::class.java.getResource("pom-case-1.xml")!!, + ) + ) + } @Test fun testCaseOne() { @@ -89,15 +101,25 @@ class POMOperatorTest : AbstractTestBase() { fun testCase4() { val pomPath = File(POMOperatorTest::class.java.getResource("webgoat-parent.xml")!!.toURI()) + val args = + if (SystemUtils.IS_OS_WINDOWS) { + listOf("cmd.exe", "/c") + } else { + listOf() + } + + listOf( + which("mvn")!!.absolutePath, + "-N", + "install:install-file", + "-DgroupId=org.owasp.webgoat", + "-DartifactId=webgoat-parent", + "-Dversion=8.2.3-SNAPSHOT", + "-Dpackaging=pom", + "-Dfile=${pomPath.absolutePath}" + ) + val exitCode = ProcessBuilder( - "mvn", - "-N", - "install:install-file", - "-DgroupId=org.owasp.webgoat", - "-DartifactId=webgoat-parent", - "-Dversion=8.2.3-SNAPSHOT", - "-Dpackaging=pom", - "-Dfile=${pomPath.absolutePath}" + *args.toTypedArray() ).start().waitFor() assertThat("POM install was successful", 0 == exitCode) diff --git a/src/test/java/io/openpixee/maven/operator/test/util.kt b/src/test/java/io/openpixee/maven/operator/test/util.kt index cd45fc554..7b8ff9169 100644 --- a/src/test/java/io/openpixee/maven/operator/test/util.kt +++ b/src/test/java/io/openpixee/maven/operator/test/util.kt @@ -1,6 +1,8 @@ package io.openpixee.maven.operator.test import io.openpixee.maven.operator.ProjectModel +import io.openpixee.maven.operator.Util.which +import org.apache.commons.lang3.SystemUtils import org.dom4j.Document import org.dom4j.io.SAXReader import java.io.File @@ -20,13 +22,18 @@ internal fun ProjectModel.getEffectivePom(): Document { val tmpOutputFile = File.createTempFile("tmp-pom", ".xml") - val processArgs = mutableListOf( - "mvn", - "-B", - "-N", - "-f", - tmpInputFile.absolutePath, - ) + val processArgs: MutableList = + mutableListOf( + which("mvn")!!.absolutePath, + "-B", + "-N", + "-f", + tmpInputFile.absolutePath, + ) + + if (SystemUtils.IS_OS_WINDOWS) { + processArgs.addAll(0, listOf("cmd.exe", "/c")) + } if (this.activeProfiles.isNotEmpty()) { // TODO Aldrin: How safe is not to escape those things? My concern is that deactivating a profile uses '!', diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-broken.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-broken.xml new file mode 100644 index 000000000..58952de39 --- /dev/null +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-broken.xml @@ -0,0 +1,5 @@ + + + missing + 4.0.0 + \ No newline at end of file From 00bd927459b6109a4ed6d981e4bbdd8a546f0902 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 13 Jan 2023 17:57:41 -0500 Subject: [PATCH 060/153] Fixing corner case of dependency management (#8) * Fixing corner case of dependency management * [no ci] Autogenerated JaCoCo coverage badge * Preparing release * Adding pom stuff Co-authored-by: Jacoco Coverage Update Action --- .github/badges/branches.svg | 2 +- .github/badges/jacoco.svg | 2 +- .github/workflows/publish.yml | 52 +++++++++++++ pom.xml | 73 ++++++++++++++----- .../openpixee/maven/operator/SimpleInsert.kt | 20 +++-- .../maven/operator/test/POMOperatorTest.kt | 38 +++++++++- .../maven/operator/test/sample-bad-pom.xml | 21 ++++++ 7 files changed, 174 insertions(+), 34 deletions(-) create mode 100644 .github/workflows/publish.yml create mode 100644 src/test/resources/io/openpixee/maven/operator/test/sample-bad-pom.xml diff --git a/.github/badges/branches.svg b/.github/badges/branches.svg index 0687eb350..056453360 100644 --- a/.github/badges/branches.svg +++ b/.github/badges/branches.svg @@ -1 +1 @@ -branches73.1% \ No newline at end of file +branches73.9% \ No newline at end of file diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index 78372f5a0..9681820dd 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage90.2% \ No newline at end of file +coverage90.7% \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 000000000..4e825b284 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,52 @@ +name: Create Release on Semantic Version Tag + +on: + push: + tags: + - "v*" + +jobs: + pre-release: + runs-on: "ubuntu-latest" + + steps: + - uses: actions/checkout@v2 + + - name: "Build, test and deploy" + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'adopt' + + - name: "Setting up Artifactory authentication" + uses: s4u/maven-settings-action@v2 + with: + servers: | + [ + {"id": "pixee-libs-release", "username": "${{ secrets.ARTIFACTORY_USER }}", "password": "${{ secrets.ARTIFACTORY_TOKEN }}"}, + {"id": "pixee-libs-snapshot", "username": "${{ secrets.ARTIFACTORY_USER }}", "password": "${{ secrets.ARTIFACTORY_TOKEN }}"} + ] + githubServer: false + + - name: "Publish to Artifactory" + env: + ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} + ARTIFACTORY_TOKEN: ${{ secrets.ARTIFACTORY_TOKEN }} + run: mvn deploy + + - name: Release + uses: qcastel/github-actions-maven-release@master + with: + ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} + env: + JAVA_HOME: /usr/lib/jvm/java-11-openjdk/ +# +# - name: "Create release" +# uses: "marvinpinto/action-automatic-releases@latest" +# with: +# java-version: '11' +# distribution: 'adopt' +# repo_token: "${{ secrets.GITHUB_TOKEN }}" +# prerelease: false +# files: | +# target/pom-operator-*.jar diff --git a/pom.xml b/pom.xml index 5dafd0a02..1a4b1adb2 100644 --- a/pom.xml +++ b/pom.xml @@ -8,14 +8,35 @@ pom-operator 0.0.1-SNAPSHOT + + scm:git:${project.scm.url} + scm:git:${project.scm.url} + git@github.com:openpixee/pom-operator.git + HEAD + + UTF-8 1.8 1.8 1.7.10 2.0.0 + 2.5.3 + + + pixee-libs-release + a0cpnsoovnjqt-artifactory-primary-0-releases + https://pixee.jfrog.io/artifactory/mailman + + + pixee-libs-snapshot + a0cpnsoovnjqt-artifactory-primary-0-snapshots + https://pixee.jfrog.io/artifactory/mailman + + + com.offbytwo @@ -246,32 +267,44 @@ + + maven-release-plugin + ${maven-release-plugin.version} + + [ci skip] + @{project.version} + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + org.jetbrains.kotlin kotlin-maven-plugin - ${kotlin.version} - - - compile - compile - - compile - - - - test-compile - test-compile - - test-compile - - - - - 1.8 - org.apache.maven.plugins diff --git a/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt b/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt index 3e8e5006a..f33260e97 100644 --- a/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt +++ b/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt @@ -10,25 +10,29 @@ import org.dom4j.Element */ val SimpleInsert = object : Command { override fun execute(c: ProjectModel): Boolean { - val dependencyManagementNode = + val dependencyManagementNodeList = c.resultPom.selectXPathNodes("/m:project/m:dependencyManagement") val elementsToFormat: MutableList = arrayListOf() - if (dependencyManagementNode.isEmpty()) { + val dependenciesNode = if (dependencyManagementNodeList.isEmpty()) { val newDependencyManagementNode = c.resultPom.rootElement.addElement("dependencyManagement") - val dependenciesNode = newDependencyManagementNode.addElement("dependencies") + elementsToFormat.add(newDependencyManagementNode) - val dependencyNode = appendCoordinates(dependenciesNode, c) + newDependencyManagementNode.addElement("dependencies") + } else { + (dependencyManagementNodeList.first() as Element).element("dependencies").apply { + elementsToFormat.add(this) + } + } - val versionNode = dependencyNode.addElement("version") + val dependencyNode = appendCoordinates(dependenciesNode, c) - upgradeVersionNode(c, versionNode) + val versionNode = dependencyNode.addElement("version") - elementsToFormat.add(newDependencyManagementNode) - } + upgradeVersionNode(c, versionNode) val dependenciesNodeList = c.resultPom.selectXPathNodes("//m:project/m:dependencies") diff --git a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt index 3286c5f3e..52f4a0671 100644 --- a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt @@ -1,9 +1,6 @@ package io.openpixee.maven.operator.test -import io.openpixee.maven.operator.Dependency -import io.openpixee.maven.operator.MissingDependencyException -import io.openpixee.maven.operator.POMOperator -import io.openpixee.maven.operator.ProjectModelFactory +import io.openpixee.maven.operator.* import io.openpixee.maven.operator.Util.buildLookupExpressionForDependency import io.openpixee.maven.operator.Util.selectXPathNodes import io.openpixee.maven.operator.Util.which @@ -13,11 +10,44 @@ import org.junit.Assert.assertEquals import org.junit.Test import org.xmlunit.diff.ComparisonType import java.io.File +import kotlin.test.assertTrue /** * Unit test for simple App. */ class POMOperatorTest : AbstractTestBase() { + @Test + fun testWithMultipleDependencies() { + val deps = listOf( + "org.slf4j:slf4j-api:1.7.25", + "io.github.pixee:java-code-security-toolkit:0.0.2", + "org.owasp.encoder:encoder:1.2.3", + ).map { Dependency.fromString(it) }.toList() + + val testPom = File.createTempFile("pom", ".xml") + + POMOperatorTest::class.java.getResourceAsStream("sample-bad-pom.xml")!!.copyTo(testPom.outputStream()) + + deps.forEach { d -> + val projectModel = ProjectModelFactory.load(testPom) + .withDependency(d) + .withUseProperties(true) + .build() + + if (POMOperator.modify(projectModel)) { + val resultPomAsXml = projectModel.resultPom.asXML() + + LOGGER.debug("resultPomAsXml: {}", resultPomAsXml) + + testPom.writeText(resultPomAsXml) + } + } + + val resolvedDeps = POMOperator.queryDependency(ProjectModelFactory.load(testPom).withQueryType(QueryType.SAFE).build()) + + assertTrue(3 == resolvedDeps.size, "Must have three dependencies") + } + @Test(expected = MissingDependencyException::class) fun testWithDependencyMissing() { gwt( diff --git a/src/test/resources/io/openpixee/maven/operator/test/sample-bad-pom.xml b/src/test/resources/io/openpixee/maven/operator/test/sample-bad-pom.xml new file mode 100644 index 000000000..467449143 --- /dev/null +++ b/src/test/resources/io/openpixee/maven/operator/test/sample-bad-pom.xml @@ -0,0 +1,21 @@ + + 4.0.0 + + com.acme + testcode + 5.1 + + + + + + + org.slf4j + slf4j-api + 1.7.25 + + + + \ No newline at end of file From 134b02fb9a08ad67102265451e6144fffcf9a9a7 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 13 Jan 2023 18:01:28 -0500 Subject: [PATCH 061/153] Triggering release from master --- .github/workflows/{publish.yml => release.yml} | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) rename .github/workflows/{publish.yml => release.yml} (85%) diff --git a/.github/workflows/publish.yml b/.github/workflows/release.yml similarity index 85% rename from .github/workflows/publish.yml rename to .github/workflows/release.yml index 4e825b284..3deacb910 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/release.yml @@ -2,15 +2,15 @@ name: Create Release on Semantic Version Tag on: push: - tags: - - "v*" + branches: + - master jobs: pre-release: runs-on: "ubuntu-latest" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: "Build, test and deploy" uses: actions/setup-java@v2 @@ -28,6 +28,11 @@ jobs: ] githubServer: false + - name: Build and Test + uses: qcastel/github-actions-maven-cmd@master + with: + maven-args: "clean install -Ddockerfile.skip -DdockerCompose.skip -Djib.skip" + - name: "Publish to Artifactory" env: ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} From 23014c331c4f784615fea4c0fe44271477c88bd7 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 13 Jan 2023 18:05:13 -0500 Subject: [PATCH 062/153] Fixing flow --- .github/workflows/push-test.yml | 5 ++++- .github/workflows/release.yml | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/push-test.yml b/.github/workflows/push-test.yml index bbd82a9ea..eec7f53cc 100644 --- a/.github/workflows/push-test.yml +++ b/.github/workflows/push-test.yml @@ -1,6 +1,9 @@ name: Java CI -on: [push] +on: + push: + branches: + - '!master' jobs: build: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3deacb910..4bd87cf8c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,14 +37,16 @@ jobs: env: ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} ARTIFACTORY_TOKEN: ${{ secrets.ARTIFACTORY_TOKEN }} - run: mvn deploy + run: | + mvn deploy + find /opt/hostedtoolcache/Java_Adopt_jdk -type d - name: Release uses: qcastel/github-actions-maven-release@master with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} env: - JAVA_HOME: /usr/lib/jvm/java-11-openjdk/ + JAVA_HOME: /opt/hostedtoolcache/Java_Adopt_jdk/11.0.17-8/x64 # # - name: "Create release" # uses: "marvinpinto/action-automatic-releases@latest" From 14da7d699d2a86fc883b8dbd9fc1c473602bffc2 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 13 Jan 2023 18:11:19 -0500 Subject: [PATCH 063/153] Fixing flow --- .github/workflows/release.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4bd87cf8c..c73f4a676 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,14 +39,11 @@ jobs: ARTIFACTORY_TOKEN: ${{ secrets.ARTIFACTORY_TOKEN }} run: | mvn deploy - find /opt/hostedtoolcache/Java_Adopt_jdk -type d - name: Release uses: qcastel/github-actions-maven-release@master with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} - env: - JAVA_HOME: /opt/hostedtoolcache/Java_Adopt_jdk/11.0.17-8/x64 # # - name: "Create release" # uses: "marvinpinto/action-automatic-releases@latest" From fa60484cc38717e4376b34268711cb6f56c88c44 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 13 Jan 2023 18:15:49 -0500 Subject: [PATCH 064/153] Fixing flow --- .github/workflows/release.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c73f4a676..9bfac4fe3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,8 @@ jobs: steps: - uses: actions/checkout@v3 - - name: "Build, test and deploy" + - id: setup-java + name: "Build, test and deploy" uses: actions/setup-java@v2 with: java-version: '11' @@ -44,6 +45,8 @@ jobs: uses: qcastel/github-actions-maven-release@master with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} + env: + JAVA_HOME: "${{ steps.setup-java.outputs.path }}" # # - name: "Create release" # uses: "marvinpinto/action-automatic-releases@latest" From dd40b4cacbe0d563c07a01c519ba2d0e66cde2d7 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 13 Jan 2023 18:18:54 -0500 Subject: [PATCH 065/153] Fixing flow --- .github/workflows/release.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9bfac4fe3..16631a77a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,10 +29,14 @@ jobs: ] githubServer: false - - name: Build and Test - uses: qcastel/github-actions-maven-cmd@master + - name: Set up Maven + uses: stCarolas/setup-maven@v4.4 with: - maven-args: "clean install -Ddockerfile.skip -DdockerCompose.skip -Djib.skip" + maven-version: 3.8.2 + + - name: Build with Maven + run: | + mvn -N -B -P integration-testing verify install - name: "Publish to Artifactory" env: From 7ac20286dad00de5be6ef7708d82797d68b464fc Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 13 Jan 2023 18:22:28 -0500 Subject: [PATCH 066/153] Fixing flow --- .github/workflows/release.yml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 16631a77a..dac8d60c8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,26 +38,9 @@ jobs: run: | mvn -N -B -P integration-testing verify install - - name: "Publish to Artifactory" - env: - ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} - ARTIFACTORY_TOKEN: ${{ secrets.ARTIFACTORY_TOKEN }} - run: | - mvn deploy - - name: Release uses: qcastel/github-actions-maven-release@master with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} env: JAVA_HOME: "${{ steps.setup-java.outputs.path }}" -# -# - name: "Create release" -# uses: "marvinpinto/action-automatic-releases@latest" -# with: -# java-version: '11' -# distribution: 'adopt' -# repo_token: "${{ secrets.GITHUB_TOKEN }}" -# prerelease: false -# files: | -# target/pom-operator-*.jar From 85c3bddbe110241d69afd45d2d1d4ea54b2c06f8 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 13 Jan 2023 18:57:49 -0500 Subject: [PATCH 067/153] Releasing --- .github/workflows/push-test.yml | 3 +++ .github/workflows/release.yml | 15 +++++++++------ .gitignore | 1 + 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.github/workflows/push-test.yml b/.github/workflows/push-test.yml index eec7f53cc..b361cc452 100644 --- a/.github/workflows/push-test.yml +++ b/.github/workflows/push-test.yml @@ -5,6 +5,9 @@ on: branches: - '!master' +env: + MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2" + jobs: build: strategy: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dac8d60c8..e5852d543 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,6 +5,9 @@ on: branches: - master +env: + M2_HOME: /opt/hostedtoolcache/maven/3.8.2 + jobs: pre-release: runs-on: "ubuntu-latest" @@ -19,6 +22,11 @@ jobs: java-version: '11' distribution: 'adopt' + - name: Set up Maven + uses: stCarolas/setup-maven@v4.4 + with: + maven-version: 3.8.2 + - name: "Setting up Artifactory authentication" uses: s4u/maven-settings-action@v2 with: @@ -29,14 +37,9 @@ jobs: ] githubServer: false - - name: Set up Maven - uses: stCarolas/setup-maven@v4.4 - with: - maven-version: 3.8.2 - - name: Build with Maven run: | - mvn -N -B -P integration-testing verify install + mvn -N -B install - name: Release uses: qcastel/github-actions-maven-release@master diff --git a/.gitignore b/.gitignore index 1621d5fe2..b8115cd81 100644 --- a/.gitignore +++ b/.gitignore @@ -66,3 +66,4 @@ fabric.properties # Android studio 3.1+ serialized cache file .idea/caches/build_file_checksums.ser +.secrets From 7ee63dfddb5a0d33a053acd9dce1f6afab342cb6 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 13 Jan 2023 19:03:41 -0500 Subject: [PATCH 068/153] Releasing --- .github/workflows/release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e5852d543..1e1347208 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,6 +40,8 @@ jobs: - name: Build with Maven run: | mvn -N -B install + env + echo `which java` - name: Release uses: qcastel/github-actions-maven-release@master From d7453f2b10167c29b788afe8c7389459867fbd81 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 13 Jan 2023 19:08:55 -0500 Subject: [PATCH 069/153] Releasing --- .github/workflows/release.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1e1347208..e09d2ba68 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,6 +7,7 @@ on: env: M2_HOME: /opt/hostedtoolcache/maven/3.8.2 + JAVA_HOME: /opt/hostedtoolcache/Java_Adopt_jdk/11.0.17-8 jobs: pre-release: @@ -47,5 +48,5 @@ jobs: uses: qcastel/github-actions-maven-release@master with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} - env: - JAVA_HOME: "${{ steps.setup-java.outputs.path }}" +# env: +# JAVA_HOME: "${{ steps.setup-java.outputs.path }}" From ecfac000307e8fcec9fd09406cc0d0fa518beb86 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 13 Jan 2023 19:14:45 -0500 Subject: [PATCH 070/153] Releasing --- .github/workflows/release.yml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e09d2ba68..960c57a14 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,13 +40,4 @@ jobs: - name: Build with Maven run: | - mvn -N -B install - env - echo `which java` - - - name: Release - uses: qcastel/github-actions-maven-release@master - with: - ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} -# env: -# JAVA_HOME: "${{ steps.setup-java.outputs.path }}" + mvn -N -B install From c834207b3ffba55449e9d45680d1c2aafd92f932 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 13 Jan 2023 19:19:38 -0500 Subject: [PATCH 071/153] Interim Commit --- pom.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pom.xml b/pom.xml index 1a4b1adb2..b2303feea 100644 --- a/pom.xml +++ b/pom.xml @@ -299,6 +299,17 @@ 1.8 + + org.codehaus.mojo + versions-maven-plugin + 2.14.2 + + false + true + true + false + + @@ -306,6 +317,10 @@ org.jetbrains.kotlin kotlin-maven-plugin + + org.codehaus.mojo + versions-maven-plugin + org.apache.maven.plugins maven-compiler-plugin From 111009c14da5434bcd165d97f1667e66fc4d9829 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 13 Jan 2023 19:23:27 -0500 Subject: [PATCH 072/153] Interim Commit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b2303feea..a6dd60f36 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.openpixee.maven pom-operator - 0.0.1-SNAPSHOT + 0.0.1 scm:git:${project.scm.url} From ab4fa66d6a6699d617da656da65b5713d5814246 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 13 Jan 2023 19:24:06 -0500 Subject: [PATCH 073/153] Adding snapshot --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a6dd60f36..d6ce38660 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.openpixee.maven pom-operator - 0.0.1 + 0.0.2-SNAPSHOT scm:git:${project.scm.url} From 2f76c8b358352cf1cb4a61243ef80526f7f047b2 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 13 Jan 2023 19:25:35 -0500 Subject: [PATCH 074/153] Updating README --- README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 31d90ede1..b11f4b888 100644 --- a/README.md +++ b/README.md @@ -45,10 +45,23 @@ public class POMOperatorJavaTest { It implements a Chain of Responsibility strategy - each `Command` class attempts a different way of fixing a POM, based around a Context (in this case, a `ProjectModel`) +## Releasing + +e.g. to generate version `0.0.2`: + +``` +mvn versions:set -DnewVersion=0.0.2 +mvn clean package source:jar javadoc:jar deploy +git commit -am "Generating Tag" +git tag 0.0.2 +git push && git push --tags +mvn versions:set -DnewVersion=0.0.3-SNAPSHOT +git commit -am "Generating Development Version" +``` # TODO: - ~~better readme~~ - be able to guess existing indenting for existing documents - investigate leverage whats on [versions-maven-plugin](https://github.com/mojohaus/versions-maven-plugin) -- consider fuzzying when testing \ No newline at end of file +- consider fuzzying when testing From c35c7c6a48739262f79dc99a873821bfa82c53bb Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Tue, 21 Feb 2023 15:37:37 -0500 Subject: [PATCH 075/153] Improves XML Formatting (#9) * Improves XML Formatting * Missing code * Adding more tests and improving coverage * Setting version --- pom.xml | 6 +- .../maven/operator/AbstractSimpleCommand.kt | 3 + .../operator/AbstractSimpleQueryCommand.kt | 1 + .../java/io/openpixee/maven/operator/Chain.kt | 29 ++++- .../io/openpixee/maven/operator/Command.kt | 7 +- .../maven/operator/DiscardFormatCommand.kt | 31 +++++ .../openpixee/maven/operator/FormatCommand.kt | 111 ++++++++++++++++++ .../openpixee/maven/operator/POMOperator.kt | 15 ++- .../openpixee/maven/operator/ProjectModel.kt | 9 +- .../maven/operator/ProjectModelFactory.kt | 16 ++- .../io/openpixee/maven/operator/QueryType.kt | 1 + .../openpixee/maven/operator/SimpleInsert.kt | 2 + .../maven/operator/SupportCommand.kt | 7 ++ .../operator/test/POMOperatorQueryTest.kt | 2 +- .../maven/operator/test/POMOperatorTest.kt | 36 +++++- .../io/openpixee/maven/operator/test/util.kt | 2 +- .../maven/operator/test/broken-pom.xml | 3 + .../maven/operator/test/pom-case-1.xml | 1 - .../maven/operator/test/sample-bad-pom.xml | 2 + 19 files changed, 260 insertions(+), 24 deletions(-) create mode 100644 src/main/java/io/openpixee/maven/operator/DiscardFormatCommand.kt create mode 100644 src/main/java/io/openpixee/maven/operator/FormatCommand.kt create mode 100644 src/main/java/io/openpixee/maven/operator/SupportCommand.kt create mode 100644 src/test/resources/io/openpixee/maven/operator/test/broken-pom.xml diff --git a/pom.xml b/pom.xml index d6ce38660..b4823569a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.openpixee.maven pom-operator - 0.0.2-SNAPSHOT + 0.0.2 scm:git:${project.scm.url} @@ -91,13 +91,13 @@ org.xmlunit xmlunit-core 2.9.0 - test + compile org.xmlunit xmlunit-assertj3 2.9.0 - test + compile org.hamcrest diff --git a/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt b/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt index d47e3f0de..bf62992a3 100644 --- a/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt +++ b/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt @@ -38,4 +38,7 @@ abstract class AbstractSimpleCommand : Command { return false } + override fun execute(c: ProjectModel): Boolean = false + + override fun postProcess(c: ProjectModel): Boolean = false } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/AbstractSimpleQueryCommand.kt b/src/main/java/io/openpixee/maven/operator/AbstractSimpleQueryCommand.kt index cf7a22e9f..15e996bea 100644 --- a/src/main/java/io/openpixee/maven/operator/AbstractSimpleQueryCommand.kt +++ b/src/main/java/io/openpixee/maven/operator/AbstractSimpleQueryCommand.kt @@ -196,4 +196,5 @@ abstract class AbstractSimpleQueryCommand : AbstractSimpleCommand() { val LOGGER: Logger = LoggerFactory.getLogger(AbstractSimpleQueryCommand::class.java) } + override fun postProcess(c: ProjectModel): Boolean = false } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/Chain.kt b/src/main/java/io/openpixee/maven/operator/Chain.kt index e41624297..6217ffac6 100644 --- a/src/main/java/io/openpixee/maven/operator/Chain.kt +++ b/src/main/java/io/openpixee/maven/operator/Chain.kt @@ -12,7 +12,7 @@ class Chain(vararg commands: Command) { /** * Internal ArrayList of the Commands */ - internal val commandList : MutableList = ArrayList(commands.toList()) + internal val commandList: MutableList = ArrayList(commands.toList()) /** * Executes the Commands in the Chain of Responsibility @@ -28,9 +28,32 @@ class Chain(vararg commands: Command) { val nextCommand = listIterator.next() done = nextCommand.execute(c) + + if (done) { + if (c.queryType == QueryType.NONE && (!(nextCommand is SupportCommand))) { + c.modifiedByCommand = true + } + + break + } + } + + val result = done + + /** + * Goes Reverse Order applying the filter pattern + */ + + while (listIterator.previousIndex() > 0) { + val nextCommand = listIterator.previous() + + done = nextCommand.postProcess(c) + + if (done) + break } - return done + return result } companion object { @@ -50,7 +73,7 @@ class Chain(vararg commands: Command) { * Returns a Pre-Configured Chain with the Defaults for Modifying a POM */ fun createForModify() = - Chain(CheckDependencyPresent, SimpleUpgrade, SimpleDependencyManagement, SimpleInsert) + Chain(CheckDependencyPresent, FormatCommand(), DiscardFormatCommand(), SimpleUpgrade, SimpleDependencyManagement, SimpleInsert) /** * returns a pre-configured chain with the defaults for Querying diff --git a/src/main/java/io/openpixee/maven/operator/Command.kt b/src/main/java/io/openpixee/maven/operator/Command.kt index c0423c48d..64aa5359e 100644 --- a/src/main/java/io/openpixee/maven/operator/Command.kt +++ b/src/main/java/io/openpixee/maven/operator/Command.kt @@ -3,7 +3,7 @@ package io.openpixee.maven.operator /** * Represents a Command in a Chain of Responsibility Pattern */ -fun interface Command { +interface Command { /** * Given a context, performs an operation * @@ -11,4 +11,9 @@ fun interface Command { * @return true if the execution was successful *AND* the chain must end */ fun execute(c: ProjectModel): Boolean + + /** + * Post Processing, implementing a Filter Pattern + */ + fun postProcess(c: ProjectModel): Boolean } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/DiscardFormatCommand.kt b/src/main/java/io/openpixee/maven/operator/DiscardFormatCommand.kt new file mode 100644 index 000000000..943b729cc --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/DiscardFormatCommand.kt @@ -0,0 +1,31 @@ +package io.openpixee.maven.operator + +import org.xmlunit.builder.DiffBuilder +import org.xmlunit.builder.Input + +/** + * Command Class to Short-Circuit/Discard Processing when no pom changes were made + */ +class DiscardFormatCommand : AbstractSimpleCommand() { + override fun postProcess(c: ProjectModel): Boolean { + val originalDoc = Input.fromString(String(c.originalPom)).build() + val modifiedDoc = Input.fromString(c.resultPom.asXML()).build() + + val diff = DiffBuilder.compare(originalDoc).withTest(modifiedDoc) + .ignoreWhitespace() + .ignoreComments() + .ignoreElementContentWhitespace() + .checkForSimilar() + .build() + + val hasDifferences = diff.hasDifferences() + + if (! (c.modifiedByCommand || hasDifferences)) { + c.resultPomBytes = c.originalPom + + return true + } + + return super.postProcess(c) + } +} \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/FormatCommand.kt b/src/main/java/io/openpixee/maven/operator/FormatCommand.kt new file mode 100644 index 000000000..ed2f89ebc --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/FormatCommand.kt @@ -0,0 +1,111 @@ +package io.openpixee.maven.operator + +import org.dom4j.io.OutputFormat +import org.dom4j.io.SAXWriter +import org.dom4j.io.XMLWriter +import java.lang.IllegalStateException +import java.nio.charset.Charset +import javax.xml.stream.XMLInputFactory +import javax.xml.stream.events.StartDocument +import javax.xml.stream.events.StartElement + +/** + * This Command handles Formatting - particularly storing the original document preamble (the Processing Instruction and the first XML Element contents), + * which are the only ones which are tricky to format (due to element and its attributes being freeform - thus formatting lost when serializing the DOM + * and the PI being completely optional for the POM Document) + */ +class FormatCommand : AbstractSimpleCommand() { + /** + * Since the PI is Optional, we can actually leverage and store its charset to facilitate rendering when needed + */ + private var charset: Charset = Charset.defaultCharset() + + /** + * Preamble Contents are stored here + */ + private var preamble: String = "" + + override fun execute(c: ProjectModel): Boolean { + /** + * Performs a StAX Parsing to Grab the first element + */ + val inputFactory = XMLInputFactory.newInstance() + val eventReader = inputFactory.createXMLEventReader(c.originalPom.inputStream()) + + while (true) { + val event = eventReader.nextEvent() + + if (event.isStartDocument && (event as StartDocument).encodingSet()) { + /** + * Processing Instruction Found - Store its Character Encoding + */ + this.charset = Charset.forName((event as StartDocument).characterEncodingScheme) + } else if (event.isStartElement) { + /** + * First Element ("Tag") found - store its offset + */ + val startElementEvent = (event as StartElement) + + var offset = startElementEvent.location.characterOffset + + preamble = c.originalPom.toString(this.charset).substring(0, offset) + + break + } + + if (! eventReader.hasNext()) + throw IllegalStateException("Couldn't find document start") + } + + return super.execute(c) + } + + /** + * When doing the opposite, render the XML using the optionally supplied encoding (defaults to UTF8 obviously) + * but apply the original formatting as well + */ + override fun postProcess(c: ProjectModel): Boolean { + val writer = SAXWriter() + + var xmlRepresentation = c.resultPom.asXML() + + /** + * We might need to replace the beginning of the POM with the same content + * from the very beginning + * + * Grab the same initial offset from the formatted element like we did + */ + val inputFactory = XMLInputFactory.newInstance() + val eventReader = inputFactory.createXMLEventReader(xmlRepresentation.toByteArray(this.charset).inputStream()) + + while (true) { + val event = eventReader.nextEvent() + + if (event.isStartElement) { + /** + * Apply the formatting and tweak its XML Representation + */ + val startElementEvent = (event as StartElement) + + var offset = startElementEvent.location.characterOffset + + xmlRepresentation = this.preamble + xmlRepresentation.substring(offset) + + break + } + + /** + * This code shouldn't be unreachable at all + */ + if (! eventReader.hasNext()) + throw IllegalStateException("Couldn't find document start") + } + + /** + * Serializes it back + */ + c.resultPomBytes = xmlRepresentation.toByteArray(this.charset) + + return super.postProcess(c) + } +} \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/POMOperator.kt b/src/main/java/io/openpixee/maven/operator/POMOperator.kt index b2a28b86c..b601cd919 100644 --- a/src/main/java/io/openpixee/maven/operator/POMOperator.kt +++ b/src/main/java/io/openpixee/maven/operator/POMOperator.kt @@ -13,17 +13,26 @@ object POMOperator { @JvmStatic fun modify(projectModel: ProjectModel) = Chain.createForModify().execute(projectModel) + /** + * Public API - Query for all the artifacts referenced inside a POM File + * + * @param projectModel Project Model (Context) Class + */ + @JvmStatic + fun queryDependency( + projectModel: ProjectModel + ) = POMOperator.queryDependency(projectModel, emptyList()) /** - * Query for all the artifacts mentioned on a POM + * Internal Use (package-wide) - Query for all the artifacts mentioned on a POM * * @param projectModel Project Model (Context) class * @param commandList do not use (required for tests) */ @JvmStatic - fun queryDependency( + internal fun queryDependency( projectModel: ProjectModel, - commandList: List = emptyList() + commandList: List ): Collection { val chain = Chain.createForQuery(projectModel.queryType) diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt index 43a8b3bd1..8caf177b2 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt @@ -11,6 +11,7 @@ import java.net.URL * @todo consider resolution and also Topological Sort of Properties for cross-property reference */ class ProjectModel internal constructor( + val originalPom : ByteArray, val pomPath: URL?, val pomDocument: Document, var dependency: Dependency?, @@ -18,9 +19,13 @@ class ProjectModel internal constructor( val useProperties: Boolean, val activeProfiles: Set, val overrideIfAlreadyExists: Boolean, - val queryType: QueryType = QueryType.SAFE, + val queryType: QueryType = QueryType.NONE, ) { - val resultPom: Document = pomDocument.clone() as Document + internal var modifiedByCommand = false + + var resultPomBytes: ByteArray = byteArrayOf() + + internal val resultPom: Document = pomDocument.clone() as Document val resolvedProperties: Map = run { diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt index 55a9d2fec..5d66395e1 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt @@ -1,7 +1,9 @@ package io.openpixee.maven.operator +import org.apache.commons.io.IOUtils import org.dom4j.Document import org.dom4j.io.SAXReader +import java.io.ByteArrayInputStream import java.io.File import java.io.InputStream import java.net.URL @@ -10,6 +12,7 @@ import java.net.URL * Builder Object for ProjectModel instances */ class ProjectModelFactory private constructor( + private val originalPom: ByteArray, private var pomPath: URL?, private var pomDocument: Document, private var dependency: Dependency? = null, @@ -78,6 +81,7 @@ class ProjectModelFactory private constructor( */ fun build(): ProjectModel { return ProjectModel( + originalPom = originalPom, pomPath = pomPath, pomDocument = pomDocument, dependency = dependency, @@ -92,9 +96,11 @@ class ProjectModelFactory private constructor( companion object { @JvmStatic fun load(`is`: InputStream): ProjectModelFactory { - val pomDocument = SAXReader().read(`is`)!! + val originalPom: ByteArray = IOUtils.toByteArray(`is`) - return ProjectModelFactory(pomPath = null, pomDocument = pomDocument) + val pomDocument = SAXReader().read(originalPom.inputStream())!! + + return ProjectModelFactory(pomPath = null, pomDocument = pomDocument, originalPom = originalPom) } @JvmStatic @@ -103,9 +109,11 @@ class ProjectModelFactory private constructor( @JvmStatic fun load(url: URL): ProjectModelFactory { - val pomDocument = SAXReader().read(url.openStream()) + val originalPom: ByteArray = IOUtils.toByteArray(url.openStream()) + + val pomDocument = SAXReader().read(originalPom.inputStream()) - return ProjectModelFactory(pomPath = url, pomDocument = pomDocument) + return ProjectModelFactory(pomPath = url, pomDocument = pomDocument, originalPom = originalPom) } } } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/QueryType.kt b/src/main/java/io/openpixee/maven/operator/QueryType.kt index 1f84f546a..37de6e8c3 100644 --- a/src/main/java/io/openpixee/maven/operator/QueryType.kt +++ b/src/main/java/io/openpixee/maven/operator/QueryType.kt @@ -1,6 +1,7 @@ package io.openpixee.maven.operator enum class QueryType { + NONE, SAFE, UNSAFE, } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt b/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt index f33260e97..ce3587d5f 100644 --- a/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt +++ b/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt @@ -74,4 +74,6 @@ val SimpleInsert = object : Command { return dependencyNode } + + override fun postProcess(c: ProjectModel): Boolean = false } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/SupportCommand.kt b/src/main/java/io/openpixee/maven/operator/SupportCommand.kt new file mode 100644 index 000000000..a4f2de191 --- /dev/null +++ b/src/main/java/io/openpixee/maven/operator/SupportCommand.kt @@ -0,0 +1,7 @@ +package io.openpixee.maven.operator + +/** + * Tag Interface to the chain to allow it to figure out whether things were modified + */ +interface SupportCommand { +} \ No newline at end of file diff --git a/src/test/java/io/openpixee/maven/operator/test/POMOperatorQueryTest.kt b/src/test/java/io/openpixee/maven/operator/test/POMOperatorQueryTest.kt index b2df0b54e..e1185c72a 100644 --- a/src/test/java/io/openpixee/maven/operator/test/POMOperatorQueryTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/POMOperatorQueryTest.kt @@ -11,7 +11,7 @@ class POMOperatorQueryTest { @Test fun testBasicQuery() { - QueryType.values().forEach { queryType -> + QueryType.values().filterNot { it == QueryType.NONE } .forEach { queryType -> val context = ProjectModelFactory .load(this.javaClass.getResource("pom-1.xml")!!) diff --git a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt index 52f4a0671..834145381 100644 --- a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt @@ -5,17 +5,30 @@ import io.openpixee.maven.operator.Util.buildLookupExpressionForDependency import io.openpixee.maven.operator.Util.selectXPathNodes import io.openpixee.maven.operator.Util.which import org.apache.commons.lang3.SystemUtils +import org.dom4j.DocumentException import org.hamcrest.MatcherAssert.assertThat import org.junit.Assert.assertEquals import org.junit.Test import org.xmlunit.diff.ComparisonType import java.io.File +import kotlin.test.assertFails +import kotlin.test.assertFailsWith import kotlin.test.assertTrue /** * Unit test for simple App. */ class POMOperatorTest : AbstractTestBase() { + @Test(expected = DocumentException::class) + fun testWithBrokenPom() { + val context = gwt( + "broken-pom", + ProjectModelFactory.load( + POMOperatorTest::class.java.getResource("broken-pom.xml")!!, + ).withDependency(Dependency.fromString("org.dom4j:dom4j:2.0.3")) + ) + } + @Test fun testWithMultipleDependencies() { val deps = listOf( @@ -26,26 +39,39 @@ class POMOperatorTest : AbstractTestBase() { val testPom = File.createTempFile("pom", ".xml") - POMOperatorTest::class.java.getResourceAsStream("sample-bad-pom.xml")!!.copyTo(testPom.outputStream()) + POMOperatorTest::class.java.getResourceAsStream("sample-bad-pom.xml")!! + .copyTo(testPom.outputStream()) deps.forEach { d -> val projectModel = ProjectModelFactory.load(testPom) .withDependency(d) .withUseProperties(true) + .withOverrideIfAlreadyExists(true) .build() if (POMOperator.modify(projectModel)) { - val resultPomAsXml = projectModel.resultPom.asXML() + val resultPomAsXml = String(projectModel.resultPomBytes) LOGGER.debug("resultPomAsXml: {}", resultPomAsXml) - testPom.writeText(resultPomAsXml) + testPom.writeBytes(projectModel.resultPomBytes) + } else { + throw IllegalStateException("Code that shouldn't be reached out at all") } } - val resolvedDeps = POMOperator.queryDependency(ProjectModelFactory.load(testPom).withQueryType(QueryType.SAFE).build()) + val resolvedDeps = POMOperator.queryDependency( + ProjectModelFactory.load(testPom).withQueryType(QueryType.SAFE).build() + ) + + val testPomContents = testPom.readText() assertTrue(3 == resolvedDeps.size, "Must have three dependencies") + assertTrue(testPomContents.contains(" + 4.0.0 com.acme From 6d67e8202f1cf9aa7987f55fa826023aea754f75 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Tue, 21 Feb 2023 15:52:59 -0500 Subject: [PATCH 076/153] Generating new dev version --- README.md | 6 ++++++ pom.xml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b11f4b888..3ebd8dd67 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,12 @@ git commit -am "Generating Development Version" # TODO: +Deploying: + +``` +mvn -N -B deploy -DaltDeploymentRepository=pixee-libs-release::default::https://pixee.jfrog.io/artifactory/default-maven-local +``` + - ~~better readme~~ - be able to guess existing indenting for existing documents - investigate leverage whats on [versions-maven-plugin](https://github.com/mojohaus/versions-maven-plugin) diff --git a/pom.xml b/pom.xml index b4823569a..898c58489 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.openpixee.maven pom-operator - 0.0.2 + 0.0.3-SNAPSHOT scm:git:${project.scm.url} From a4e0f33f9ef1881e3b828b1d70688d46b34baa80 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Thu, 2 Mar 2023 14:07:08 -0500 Subject: [PATCH 077/153] Improving Formatting, Take 3 (#10) * Improving Formatting * Fixing syntax to enable workflow * Code Updates * Fixing bugs * Indent, Charset and improved formatting * Indenting on props * Reformatting test cases * Updating build * [no ci] Autogenerated JaCoCo coverage badge * cleanup * Generating Tag --------- Co-authored-by: Jacoco Coverage Update Action --- .github/badges/branches.svg | 2 +- .github/badges/jacoco.svg | 2 +- .github/workflows/push-test.yml | 5 +- README.md | 2 +- java-sample/pom.xml | 4 +- pom.xml | 7 +- .../java/io/openpixee/maven/operator/Chain.kt | 1 + .../openpixee/maven/operator/FormatCommand.kt | 156 +++++++- .../openpixee/maven/operator/ProjectModel.kt | 6 + .../maven/operator/ProjectModelFactory.kt | 8 +- .../maven/operator/QueryByResolver.kt | 1 + .../openpixee/maven/operator/SimpleInsert.kt | 36 +- .../java/io/openpixee/maven/operator/Util.kt | 94 ++--- .../maven/operator/test/AbstractTestBase.kt | 2 +- .../maven/operator/test/MassRepoTest.kt | 17 +- .../maven/operator/test/pom-case-1-result.xml | 31 +- .../maven/operator/test/pom-case-3-result.xml | 7 +- .../maven/operator/test/pom-case-4-result.xml | 369 +++++++++--------- .../test/pom-case-with-property-result.xml | 11 +- ...m-case-three-with-lower-version-result.xml | 7 +- 20 files changed, 447 insertions(+), 321 deletions(-) diff --git a/.github/badges/branches.svg b/.github/badges/branches.svg index 056453360..1b3574ecc 100644 --- a/.github/badges/branches.svg +++ b/.github/badges/branches.svg @@ -1 +1 @@ -branches73.9% \ No newline at end of file +branches73.6% \ No newline at end of file diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index 9681820dd..58cb94897 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage90.7% \ No newline at end of file +coverage91.6% \ No newline at end of file diff --git a/.github/workflows/push-test.yml b/.github/workflows/push-test.yml index b361cc452..078cafe8c 100644 --- a/.github/workflows/push-test.yml +++ b/.github/workflows/push-test.yml @@ -2,8 +2,8 @@ name: Java CI on: push: - branches: - - '!master' + branches-ignore: + - 'master' env: MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2" @@ -43,6 +43,7 @@ jobs: - name: Integration Testing (Linux Only) if: matrix.platform == 'ubuntu-latest' run: | + mvn -N -B -Dmaven.test.skip install mvn -N -B -P integration-testing verify - name: Generate Coverage Badge id: jacoco diff --git a/README.md b/README.md index 3ebd8dd67..e5c025e74 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ mvn clean package source:jar javadoc:jar deploy git commit -am "Generating Tag" git tag 0.0.2 git push && git push --tags -mvn versions:set -DnewVersion=0.0.3-SNAPSHOT +V=0.0.3 mvn versions:set -DnewVersion=0.0.3-SNAPSHOT && (cd java-sample ; mvn versions:set -DnewVersion=0.0.3-SNAPSHOT) git commit -am "Generating Development Version" ``` diff --git a/java-sample/pom.xml b/java-sample/pom.xml index 7844749ca..0522b7e96 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.openpixee.pom java-sample - 0.0.1-SNAPSHOT + 0.0.3-SNAPSHOT UTF-8 @@ -19,7 +19,7 @@ io.openpixee.maven pom-operator - 0.0.1-SNAPSHOT + ${project.version} org.slf4j diff --git a/pom.xml b/pom.xml index 898c58489..6abc30aa0 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.openpixee.maven pom-operator - 0.0.3-SNAPSHOT + 0.0.3 scm:git:${project.scm.url} @@ -205,6 +205,11 @@ 3.8.6 provided + + com.github.albfernandez + juniversalchardet + 2.4.0 + diff --git a/src/main/java/io/openpixee/maven/operator/Chain.kt b/src/main/java/io/openpixee/maven/operator/Chain.kt index 6217ffac6..d1716b5de 100644 --- a/src/main/java/io/openpixee/maven/operator/Chain.kt +++ b/src/main/java/io/openpixee/maven/operator/Chain.kt @@ -84,6 +84,7 @@ class Chain(vararg commands: Command) { val commandClassName = "io.openpixee.maven.operator.${it.second}" try { + @Suppress("DEPRECATION") Class.forName(commandClassName).newInstance() as Command } catch (e: Throwable) { LOGGER.warn("Creating class '{}': ", commandClassName, e) diff --git a/src/main/java/io/openpixee/maven/operator/FormatCommand.kt b/src/main/java/io/openpixee/maven/operator/FormatCommand.kt index ed2f89ebc..8dff86a8e 100644 --- a/src/main/java/io/openpixee/maven/operator/FormatCommand.kt +++ b/src/main/java/io/openpixee/maven/operator/FormatCommand.kt @@ -1,11 +1,14 @@ package io.openpixee.maven.operator -import org.dom4j.io.OutputFormat -import org.dom4j.io.SAXWriter -import org.dom4j.io.XMLWriter -import java.lang.IllegalStateException +import org.apache.commons.lang3.StringUtils +import org.dom4j.Comment +import org.dom4j.Element +import org.dom4j.Text +import org.dom4j.VisitorSupport +import org.mozilla.universalchardet.UniversalDetector import java.nio.charset.Charset import javax.xml.stream.XMLInputFactory +import javax.xml.stream.events.Characters import javax.xml.stream.events.StartDocument import javax.xml.stream.events.StartElement @@ -16,22 +19,115 @@ import javax.xml.stream.events.StartElement */ class FormatCommand : AbstractSimpleCommand() { /** - * Since the PI is Optional, we can actually leverage and store its charset to facilitate rendering when needed + * Preamble Contents are stored here */ - private var charset: Charset = Charset.defaultCharset() + private var preamble: String = "" /** - * Preamble Contents are stored here + * Afterword - if needed */ - private var preamble: String = "" + private var suffix: String = "" + + /** + * StAX InputFactory + */ + private val inputFactory = XMLInputFactory.newInstance() override fun execute(c: ProjectModel): Boolean { + storeOriginalElements(c) + + parseXmlAndCharset(c) + + parseLineEndings(c) + + c.endl = parseLineEndings(c) + c.indent = guessIndent(c) + + return super.execute(c) + } + + private fun storeOriginalElements(c: ProjectModel) { + val elementSet : MutableSet = mutableSetOf() + + c.resultPom.accept(object : VisitorSupport() { + override fun visit(node: Element?) { + elementSet.add(System.identityHashCode(node!!)) + + super.visit(node) + } + + override fun visit(node: Comment?) { + elementSet.add(System.identityHashCode(node!!)) + + super.visit(node) + } + + override fun visit(node: Text?) { + elementSet.add(System.identityHashCode(node!!)) + + super.visit(node) + } + }) + + c.originalElements = elementSet.toSet() + } + + private fun guessIndent(c: ProjectModel): String { + val eventReader = inputFactory.createXMLEventReader(c.originalPom.inputStream()) + + val indent = " " + val freqMap: MutableMap = mutableMapOf() + + /** + * Parse, while grabbing whitespace sequences and counting + */ + while (eventReader.hasNext()) { + val event = eventReader.nextEvent() + + if (event is Characters) { + if (StringUtils.isWhitespace(event.asCharacters().data)) { + val patterns = event.asCharacters().data.split(*LINE_ENDINGS.toTypedArray()) + + /** + * Updates space frequencies + */ + patterns + .filter { it.length != 0 } + .filter { StringUtils.isAllBlank(it) } + .map { it to it.length } + .forEach { + freqMap.merge(it.second, 1) { a, b -> a + b} + } + } + } + } + + val indentLength = freqMap.entries.minBy { it.key }.key + + return StringUtils.repeat(indent, indentLength) + } + + private fun parseLineEndings(c: ProjectModel): String { + val str = String(c.originalPom.inputStream().readBytes(), c.charset) + + return LINE_ENDINGS + .map { it to str.split(it).size } + .toMap() + .maxBy { it.value } + .key + } + + private fun parseXmlAndCharset(c: ProjectModel) { /** * Performs a StAX Parsing to Grab the first element */ - val inputFactory = XMLInputFactory.newInstance() val eventReader = inputFactory.createXMLEventReader(c.originalPom.inputStream()) + var charset: Charset? = null + + /** + * Parse, while grabbing its preamble and encoding + */ while (true) { val event = eventReader.nextEvent() @@ -39,25 +135,38 @@ class FormatCommand : AbstractSimpleCommand() { /** * Processing Instruction Found - Store its Character Encoding */ - this.charset = Charset.forName((event as StartDocument).characterEncodingScheme) + charset = Charset.forName(event.characterEncodingScheme) } else if (event.isStartElement) { /** * First Element ("Tag") found - store its offset */ val startElementEvent = (event as StartElement) - var offset = startElementEvent.location.characterOffset + val offset = startElementEvent.location.characterOffset - preamble = c.originalPom.toString(this.charset).substring(0, offset) + preamble = c.originalPom.toString(c.charset).substring(0, offset) break } - if (! eventReader.hasNext()) + if (!eventReader.hasNext()) throw IllegalStateException("Couldn't find document start") } - return super.execute(c) + if (null == charset) { + val detectedCharsetName = UniversalDetector.detectCharset(c.originalPom.inputStream()) + + charset = Charset.forName(detectedCharsetName) + } + + c.charset = charset!! + + val lastLine = String(c.originalPom, c.charset) + + val lastLineTrimmed = lastLine.trimEnd() + + this.suffix = lastLine.substring(lastLineTrimmed.length) + } /** @@ -65,8 +174,6 @@ class FormatCommand : AbstractSimpleCommand() { * but apply the original formatting as well */ override fun postProcess(c: ProjectModel): Boolean { - val writer = SAXWriter() - var xmlRepresentation = c.resultPom.asXML() /** @@ -76,7 +183,9 @@ class FormatCommand : AbstractSimpleCommand() { * Grab the same initial offset from the formatted element like we did */ val inputFactory = XMLInputFactory.newInstance() - val eventReader = inputFactory.createXMLEventReader(xmlRepresentation.toByteArray(this.charset).inputStream()) + val eventReader = inputFactory.createXMLEventReader( + xmlRepresentation.toByteArray(c.charset).inputStream() + ) while (true) { val event = eventReader.nextEvent() @@ -87,9 +196,10 @@ class FormatCommand : AbstractSimpleCommand() { */ val startElementEvent = (event as StartElement) - var offset = startElementEvent.location.characterOffset + val offset = startElementEvent.location.characterOffset - xmlRepresentation = this.preamble + xmlRepresentation.substring(offset) + xmlRepresentation = + this.preamble + xmlRepresentation.substring(offset) + this.suffix break } @@ -97,15 +207,19 @@ class FormatCommand : AbstractSimpleCommand() { /** * This code shouldn't be unreachable at all */ - if (! eventReader.hasNext()) + if (!eventReader.hasNext()) throw IllegalStateException("Couldn't find document start") } /** * Serializes it back */ - c.resultPomBytes = xmlRepresentation.toByteArray(this.charset) + c.resultPomBytes = xmlRepresentation.toByteArray(c.charset) return super.postProcess(c) } + + companion object { + val LINE_ENDINGS = setOf("\r\n", "\n", "\r") + } } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt index 8caf177b2..e537a25fe 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt @@ -4,6 +4,7 @@ import io.openpixee.maven.operator.Util.selectXPathNodes import org.dom4j.Document import org.dom4j.Element import java.net.URL +import java.nio.charset.Charset /** * ProjectModel represents the input parameters for the chain @@ -20,6 +21,11 @@ class ProjectModel internal constructor( val activeProfiles: Set, val overrideIfAlreadyExists: Boolean, val queryType: QueryType = QueryType.NONE, + + var charset: Charset, + var endl: String, + var indent: String, + var originalElements : Set, ) { internal var modifiedByCommand = false diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt index 5d66395e1..a7eb3bd86 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt @@ -3,10 +3,10 @@ package io.openpixee.maven.operator import org.apache.commons.io.IOUtils import org.dom4j.Document import org.dom4j.io.SAXReader -import java.io.ByteArrayInputStream import java.io.File import java.io.InputStream import java.net.URL +import java.nio.charset.Charset /** * Builder Object for ProjectModel instances @@ -20,7 +20,7 @@ class ProjectModelFactory private constructor( private var useProperties: Boolean = false, private var activeProfiles: Set = emptySet(), private var overrideIfAlreadyExists: Boolean = false, - private var queryType: QueryType = QueryType.SAFE, + private var queryType: QueryType = QueryType.NONE, ) { /** * Fluent Setter @@ -90,6 +90,10 @@ class ProjectModelFactory private constructor( activeProfiles = activeProfiles, overrideIfAlreadyExists = overrideIfAlreadyExists, queryType = queryType, + charset = Charset.defaultCharset(), + endl = "", + indent = "", + originalElements = emptySet(), ) } diff --git a/src/main/java/io/openpixee/maven/operator/QueryByResolver.kt b/src/main/java/io/openpixee/maven/operator/QueryByResolver.kt index 63a3408d3..283fe4863 100644 --- a/src/main/java/io/openpixee/maven/operator/QueryByResolver.kt +++ b/src/main/java/io/openpixee/maven/operator/QueryByResolver.kt @@ -54,6 +54,7 @@ class QueryByResolver : AbstractSimpleQueryCommand() { TODO("Not yet implemented") } + @Suppress("DEPRECATION") override fun execute(c: ProjectModel): Boolean { /* * Aether's components implement org.eclipse.aether.spi.locator.Service to ease manual wiring and using the diff --git a/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt b/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt index ce3587d5f..b0ac9a859 100644 --- a/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt +++ b/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt @@ -1,9 +1,13 @@ package io.openpixee.maven.operator -import io.openpixee.maven.operator.Util.formatNode +import io.openpixee.maven.operator.Util.addIndentedElement +import io.openpixee.maven.operator.Util.findIndentLevel import io.openpixee.maven.operator.Util.selectXPathNodes import io.openpixee.maven.operator.Util.upgradeVersionNode +import org.apache.commons.lang3.StringUtils import org.dom4j.Element +import org.dom4j.Text +import org.dom4j.tree.DefaultText /** * Represents a POM Upgrade Strategy by simply adding a dependency/ section (and optionally a dependencyManagement/ section as well) @@ -13,43 +17,36 @@ val SimpleInsert = object : Command { val dependencyManagementNodeList = c.resultPom.selectXPathNodes("/m:project/m:dependencyManagement") - val elementsToFormat: MutableList = arrayListOf() - val dependenciesNode = if (dependencyManagementNodeList.isEmpty()) { val newDependencyManagementNode = - c.resultPom.rootElement.addElement("dependencyManagement") + c.resultPom.rootElement.addIndentedElement(c, "dependencyManagement") - elementsToFormat.add(newDependencyManagementNode) + val dependencyManagementNode = + newDependencyManagementNode.addIndentedElement(c, "dependencies") - newDependencyManagementNode.addElement("dependencies") + dependencyManagementNode } else { - (dependencyManagementNodeList.first() as Element).element("dependencies").apply { - elementsToFormat.add(this) - } + (dependencyManagementNodeList.first() as Element).element("dependencies") } val dependencyNode = appendCoordinates(dependenciesNode, c) - val versionNode = dependencyNode.addElement("version") + val versionNode = dependencyNode.addIndentedElement(c, "version") upgradeVersionNode(c, versionNode) val dependenciesNodeList = c.resultPom.selectXPathNodes("//m:project/m:dependencies") val rootDependencyNode: Element = if (dependenciesNodeList.isEmpty()) { - c.resultPom.rootElement.addElement("dependencies") + c.resultPom.rootElement.addIndentedElement(c, "dependencies") } else if (dependenciesNodeList.size == 1) { dependenciesNodeList[0] as Element } else { throw IllegalStateException("More than one dependencies node") } - elementsToFormat.add(rootDependencyNode) - appendCoordinates(rootDependencyNode, c) - elementsToFormat.forEach { formatNode(it) } - return true } @@ -60,15 +57,15 @@ val SimpleInsert = object : Command { dependenciesNode: Element, c: ProjectModel ): Element { - val dependencyNode = dependenciesNode.addElement("dependency") + val dependencyNode = dependenciesNode.addIndentedElement(c, "dependency") - val groupIdNode = dependencyNode.addElement("groupId") + val groupIdNode = dependencyNode.addIndentedElement(c, "groupId") val dep = c.dependency!! groupIdNode.text = dep.groupId - val artifactIdNode = dependencyNode.addElement("artifactId") + val artifactIdNode = dependencyNode.addIndentedElement(c, "artifactId") artifactIdNode.text = dep.artifactId @@ -76,4 +73,5 @@ val SimpleInsert = object : Command { } override fun postProcess(c: ProjectModel): Boolean = false -} \ No newline at end of file +} + diff --git a/src/main/java/io/openpixee/maven/operator/Util.kt b/src/main/java/io/openpixee/maven/operator/Util.kt index b7624561e..c8077a1f0 100644 --- a/src/main/java/io/openpixee/maven/operator/Util.kt +++ b/src/main/java/io/openpixee/maven/operator/Util.kt @@ -9,100 +9,92 @@ import org.apache.commons.lang3.text.StrSubstitutor import org.dom4j.Element import org.dom4j.Node import org.dom4j.Text -import org.dom4j.io.OutputFormat -import org.dom4j.io.SAXReader -import org.dom4j.io.XMLWriter import org.dom4j.tree.DefaultText import org.jaxen.SimpleNamespaceContext import org.jaxen.XPath import org.jaxen.dom4j.Dom4jXPath -import java.io.File -import java.io.StringReader -import java.io.StringWriter -import kotlin.math.ceil +import java.io.* + /** * Common Utilities */ object Util { /** - * Formats a XML Element Node + * Extension Method that easily allows to add an element inside another while + * retaining formatting + * + * @param c ProjectModel / Context + * @param name new element ("tag") name + * @return created element inside `this` object, already indented after and (optionally) before */ - internal fun formatNode(node: Element) { - val parent = node.parent - //val siblings = parent.content() - - val indentLevel = findIndentLevel(node) - - val clonedNode = node.clone() as Element + fun Element.addIndentedElement(c: ProjectModel, name: String): Element { + val contentList = this.content() - val out = StringWriter() + val indentLevel = findIndentLevel(this) - val outputFormat = OutputFormat.createPrettyPrint() + val prefix = c.endl + StringUtils.repeat(c.indent, 1 + indentLevel) - val xmlWriter = XMLWriter(out, outputFormat) + val suffix = c.endl + StringUtils.repeat(c.indent, indentLevel) - xmlWriter.setIndentLevel(ceil(indentLevel.toDouble() / 2).toInt()) + if (contentList.isNotEmpty() && contentList.last() is Text) { + val lastElement = contentList.last() as Text - xmlWriter.write(clonedNode) + if (StringUtils.isWhitespace(lastElement.text)) { + contentList.remove(contentList.last()) + } + } - val content = out.toString() + contentList.add(DefaultText(prefix)) - val newElement = SAXReader().read(StringReader(content)).rootElement.clone() as Element + val newElement = this.addElement(name) - parent.remove(node) + contentList.add(DefaultText(suffix)) - parent.add(DefaultText("\n" + StringUtils.repeat(" ", indentLevel))) - parent.add(newElement) - parent.add(DefaultText("\n" + StringUtils.repeat(" ", ((indentLevel - 1) / 2)))) + return newElement } /** * Guesses the current indent level of the nearest nodes + * + * @return indent level */ - internal fun findIndentLevel(node: Element): Int { - val siblings = node.parent.content() - val myIndex = siblings.indexOf(node) + internal fun findIndentLevel(startingNode: Element): Int { + var level = 0 - if (myIndex > 0) { - val lastElement = siblings.subList(0, myIndex).findLast { - (it is Text) && it.text.matches(Regex("\\n+\\s+")) - } - - val lastElementText = lastElement?.text ?: "" + var node = startingNode - return lastElementText.trimStart('\n').length + while (node.parent != null) { + level += 1 + node = node.parent } - return 0 + return level } /** * Represents a Property Reference - as a regex */ - internal val PROPERTY_REFERENCE_REGEX = Regex("^\\\$\\{(.*)}$") + private val PROPERTY_REFERENCE_REGEX = Regex("^\\\$\\{(.*)}$") /** * Upserts a given property */ - internal fun upgradeProperty(c: ProjectModel, propertyName: String) { + private fun upgradeProperty(c: ProjectModel, propertyName: String) { if (null == c.resultPom.rootElement.element("properties")) { - val propertyElement = c.resultPom.rootElement.addElement("properties") - - formatNode(propertyElement) + c.resultPom.rootElement.addIndentedElement(c, "properties") } val parentPropertyElement = c.resultPom.rootElement.element("properties") if (null == parentPropertyElement.element(propertyName)) { - val newElement = parentPropertyElement.addElement(propertyName) - - formatNode(newElement) + parentPropertyElement.addIndentedElement(c, propertyName) } else { if (!c.overrideIfAlreadyExists) { val propertyReferenceRE = Regex.fromLiteral("\${$propertyName}") - val numberOfAllCurrentMatches = propertyReferenceRE.findAll(c.pomDocument.asXML()).toList().size + val numberOfAllCurrentMatches = + propertyReferenceRE.findAll(c.pomDocument.asXML()).toList().size if (numberOfAllCurrentMatches > 1) { throw IllegalStateException("Property $propertyName is already defined - and used more than once.") @@ -113,8 +105,6 @@ object Util { val propertyElement = parentPropertyElement.element(propertyName) propertyElement.text = c.dependency!!.version - - formatNode(propertyElement) } /** @@ -143,12 +133,13 @@ object Util { val currentVersion = Version.valueOf(currentVersionNodeText) val newVersion = Version.valueOf(c.dependency!!.version) - @Suppress("UnnecessaryVariable") val versionsAreIncreasing = newVersion.greaterThan(currentVersion) + @Suppress("UnnecessaryVariable") val versionsAreIncreasing = + newVersion.greaterThan(currentVersion) return versionsAreIncreasing } - internal fun resolveVersion(c: ProjectModel, versionText: String): String = + private fun resolveVersion(c: ProjectModel, versionText: String): String = if (PROPERTY_REFERENCE_REGEX.matches(versionText)) { @Suppress("DEPRECATION") StrSubstitutor(c.resolvedProperties).replace(versionText) @@ -159,7 +150,7 @@ object Util { /** * Escapes a Property Name */ - internal fun escapedPropertyName(propertyName: String): String = + private fun escapedPropertyName(propertyName: String): String = "\${$propertyName}" /** @@ -272,5 +263,4 @@ object Util { return result } - } diff --git a/src/test/java/io/openpixee/maven/operator/test/AbstractTestBase.kt b/src/test/java/io/openpixee/maven/operator/test/AbstractTestBase.kt index 29465ad60..95650b586 100644 --- a/src/test/java/io/openpixee/maven/operator/test/AbstractTestBase.kt +++ b/src/test/java/io/openpixee/maven/operator/test/AbstractTestBase.kt @@ -70,7 +70,7 @@ open class AbstractTestBase { LOGGER.warn("File $resultFilePath not found - writing results instead and ignorning assertions at all") - File(resultFilePath).writeText(context.resultPom.asXML()) + File(resultFilePath).writeBytes(context.resultPomBytes) } return context diff --git a/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt b/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt index bfdfd567d..b9181954c 100644 --- a/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt @@ -15,7 +15,8 @@ import java.io.File data class TestRepo( val slug: String, val branch: String = "master", - val pomPath: String = "pom.xml" + val pomPath: String = "pom.xml", + val useProperties: Boolean = false, ) { fun cacheDir() = BASE_CACHE_DIR.resolve("repo-%08X".format(slug.hashCode())) @@ -45,6 +46,10 @@ class MassRepoIT { */ private val repos = listOf( + TestRepo( + "CRRogo/vert.x", + useProperties = true, + ) to "io.openpixee:java-security-toolkit:1.0.0", TestRepo( "apache/pulsar", pomPath = "pulsar-broker/pom.xml" @@ -74,17 +79,14 @@ class MassRepoIT { TestRepo( "bytedeco/javacv" ) to "org.jogamp.jocl:jocl-main:2.3.1", - TestRepo( - "flowable/flowable-engine", - branch = "main", - pomPath = "modules/flowable-engine-common-api/pom.xml" - ) to "org.apache.commons:commons-lang3:3.11", ) /** * Checks out - or resets - a stored github repo */ private fun checkoutOrResetCachedRepo(repo: TestRepo) { + LOGGER.info("Checkout out $repo into ${repo.cacheDir()}") + if (!repo.cacheDir().exists()) { // git clone -b branch github.com/slug/ dir val command = arrayOf( @@ -157,6 +159,7 @@ class MassRepoIT { val context = ProjectModelFactory.load(File(sampleRepo.cacheDir(), sampleRepo.pomPath)) .withDependency(dependencyToUpgrade) .withSkipIfNewer(false) + .withUseProperties(sampleRepo.useProperties) .build() POMOperator.modify(context) @@ -164,7 +167,7 @@ class MassRepoIT { val alternatePomFile = File(File(sampleRepo.cacheDir(), sampleRepo.pomPath).parent, "pom-modified.xml") - alternatePomFile.writeText(context.resultPom.asXML()) + alternatePomFile.writeBytes(context.resultPomBytes) val finalDependencies = getDependenciesFrom(alternatePomFile.canonicalPath, sampleRepo.cacheDir()) diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-1-result.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-case-1-result.xml index a1e82e0ae..ff03447ec 100644 --- a/src/test/resources/io/openpixee/maven/operator/test/pom-case-1-result.xml +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-case-1-result.xml @@ -1,5 +1,6 @@ - - + 4.0.0 br.com.ingenieux @@ -12,21 +13,19 @@ 1.8 1.5.31 - - - - org.dom4j - dom4j - 2.0.3 - - + + + org.dom4j + dom4j + 2.0.3 + + - - - org.dom4j - dom4j - + + org.dom4j + dom4j + - \ No newline at end of file + diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-3-result.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-case-3-result.xml index 99b59658b..3e79270b2 100644 --- a/src/test/resources/io/openpixee/maven/operator/test/pom-case-3-result.xml +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-case-3-result.xml @@ -1,5 +1,8 @@ - + 4.0.0 br.com.ingenieux @@ -144,4 +147,4 @@ - \ No newline at end of file + diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-4-result.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-case-4-result.xml index 331f5b870..324a9a7ec 100644 --- a/src/test/resources/io/openpixee/maven/operator/test/pom-case-4-result.xml +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-case-4-result.xml @@ -1,5 +1,6 @@ - - + 4.0.0 webgoat-server jar @@ -13,7 +14,176 @@ org.owasp.webgoat.StartWebGoat - + + + org.owasp.webgoat + webgoat-container + ${project.version} + + + org.owasp.webgoat.lesson + challenge + ${project.version} + + + org.owasp.webgoat.lesson + bypass-restrictions + ${project.version} + + + org.owasp.webgoat.lesson + client-side-filtering + ${project.version} + + + org.owasp.webgoat.lesson + crypto + ${project.version} + + + org.owasp.webgoat.lesson + cross-site-scripting + ${project.version} + + + org.owasp.webgoat.lesson + html-tampering + ${project.version} + + + org.owasp.webgoat.lesson + http-basics + ${project.version} + + + org.owasp.webgoat.lesson + http-proxies + ${project.version} + + + org.owasp.webgoat.lesson + cia + ${project.version} + + + org.owasp.webgoat.lesson + chrome-dev-tools + ${project.version} + + + org.owasp.webgoat.lesson + idor + ${project.version} + + + org.owasp.webgoat.lesson + csrf + ${project.version} + + + org.owasp.webgoat.lesson + insecure-login + ${project.version} + + + org.owasp.webgoat.lesson + insecure-deserialization + ${project.version} + + + org.owasp.webgoat.lesson + jwt + ${project.version} + + + org.owasp.webgoat.lesson + path-traversal + ${project.version} + + + org.owasp.webgoat.lesson + sql-injection + ${project.version} + + + org.owasp.webgoat.lesson + vulnerable-components + ${project.version} + + + org.owasp.webgoat.lesson + xxe + ${project.version} + + + org.owasp.webgoat.lesson + auth-bypass + ${project.version} + + + org.owasp.webgoat.lesson + webgoat-introduction + ${project.version} + + + org.owasp.webgoat.lesson + webwolf-introduction + ${project.version} + + + org.owasp.webgoat.lesson + missing-function-ac + ${project.version} + + + org.owasp.webgoat.lesson + password-reset + ${project.version} + + + org.owasp.webgoat.lesson + ssrf + ${project.version} + + + org.owasp.webgoat.lesson + secure-passwords + ${project.version} + + + org.owasp.webgoat.lesson + spoof-cookie + ${project.version} + + + org.owasp.webgoat.lesson + hijack-session + ${project.version} + + + org.owasp.webgoat.lesson + webgoat-lesson-template + ${project.version} + + + org.owasp.webgoat.lesson + logging + ${project.version} + + + org.springframework.boot + spring-boot-devtools + true + + + org.postgresql + postgresql + + + org.apache.activemq + activemq-amqp + + @@ -60,186 +230,13 @@ - - - - - - org.apache.activemq - activemq-amqp - 5.16.2 - - - - - - - org.owasp.webgoat - webgoat-container - ${project.version} - - - org.owasp.webgoat.lesson - challenge - ${project.version} - - - org.owasp.webgoat.lesson - bypass-restrictions - ${project.version} - - - org.owasp.webgoat.lesson - client-side-filtering - ${project.version} - - - org.owasp.webgoat.lesson - crypto - ${project.version} - - - org.owasp.webgoat.lesson - cross-site-scripting - ${project.version} - - - org.owasp.webgoat.lesson - html-tampering - ${project.version} - - - org.owasp.webgoat.lesson - http-basics - ${project.version} - - - org.owasp.webgoat.lesson - http-proxies - ${project.version} - - - org.owasp.webgoat.lesson - cia - ${project.version} - - - org.owasp.webgoat.lesson - chrome-dev-tools - ${project.version} - - - org.owasp.webgoat.lesson - idor - ${project.version} - - - org.owasp.webgoat.lesson - csrf - ${project.version} - - - org.owasp.webgoat.lesson - insecure-login - ${project.version} - - - org.owasp.webgoat.lesson - insecure-deserialization - ${project.version} - - - org.owasp.webgoat.lesson - jwt - ${project.version} - - - org.owasp.webgoat.lesson - path-traversal - ${project.version} - - - org.owasp.webgoat.lesson - sql-injection - ${project.version} - - - org.owasp.webgoat.lesson - vulnerable-components - ${project.version} - - - org.owasp.webgoat.lesson - xxe - ${project.version} - - - org.owasp.webgoat.lesson - auth-bypass - ${project.version} - - - org.owasp.webgoat.lesson - webgoat-introduction - ${project.version} - - - org.owasp.webgoat.lesson - webwolf-introduction - ${project.version} - - - org.owasp.webgoat.lesson - missing-function-ac - ${project.version} - - - org.owasp.webgoat.lesson - password-reset - ${project.version} - - - org.owasp.webgoat.lesson - ssrf - ${project.version} - - - org.owasp.webgoat.lesson - secure-passwords - ${project.version} - - - org.owasp.webgoat.lesson - spoof-cookie - ${project.version} - - - org.owasp.webgoat.lesson - hijack-session - ${project.version} - - - org.owasp.webgoat.lesson - webgoat-lesson-template - ${project.version} - - - org.owasp.webgoat.lesson - logging - ${project.version} - - - org.springframework.boot - spring-boot-devtools - true - - - org.postgresql - postgresql - - - org.apache.activemq - activemq-amqp - - - \ No newline at end of file + + + + org.apache.activemq + activemq-amqp + 5.16.2 + + + + diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-with-property-result.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-case-with-property-result.xml index acf877958..55e673dca 100644 --- a/src/test/resources/io/openpixee/maven/operator/test/pom-case-with-property-result.xml +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-case-with-property-result.xml @@ -1,5 +1,8 @@ - + 4.0.0 br.com.ingenieux @@ -7,10 +10,8 @@ 0.0.1-SNAPSHOT - - 1.0.0 - + @@ -28,4 +29,4 @@ ${sample.version} - \ No newline at end of file + diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-pom-case-three-with-lower-version-result.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-pom-case-three-with-lower-version-result.xml index 1b992ed0e..6de228aa5 100644 --- a/src/test/resources/io/openpixee/maven/operator/test/pom-pom-case-three-with-lower-version-result.xml +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-pom-case-three-with-lower-version-result.xml @@ -1,5 +1,8 @@ - + 4.0.0 br.com.ingenieux @@ -144,4 +147,4 @@
- \ No newline at end of file + From ee6f0c24d10ad7b33ddcf5a5f339778eb8270bf2 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Thu, 2 Mar 2023 14:08:28 -0500 Subject: [PATCH 078/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index 0522b7e96..ee785ee97 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.openpixee.pom java-sample - 0.0.3-SNAPSHOT + 0.0.4-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index 6abc30aa0..c5cd33d4b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.openpixee.maven pom-operator - 0.0.3 + 0.0.4-SNAPSHOT scm:git:${project.scm.url} From eb3280f50e21bad63fec259bcd626a72fa6a9e2a Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 3 Mar 2023 20:11:03 -0500 Subject: [PATCH 079/153] * Cleanup (#11) * * Cleanup * [no ci] Autogenerated JaCoCo coverage badge --------- Co-authored-by: Jacoco Coverage Update Action --- .github/badges/jacoco.svg | 2 +- .../openpixee/maven/operator/FormatCommand.kt | 38 +------------------ .../openpixee/maven/operator/ProjectModel.kt | 1 - .../maven/operator/ProjectModelFactory.kt | 1 - 4 files changed, 3 insertions(+), 39 deletions(-) diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index 58cb94897..cce3498bf 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage91.6% \ No newline at end of file +coverage91.5% \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/FormatCommand.kt b/src/main/java/io/openpixee/maven/operator/FormatCommand.kt index 8dff86a8e..93a2baa8e 100644 --- a/src/main/java/io/openpixee/maven/operator/FormatCommand.kt +++ b/src/main/java/io/openpixee/maven/operator/FormatCommand.kt @@ -1,10 +1,6 @@ package io.openpixee.maven.operator import org.apache.commons.lang3.StringUtils -import org.dom4j.Comment -import org.dom4j.Element -import org.dom4j.Text -import org.dom4j.VisitorSupport import org.mozilla.universalchardet.UniversalDetector import java.nio.charset.Charset import javax.xml.stream.XMLInputFactory @@ -34,8 +30,6 @@ class FormatCommand : AbstractSimpleCommand() { private val inputFactory = XMLInputFactory.newInstance() override fun execute(c: ProjectModel): Boolean { - storeOriginalElements(c) - parseXmlAndCharset(c) parseLineEndings(c) @@ -46,32 +40,6 @@ class FormatCommand : AbstractSimpleCommand() { return super.execute(c) } - private fun storeOriginalElements(c: ProjectModel) { - val elementSet : MutableSet = mutableSetOf() - - c.resultPom.accept(object : VisitorSupport() { - override fun visit(node: Element?) { - elementSet.add(System.identityHashCode(node!!)) - - super.visit(node) - } - - override fun visit(node: Comment?) { - elementSet.add(System.identityHashCode(node!!)) - - super.visit(node) - } - - override fun visit(node: Text?) { - elementSet.add(System.identityHashCode(node!!)) - - super.visit(node) - } - }) - - c.originalElements = elementSet.toSet() - } - private fun guessIndent(c: ProjectModel): String { val eventReader = inputFactory.createXMLEventReader(c.originalPom.inputStream()) @@ -92,7 +60,7 @@ class FormatCommand : AbstractSimpleCommand() { * Updates space frequencies */ patterns - .filter { it.length != 0 } + .filter { it.isNotEmpty() } .filter { StringUtils.isAllBlank(it) } .map { it to it.length } .forEach { @@ -110,9 +78,7 @@ class FormatCommand : AbstractSimpleCommand() { private fun parseLineEndings(c: ProjectModel): String { val str = String(c.originalPom.inputStream().readBytes(), c.charset) - return LINE_ENDINGS - .map { it to str.split(it).size } - .toMap() + return LINE_ENDINGS.associateWith { str.split(it).size } .maxBy { it.value } .key } diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt index e537a25fe..aebfb2eae 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModel.kt @@ -25,7 +25,6 @@ class ProjectModel internal constructor( var charset: Charset, var endl: String, var indent: String, - var originalElements : Set, ) { internal var modifiedByCommand = false diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt index a7eb3bd86..d1149cac5 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt @@ -93,7 +93,6 @@ class ProjectModelFactory private constructor( charset = Charset.defaultCharset(), endl = "", indent = "", - originalElements = emptySet(), ) } From 1625be701bb28b021a7c05361ce4b8caac87d17d Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 8 Mar 2023 10:17:11 -0500 Subject: [PATCH 080/153] Generating Tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c5cd33d4b..7aded53db 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.openpixee.maven pom-operator - 0.0.4-SNAPSHOT + 0.0.4 scm:git:${project.scm.url} From b56a69dbc662db51f4f152685611ebc20b7f3cd0 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 8 Mar 2023 10:18:16 -0500 Subject: [PATCH 081/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index ee785ee97..6c4a77542 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.openpixee.pom java-sample - 0.0.4-SNAPSHOT + 0.0.5-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index 7aded53db..c306c3e8a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.openpixee.maven pom-operator - 0.0.4 + 0.0.5-SNAPSHOT scm:git:${project.scm.url} From 7d342860e69ccb69895c681f84614107fdfc7251 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Sun, 12 Mar 2023 13:40:16 -0500 Subject: [PATCH 082/153] Manage empty elements and improve preamble keeping (#12) * Manage empty elements * [no ci] Autogenerated JaCoCo coverage badge * Improving preamble handling * Disabling windows * [no ci] Autogenerated JaCoCo coverage badge * Updating README --------- Co-authored-by: Jacoco Coverage Update Action --- .github/badges/branches.svg | 2 +- .github/badges/jacoco.svg | 2 +- .github/workflows/push-test.yml | 2 +- README.md | 9 +- .../openpixee/maven/operator/FormatCommand.kt | 93 +- .../maven/operator/ProjectModelFactory.kt | 4 +- .../maven/operator/test/POMOperatorTest.kt | 71 +- .../maven/operator/test/pom-case-5-result.xml | 820 +++++++++++++++++ .../maven/operator/test/pom-case-5.xml | 810 +++++++++++++++++ .../maven/operator/test/pom-case-6-result.xml | 824 ++++++++++++++++++ .../maven/operator/test/pom-case-6.xml | 814 +++++++++++++++++ 11 files changed, 3430 insertions(+), 21 deletions(-) create mode 100644 src/test/resources/io/openpixee/maven/operator/test/pom-case-5-result.xml create mode 100644 src/test/resources/io/openpixee/maven/operator/test/pom-case-5.xml create mode 100644 src/test/resources/io/openpixee/maven/operator/test/pom-case-6-result.xml create mode 100644 src/test/resources/io/openpixee/maven/operator/test/pom-case-6.xml diff --git a/.github/badges/branches.svg b/.github/badges/branches.svg index 1b3574ecc..2f8dd3c1e 100644 --- a/.github/badges/branches.svg +++ b/.github/badges/branches.svg @@ -1 +1 @@ -branches73.6% \ No newline at end of file +branches73.7% \ No newline at end of file diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index cce3498bf..2b337d7d4 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage91.5% \ No newline at end of file +coverage91.9% \ No newline at end of file diff --git a/.github/workflows/push-test.yml b/.github/workflows/push-test.yml index 078cafe8c..2504f91ef 100644 --- a/.github/workflows/push-test.yml +++ b/.github/workflows/push-test.yml @@ -12,7 +12,7 @@ jobs: build: strategy: matrix: - platform: [ubuntu-latest, macos-latest, windows-latest] + platform: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.platform }} environment: name: default diff --git a/README.md b/README.md index e5c025e74..ac21e2073 100644 --- a/README.md +++ b/README.md @@ -50,13 +50,8 @@ It implements a Chain of Responsibility strategy - each `Command` class attempts e.g. to generate version `0.0.2`: ``` -mvn versions:set -DnewVersion=0.0.2 -mvn clean package source:jar javadoc:jar deploy -git commit -am "Generating Tag" -git tag 0.0.2 -git push && git push --tags -V=0.0.3 mvn versions:set -DnewVersion=0.0.3-SNAPSHOT && (cd java-sample ; mvn versions:set -DnewVersion=0.0.3-SNAPSHOT) -git commit -am "Generating Development Version" +(mvn versions:set -DnewVersion=0.0.3 && mvn clean package source:jar javadoc:jar deploy && git commit -am "Generating Tag" && git tag v0.0.3 && git push && git push --tags) +(V=0.0.4-SNAPSHOT mvn versions:set -DnewVersion=$V && (cd java-sample ; mvn versions:set -DnewVersion=$V && git commit -am "Generating development version" && git push)) ``` # TODO: diff --git a/src/main/java/io/openpixee/maven/operator/FormatCommand.kt b/src/main/java/io/openpixee/maven/operator/FormatCommand.kt index 93a2baa8e..aa2aa0792 100644 --- a/src/main/java/io/openpixee/maven/operator/FormatCommand.kt +++ b/src/main/java/io/openpixee/maven/operator/FormatCommand.kt @@ -2,12 +2,25 @@ package io.openpixee.maven.operator import org.apache.commons.lang3.StringUtils import org.mozilla.universalchardet.UniversalDetector +import java.io.StringWriter import java.nio.charset.Charset +import java.util.BitSet import javax.xml.stream.XMLInputFactory +import javax.xml.stream.XMLOutputFactory import javax.xml.stream.events.Characters +import javax.xml.stream.events.EndElement import javax.xml.stream.events.StartDocument import javax.xml.stream.events.StartElement +/** + * Data Class used to keep track of matches (ranges, content, referring tag name) + */ +data class MatchData( + val range: IntRange, + val content: String, + val elementName: String +) + /** * This Command handles Formatting - particularly storing the original document preamble (the Processing Instruction and the first XML Element contents), * which are the only ones which are tricky to format (due to element and its attributes being freeform - thus formatting lost when serializing the DOM @@ -29,6 +42,11 @@ class FormatCommand : AbstractSimpleCommand() { */ private val inputFactory = XMLInputFactory.newInstance() + /** + * StAX OutputFactory + */ + private val outputFactory = XMLOutputFactory.newInstance() + override fun execute(c: ProjectModel): Boolean { parseXmlAndCharset(c) @@ -40,6 +58,41 @@ class FormatCommand : AbstractSimpleCommand() { return super.execute(c) } + private fun elementBitSet(doc: ByteArray): BitSet { + val result = BitSet() + val eventReader = inputFactory.createXMLEventReader(doc.inputStream()) + val eventContent = StringWriter() + val xmlEventWriter = outputFactory.createXMLEventWriter(eventContent) + + while (eventReader.hasNext()) { + val next = eventReader.nextEvent() + + if (next is StartElement || next is EndElement) { + val startIndex = next.location.characterOffset + + eventContent.buffer.setLength(0) + + xmlEventWriter.add(next) + xmlEventWriter.flush() + + val endIndex = startIndex + eventContent.buffer.length + + result.set(startIndex, startIndex + endIndex) + } + } + + return result + } + + private fun findSingleElementMatchesFrom(pomDocument: String) = + RE_EMPTY_ELEMENT.findAll(pomDocument).map { + it.range.first to MatchData( + range = it.range, + content = it.value, + elementName = ((it.groups[1]?.value ?: it.groups[2]?.value)!!) + ) + }.sortedByDescending { it.first }.toMap(LinkedHashMap()) + private fun guessIndent(c: ProjectModel): String { val eventReader = inputFactory.createXMLEventReader(c.originalPom.inputStream()) @@ -102,13 +155,13 @@ class FormatCommand : AbstractSimpleCommand() { * Processing Instruction Found - Store its Character Encoding */ charset = Charset.forName(event.characterEncodingScheme) - } else if (event.isStartElement) { + } else if (event.isEndElement) { /** - * First Element ("Tag") found - store its offset + * First End of Element ("Tag") found - store its offset */ - val startElementEvent = (event as StartElement) + val endElementEvent = (event as EndElement) - val offset = startElementEvent.location.characterOffset + val offset = endElementEvent.location.characterOffset preamble = c.originalPom.toString(c.charset).substring(0, offset) @@ -140,7 +193,29 @@ class FormatCommand : AbstractSimpleCommand() { * but apply the original formatting as well */ override fun postProcess(c: ProjectModel): Boolean { - var xmlRepresentation = c.resultPom.asXML() + var xmlRepresentation = c.resultPom.asXML().toString() + + val originalElementMap = elementBitSet(c.originalPom) + val targetElementMap = elementBitSet(xmlRepresentation.toByteArray()) + + // Let's find out the original empty elements from the original pom and store into a stack + val elementsToReplace : MutableList = ArrayList().apply{ + val matches = findSingleElementMatchesFrom(c.originalPom.toString(c.charset)).values + + val filteredMatches = matches.filter { originalElementMap[it.range.first] } + + this.addAll(filteredMatches) + } + + // Lets to the replacements backwards on the existing, current pom + val emptyElements = findSingleElementMatchesFrom(xmlRepresentation) + .filter { targetElementMap[it.value.range.first] } + + emptyElements.forEach { (_, match) -> + val nextMatch = elementsToReplace.removeFirst() + + xmlRepresentation = xmlRepresentation.replaceRange(match.range, nextMatch.content) + } /** * We might need to replace the beginning of the POM with the same content @@ -156,13 +231,13 @@ class FormatCommand : AbstractSimpleCommand() { while (true) { val event = eventReader.nextEvent() - if (event.isStartElement) { + if (event.isEndElement) { /** * Apply the formatting and tweak its XML Representation */ - val startElementEvent = (event as StartElement) + val endElementEvent = (event as EndElement) - val offset = startElementEvent.location.characterOffset + val offset = endElementEvent.location.characterOffset xmlRepresentation = this.preamble + xmlRepresentation.substring(offset) + this.suffix @@ -187,5 +262,7 @@ class FormatCommand : AbstractSimpleCommand() { companion object { val LINE_ENDINGS = setOf("\r\n", "\n", "\r") + + val RE_EMPTY_ELEMENT = Regex("""<(\p{Alnum}+)>|<(\p{Alnum}+)\s*/>""") } } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt index d1149cac5..f2846b513 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt +++ b/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt @@ -114,7 +114,9 @@ class ProjectModelFactory private constructor( fun load(url: URL): ProjectModelFactory { val originalPom: ByteArray = IOUtils.toByteArray(url.openStream()) - val pomDocument = SAXReader().read(originalPom.inputStream()) + val saxReader = SAXReader() + + val pomDocument = saxReader.read(originalPom.inputStream()) return ProjectModelFactory(pomPath = url, pomDocument = pomDocument, originalPom = originalPom) } diff --git a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt index 834145381..c5e326e74 100644 --- a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt @@ -11,8 +11,6 @@ import org.junit.Assert.assertEquals import org.junit.Test import org.xmlunit.diff.ComparisonType import java.io.File -import kotlin.test.assertFails -import kotlin.test.assertFailsWith import kotlin.test.assertTrue /** @@ -203,6 +201,75 @@ class POMOperatorTest : AbstractTestBase() { ) } + @Test + fun testCaseWithEmptyElement() { + val dependencyToUpgrade = + Dependency("io.openpixee", "java-security-toolkit", version = "1.0.0") + + val context = gwt( + "case-5", + ProjectModelFactory.load( + POMOperatorTest::class.java.getResource("pom-case-5.xml")!!, + ).withDependency(dependencyToUpgrade).withUseProperties(true) + ) + + val resultPomAsString = String(context.resultPomBytes) + + assertTrue( + resultPomAsString.contains(""), + "There must be an unformatted preamble last line" + ) + + assertTrue( + resultPomAsString.contains(""), + "There must be a dumb empty element" + ) + assertTrue( + resultPomAsString.contains(""), + "There must be an empty element with zero spaces" + ) + assertTrue( + resultPomAsString.contains(""), + "There must be an empty element with one spaces" + ) + } + + @Test + fun testCaseWithEmptyElementHiddenInComment() { + val dependencyToUpgrade = + Dependency("io.openpixee", "java-security-toolkit", version = "1.0.0") + + val context = gwt( + "case-6", + ProjectModelFactory.load( + POMOperatorTest::class.java.getResource("pom-case-6.xml")!!, + ).withDependency(dependencyToUpgrade).withUseProperties(true) + ) + + val resultPomAsString = String(context.resultPomBytes) + + assertTrue( + resultPomAsString.contains(""), + "There must be a dumb empty element" + ) + assertTrue( + resultPomAsString.contains(""), + "There must be an empty element with zero spaces" + ) + assertTrue( + resultPomAsString.contains(""), + "There must be an empty element with one spaces" + ) + assertTrue( + resultPomAsString.contains(" -->"), + "There must be an empty element with three spaces inside a comment" + ) + } + @Test fun testCaseWithProperty() { val dependencyToUpgrade = diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-5-result.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-case-5-result.xml new file mode 100644 index 000000000..fb6be45d6 --- /dev/null +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-case-5-result.xml @@ -0,0 +1,820 @@ + + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.7.1 + + org.owasp.webgoat + webgoat + 2023.5-SNAPSHOT + jar + + WebGoat + WebGoat, a deliberately insecure Web Application + https://github.com/WebGoat/WebGoat + 2006 + + OWASP + https://github.com/WebGoat/WebGoat/ + + + + GNU General Public License, version 2 + https://www.gnu.org/licenses/gpl-2.0.txt + + + + + mayhew64 + Bruce Mayhew + webgoat@owasp.org + OWASP + https://github.com/WebGoat/WebGoat + + + nbaars + Nanne Baars + nanne.baars@owasp.org + https://github.com/nbaars + Europe/Amsterdam + + + misfir3 + Jason White + jason.white@owasp.org + + + zubcevic + René Zubcevic + rene.zubcevic@owasp.org + + + aolle + Àngel Ollé Blázquez + angel@olleb.com + + + jwayman + Jeff Wayman + + + + dcowden + Dave Cowden + + + + lawson89 + Richard Lawson + + + + dougmorato + Doug Morato + doug.morato@owasp.org + OWASP + https://github.com/dougmorato + America/New_York + + https://avatars2.githubusercontent.com/u/9654?v=3&s=150 + + + + + + + OWASP WebGoat Mailing List + https://lists.owasp.org/mailman/listinfo/owasp-webgoat + Owasp-webgoat-request@lists.owasp.org + owasp-webgoat@lists.owasp.org + http://lists.owasp.org/pipermail/owasp-webgoat/ + + + + + scm:git:git@github.com:WebGoat/WebGoat.git + scm:git:git@github.com:WebGoat/WebGoat.git + HEAD + https://github.com/WebGoat/WebGoat + + + + Github Issues + https://github.com/WebGoat/WebGoat/issues + + + + + 2.5.3 + 3.3.7 + 2.2 + + 3.1.2 + 3.2.1 + 2.11.0 + 3.12.0 + 1.10.0 + 30.1-jre + 0.8.8 + 17 + 0.9.1 + 0.9.3 + 3.5.1 + 1.15.4 + 3.8.0 + 2.22.0 + 3.1.2 + 3.1.1 + 3.1.0 + 3.0.0-M9 + 17 + 17 + 3.15.0 + + UTF-8 + UTF-8 + 3.0.15.RELEASE + 5.3.2 + 8080 + 9090 + 2.27.2 + 1.2 + 1.4.5 + + 1.5.2 + 1.0.0 + + + + + + + org.ow2.asm + asm + 9.1 + + + + org.apache.commons + commons-exec + 1.3 + + + org.asciidoctor + asciidoctorj + ${asciidoctorj.version} + + + + org.jsoup + jsoup + ${jsoup.version} + + + com.nulab-inc + zxcvbn + ${zxcvbn.version} + + + com.thoughtworks.xstream + xstream + ${xstream.version} + + + cglib + cglib-nodep + ${cglib.version} + + + xml-resolver + xml-resolver + ${xml-resolver.version} + + + io.jsonwebtoken + jjwt + ${jjwt.version} + + + com.google.guava + guava + ${guava.version} + + + commons-io + commons-io + ${commons-io.version} + + + org.apache.commons + commons-text + ${commons-text.version} + + + org.bitbucket.b_c + jose4j + ${jose4j.version} + + + org.webjars + bootstrap + ${bootstrap.version} + + + org.webjars + jquery + ${jquery.version} + + + com.github.tomakehurst + wiremock + ${wiremock.version} + + + io.github.bonigarcia + webdrivermanager + ${webdriver.version} + + + org.apache.commons + commons-compress + 1.22 + + + org.jruby + jruby + 9.3.6.0 + + + io.openpixee + java-security-toolkit + ${versions.java-security-toolkit} + + + + + + + org.apache.commons + commons-exec + + + org.springframework.boot + spring-boot-starter-validation + + + org.projectlombok + lombok + provided + true + + + javax.xml.bind + jaxb-api + + + org.springframework.boot + spring-boot-starter-undertow + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.flywaydb + flyway-core + + + org.asciidoctor + asciidoctorj + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.thymeleaf.extras + thymeleaf-extras-springsecurity5 + + + org.hsqldb + hsqldb + + + org.jsoup + jsoup + + + com.nulab-inc + zxcvbn + + + com.thoughtworks.xstream + xstream + + + cglib + cglib-nodep + + + xml-resolver + xml-resolver + + + io.jsonwebtoken + jjwt + + + com.google.guava + guava + + + commons-io + commons-io + + + org.apache.commons + commons-lang3 + + + org.apache.commons + commons-text + + + org.bitbucket.b_c + jose4j + + + org.webjars + bootstrap + + + org.webjars + jquery + + + org.glassfish.jaxb + jaxb-runtime + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + com.github.tomakehurst + wiremock + test + + + io.rest-assured + rest-assured + test + + + io.openpixee + java-security-toolkit + + + + + + + false + + central + https://repo.maven.apache.org/maven2 + + + + + + false + + central + https://repo.maven.apache.org/maven2 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + true + org.owasp.webgoat.server.StartWebGoat + + + + org.asciidoctor + asciidoctorj + + + + + + + repackage + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-integration-test-source-as-test-sources + + add-test-source + + generate-test-sources + + + src/it/java + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + ${basedir}/src/test/resources/logback-test.xml + + -Xmx512m -Dwebgoatport=${webgoat.port} -Dwebwolfport=${webwolf.port} + org/owasp/webgoat/*Test + + + + integration-test + + integration-test + + + + verify + + verify + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED + --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED + + **/*IntegrationTest.java + src/it/java + org/owasp/webgoat/*Test + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${checkstyle.version} + + UTF-8 + true + true + config/checkstyle/checkstyle.xml + config/checkstyle/suppressions.xml + checkstyle.suppressions.file + + + + com.diffplug.spotless + spotless-maven-plugin + 2.33.0 + + + + + .gitignore + + + + + true + 4 + + + + + + **/*.md + + + + + + src/main/java/**/*.java + src/test/java/**/*.java + src/it/java/**/*.java + + + + + true + + + + + UTF-8 + ${line.separator} + true + false + true + 2 + false + false + recommended_2008_06 + true + true + true + + + + + + + check + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.2.1 + + + restrict-log4j-versions + + enforce + + validate + + + + + org.apache.logging.log4j:log4j-core + + + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 17 + 17 + + + + + + + + local-server + + + start-server + + true + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + reserve-container-port + + reserve-network-port + + process-resources + + + webgoat.port + webwolf.port + jmxPort + + + + + + + com.bazaarvoice.maven.plugins + process-exec-maven-plugin + 0.9 + + + start-jar + + start + + pre-integration-test + + ${project.build.directory} + + java + -jar + -Dlogging.pattern.console= + -Dwebgoat.server.directory=${java.io.tmpdir}/webgoat_${webgoat.port} + -Dwebgoat.user.directory=${java.io.tmpdir}/webgoat_${webgoat.port} + -Dspring.main.banner-mode=off + -Dwebgoat.port=${webgoat.port} + -Dwebwolf.port=${webwolf.port} + --add-opens + java.base/java.lang=ALL-UNNAMED + --add-opens + java.base/java.util=ALL-UNNAMED + --add-opens + java.base/java.lang.reflect=ALL-UNNAMED + --add-opens + java.base/java.text=ALL-UNNAMED + --add-opens + java.desktop/java.beans=ALL-UNNAMED + --add-opens + java.desktop/java.awt.font=ALL-UNNAMED + --add-opens + java.base/sun.nio.ch=ALL-UNNAMED + --add-opens + java.base/java.io=ALL-UNNAMED + --add-opens + java.base/java.util=ALL-UNNAMED + ${project.build.directory}/webgoat-${project.version}.jar + + false + http://localhost:${webgoat.port}/WebGoat/actuator/health + + + + stop-jar-process + + stop-all + + post-integration-test + + + + + + + + owasp + + false + + + + + org.owasp + dependency-check-maven + 6.5.1 + + 7 + false + false + + + ${maven.multiModuleProjectDirectory}/config/dependency-check/project-suppression.xml + + + + + + check + + + + + + + + + + coverage + + false + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED + --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED + ${surefire.jacoco.args} + + **/*IntegrationTest.java + src/it/java + org/owasp/webgoat/*Test + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco.version} + + + before-unit-test + + prepare-agent + + + ${project.build.directory}/jacoco/jacoco-ut.exec + surefire.jacoco.args + + + + check + + check + + + + + BUNDLE + + + CLASS + COVEREDCOUNT + 0.6 + + + + + ${project.build.directory}/jacoco/jacoco-ut.exec + + + + after-unit-test + + report + + test + + ${project.build.directory}/jacoco/jacoco-ut.exec + ${project.reporting.outputDirectory}/jacoco-unit-test-coverage-report + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-5.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-case-5.xml new file mode 100644 index 000000000..24b8db115 --- /dev/null +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-case-5.xml @@ -0,0 +1,810 @@ + + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.7.1 + + org.owasp.webgoat + webgoat + 2023.5-SNAPSHOT + jar + + WebGoat + WebGoat, a deliberately insecure Web Application + https://github.com/WebGoat/WebGoat + 2006 + + OWASP + https://github.com/WebGoat/WebGoat/ + + + + GNU General Public License, version 2 + https://www.gnu.org/licenses/gpl-2.0.txt + + + + + mayhew64 + Bruce Mayhew + webgoat@owasp.org + OWASP + https://github.com/WebGoat/WebGoat + + + nbaars + Nanne Baars + nanne.baars@owasp.org + https://github.com/nbaars + Europe/Amsterdam + + + misfir3 + Jason White + jason.white@owasp.org + + + zubcevic + René Zubcevic + rene.zubcevic@owasp.org + + + aolle + Àngel Ollé Blázquez + angel@olleb.com + + + jwayman + Jeff Wayman + + + + dcowden + Dave Cowden + + + + lawson89 + Richard Lawson + + + + dougmorato + Doug Morato + doug.morato@owasp.org + OWASP + https://github.com/dougmorato + America/New_York + + https://avatars2.githubusercontent.com/u/9654?v=3&s=150 + + + + + + + OWASP WebGoat Mailing List + https://lists.owasp.org/mailman/listinfo/owasp-webgoat + Owasp-webgoat-request@lists.owasp.org + owasp-webgoat@lists.owasp.org + http://lists.owasp.org/pipermail/owasp-webgoat/ + + + + + scm:git:git@github.com:WebGoat/WebGoat.git + scm:git:git@github.com:WebGoat/WebGoat.git + HEAD + https://github.com/WebGoat/WebGoat + + + + Github Issues + https://github.com/WebGoat/WebGoat/issues + + + + + 2.5.3 + 3.3.7 + 2.2 + + 3.1.2 + 3.2.1 + 2.11.0 + 3.12.0 + 1.10.0 + 30.1-jre + 0.8.8 + 17 + 0.9.1 + 0.9.3 + 3.5.1 + 1.15.4 + 3.8.0 + 2.22.0 + 3.1.2 + 3.1.1 + 3.1.0 + 3.0.0-M9 + 17 + 17 + 3.15.0 + + UTF-8 + UTF-8 + 3.0.15.RELEASE + 5.3.2 + 8080 + 9090 + 2.27.2 + 1.2 + 1.4.5 + + 1.5.2 + + + + + + + org.ow2.asm + asm + 9.1 + + + + org.apache.commons + commons-exec + 1.3 + + + org.asciidoctor + asciidoctorj + ${asciidoctorj.version} + + + + org.jsoup + jsoup + ${jsoup.version} + + + com.nulab-inc + zxcvbn + ${zxcvbn.version} + + + com.thoughtworks.xstream + xstream + ${xstream.version} + + + cglib + cglib-nodep + ${cglib.version} + + + xml-resolver + xml-resolver + ${xml-resolver.version} + + + io.jsonwebtoken + jjwt + ${jjwt.version} + + + com.google.guava + guava + ${guava.version} + + + commons-io + commons-io + ${commons-io.version} + + + org.apache.commons + commons-text + ${commons-text.version} + + + org.bitbucket.b_c + jose4j + ${jose4j.version} + + + org.webjars + bootstrap + ${bootstrap.version} + + + org.webjars + jquery + ${jquery.version} + + + com.github.tomakehurst + wiremock + ${wiremock.version} + + + io.github.bonigarcia + webdrivermanager + ${webdriver.version} + + + org.apache.commons + commons-compress + 1.22 + + + org.jruby + jruby + 9.3.6.0 + + + + + + + org.apache.commons + commons-exec + + + org.springframework.boot + spring-boot-starter-validation + + + org.projectlombok + lombok + provided + true + + + javax.xml.bind + jaxb-api + + + org.springframework.boot + spring-boot-starter-undertow + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.flywaydb + flyway-core + + + org.asciidoctor + asciidoctorj + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.thymeleaf.extras + thymeleaf-extras-springsecurity5 + + + org.hsqldb + hsqldb + + + org.jsoup + jsoup + + + com.nulab-inc + zxcvbn + + + com.thoughtworks.xstream + xstream + + + cglib + cglib-nodep + + + xml-resolver + xml-resolver + + + io.jsonwebtoken + jjwt + + + com.google.guava + guava + + + commons-io + commons-io + + + org.apache.commons + commons-lang3 + + + org.apache.commons + commons-text + + + org.bitbucket.b_c + jose4j + + + org.webjars + bootstrap + + + org.webjars + jquery + + + org.glassfish.jaxb + jaxb-runtime + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + com.github.tomakehurst + wiremock + test + + + io.rest-assured + rest-assured + test + + + + + + + false + + central + https://repo.maven.apache.org/maven2 + + + + + + false + + central + https://repo.maven.apache.org/maven2 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + true + org.owasp.webgoat.server.StartWebGoat + + + + org.asciidoctor + asciidoctorj + + + + + + + repackage + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-integration-test-source-as-test-sources + + add-test-source + + generate-test-sources + + + src/it/java + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + ${basedir}/src/test/resources/logback-test.xml + + -Xmx512m -Dwebgoatport=${webgoat.port} -Dwebwolfport=${webwolf.port} + org/owasp/webgoat/*Test + + + + integration-test + + integration-test + + + + verify + + verify + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED + --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED + + **/*IntegrationTest.java + src/it/java + org/owasp/webgoat/*Test + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${checkstyle.version} + + UTF-8 + true + true + config/checkstyle/checkstyle.xml + config/checkstyle/suppressions.xml + checkstyle.suppressions.file + + + + com.diffplug.spotless + spotless-maven-plugin + 2.33.0 + + + + + .gitignore + + + + + true + 4 + + + + + + **/*.md + + + + + + src/main/java/**/*.java + src/test/java/**/*.java + src/it/java/**/*.java + + + + + true + + + + + UTF-8 + ${line.separator} + true + false + true + 2 + false + false + recommended_2008_06 + true + true + true + + + + + + + check + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.2.1 + + + restrict-log4j-versions + + enforce + + validate + + + + + org.apache.logging.log4j:log4j-core + + + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 17 + 17 + + + + + + + + local-server + + + start-server + + true + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + reserve-container-port + + reserve-network-port + + process-resources + + + webgoat.port + webwolf.port + jmxPort + + + + + + + com.bazaarvoice.maven.plugins + process-exec-maven-plugin + 0.9 + + + start-jar + + start + + pre-integration-test + + ${project.build.directory} + + java + -jar + -Dlogging.pattern.console= + -Dwebgoat.server.directory=${java.io.tmpdir}/webgoat_${webgoat.port} + -Dwebgoat.user.directory=${java.io.tmpdir}/webgoat_${webgoat.port} + -Dspring.main.banner-mode=off + -Dwebgoat.port=${webgoat.port} + -Dwebwolf.port=${webwolf.port} + --add-opens + java.base/java.lang=ALL-UNNAMED + --add-opens + java.base/java.util=ALL-UNNAMED + --add-opens + java.base/java.lang.reflect=ALL-UNNAMED + --add-opens + java.base/java.text=ALL-UNNAMED + --add-opens + java.desktop/java.beans=ALL-UNNAMED + --add-opens + java.desktop/java.awt.font=ALL-UNNAMED + --add-opens + java.base/sun.nio.ch=ALL-UNNAMED + --add-opens + java.base/java.io=ALL-UNNAMED + --add-opens + java.base/java.util=ALL-UNNAMED + ${project.build.directory}/webgoat-${project.version}.jar + + false + http://localhost:${webgoat.port}/WebGoat/actuator/health + + + + stop-jar-process + + stop-all + + post-integration-test + + + + + + + + owasp + + false + + + + + org.owasp + dependency-check-maven + 6.5.1 + + 7 + false + false + + + ${maven.multiModuleProjectDirectory}/config/dependency-check/project-suppression.xml + + + + + + check + + + + + + + + + + coverage + + false + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED + --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED + ${surefire.jacoco.args} + + **/*IntegrationTest.java + src/it/java + org/owasp/webgoat/*Test + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco.version} + + + before-unit-test + + prepare-agent + + + ${project.build.directory}/jacoco/jacoco-ut.exec + surefire.jacoco.args + + + + check + + check + + + + + BUNDLE + + + CLASS + COVEREDCOUNT + 0.6 + + + + + ${project.build.directory}/jacoco/jacoco-ut.exec + + + + after-unit-test + + report + + test + + ${project.build.directory}/jacoco/jacoco-ut.exec + ${project.reporting.outputDirectory}/jacoco-unit-test-coverage-report + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-6-result.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-case-6-result.xml new file mode 100644 index 000000000..3807c0172 --- /dev/null +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-case-6-result.xml @@ -0,0 +1,824 @@ + + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.7.1 + + org.owasp.webgoat + webgoat + 2023.5-SNAPSHOT + jar + + WebGoat + WebGoat, a deliberately insecure Web Application + https://github.com/WebGoat/WebGoat + 2006 + + OWASP + https://github.com/WebGoat/WebGoat/ + + + + GNU General Public License, version 2 + https://www.gnu.org/licenses/gpl-2.0.txt + + + + + mayhew64 + Bruce Mayhew + webgoat@owasp.org + OWASP + https://github.com/WebGoat/WebGoat + + + nbaars + Nanne Baars + nanne.baars@owasp.org + https://github.com/nbaars + Europe/Amsterdam + + + misfir3 + Jason White + jason.white@owasp.org + + + zubcevic + René Zubcevic + rene.zubcevic@owasp.org + + + aolle + Àngel Ollé Blázquez + angel@olleb.com + + + jwayman + Jeff Wayman + + + + + + dcowden + Dave Cowden + + + + lawson89 + Richard Lawson + + + + dougmorato + Doug Morato + doug.morato@owasp.org + OWASP + https://github.com/dougmorato + America/New_York + + https://avatars2.githubusercontent.com/u/9654?v=3&s=150 + + + + + + + OWASP WebGoat Mailing List + https://lists.owasp.org/mailman/listinfo/owasp-webgoat + Owasp-webgoat-request@lists.owasp.org + owasp-webgoat@lists.owasp.org + http://lists.owasp.org/pipermail/owasp-webgoat/ + + + + + scm:git:git@github.com:WebGoat/WebGoat.git + scm:git:git@github.com:WebGoat/WebGoat.git + HEAD + https://github.com/WebGoat/WebGoat + + + + Github Issues + https://github.com/WebGoat/WebGoat/issues + + + + + 2.5.3 + 3.3.7 + 2.2 + + 3.1.2 + 3.2.1 + 2.11.0 + 3.12.0 + 1.10.0 + 30.1-jre + 0.8.8 + 17 + 0.9.1 + 0.9.3 + 3.5.1 + 1.15.4 + 3.8.0 + 2.22.0 + 3.1.2 + 3.1.1 + 3.1.0 + 3.0.0-M9 + 17 + 17 + 3.15.0 + + UTF-8 + UTF-8 + 3.0.15.RELEASE + 5.3.2 + 8080 + 9090 + 2.27.2 + 1.2 + 1.4.5 + + 1.5.2 + 1.0.0 + + + + + + + org.ow2.asm + asm + 9.1 + + + + org.apache.commons + commons-exec + 1.3 + + + org.asciidoctor + asciidoctorj + ${asciidoctorj.version} + + + + org.jsoup + jsoup + ${jsoup.version} + + + com.nulab-inc + zxcvbn + ${zxcvbn.version} + + + com.thoughtworks.xstream + xstream + ${xstream.version} + + + cglib + cglib-nodep + ${cglib.version} + + + xml-resolver + xml-resolver + ${xml-resolver.version} + + + io.jsonwebtoken + jjwt + ${jjwt.version} + + + com.google.guava + guava + ${guava.version} + + + commons-io + commons-io + ${commons-io.version} + + + org.apache.commons + commons-text + ${commons-text.version} + + + org.bitbucket.b_c + jose4j + ${jose4j.version} + + + org.webjars + bootstrap + ${bootstrap.version} + + + org.webjars + jquery + ${jquery.version} + + + com.github.tomakehurst + wiremock + ${wiremock.version} + + + io.github.bonigarcia + webdrivermanager + ${webdriver.version} + + + org.apache.commons + commons-compress + 1.22 + + + org.jruby + jruby + 9.3.6.0 + + + io.openpixee + java-security-toolkit + ${versions.java-security-toolkit} + + + + + + + org.apache.commons + commons-exec + + + org.springframework.boot + spring-boot-starter-validation + + + org.projectlombok + lombok + provided + true + + + javax.xml.bind + jaxb-api + + + org.springframework.boot + spring-boot-starter-undertow + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.flywaydb + flyway-core + + + org.asciidoctor + asciidoctorj + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.thymeleaf.extras + thymeleaf-extras-springsecurity5 + + + org.hsqldb + hsqldb + + + org.jsoup + jsoup + + + com.nulab-inc + zxcvbn + + + com.thoughtworks.xstream + xstream + + + cglib + cglib-nodep + + + xml-resolver + xml-resolver + + + io.jsonwebtoken + jjwt + + + com.google.guava + guava + + + commons-io + commons-io + + + org.apache.commons + commons-lang3 + + + org.apache.commons + commons-text + + + org.bitbucket.b_c + jose4j + + + org.webjars + bootstrap + + + org.webjars + jquery + + + org.glassfish.jaxb + jaxb-runtime + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + com.github.tomakehurst + wiremock + test + + + io.rest-assured + rest-assured + test + + + io.openpixee + java-security-toolkit + + + + + + + false + + central + https://repo.maven.apache.org/maven2 + + + + + + false + + central + https://repo.maven.apache.org/maven2 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + true + org.owasp.webgoat.server.StartWebGoat + + + + org.asciidoctor + asciidoctorj + + + + + + + repackage + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-integration-test-source-as-test-sources + + add-test-source + + generate-test-sources + + + src/it/java + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + ${basedir}/src/test/resources/logback-test.xml + + -Xmx512m -Dwebgoatport=${webgoat.port} -Dwebwolfport=${webwolf.port} + org/owasp/webgoat/*Test + + + + integration-test + + integration-test + + + + verify + + verify + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED + --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED + + **/*IntegrationTest.java + src/it/java + org/owasp/webgoat/*Test + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${checkstyle.version} + + UTF-8 + true + true + config/checkstyle/checkstyle.xml + config/checkstyle/suppressions.xml + checkstyle.suppressions.file + + + + com.diffplug.spotless + spotless-maven-plugin + 2.33.0 + + + + + .gitignore + + + + + true + 4 + + + + + + **/*.md + + + + + + src/main/java/**/*.java + src/test/java/**/*.java + src/it/java/**/*.java + + + + + true + + + + + UTF-8 + ${line.separator} + true + false + true + 2 + false + false + recommended_2008_06 + true + true + true + + + + + + + check + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.2.1 + + + restrict-log4j-versions + + enforce + + validate + + + + + org.apache.logging.log4j:log4j-core + + + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 17 + 17 + + + + + + + + local-server + + + start-server + + true + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + reserve-container-port + + reserve-network-port + + process-resources + + + webgoat.port + webwolf.port + jmxPort + + + + + + + com.bazaarvoice.maven.plugins + process-exec-maven-plugin + 0.9 + + + start-jar + + start + + pre-integration-test + + ${project.build.directory} + + java + -jar + -Dlogging.pattern.console= + -Dwebgoat.server.directory=${java.io.tmpdir}/webgoat_${webgoat.port} + -Dwebgoat.user.directory=${java.io.tmpdir}/webgoat_${webgoat.port} + -Dspring.main.banner-mode=off + -Dwebgoat.port=${webgoat.port} + -Dwebwolf.port=${webwolf.port} + --add-opens + java.base/java.lang=ALL-UNNAMED + --add-opens + java.base/java.util=ALL-UNNAMED + --add-opens + java.base/java.lang.reflect=ALL-UNNAMED + --add-opens + java.base/java.text=ALL-UNNAMED + --add-opens + java.desktop/java.beans=ALL-UNNAMED + --add-opens + java.desktop/java.awt.font=ALL-UNNAMED + --add-opens + java.base/sun.nio.ch=ALL-UNNAMED + --add-opens + java.base/java.io=ALL-UNNAMED + --add-opens + java.base/java.util=ALL-UNNAMED + ${project.build.directory}/webgoat-${project.version}.jar + + false + http://localhost:${webgoat.port}/WebGoat/actuator/health + + + + stop-jar-process + + stop-all + + post-integration-test + + + + + + + + owasp + + false + + + + + org.owasp + dependency-check-maven + 6.5.1 + + 7 + false + false + + + ${maven.multiModuleProjectDirectory}/config/dependency-check/project-suppression.xml + + + + + + check + + + + + + + + + + coverage + + false + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED + --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED + ${surefire.jacoco.args} + + **/*IntegrationTest.java + src/it/java + org/owasp/webgoat/*Test + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco.version} + + + before-unit-test + + prepare-agent + + + ${project.build.directory}/jacoco/jacoco-ut.exec + surefire.jacoco.args + + + + check + + check + + + + + BUNDLE + + + CLASS + COVEREDCOUNT + 0.6 + + + + + ${project.build.directory}/jacoco/jacoco-ut.exec + + + + after-unit-test + + report + + test + + ${project.build.directory}/jacoco/jacoco-ut.exec + ${project.reporting.outputDirectory}/jacoco-unit-test-coverage-report + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-6.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-case-6.xml new file mode 100644 index 000000000..de2f19e0c --- /dev/null +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-case-6.xml @@ -0,0 +1,814 @@ + + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.7.1 + + org.owasp.webgoat + webgoat + 2023.5-SNAPSHOT + jar + + WebGoat + WebGoat, a deliberately insecure Web Application + https://github.com/WebGoat/WebGoat + 2006 + + OWASP + https://github.com/WebGoat/WebGoat/ + + + + GNU General Public License, version 2 + https://www.gnu.org/licenses/gpl-2.0.txt + + + + + mayhew64 + Bruce Mayhew + webgoat@owasp.org + OWASP + https://github.com/WebGoat/WebGoat + + + nbaars + Nanne Baars + nanne.baars@owasp.org + https://github.com/nbaars + Europe/Amsterdam + + + misfir3 + Jason White + jason.white@owasp.org + + + zubcevic + René Zubcevic + rene.zubcevic@owasp.org + + + aolle + Àngel Ollé Blázquez + angel@olleb.com + + + jwayman + Jeff Wayman + + + + + + dcowden + Dave Cowden + + + + lawson89 + Richard Lawson + + + + dougmorato + Doug Morato + doug.morato@owasp.org + OWASP + https://github.com/dougmorato + America/New_York + + https://avatars2.githubusercontent.com/u/9654?v=3&s=150 + + + + + + + OWASP WebGoat Mailing List + https://lists.owasp.org/mailman/listinfo/owasp-webgoat + Owasp-webgoat-request@lists.owasp.org + owasp-webgoat@lists.owasp.org + http://lists.owasp.org/pipermail/owasp-webgoat/ + + + + + scm:git:git@github.com:WebGoat/WebGoat.git + scm:git:git@github.com:WebGoat/WebGoat.git + HEAD + https://github.com/WebGoat/WebGoat + + + + Github Issues + https://github.com/WebGoat/WebGoat/issues + + + + + 2.5.3 + 3.3.7 + 2.2 + + 3.1.2 + 3.2.1 + 2.11.0 + 3.12.0 + 1.10.0 + 30.1-jre + 0.8.8 + 17 + 0.9.1 + 0.9.3 + 3.5.1 + 1.15.4 + 3.8.0 + 2.22.0 + 3.1.2 + 3.1.1 + 3.1.0 + 3.0.0-M9 + 17 + 17 + 3.15.0 + + UTF-8 + UTF-8 + 3.0.15.RELEASE + 5.3.2 + 8080 + 9090 + 2.27.2 + 1.2 + 1.4.5 + + 1.5.2 + + + + + + + org.ow2.asm + asm + 9.1 + + + + org.apache.commons + commons-exec + 1.3 + + + org.asciidoctor + asciidoctorj + ${asciidoctorj.version} + + + + org.jsoup + jsoup + ${jsoup.version} + + + com.nulab-inc + zxcvbn + ${zxcvbn.version} + + + com.thoughtworks.xstream + xstream + ${xstream.version} + + + cglib + cglib-nodep + ${cglib.version} + + + xml-resolver + xml-resolver + ${xml-resolver.version} + + + io.jsonwebtoken + jjwt + ${jjwt.version} + + + com.google.guava + guava + ${guava.version} + + + commons-io + commons-io + ${commons-io.version} + + + org.apache.commons + commons-text + ${commons-text.version} + + + org.bitbucket.b_c + jose4j + ${jose4j.version} + + + org.webjars + bootstrap + ${bootstrap.version} + + + org.webjars + jquery + ${jquery.version} + + + com.github.tomakehurst + wiremock + ${wiremock.version} + + + io.github.bonigarcia + webdrivermanager + ${webdriver.version} + + + org.apache.commons + commons-compress + 1.22 + + + org.jruby + jruby + 9.3.6.0 + + + + + + + org.apache.commons + commons-exec + + + org.springframework.boot + spring-boot-starter-validation + + + org.projectlombok + lombok + provided + true + + + javax.xml.bind + jaxb-api + + + org.springframework.boot + spring-boot-starter-undertow + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.flywaydb + flyway-core + + + org.asciidoctor + asciidoctorj + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.thymeleaf.extras + thymeleaf-extras-springsecurity5 + + + org.hsqldb + hsqldb + + + org.jsoup + jsoup + + + com.nulab-inc + zxcvbn + + + com.thoughtworks.xstream + xstream + + + cglib + cglib-nodep + + + xml-resolver + xml-resolver + + + io.jsonwebtoken + jjwt + + + com.google.guava + guava + + + commons-io + commons-io + + + org.apache.commons + commons-lang3 + + + org.apache.commons + commons-text + + + org.bitbucket.b_c + jose4j + + + org.webjars + bootstrap + + + org.webjars + jquery + + + org.glassfish.jaxb + jaxb-runtime + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + com.github.tomakehurst + wiremock + test + + + io.rest-assured + rest-assured + test + + + + + + + false + + central + https://repo.maven.apache.org/maven2 + + + + + + false + + central + https://repo.maven.apache.org/maven2 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + true + org.owasp.webgoat.server.StartWebGoat + + + + org.asciidoctor + asciidoctorj + + + + + + + repackage + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-integration-test-source-as-test-sources + + add-test-source + + generate-test-sources + + + src/it/java + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + ${basedir}/src/test/resources/logback-test.xml + + -Xmx512m -Dwebgoatport=${webgoat.port} -Dwebwolfport=${webwolf.port} + org/owasp/webgoat/*Test + + + + integration-test + + integration-test + + + + verify + + verify + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED + --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED + + **/*IntegrationTest.java + src/it/java + org/owasp/webgoat/*Test + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${checkstyle.version} + + UTF-8 + true + true + config/checkstyle/checkstyle.xml + config/checkstyle/suppressions.xml + checkstyle.suppressions.file + + + + com.diffplug.spotless + spotless-maven-plugin + 2.33.0 + + + + + .gitignore + + + + + true + 4 + + + + + + **/*.md + + + + + + src/main/java/**/*.java + src/test/java/**/*.java + src/it/java/**/*.java + + + + + true + + + + + UTF-8 + ${line.separator} + true + false + true + 2 + false + false + recommended_2008_06 + true + true + true + + + + + + + check + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.2.1 + + + restrict-log4j-versions + + enforce + + validate + + + + + org.apache.logging.log4j:log4j-core + + + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 17 + 17 + + + + + + + + local-server + + + start-server + + true + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + reserve-container-port + + reserve-network-port + + process-resources + + + webgoat.port + webwolf.port + jmxPort + + + + + + + com.bazaarvoice.maven.plugins + process-exec-maven-plugin + 0.9 + + + start-jar + + start + + pre-integration-test + + ${project.build.directory} + + java + -jar + -Dlogging.pattern.console= + -Dwebgoat.server.directory=${java.io.tmpdir}/webgoat_${webgoat.port} + -Dwebgoat.user.directory=${java.io.tmpdir}/webgoat_${webgoat.port} + -Dspring.main.banner-mode=off + -Dwebgoat.port=${webgoat.port} + -Dwebwolf.port=${webwolf.port} + --add-opens + java.base/java.lang=ALL-UNNAMED + --add-opens + java.base/java.util=ALL-UNNAMED + --add-opens + java.base/java.lang.reflect=ALL-UNNAMED + --add-opens + java.base/java.text=ALL-UNNAMED + --add-opens + java.desktop/java.beans=ALL-UNNAMED + --add-opens + java.desktop/java.awt.font=ALL-UNNAMED + --add-opens + java.base/sun.nio.ch=ALL-UNNAMED + --add-opens + java.base/java.io=ALL-UNNAMED + --add-opens + java.base/java.util=ALL-UNNAMED + ${project.build.directory}/webgoat-${project.version}.jar + + false + http://localhost:${webgoat.port}/WebGoat/actuator/health + + + + stop-jar-process + + stop-all + + post-integration-test + + + + + + + + owasp + + false + + + + + org.owasp + dependency-check-maven + 6.5.1 + + 7 + false + false + + + ${maven.multiModuleProjectDirectory}/config/dependency-check/project-suppression.xml + + + + + + check + + + + + + + + + + coverage + + false + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED + --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED + ${surefire.jacoco.args} + + **/*IntegrationTest.java + src/it/java + org/owasp/webgoat/*Test + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco.version} + + + before-unit-test + + prepare-agent + + + ${project.build.directory}/jacoco/jacoco-ut.exec + surefire.jacoco.args + + + + check + + check + + + + + BUNDLE + + + CLASS + COVEREDCOUNT + 0.6 + + + + + ${project.build.directory}/jacoco/jacoco-ut.exec + + + + after-unit-test + + report + + test + + ${project.build.directory}/jacoco/jacoco-ut.exec + ${project.reporting.outputDirectory}/jacoco-unit-test-coverage-report + + + + + + + + + \ No newline at end of file From fac3c4bb9bf295ca4a1ea267ab8b5c6a6043e499 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Sun, 12 Mar 2023 13:42:06 -0500 Subject: [PATCH 083/153] Releasing --- README.md | 4 ++-- pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ac21e2073..16182a0bd 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,6 @@ mvn -N -B deploy -DaltDeploymentRepository=pixee-libs-release::default::https:/ ``` - ~~better readme~~ -- be able to guess existing indenting for existing documents -- investigate leverage whats on [versions-maven-plugin](https://github.com/mojohaus/versions-maven-plugin) +- ~~be able to guess existing indenting for existing documents~~ +- ~~investigate leverage whats on [versions-maven-plugin](https://github.com/mojohaus/versions-maven-plugin)~~ - consider fuzzying when testing diff --git a/pom.xml b/pom.xml index c306c3e8a..64bb1fc5b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.openpixee.maven pom-operator - 0.0.5-SNAPSHOT + 0.0.5 scm:git:${project.scm.url} From 350b976e0393e4e165e1255a16cd5c0ed0d8e7a3 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Sun, 12 Mar 2023 13:44:50 -0500 Subject: [PATCH 084/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index 6c4a77542..e27e52eee 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.openpixee.pom java-sample - 0.0.5-SNAPSHOT + 0.0.6-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index 64bb1fc5b..c4d6f973b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.openpixee.maven pom-operator - 0.0.5 + 0.0.6-SNAPSHOT scm:git:${project.scm.url} From aca7a87ccfbb52931a957ecc4d34fb5375d7463b Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 7 Apr 2023 12:59:58 -0500 Subject: [PATCH 085/153] Implement Tab Handling (#13) * Implement Tab Handling * [no ci] Autogenerated JaCoCo coverage badge * Reformatting - making meaning clearer * [no ci] Autogenerated JaCoCo coverage badge --------- Co-authored-by: Jacoco Coverage Update Action --- .../openpixee/maven/operator/FormatCommand.kt | 53 +++++++++++--- .../maven/operator/test/POMOperatorTest.kt | 28 ++++++++ .../test/pom-case-with-tabs-result.xml | 69 +++++++++++++++++++ 3 files changed, 142 insertions(+), 8 deletions(-) create mode 100644 src/test/resources/io/openpixee/maven/operator/test/pom-case-with-tabs-result.xml diff --git a/src/main/java/io/openpixee/maven/operator/FormatCommand.kt b/src/main/java/io/openpixee/maven/operator/FormatCommand.kt index aa2aa0792..f0f19fab5 100644 --- a/src/main/java/io/openpixee/maven/operator/FormatCommand.kt +++ b/src/main/java/io/openpixee/maven/operator/FormatCommand.kt @@ -4,7 +4,7 @@ import org.apache.commons.lang3.StringUtils import org.mozilla.universalchardet.UniversalDetector import java.io.StringWriter import java.nio.charset.Charset -import java.util.BitSet +import java.util.* import javax.xml.stream.XMLInputFactory import javax.xml.stream.XMLOutputFactory import javax.xml.stream.events.Characters @@ -93,14 +93,21 @@ class FormatCommand : AbstractSimpleCommand() { ) }.sortedByDescending { it.first }.toMap(LinkedHashMap()) + /** + * Guesses the indent character (spaces / tabs) and length from the original document + * formatting settings + * + * @param c (project model) where it takes its input pom + * @return indent string + */ private fun guessIndent(c: ProjectModel): String { val eventReader = inputFactory.createXMLEventReader(c.originalPom.inputStream()) - val indent = " " val freqMap: MutableMap = mutableMapOf() + val charFreqMap: MutableMap = mutableMapOf() /** - * Parse, while grabbing whitespace sequences and counting + * Parse, while grabbing whitespace sequences and examining it */ while (eventReader.hasNext()) { val event = eventReader.nextEvent() @@ -110,22 +117,52 @@ class FormatCommand : AbstractSimpleCommand() { val patterns = event.asCharacters().data.split(*LINE_ENDINGS.toTypedArray()) /** - * Updates space frequencies + * Updates space / character frequencies found */ - patterns + val blankPatterns = patterns .filter { it.isNotEmpty() } .filter { StringUtils.isAllBlank(it) } + + blankPatterns .map { it to it.length } .forEach { - freqMap.merge(it.second, 1) { a, b -> a + b} + freqMap.merge(it.second, 1) { a, b -> a + b } + } + + blankPatterns.map { it[0] } + .forEach { + charFreqMap.merge(it, 1) { a, b -> + a + b + } } } } } + /** + * Assign most frequent indent char + */ + val indentCharacter: Char = charFreqMap.entries.maxBy { it.value }.key + + /** + * Casts as a String + */ + val indentcharacterAsString = String(charArrayOf(indentCharacter)) + + /** + * Picks the length + */ val indentLength = freqMap.entries.minBy { it.key }.key - return StringUtils.repeat(indent, indentLength) + /** + * Builds the standard indent string (length vs char) + */ + val indentString = StringUtils.repeat(indentcharacterAsString, indentLength) + + /** + * Returns it + */ + return indentString } private fun parseLineEndings(c: ProjectModel): String { @@ -199,7 +236,7 @@ class FormatCommand : AbstractSimpleCommand() { val targetElementMap = elementBitSet(xmlRepresentation.toByteArray()) // Let's find out the original empty elements from the original pom and store into a stack - val elementsToReplace : MutableList = ArrayList().apply{ + val elementsToReplace: MutableList = ArrayList().apply { val matches = findSingleElementMatchesFrom(c.originalPom.toString(c.charset)).values val filteredMatches = matches.filter { originalElementMap[it.range.first] } diff --git a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt index c5e326e74..e0ecc4ece 100644 --- a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt +++ b/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt @@ -11,6 +11,7 @@ import org.junit.Assert.assertEquals import org.junit.Test import org.xmlunit.diff.ComparisonType import java.io.File +import java.nio.charset.Charset import kotlin.test.assertTrue /** @@ -397,4 +398,31 @@ class POMOperatorTest : AbstractTestBase() { assertThat("Document has several differences", differencesAsList.size > 1) } + @Test + fun testFileWithTabs() { + val dependencyToUpgrade = + Dependency("org.dom4j", "dom4j", version = "1.0.0") + + val originalPom = + "\n\n\t4.0.0\n\t\n\t\tbuild-utils\n\t\torg.modafocas.mojo\n\t\t0.0.1-SNAPSHOT\n\t\t../pom.xml\n\t\n\n\tderby-maven-plugin\n\tmaven-plugin\n\n\t\n\t\t\n\t\t\torg.apache.maven\n\t\t\tmaven-plugin-api\n\t\t\t2.0\n\t\t\n\t\t\n\t\t\tjunit\n\t\t\tjunit\n\t\t\t3.8.1\n\t\t\ttest\n\t\t\n\t\t\n\t\t\torg.apache.derby\n\t\t\tderby\n\t\t\t\${derbyVersion}\n\t\t\n\t\t\n\t\t\torg.apache.derby\n\t\t\tderbynet\n\t\t\t\${derbyVersion}\n\t\t\n\t\t\n\t\t\torg.apache.derby\n\t\t\tderbyclient\n\t\t\t\${derbyVersion}\n\t\t\n\t\t\n\t\t\tcommons-io\n\t\t\tcommons-io\n\t\t\t1.4\n\t\t\tjar\n\t\t\tcompile\n\t\t\n\t\n\n\t\n\t\t10.6.2.1\n\t\n\n" + + val context = + ProjectModelFactory.load( + originalPom.byteInputStream(), + ).withDependency(dependencyToUpgrade).withUseProperties(true).withSkipIfNewer(true) + .build() + + POMOperator.modify(context) + + val resultPom = context.resultPomBytes.toString(Charset.defaultCharset()) + + // aldrin: uncomment this to check out formatting - useful for the next section + // println(StringEscapeUtils.escapeJava(resultPom)) + + assertThat( + "Document should have a tab-based string", + resultPom.contains("\n\t\t\n\t\t\torg.dom4j\n\t\t\tdom4j\n\t\t\n") + ) + } + } diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-with-tabs-result.xml b/src/test/resources/io/openpixee/maven/operator/test/pom-case-with-tabs-result.xml new file mode 100644 index 000000000..d9ce1162a --- /dev/null +++ b/src/test/resources/io/openpixee/maven/operator/test/pom-case-with-tabs-result.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + + build-utils + org.modafocas.mojo + 0.0.1-SNAPSHOT + ../pom.xml + + + derby-maven-plugin + maven-plugin + + + + org.apache.maven + maven-plugin-api + 2.0 + + + junit + junit + 3.8.1 + test + + + org.apache.derby + derby + ${derbyVersion} + + + org.apache.derby + derbynet + ${derbyVersion} + + + org.apache.derby + derbyclient + ${derbyVersion} + + + commons-io + commons-io + 1.4 + jar + compile + + + org.dom4j + dom4j + + + + + 10.6.2.1 + 1.0.0 + + + + + org.dom4j + dom4j + ${versions.dom4j} + + + + From efd85a63a154eec252bcf7bde27d2654c19b9c38 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 7 Apr 2023 13:01:13 -0500 Subject: [PATCH 086/153] Generating Tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c4d6f973b..c0b9f8352 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.openpixee.maven pom-operator - 0.0.6-SNAPSHOT + 0.0.6 scm:git:${project.scm.url} From 3f6479dac6987a0944d09f277ce3e67940a853de Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 7 Apr 2023 13:02:06 -0500 Subject: [PATCH 087/153] Missing part --- java-sample/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index e27e52eee..f1a6b3726 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.openpixee.pom java-sample - 0.0.6-SNAPSHOT + 0.0.6 UTF-8 From 6546ea4683aef06136b1a296af99af96719eeb3e Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 7 Apr 2023 13:11:15 -0500 Subject: [PATCH 088/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index f1a6b3726..63d3213a6 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.openpixee.pom java-sample - 0.0.6 + 0.0.7-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index c0b9f8352..47804aa5b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.openpixee.maven pom-operator - 0.0.6 + 0.0.7-SNAPSHOT scm:git:${project.scm.url} From 43a2b3e3b375f2203103a1cbf4da97fce868b1ad Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 5 May 2023 19:09:39 -0500 Subject: [PATCH 089/153] Refactor POM to Expose Dependencies (#14) * Refactor POM to Expose Dependencies * bumping versions --- pom.xml | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/pom.xml b/pom.xml index 47804aa5b..3df237e38 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,8 @@ 1.7.10 2.0.0 2.5.3 + 1.9.2 + 3.8.6 @@ -139,71 +141,73 @@ 3.2.0 compile + + com.google.inject + guice + 5.1.0 + org.apache.maven maven-embedder - 3.8.6 + ${versions.maven.core} compile + + + com.google.inject + guice + + org.apache.maven maven-compat - 3.8.6 + ${versions.maven.core} compile org.apache.maven.resolver maven-resolver-api - 1.9.2 - provided + ${versions.maven.resolver} org.apache.maven.resolver maven-resolver-spi - 1.9.2 - provided + ${versions.maven.resolver} org.apache.maven.resolver maven-resolver-util - 1.9.2 - provided + ${versions.maven.resolver} org.apache.maven.resolver maven-resolver-impl - 1.9.2 - provided + ${versions.maven.resolver} org.apache.maven.resolver maven-resolver-transport-file - 1.9.2 - provided + ${versions.maven.resolver} org.apache.maven.resolver maven-resolver-transport-http - 1.9.2 - provided + ${versions.maven.resolver} org.apache.maven.resolver maven-resolver-connector-basic - 1.9.2 - provided + ${versions.maven.resolver} org.apache.maven maven-resolver-provider - 3.8.6 - provided + ${versions.maven.core} org.apache.maven maven-model-builder - 3.8.6 - provided + ${versions.maven.core} com.github.albfernandez From 69b2ee17bc41d77452301b5ba61c2f0d12b8416a Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 5 May 2023 19:11:35 -0500 Subject: [PATCH 090/153] Generating Tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3df237e38..b47582de9 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.openpixee.maven pom-operator - 0.0.7-SNAPSHOT + 0.0.7 scm:git:${project.scm.url} From b24f6bafbb81c93e4ffcef687eec32c662d99c37 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 5 May 2023 19:19:24 -0500 Subject: [PATCH 091/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index 63d3213a6..a596255bd 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.openpixee.pom java-sample - 0.0.7-SNAPSHOT + 0.0.8-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index b47582de9..1fc28544d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.openpixee.maven pom-operator - 0.0.7 + 0.0.8-SNAPSHOT scm:git:${project.scm.url} From b34ba332f3d949ada85abaee5789fd5bd120e0c7 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 8 May 2023 19:09:50 -0500 Subject: [PATCH 092/153] Mass renaming (#15) --- README.md | 12 ++++---- java-sample/pom.xml | 4 +-- .../pixee}/it/POMOperatorJavaTest.java | 10 +++---- .../io/{openpixee => github/pixee}/it/pom.xml | 0 pom.xml | 4 +-- .../maven/operator/AbstractSimpleCommand.kt | 16 +++++------ .../operator/AbstractSimpleQueryCommand.kt | 28 +++++++++---------- .../pixee}/maven/operator/Chain.kt | 4 +-- .../maven/operator/CheckDependencyPresent.kt | 4 +-- .../pixee}/maven/operator/Command.kt | 2 +- .../pixee}/maven/operator/Dependency.kt | 2 +- .../maven/operator/DiscardFormatCommand.kt | 4 +-- .../pixee}/maven/operator/FormatCommand.kt | 4 +-- .../maven/operator/InvalidContextException.kt | 2 +- .../operator/MissingDependencyException.kt | 2 +- .../pixee}/maven/operator/POMOperator.kt | 4 +-- .../pixee}/maven/operator/ProjectModel.kt | 4 +-- .../maven/operator/ProjectModelFactory.kt | 2 +- .../pixee}/maven/operator/QueryByEmbedder.kt | 4 +-- .../pixee}/maven/operator/QueryByInvoker.kt | 4 +-- .../pixee}/maven/operator/QueryByResolver.kt | 4 +-- .../pixee}/maven/operator/QueryType.kt | 2 +- .../operator/SimpleDependencyManagement.kt | 13 +++++++++ .../pixee}/maven/operator/SimpleInsert.kt | 10 +++---- .../pixee}/maven/operator/SimpleUpgrade.kt | 6 ++-- .../pixee}/maven/operator/SupportCommand.kt | 2 +- .../pixee}/maven/operator/Util.kt | 4 +-- .../operator/SimpleDependencyManagement.kt | 13 --------- .../maven/operator/test/AbstractTestBase.kt | 8 +++--- .../maven/operator/test/MassRepoTest.kt | 12 ++++---- .../operator/test/POMOperatorJavaIT.java | 4 +-- .../operator/test/POMOperatorQueryTest.kt | 6 ++-- .../maven/operator/test/POMOperatorTest.kt | 16 +++++------ .../operator/test/PropertyResolutionTest.kt | 6 ++-- .../pixee}/maven/operator/test/util.kt | 6 ++-- .../pixee}/maven/operator/test/broken-pom.xml | 0 .../pixee}/maven/operator/test/pom-1.xml | 0 .../pixee}/maven/operator/test/pom-3.xml | 0 .../pixee}/maven/operator/test/pom-broken.xml | 0 .../maven/operator/test/pom-case-1-result.xml | 0 .../pixee}/maven/operator/test/pom-case-1.xml | 0 .../maven/operator/test/pom-case-3-result.xml | 0 .../pixee}/maven/operator/test/pom-case-3.xml | 0 .../maven/operator/test/pom-case-4-result.xml | 0 .../pixee}/maven/operator/test/pom-case-4.xml | 0 .../maven/operator/test/pom-case-5-result.xml | 6 ++-- .../pixee}/maven/operator/test/pom-case-5.xml | 0 .../maven/operator/test/pom-case-6-result.xml | 6 ++-- .../pixee}/maven/operator/test/pom-case-6.xml | 0 .../test/pom-case-with-property-result.xml | 0 .../test/pom-case-with-tabs-result.xml | 0 ...m-case-three-with-lower-version-result.xml | 0 .../test/pom-with-property-simple.xml | 0 .../maven/operator/test/sample-bad-pom.xml | 0 .../maven/operator/test/webgoat-parent.xml | 0 55 files changed, 120 insertions(+), 120 deletions(-) rename java-sample/src/test/java/io/{openpixee => github/pixee}/it/POMOperatorJavaTest.java (59%) rename java-sample/src/test/resources/io/{openpixee => github/pixee}/it/pom.xml (100%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/AbstractSimpleCommand.kt (59%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/AbstractSimpleQueryCommand.kt (81%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/Chain.kt (95%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/CheckDependencyPresent.kt (73%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/Command.kt (91%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/Dependency.kt (95%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/DiscardFormatCommand.kt (87%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/FormatCommand.kt (98%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/InvalidContextException.kt (83%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/MissingDependencyException.kt (66%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/POMOperator.kt (89%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/ProjectModel.kt (95%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/ProjectModelFactory.kt (98%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/QueryByEmbedder.kt (95%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/QueryByInvoker.kt (85%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/QueryByResolver.kt (98%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/QueryType.kt (59%) create mode 100644 src/main/java/io/github/pixee/maven/operator/SimpleDependencyManagement.kt rename src/main/java/io/{openpixee => github/pixee}/maven/operator/SimpleInsert.kt (89%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/SimpleUpgrade.kt (58%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/SupportCommand.kt (75%) rename src/main/java/io/{openpixee => github/pixee}/maven/operator/Util.kt (98%) delete mode 100644 src/main/java/io/openpixee/maven/operator/SimpleDependencyManagement.kt rename src/test/java/io/{openpixee => github/pixee}/maven/operator/test/AbstractTestBase.kt (93%) rename src/test/java/io/{openpixee => github/pixee}/maven/operator/test/MassRepoTest.kt (95%) rename src/test/java/io/{openpixee => github/pixee}/maven/operator/test/POMOperatorJavaIT.java (92%) rename src/test/java/io/{openpixee => github/pixee}/maven/operator/test/POMOperatorQueryTest.kt (93%) rename src/test/java/io/{openpixee => github/pixee}/maven/operator/test/POMOperatorTest.kt (96%) rename src/test/java/io/{openpixee => github/pixee}/maven/operator/test/PropertyResolutionTest.kt (91%) rename src/test/java/io/{openpixee => github/pixee}/maven/operator/test/util.kt (92%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/broken-pom.xml (100%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/pom-1.xml (100%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/pom-3.xml (100%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/pom-broken.xml (100%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/pom-case-1-result.xml (100%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/pom-case-1.xml (100%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/pom-case-3-result.xml (100%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/pom-case-3.xml (100%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/pom-case-4-result.xml (100%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/pom-case-4.xml (100%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/pom-case-5-result.xml (99%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/pom-case-5.xml (100%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/pom-case-6-result.xml (99%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/pom-case-6.xml (100%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/pom-case-with-property-result.xml (100%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/pom-case-with-tabs-result.xml (100%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/pom-pom-case-three-with-lower-version-result.xml (100%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/pom-with-property-simple.xml (100%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/sample-bad-pom.xml (100%) rename src/test/resources/io/{openpixee => github/pixee}/maven/operator/test/webgoat-parent.xml (100%) diff --git a/README.md b/README.md index 16182a0bd..1e637196f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Actions Status](https://github.com/openpixee/pom-operator/workflows/Java%20CI/badge.svg)](https://github.com/openpixee/pom-operator/actions) +[![Actions Status](https://github.com/pixee/pom-operator/workflows/Java%20CI/badge.svg)](https://github.com/pixee/pom-operator/actions) ![Coverage](.github/badges/jacoco.svg) # pom-operator @@ -10,7 +10,7 @@ POM Operator is a library responsible for injecting dependencies into POM files Use [Maven](https://maven.apache.org): ``` -$ git clone git@github.com:openpixee/pom-operator.git && cd pom-operator +$ git clone git@github.com:pixee/pom-operator.git && cd pom-operator $ mvn clean install ``` @@ -21,10 +21,10 @@ There's a sample of usage from Java on the `java-sample` directory - of look und ```java import org.junit.Test; -import io.openpixee.maven.operator.ProjectModel; -import io.openpixee.maven.operator.Dependency; -import io.openpixee.maven.operator.POMOperator; -import io.openpixee.maven.operator.ProjectModelFactory; +import io.github.pixee.maven.operator.ProjectModel; +import io.github.pixee.maven.operator.Dependency; +import io.github.pixee.maven.operator.POMOperator; +import io.github.pixee.maven.operator.ProjectModelFactory; public class POMOperatorJavaTest { @Test diff --git a/java-sample/pom.xml b/java-sample/pom.xml index a596255bd..dc5982004 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - io.openpixee.pom + io.github.pixee.maven.sample java-sample 0.0.8-SNAPSHOT @@ -17,7 +17,7 @@ - io.openpixee.maven + io.github.pixee.maven pom-operator ${project.version} diff --git a/java-sample/src/test/java/io/openpixee/it/POMOperatorJavaTest.java b/java-sample/src/test/java/io/github/pixee/it/POMOperatorJavaTest.java similarity index 59% rename from java-sample/src/test/java/io/openpixee/it/POMOperatorJavaTest.java rename to java-sample/src/test/java/io/github/pixee/it/POMOperatorJavaTest.java index 9be326dfb..d6267f3b4 100644 --- a/java-sample/src/test/java/io/openpixee/it/POMOperatorJavaTest.java +++ b/java-sample/src/test/java/io/github/pixee/it/POMOperatorJavaTest.java @@ -1,11 +1,11 @@ -package io.openpixee.it; +package io.github.pixee.it; import org.junit.Test; -import io.openpixee.maven.operator.ProjectModel; -import io.openpixee.maven.operator.Dependency; -import io.openpixee.maven.operator.POMOperator; -import io.openpixee.maven.operator.ProjectModelFactory; +import io.github.pixee.maven.operator.ProjectModel; +import io.github.pixee.maven.operator.Dependency; +import io.github.pixee.maven.operator.POMOperator; +import io.github.pixee.maven.operator.ProjectModelFactory; public class POMOperatorJavaTest { @Test diff --git a/java-sample/src/test/resources/io/openpixee/it/pom.xml b/java-sample/src/test/resources/io/github/pixee/it/pom.xml similarity index 100% rename from java-sample/src/test/resources/io/openpixee/it/pom.xml rename to java-sample/src/test/resources/io/github/pixee/it/pom.xml diff --git a/pom.xml b/pom.xml index 1fc28544d..9c6a70f9e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,14 +4,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - io.openpixee.maven + io.github.pixee.maven pom-operator 0.0.8-SNAPSHOT scm:git:${project.scm.url} scm:git:${project.scm.url} - git@github.com:openpixee/pom-operator.git + git@github.com:pixee/pom-operator.git HEAD diff --git a/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt b/src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt similarity index 59% rename from src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt rename to src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt index bf62992a3..d2659fe8f 100644 --- a/src/main/java/io/openpixee/maven/operator/AbstractSimpleCommand.kt +++ b/src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt @@ -1,18 +1,18 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator -import io.openpixee.maven.operator.Util.findOutIfUpgradeIsNeeded -import io.openpixee.maven.operator.Util.selectXPathNodes -import io.openpixee.maven.operator.Util.upgradeVersionNode +import io.github.pixee.maven.operator.Util.findOutIfUpgradeIsNeeded +import io.github.pixee.maven.operator.Util.selectXPathNodes +import io.github.pixee.maven.operator.Util.upgradeVersionNode import org.dom4j.Element /** * Base implementation of Command - used by SimpleDependency and SimpleInsert */ -abstract class AbstractSimpleCommand : Command { +abstract class AbstractSimpleCommand : io.github.pixee.maven.operator.Command { /** * Given a POM, locate its coordinates for a given dependency based on lookupExpression and figures out the upgrade */ - protected fun handleDependency(c: ProjectModel, lookupExpression: String): Boolean { + protected fun handleDependency(c: io.github.pixee.maven.operator.ProjectModel, lookupExpression: String): Boolean { val dependencyNodes = c.resultPom.selectXPathNodes(lookupExpression) if (1 == dependencyNodes.size) { @@ -38,7 +38,7 @@ abstract class AbstractSimpleCommand : Command { return false } - override fun execute(c: ProjectModel): Boolean = false + override fun execute(c: io.github.pixee.maven.operator.ProjectModel): Boolean = false - override fun postProcess(c: ProjectModel): Boolean = false + override fun postProcess(c: io.github.pixee.maven.operator.ProjectModel): Boolean = false } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/AbstractSimpleQueryCommand.kt b/src/main/java/io/github/pixee/maven/operator/AbstractSimpleQueryCommand.kt similarity index 81% rename from src/main/java/io/openpixee/maven/operator/AbstractSimpleQueryCommand.kt rename to src/main/java/io/github/pixee/maven/operator/AbstractSimpleQueryCommand.kt index 15e996bea..0d5bf0517 100644 --- a/src/main/java/io/openpixee/maven/operator/AbstractSimpleQueryCommand.kt +++ b/src/main/java/io/github/pixee/maven/operator/AbstractSimpleQueryCommand.kt @@ -1,6 +1,6 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator -import io.openpixee.maven.operator.Util.which +import io.github.pixee.maven.operator.Util.which import org.apache.commons.lang3.SystemUtils import org.apache.maven.shared.invoker.DefaultInvocationRequest import org.apache.maven.shared.invoker.InvocationRequest @@ -15,7 +15,7 @@ import java.util.* * relying on dependency:tree mojo outputting into a text file - which might be cached. * */ -abstract class AbstractSimpleQueryCommand : AbstractSimpleCommand() { +abstract class AbstractSimpleQueryCommand : io.github.pixee.maven.operator.AbstractSimpleCommand() { /** * Generates a temporary file path used to store the output of the
dependency:tree
mojo * @@ -36,7 +36,7 @@ abstract class AbstractSimpleQueryCommand : AbstractSimpleCommand() { * * @param c ProjectModel */ - protected fun getPomFilePath(c: ProjectModel): File = Paths.get(c.pomPath!!.toURI()).toFile() + protected fun getPomFilePath(c: io.github.pixee.maven.operator.ProjectModel): File = Paths.get(c.pomPath!!.toURI()).toFile() /** * Abstract Method to extract dependencies @@ -45,19 +45,19 @@ abstract class AbstractSimpleQueryCommand : AbstractSimpleCommand() { * @param pomFilePath Input Pom Path * @param c Project Model */ - abstract fun extractDependencyTree(outputPath: File, pomFilePath: File, c: ProjectModel) + abstract fun extractDependencyTree(outputPath: File, pomFilePath: File, c: io.github.pixee.maven.operator.ProjectModel) /** * Internal Holder Variable * * Todo: OF COURSE IT BREAKS THE PROTOCOL */ - internal var result: Collection? = null + internal var result: Collection? = null /** * We declare the main logic here - details are made in the child classes for now */ - override fun execute(c: ProjectModel): Boolean { + override fun execute(c: io.github.pixee.maven.operator.ProjectModel): Boolean { val pomFilePath = getPomFilePath(c) val outputPath = getOutputPath(pomFilePath) @@ -68,7 +68,7 @@ abstract class AbstractSimpleQueryCommand : AbstractSimpleCommand() { try { extractDependencyTree(outputPath, pomFilePath, c) - } catch (e: InvalidContextException) { + } catch (e: io.github.pixee.maven.operator.InvalidContextException) { return false } @@ -98,7 +98,7 @@ abstract class AbstractSimpleQueryCommand : AbstractSimpleCommand() { }.associate { (line, elements) -> val (groupId, artifactId, packaging, version, scope) = elements - line to Dependency( + line to io.github.pixee.maven.operator.Dependency( groupId = groupId, artifactId = artifactId, version = version, @@ -110,7 +110,7 @@ abstract class AbstractSimpleQueryCommand : AbstractSimpleCommand() { protected fun buildInvocationRequest( outputPath: File, pomFilePath: File, - c: ProjectModel + c: io.github.pixee.maven.operator.ProjectModel ): InvocationRequest { val props = Properties(System.getProperties()).apply { //System.getProperties().forEach { t, u -> setProperty(t as String, u as String) } @@ -132,7 +132,7 @@ abstract class AbstractSimpleQueryCommand : AbstractSimpleCommand() { properties = props - goals = listOf(DEPENDENCY_TREE_MOJO_REFERENCE) + goals = listOf(io.github.pixee.maven.operator.AbstractSimpleQueryCommand.Companion.DEPENDENCY_TREE_MOJO_REFERENCE) } return request @@ -163,7 +163,7 @@ abstract class AbstractSimpleQueryCommand : AbstractSimpleCommand() { val inferredHome = File(SystemUtils.getUserHome(), ".m2") if (!(inferredHome.exists() && inferredHome.isDirectory)) { - LOGGER.warn( + io.github.pixee.maven.operator.AbstractSimpleQueryCommand.Companion.LOGGER.warn( "Inferred User Home - which does not exist or not a directory: {}", inferredHome ) @@ -193,8 +193,8 @@ abstract class AbstractSimpleQueryCommand : AbstractSimpleCommand() { const val DEPENDENCY_TREE_MOJO_REFERENCE = "org.apache.maven.plugins:maven-dependency-plugin:3.3.0:tree" - val LOGGER: Logger = LoggerFactory.getLogger(AbstractSimpleQueryCommand::class.java) + val LOGGER: Logger = LoggerFactory.getLogger(io.github.pixee.maven.operator.AbstractSimpleQueryCommand::class.java) } - override fun postProcess(c: ProjectModel): Boolean = false + override fun postProcess(c: io.github.pixee.maven.operator.ProjectModel): Boolean = false } \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/Chain.kt b/src/main/java/io/github/pixee/maven/operator/Chain.kt similarity index 95% rename from src/main/java/io/openpixee/maven/operator/Chain.kt rename to src/main/java/io/github/pixee/maven/operator/Chain.kt index d1716b5de..be71eb3e0 100644 --- a/src/main/java/io/openpixee/maven/operator/Chain.kt +++ b/src/main/java/io/github/pixee/maven/operator/Chain.kt @@ -1,4 +1,4 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -81,7 +81,7 @@ class Chain(vararg commands: Command) { fun createForQuery(queryType: QueryType = QueryType.SAFE): Chain { val commands: List = AVAILABLE_QUERY_COMMANDS .filter { it.first == queryType }.mapNotNull { - val commandClassName = "io.openpixee.maven.operator.${it.second}" + val commandClassName = "io.github.pixee.maven.operator.${it.second}" try { @Suppress("DEPRECATION") diff --git a/src/main/java/io/openpixee/maven/operator/CheckDependencyPresent.kt b/src/main/java/io/github/pixee/maven/operator/CheckDependencyPresent.kt similarity index 73% rename from src/main/java/io/openpixee/maven/operator/CheckDependencyPresent.kt rename to src/main/java/io/github/pixee/maven/operator/CheckDependencyPresent.kt index eb552c6dc..912f11af3 100644 --- a/src/main/java/io/openpixee/maven/operator/CheckDependencyPresent.kt +++ b/src/main/java/io/github/pixee/maven/operator/CheckDependencyPresent.kt @@ -1,9 +1,9 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator /** * Guard Command Singleton use to validate required parameters */ -val CheckDependencyPresent = object : AbstractSimpleCommand() { +val CheckDependencyPresent = object : io.github.pixee.maven.operator.AbstractSimpleCommand() { override fun execute(c: ProjectModel): Boolean { /** * CheckDependencyPresent requires a Dependency to be Present diff --git a/src/main/java/io/openpixee/maven/operator/Command.kt b/src/main/java/io/github/pixee/maven/operator/Command.kt similarity index 91% rename from src/main/java/io/openpixee/maven/operator/Command.kt rename to src/main/java/io/github/pixee/maven/operator/Command.kt index 64aa5359e..befa37c1d 100644 --- a/src/main/java/io/openpixee/maven/operator/Command.kt +++ b/src/main/java/io/github/pixee/maven/operator/Command.kt @@ -1,4 +1,4 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator /** * Represents a Command in a Chain of Responsibility Pattern diff --git a/src/main/java/io/openpixee/maven/operator/Dependency.kt b/src/main/java/io/github/pixee/maven/operator/Dependency.kt similarity index 95% rename from src/main/java/io/openpixee/maven/operator/Dependency.kt rename to src/main/java/io/github/pixee/maven/operator/Dependency.kt index 9ab5a2292..b420b1c62 100644 --- a/src/main/java/io/openpixee/maven/operator/Dependency.kt +++ b/src/main/java/io/github/pixee/maven/operator/Dependency.kt @@ -1,4 +1,4 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator /** * Represents a Dependency diff --git a/src/main/java/io/openpixee/maven/operator/DiscardFormatCommand.kt b/src/main/java/io/github/pixee/maven/operator/DiscardFormatCommand.kt similarity index 87% rename from src/main/java/io/openpixee/maven/operator/DiscardFormatCommand.kt rename to src/main/java/io/github/pixee/maven/operator/DiscardFormatCommand.kt index 943b729cc..113f0f988 100644 --- a/src/main/java/io/openpixee/maven/operator/DiscardFormatCommand.kt +++ b/src/main/java/io/github/pixee/maven/operator/DiscardFormatCommand.kt @@ -1,4 +1,4 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator import org.xmlunit.builder.DiffBuilder import org.xmlunit.builder.Input @@ -6,7 +6,7 @@ import org.xmlunit.builder.Input /** * Command Class to Short-Circuit/Discard Processing when no pom changes were made */ -class DiscardFormatCommand : AbstractSimpleCommand() { +class DiscardFormatCommand : io.github.pixee.maven.operator.AbstractSimpleCommand() { override fun postProcess(c: ProjectModel): Boolean { val originalDoc = Input.fromString(String(c.originalPom)).build() val modifiedDoc = Input.fromString(c.resultPom.asXML()).build() diff --git a/src/main/java/io/openpixee/maven/operator/FormatCommand.kt b/src/main/java/io/github/pixee/maven/operator/FormatCommand.kt similarity index 98% rename from src/main/java/io/openpixee/maven/operator/FormatCommand.kt rename to src/main/java/io/github/pixee/maven/operator/FormatCommand.kt index f0f19fab5..444247158 100644 --- a/src/main/java/io/openpixee/maven/operator/FormatCommand.kt +++ b/src/main/java/io/github/pixee/maven/operator/FormatCommand.kt @@ -1,4 +1,4 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator import org.apache.commons.lang3.StringUtils import org.mozilla.universalchardet.UniversalDetector @@ -26,7 +26,7 @@ data class MatchData( * which are the only ones which are tricky to format (due to element and its attributes being freeform - thus formatting lost when serializing the DOM * and the PI being completely optional for the POM Document) */ -class FormatCommand : AbstractSimpleCommand() { +class FormatCommand : io.github.pixee.maven.operator.AbstractSimpleCommand() { /** * Preamble Contents are stored here */ diff --git a/src/main/java/io/openpixee/maven/operator/InvalidContextException.kt b/src/main/java/io/github/pixee/maven/operator/InvalidContextException.kt similarity index 83% rename from src/main/java/io/openpixee/maven/operator/InvalidContextException.kt rename to src/main/java/io/github/pixee/maven/operator/InvalidContextException.kt index 987aa1362..12817b9ce 100644 --- a/src/main/java/io/openpixee/maven/operator/InvalidContextException.kt +++ b/src/main/java/io/github/pixee/maven/operator/InvalidContextException.kt @@ -1,4 +1,4 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator /** * This is an exception to tag when the output file couldn't be generated - perhaps due a missing or incompatible maven installation diff --git a/src/main/java/io/openpixee/maven/operator/MissingDependencyException.kt b/src/main/java/io/github/pixee/maven/operator/MissingDependencyException.kt similarity index 66% rename from src/main/java/io/openpixee/maven/operator/MissingDependencyException.kt rename to src/main/java/io/github/pixee/maven/operator/MissingDependencyException.kt index cd6ded0c1..757c89f14 100644 --- a/src/main/java/io/openpixee/maven/operator/MissingDependencyException.kt +++ b/src/main/java/io/github/pixee/maven/operator/MissingDependencyException.kt @@ -1,3 +1,3 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator class MissingDependencyException(message: String?) : RuntimeException(message) \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/POMOperator.kt b/src/main/java/io/github/pixee/maven/operator/POMOperator.kt similarity index 89% rename from src/main/java/io/openpixee/maven/operator/POMOperator.kt rename to src/main/java/io/github/pixee/maven/operator/POMOperator.kt index b601cd919..c8206c8b2 100644 --- a/src/main/java/io/openpixee/maven/operator/POMOperator.kt +++ b/src/main/java/io/github/pixee/maven/operator/POMOperator.kt @@ -1,4 +1,4 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator /** @@ -43,7 +43,7 @@ object POMOperator { chain.execute(projectModel) - val lastCommand = chain.commandList.filterIsInstance() + val lastCommand = chain.commandList.filterIsInstance() .lastOrNull { it.result != null } ?: return emptyList() diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt b/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt similarity index 95% rename from src/main/java/io/openpixee/maven/operator/ProjectModel.kt rename to src/main/java/io/github/pixee/maven/operator/ProjectModel.kt index aebfb2eae..ecdcf0b90 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModel.kt +++ b/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt @@ -1,6 +1,6 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator -import io.openpixee.maven.operator.Util.selectXPathNodes +import io.github.pixee.maven.operator.Util.selectXPathNodes import org.dom4j.Document import org.dom4j.Element import java.net.URL diff --git a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt b/src/main/java/io/github/pixee/maven/operator/ProjectModelFactory.kt similarity index 98% rename from src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt rename to src/main/java/io/github/pixee/maven/operator/ProjectModelFactory.kt index f2846b513..e9183c400 100644 --- a/src/main/java/io/openpixee/maven/operator/ProjectModelFactory.kt +++ b/src/main/java/io/github/pixee/maven/operator/ProjectModelFactory.kt @@ -1,4 +1,4 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator import org.apache.commons.io.IOUtils import org.dom4j.Document diff --git a/src/main/java/io/openpixee/maven/operator/QueryByEmbedder.kt b/src/main/java/io/github/pixee/maven/operator/QueryByEmbedder.kt similarity index 95% rename from src/main/java/io/openpixee/maven/operator/QueryByEmbedder.kt rename to src/main/java/io/github/pixee/maven/operator/QueryByEmbedder.kt index 3e30e4cff..7a80d0d72 100644 --- a/src/main/java/io/openpixee/maven/operator/QueryByEmbedder.kt +++ b/src/main/java/io/github/pixee/maven/operator/QueryByEmbedder.kt @@ -1,4 +1,4 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator import org.apache.commons.io.output.NullOutputStream import org.apache.maven.cli.MavenCli @@ -13,7 +13,7 @@ import java.io.PrintStream /** * Uses Maven Embedder to Implement */ -class QueryByEmbedder : AbstractSimpleQueryCommand() { +class QueryByEmbedder : io.github.pixee.maven.operator.AbstractSimpleQueryCommand() { /** * Runs the "dependency:tree" mojo - but using Embedder instead. */ diff --git a/src/main/java/io/openpixee/maven/operator/QueryByInvoker.kt b/src/main/java/io/github/pixee/maven/operator/QueryByInvoker.kt similarity index 85% rename from src/main/java/io/openpixee/maven/operator/QueryByInvoker.kt rename to src/main/java/io/github/pixee/maven/operator/QueryByInvoker.kt index ac4a71cb0..c5e44a6b2 100644 --- a/src/main/java/io/openpixee/maven/operator/QueryByInvoker.kt +++ b/src/main/java/io/github/pixee/maven/operator/QueryByInvoker.kt @@ -1,10 +1,10 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator import org.apache.maven.shared.invoker.DefaultInvoker import org.apache.maven.shared.invoker.InvocationRequest import java.io.File -class QueryByInvoker : AbstractSimpleQueryCommand() { +class QueryByInvoker : io.github.pixee.maven.operator.AbstractSimpleQueryCommand() { override fun extractDependencyTree( outputPath: File, diff --git a/src/main/java/io/openpixee/maven/operator/QueryByResolver.kt b/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt similarity index 98% rename from src/main/java/io/openpixee/maven/operator/QueryByResolver.kt rename to src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt index 283fe4863..ba43688ae 100644 --- a/src/main/java/io/openpixee/maven/operator/QueryByResolver.kt +++ b/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt @@ -1,4 +1,4 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator import org.apache.maven.model.building.DefaultModelBuilderFactory import org.apache.maven.model.building.DefaultModelBuildingRequest @@ -29,7 +29,7 @@ import kotlin.io.path.toPath * TODO: Support Profiles / Environment Variables * Support Third Party / User-Supplied Repositories (right now it only supports central) */ -class QueryByResolver : AbstractSimpleQueryCommand() { +class QueryByResolver : io.github.pixee.maven.operator.AbstractSimpleQueryCommand() { private val localRepo = LocalRepository( File( System.getProperty("user.home"), diff --git a/src/main/java/io/openpixee/maven/operator/QueryType.kt b/src/main/java/io/github/pixee/maven/operator/QueryType.kt similarity index 59% rename from src/main/java/io/openpixee/maven/operator/QueryType.kt rename to src/main/java/io/github/pixee/maven/operator/QueryType.kt index 37de6e8c3..14d22cbd6 100644 --- a/src/main/java/io/openpixee/maven/operator/QueryType.kt +++ b/src/main/java/io/github/pixee/maven/operator/QueryType.kt @@ -1,4 +1,4 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator enum class QueryType { NONE, diff --git a/src/main/java/io/github/pixee/maven/operator/SimpleDependencyManagement.kt b/src/main/java/io/github/pixee/maven/operator/SimpleDependencyManagement.kt new file mode 100644 index 000000000..76dadadad --- /dev/null +++ b/src/main/java/io/github/pixee/maven/operator/SimpleDependencyManagement.kt @@ -0,0 +1,13 @@ +package io.github.pixee.maven.operator + +import io.github.pixee.maven.operator.Util.buildLookupExpressionForDependencyManagement + + +val SimpleDependencyManagement = object : io.github.pixee.maven.operator.AbstractSimpleCommand() { + override fun execute(c: ProjectModel): Boolean { + val lookupExpression = + buildLookupExpressionForDependencyManagement(c.dependency!!) + + return handleDependency(c, lookupExpression) + } +} \ No newline at end of file diff --git a/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt b/src/main/java/io/github/pixee/maven/operator/SimpleInsert.kt similarity index 89% rename from src/main/java/io/openpixee/maven/operator/SimpleInsert.kt rename to src/main/java/io/github/pixee/maven/operator/SimpleInsert.kt index b0ac9a859..783865d5b 100644 --- a/src/main/java/io/openpixee/maven/operator/SimpleInsert.kt +++ b/src/main/java/io/github/pixee/maven/operator/SimpleInsert.kt @@ -1,9 +1,9 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator -import io.openpixee.maven.operator.Util.addIndentedElement -import io.openpixee.maven.operator.Util.findIndentLevel -import io.openpixee.maven.operator.Util.selectXPathNodes -import io.openpixee.maven.operator.Util.upgradeVersionNode +import io.github.pixee.maven.operator.Util.addIndentedElement +import io.github.pixee.maven.operator.Util.findIndentLevel +import io.github.pixee.maven.operator.Util.selectXPathNodes +import io.github.pixee.maven.operator.Util.upgradeVersionNode import org.apache.commons.lang3.StringUtils import org.dom4j.Element import org.dom4j.Text diff --git a/src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt b/src/main/java/io/github/pixee/maven/operator/SimpleUpgrade.kt similarity index 58% rename from src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt rename to src/main/java/io/github/pixee/maven/operator/SimpleUpgrade.kt index fd8e751b3..6a4d130e7 100644 --- a/src/main/java/io/openpixee/maven/operator/SimpleUpgrade.kt +++ b/src/main/java/io/github/pixee/maven/operator/SimpleUpgrade.kt @@ -1,12 +1,12 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator -import io.openpixee.maven.operator.Util.buildLookupExpressionForDependency +import io.github.pixee.maven.operator.Util.buildLookupExpressionForDependency /** * Represents bumping an existing dependency/ */ -val SimpleUpgrade = object : AbstractSimpleCommand() { +val SimpleUpgrade = object : io.github.pixee.maven.operator.AbstractSimpleCommand() { override fun execute(c: ProjectModel): Boolean { val lookupExpressionForDependency = buildLookupExpressionForDependency(c.dependency!!) diff --git a/src/main/java/io/openpixee/maven/operator/SupportCommand.kt b/src/main/java/io/github/pixee/maven/operator/SupportCommand.kt similarity index 75% rename from src/main/java/io/openpixee/maven/operator/SupportCommand.kt rename to src/main/java/io/github/pixee/maven/operator/SupportCommand.kt index a4f2de191..b6e1c15ee 100644 --- a/src/main/java/io/openpixee/maven/operator/SupportCommand.kt +++ b/src/main/java/io/github/pixee/maven/operator/SupportCommand.kt @@ -1,4 +1,4 @@ -package io.openpixee.maven.operator +package io.github.pixee.maven.operator /** * Tag Interface to the chain to allow it to figure out whether things were modified diff --git a/src/main/java/io/openpixee/maven/operator/Util.kt b/src/main/java/io/github/pixee/maven/operator/Util.kt similarity index 98% rename from src/main/java/io/openpixee/maven/operator/Util.kt rename to src/main/java/io/github/pixee/maven/operator/Util.kt index c8077a1f0..8088d31d3 100644 --- a/src/main/java/io/openpixee/maven/operator/Util.kt +++ b/src/main/java/io/github/pixee/maven/operator/Util.kt @@ -1,6 +1,6 @@ @file:Suppress("DEPRECATION") -package io.openpixee.maven.operator +package io.github.pixee.maven.operator import com.github.zafarkhaja.semver.Version import org.apache.commons.lang3.StringUtils @@ -254,7 +254,7 @@ object Util { val result = possiblePaths.findLast(isCliCallable) if (null == result) { - AbstractSimpleQueryCommand.LOGGER.warn( + io.github.pixee.maven.operator.AbstractSimpleQueryCommand.LOGGER.warn( "Unable to find mvn executable (execs: {}, path: {})", nativeExecutables.joinToString("/"), pathContentString diff --git a/src/main/java/io/openpixee/maven/operator/SimpleDependencyManagement.kt b/src/main/java/io/openpixee/maven/operator/SimpleDependencyManagement.kt deleted file mode 100644 index 7d6f7643a..000000000 --- a/src/main/java/io/openpixee/maven/operator/SimpleDependencyManagement.kt +++ /dev/null @@ -1,13 +0,0 @@ -package io.openpixee.maven.operator - -import io.openpixee.maven.operator.Util.buildLookupExpressionForDependencyManagement - - -val SimpleDependencyManagement = object : AbstractSimpleCommand() { - override fun execute(c: ProjectModel): Boolean { - val lookupExpression = - buildLookupExpressionForDependencyManagement(c.dependency!!) - - return handleDependency(c, lookupExpression) - } -} \ No newline at end of file diff --git a/src/test/java/io/openpixee/maven/operator/test/AbstractTestBase.kt b/src/test/java/io/github/pixee/maven/operator/test/AbstractTestBase.kt similarity index 93% rename from src/test/java/io/openpixee/maven/operator/test/AbstractTestBase.kt rename to src/test/java/io/github/pixee/maven/operator/test/AbstractTestBase.kt index 95650b586..c537316d0 100644 --- a/src/test/java/io/openpixee/maven/operator/test/AbstractTestBase.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/AbstractTestBase.kt @@ -1,9 +1,9 @@ -package io.openpixee.maven.operator.test +package io.github.pixee.maven.operator.test import `fun`.mike.dmp.DiffMatchPatch -import io.openpixee.maven.operator.POMOperator -import io.openpixee.maven.operator.ProjectModel -import io.openpixee.maven.operator.ProjectModelFactory +import io.github.pixee.maven.operator.POMOperator +import io.github.pixee.maven.operator.ProjectModel +import io.github.pixee.maven.operator.ProjectModelFactory import org.dom4j.Document import org.dom4j.io.SAXReader import org.junit.Assert.assertFalse diff --git a/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt b/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt similarity index 95% rename from src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt rename to src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt index b9181954c..9445614d3 100644 --- a/src/test/java/io/openpixee/maven/operator/test/MassRepoTest.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt @@ -1,9 +1,9 @@ -package io.openpixee.maven.operator.test +package io.github.pixee.maven.operator.test -import io.openpixee.maven.operator.Dependency -import io.openpixee.maven.operator.POMOperator -import io.openpixee.maven.operator.ProjectModelFactory -import io.openpixee.maven.operator.Util.which +import io.github.pixee.maven.operator.Dependency +import io.github.pixee.maven.operator.POMOperator +import io.github.pixee.maven.operator.ProjectModelFactory +import io.github.pixee.maven.operator.Util.which import org.apache.commons.lang3.SystemUtils import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue @@ -49,7 +49,7 @@ class MassRepoIT { TestRepo( "CRRogo/vert.x", useProperties = true, - ) to "io.openpixee:java-security-toolkit:1.0.0", + ) to "io.github.pixee:java-security-toolkit:1.0.2", TestRepo( "apache/pulsar", pomPath = "pulsar-broker/pom.xml" diff --git a/src/test/java/io/openpixee/maven/operator/test/POMOperatorJavaIT.java b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorJavaIT.java similarity index 92% rename from src/test/java/io/openpixee/maven/operator/test/POMOperatorJavaIT.java rename to src/test/java/io/github/pixee/maven/operator/test/POMOperatorJavaIT.java index 8f9354c21..93005133d 100644 --- a/src/test/java/io/openpixee/maven/operator/test/POMOperatorJavaIT.java +++ b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorJavaIT.java @@ -1,4 +1,4 @@ -package io.openpixee.maven.operator.test; +package io.github.pixee.maven.operator.test; import org.apache.commons.lang3.SystemUtils; import org.junit.Test; @@ -6,7 +6,7 @@ import java.util.Arrays; import java.util.List; -import io.openpixee.maven.operator.Util; +import io.github.pixee.maven.operator.Util; import static org.junit.Assert.assertEquals; diff --git a/src/test/java/io/openpixee/maven/operator/test/POMOperatorQueryTest.kt b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt similarity index 93% rename from src/test/java/io/openpixee/maven/operator/test/POMOperatorQueryTest.kt rename to src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt index e1185c72a..60af91fcf 100644 --- a/src/test/java/io/openpixee/maven/operator/test/POMOperatorQueryTest.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt @@ -1,6 +1,6 @@ -package io.openpixee.maven.operator.test +package io.github.pixee.maven.operator.test -import io.openpixee.maven.operator.* +import io.github.pixee.maven.operator.* import org.junit.Test import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -56,7 +56,7 @@ class POMOperatorQueryTest { fun testAllQueryTypes() { listOf("pom-1.xml", "pom-3.xml").forEach { pomFile -> Chain.AVAILABLE_QUERY_COMMANDS.forEach { - val commandClassName = "io.openpixee.maven.operator.${it.second}" + val commandClassName = "io.github.pixee.maven.operator.${it.second}" val commandListOverride = listOf(Class.forName(commandClassName).newInstance() as Command) diff --git a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorTest.kt similarity index 96% rename from src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt rename to src/test/java/io/github/pixee/maven/operator/test/POMOperatorTest.kt index e0ecc4ece..cd35742ab 100644 --- a/src/test/java/io/openpixee/maven/operator/test/POMOperatorTest.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorTest.kt @@ -1,9 +1,9 @@ -package io.openpixee.maven.operator.test +package io.github.pixee.maven.operator.test -import io.openpixee.maven.operator.* -import io.openpixee.maven.operator.Util.buildLookupExpressionForDependency -import io.openpixee.maven.operator.Util.selectXPathNodes -import io.openpixee.maven.operator.Util.which +import io.github.pixee.maven.operator.* +import io.github.pixee.maven.operator.Util.buildLookupExpressionForDependency +import io.github.pixee.maven.operator.Util.selectXPathNodes +import io.github.pixee.maven.operator.Util.which import org.apache.commons.lang3.SystemUtils import org.dom4j.DocumentException import org.hamcrest.MatcherAssert.assertThat @@ -32,7 +32,7 @@ class POMOperatorTest : AbstractTestBase() { fun testWithMultipleDependencies() { val deps = listOf( "org.slf4j:slf4j-api:1.7.25", - "io.github.pixee:java-code-security-toolkit:0.0.2", + "io.github.pixee:java-code-security-toolkit:1.0.2", "org.owasp.encoder:encoder:1.2.3", ).map { Dependency.fromString(it) }.toList() @@ -205,7 +205,7 @@ class POMOperatorTest : AbstractTestBase() { @Test fun testCaseWithEmptyElement() { val dependencyToUpgrade = - Dependency("io.openpixee", "java-security-toolkit", version = "1.0.0") + Dependency("io.github.pixee", "java-security-toolkit", version = "1.0.2") val context = gwt( "case-5", @@ -242,7 +242,7 @@ class POMOperatorTest : AbstractTestBase() { @Test fun testCaseWithEmptyElementHiddenInComment() { val dependencyToUpgrade = - Dependency("io.openpixee", "java-security-toolkit", version = "1.0.0") + Dependency("io.github.pixee", "java-security-toolkit", version = "1.0.2") val context = gwt( "case-6", diff --git a/src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt b/src/test/java/io/github/pixee/maven/operator/test/PropertyResolutionTest.kt similarity index 91% rename from src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt rename to src/test/java/io/github/pixee/maven/operator/test/PropertyResolutionTest.kt index bb9b26bf7..a401b301d 100644 --- a/src/test/java/io/openpixee/maven/operator/test/PropertyResolutionTest.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/PropertyResolutionTest.kt @@ -1,7 +1,7 @@ -package io.openpixee.maven.operator.test +package io.github.pixee.maven.operator.test -import io.openpixee.maven.operator.Dependency -import io.openpixee.maven.operator.ProjectModelFactory +import io.github.pixee.maven.operator.Dependency +import io.github.pixee.maven.operator.ProjectModelFactory import junit.framework.TestCase.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue diff --git a/src/test/java/io/openpixee/maven/operator/test/util.kt b/src/test/java/io/github/pixee/maven/operator/test/util.kt similarity index 92% rename from src/test/java/io/openpixee/maven/operator/test/util.kt rename to src/test/java/io/github/pixee/maven/operator/test/util.kt index e2fe0032a..88ef5d71c 100644 --- a/src/test/java/io/openpixee/maven/operator/test/util.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/util.kt @@ -1,7 +1,7 @@ -package io.openpixee.maven.operator.test +package io.github.pixee.maven.operator.test -import io.openpixee.maven.operator.ProjectModel -import io.openpixee.maven.operator.Util.which +import io.github.pixee.maven.operator.ProjectModel +import io.github.pixee.maven.operator.Util.which import org.apache.commons.lang3.SystemUtils import org.dom4j.Document import org.dom4j.io.SAXReader diff --git a/src/test/resources/io/openpixee/maven/operator/test/broken-pom.xml b/src/test/resources/io/github/pixee/maven/operator/test/broken-pom.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/broken-pom.xml rename to src/test/resources/io/github/pixee/maven/operator/test/broken-pom.xml diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-1.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-1.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/pom-1.xml rename to src/test/resources/io/github/pixee/maven/operator/test/pom-1.xml diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-3.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-3.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/pom-3.xml rename to src/test/resources/io/github/pixee/maven/operator/test/pom-3.xml diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-broken.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-broken.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/pom-broken.xml rename to src/test/resources/io/github/pixee/maven/operator/test/pom-broken.xml diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-1-result.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-case-1-result.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/pom-case-1-result.xml rename to src/test/resources/io/github/pixee/maven/operator/test/pom-case-1-result.xml diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-1.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-case-1.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/pom-case-1.xml rename to src/test/resources/io/github/pixee/maven/operator/test/pom-case-1.xml diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-3-result.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-case-3-result.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/pom-case-3-result.xml rename to src/test/resources/io/github/pixee/maven/operator/test/pom-case-3-result.xml diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-3.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-case-3.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/pom-case-3.xml rename to src/test/resources/io/github/pixee/maven/operator/test/pom-case-3.xml diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-4-result.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-case-4-result.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/pom-case-4-result.xml rename to src/test/resources/io/github/pixee/maven/operator/test/pom-case-4-result.xml diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-4.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-case-4.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/pom-case-4.xml rename to src/test/resources/io/github/pixee/maven/operator/test/pom-case-4.xml diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-5-result.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-case-5-result.xml similarity index 99% rename from src/test/resources/io/openpixee/maven/operator/test/pom-case-5-result.xml rename to src/test/resources/io/github/pixee/maven/operator/test/pom-case-5-result.xml index fb6be45d6..0f3bdca62 100644 --- a/src/test/resources/io/openpixee/maven/operator/test/pom-case-5-result.xml +++ b/src/test/resources/io/github/pixee/maven/operator/test/pom-case-5-result.xml @@ -148,7 +148,7 @@ 1.4.5 1.5.2 - 1.0.0 + 1.0.2
@@ -252,7 +252,7 @@ 9.3.6.0
- io.openpixee + io.github.pixee java-security-toolkit ${versions.java-security-toolkit} @@ -402,7 +402,7 @@ test - io.openpixee + io.github.pixee java-security-toolkit diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-5.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-case-5.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/pom-case-5.xml rename to src/test/resources/io/github/pixee/maven/operator/test/pom-case-5.xml diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-6-result.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-case-6-result.xml similarity index 99% rename from src/test/resources/io/openpixee/maven/operator/test/pom-case-6-result.xml rename to src/test/resources/io/github/pixee/maven/operator/test/pom-case-6-result.xml index 3807c0172..8be353890 100644 --- a/src/test/resources/io/openpixee/maven/operator/test/pom-case-6-result.xml +++ b/src/test/resources/io/github/pixee/maven/operator/test/pom-case-6-result.xml @@ -152,7 +152,7 @@ 1.4.5 1.5.2 - 1.0.0 + 1.0.2
@@ -256,7 +256,7 @@ 9.3.6.0 - io.openpixee + io.github.pixee java-security-toolkit ${versions.java-security-toolkit} @@ -406,7 +406,7 @@ test - io.openpixee + io.github.pixee java-security-toolkit diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-6.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-case-6.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/pom-case-6.xml rename to src/test/resources/io/github/pixee/maven/operator/test/pom-case-6.xml diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-with-property-result.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-case-with-property-result.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/pom-case-with-property-result.xml rename to src/test/resources/io/github/pixee/maven/operator/test/pom-case-with-property-result.xml diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-case-with-tabs-result.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-case-with-tabs-result.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/pom-case-with-tabs-result.xml rename to src/test/resources/io/github/pixee/maven/operator/test/pom-case-with-tabs-result.xml diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-pom-case-three-with-lower-version-result.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-pom-case-three-with-lower-version-result.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/pom-pom-case-three-with-lower-version-result.xml rename to src/test/resources/io/github/pixee/maven/operator/test/pom-pom-case-three-with-lower-version-result.xml diff --git a/src/test/resources/io/openpixee/maven/operator/test/pom-with-property-simple.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-with-property-simple.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/pom-with-property-simple.xml rename to src/test/resources/io/github/pixee/maven/operator/test/pom-with-property-simple.xml diff --git a/src/test/resources/io/openpixee/maven/operator/test/sample-bad-pom.xml b/src/test/resources/io/github/pixee/maven/operator/test/sample-bad-pom.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/sample-bad-pom.xml rename to src/test/resources/io/github/pixee/maven/operator/test/sample-bad-pom.xml diff --git a/src/test/resources/io/openpixee/maven/operator/test/webgoat-parent.xml b/src/test/resources/io/github/pixee/maven/operator/test/webgoat-parent.xml similarity index 100% rename from src/test/resources/io/openpixee/maven/operator/test/webgoat-parent.xml rename to src/test/resources/io/github/pixee/maven/operator/test/webgoat-parent.xml From fa154a0a92fb61fafe7d43912ff18f831a59762a Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 8 May 2023 19:11:59 -0500 Subject: [PATCH 093/153] Generating Tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9c6a70f9e..feb217584 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.8-SNAPSHOT + 0.0.8 scm:git:${project.scm.url} From 1a28e70a50ec285eb256fd4d26213d3a6176ac77 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 8 May 2023 19:13:31 -0500 Subject: [PATCH 094/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index dc5982004..392985c85 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.github.pixee.maven.sample java-sample - 0.0.8-SNAPSHOT + 0.0.9-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index feb217584..500b17ccc 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.8 + 0.0.9-SNAPSHOT scm:git:${project.scm.url} From 3c470e4e6f92d0e191327b8d920a9f67aad9b006 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 28 Jun 2023 15:44:02 -0500 Subject: [PATCH 095/153] Multiple POM Support (#16) * Interim Commit: * Cleanup * Formatting * Adding more context * Moar javadocs * Wraps around POM into a Data Class * Beginnings of Multi-POM Support * [no ci] Autogenerated JaCoCo coverage badge * Interim Commit - multi-pom * [no ci] Autogenerated JaCoCo coverage badge * Updates * [no ci] Autogenerated JaCoCo coverage badge * CompositeDependencyManagement and tests * [no ci] Autogenerated JaCoCo coverage badge * POM Scanner + tests * POM Scanner * [no ci] Autogenerated JaCoCo coverage badge * TODOs cleanup * Adding more tests --------- Co-authored-by: Jacoco Coverage Update Action --- .github/badges/branches.svg | 2 +- .github/badges/jacoco.svg | 2 +- pom.xml | 2 +- ...actSimpleCommand.kt => AbstractCommand.kt} | 18 +- ...ueryCommand.kt => AbstractQueryCommand.kt} | 30 ++-- .../io/github/pixee/maven/operator/Chain.kt | 11 +- .../maven/operator/CheckDependencyPresent.kt | 6 +- .../maven/operator/CheckParentPackaging.kt | 54 ++++++ .../io/github/pixee/maven/operator/Command.kt | 4 +- .../operator/CompositeDependencyManagement.kt | 123 ++++++++++++++ .../maven/operator/DiscardFormatCommand.kt | 40 +++-- .../pixee/maven/operator/FormatCommand.kt | 120 +++++++++----- .../maven/operator/InvalidPathException.kt | 10 ++ .../pixee/maven/operator/POMDocument.kt | 59 +++++++ .../maven/operator/POMDocumentFactory.kt | 36 ++++ .../pixee/maven/operator/POMOperator.kt | 4 +- .../github/pixee/maven/operator/POMScanner.kt | 110 +++++++++++++ .../pixee/maven/operator/ProjectModel.kt | 129 +++++++++++---- .../maven/operator/ProjectModelFactory.kt | 59 ++++--- .../pixee/maven/operator/QueryByEmbedder.kt | 2 +- .../pixee/maven/operator/QueryByInvoker.kt | 5 +- .../pixee/maven/operator/QueryByResolver.kt | 10 +- .../operator/SimpleDependencyManagement.kt | 8 +- .../pixee/maven/operator/SimpleInsert.kt | 34 ++-- .../pixee/maven/operator/SimpleUpgrade.kt | 8 +- .../pixee/maven/operator/SupportCommand.kt | 3 +- .../io/github/pixee/maven/operator/Util.kt | 47 ++++-- .../operator/WrongDependencyTypeException.kt | 3 + .../maven/operator/test/AbstractTestBase.kt | 8 +- .../pixee/maven/operator/test/MassRepoTest.kt | 13 +- .../operator/test/POMOperatorMultipomTest.kt | 155 ++++++++++++++++++ .../maven/operator/test/POMOperatorTest.kt | 55 +++++-- .../maven/operator/test/POMScannerTest.kt | 83 ++++++++++ .../github/pixee/maven/operator/test/util.kt | 2 +- .../test/nested/child/pom/pom-1-child.xml | 16 ++ .../operator/test/nested/child/pom/pom-1.xml | 17 ++ .../test/nested/child/pom/pom-2-child.xml | 16 ++ .../operator/test/nested/child/pom/pom-2.xml | 17 ++ .../test/nested/child/pom/pom-3-child.xml | 16 ++ .../operator/test/nested/child/pom/pom-3.xml | 17 ++ .../test/nested/super/pom/other-pom.xml | 13 ++ .../operator/test/nested/super/pom/pom.xml | 13 ++ .../test/parent-and-child-child-broken.xml | 18 ++ .../test/parent-and-child-parent-broken.xml | 16 ++ .../operator/test/parent-and-child-parent.xml | 19 +++ ...e-pom-basic-no-version-property-result.xml | 22 +++ .../test/pom-multiple-pom-basic-result.xml | 16 ++ ...pom-basic-with-version-property-result.xml | 22 +++ .../operator/test/pom-with-parent-level-1.xml | 13 ++ .../test/sample-child-with-broken-path-1.xml | 16 ++ .../test/sample-child-with-broken-path-2.xml | 16 ++ .../test/sample-child-with-broken-path-3.xml | 16 ++ .../test/sample-child-with-broken-path-4.xml | 16 ++ .../test/sample-child-with-relativepath-2.xml | 16 ++ ...th-relativepath-and-two-levels-nonloop.xml | 16 ++ ...child-with-relativepath-and-two-levels.xml | 16 ++ .../test/sample-child-with-relativepath.xml | 16 ++ .../operator/test/sample-parent/other-pom.xml | 13 ++ .../pom-with-parent-level-2-nonloop.xml | 18 ++ .../sample-parent/pom-with-parent-level-2.xml | 18 ++ .../maven/operator/test/sample-parent/pom.xml | 13 ++ .../maven/operator/test/superpom-nonloop.xml | 13 ++ 62 files changed, 1473 insertions(+), 236 deletions(-) rename src/main/java/io/github/pixee/maven/operator/{AbstractSimpleCommand.kt => AbstractCommand.kt} (58%) rename src/main/java/io/github/pixee/maven/operator/{AbstractSimpleQueryCommand.kt => AbstractQueryCommand.kt} (81%) create mode 100644 src/main/java/io/github/pixee/maven/operator/CheckParentPackaging.kt create mode 100644 src/main/java/io/github/pixee/maven/operator/CompositeDependencyManagement.kt create mode 100644 src/main/java/io/github/pixee/maven/operator/InvalidPathException.kt create mode 100644 src/main/java/io/github/pixee/maven/operator/POMDocument.kt create mode 100644 src/main/java/io/github/pixee/maven/operator/POMDocumentFactory.kt create mode 100644 src/main/java/io/github/pixee/maven/operator/POMScanner.kt create mode 100644 src/main/java/io/github/pixee/maven/operator/WrongDependencyTypeException.kt create mode 100644 src/test/java/io/github/pixee/maven/operator/test/POMOperatorMultipomTest.kt create mode 100644 src/test/java/io/github/pixee/maven/operator/test/POMScannerTest.kt create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-1-child.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-1.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-2-child.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-2.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-3-child.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-3.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/nested/super/pom/other-pom.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/nested/super/pom/pom.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/parent-and-child-child-broken.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/parent-and-child-parent-broken.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/parent-and-child-parent.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-basic-no-version-property-result.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-basic-result.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-basic-with-version-property-result.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/pom-with-parent-level-1.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-1.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-2.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-3.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-4.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-relativepath-2.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-relativepath-and-two-levels-nonloop.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-relativepath-and-two-levels.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-relativepath.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/sample-parent/other-pom.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom-with-parent-level-2-nonloop.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom-with-parent-level-2.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/superpom-nonloop.xml diff --git a/.github/badges/branches.svg b/.github/badges/branches.svg index 2f8dd3c1e..de17db21d 100644 --- a/.github/badges/branches.svg +++ b/.github/badges/branches.svg @@ -1 +1 @@ -branches73.7% \ No newline at end of file +branches74.4% \ No newline at end of file diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index 2b337d7d4..de2c1118a 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage91.9% \ No newline at end of file +coverage91.8% \ No newline at end of file diff --git a/pom.xml b/pom.xml index 500b17ccc..13cdf4d3d 100644 --- a/pom.xml +++ b/pom.xml @@ -120,7 +120,7 @@ org.jetbrains.kotlin - kotlin-test + kotlin-test-junit ${kotlin.version} test diff --git a/src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt b/src/main/java/io/github/pixee/maven/operator/AbstractCommand.kt similarity index 58% rename from src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt rename to src/main/java/io/github/pixee/maven/operator/AbstractCommand.kt index d2659fe8f..86a0e5326 100644 --- a/src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt +++ b/src/main/java/io/github/pixee/maven/operator/AbstractCommand.kt @@ -8,12 +8,14 @@ import org.dom4j.Element /** * Base implementation of Command - used by SimpleDependency and SimpleInsert */ -abstract class AbstractSimpleCommand : io.github.pixee.maven.operator.Command { +abstract class AbstractCommand : Command { /** * Given a POM, locate its coordinates for a given dependency based on lookupExpression and figures out the upgrade + * + * TODO review this */ - protected fun handleDependency(c: io.github.pixee.maven.operator.ProjectModel, lookupExpression: String): Boolean { - val dependencyNodes = c.resultPom.selectXPathNodes(lookupExpression) + protected fun handleDependency(pm: ProjectModel, lookupExpression: String): Boolean { + val dependencyNodes = pm.pomFile.resultPom.selectXPathNodes(lookupExpression) if (1 == dependencyNodes.size) { val versionNodes = dependencyNodes[0].selectXPathNodes("./m:version") @@ -23,12 +25,12 @@ abstract class AbstractSimpleCommand : io.github.pixee.maven.operator.Command { var mustUpgrade = true - if (c.skipIfNewer) { - mustUpgrade = findOutIfUpgradeIsNeeded(c, versionNode) + if (pm.skipIfNewer) { + mustUpgrade = findOutIfUpgradeIsNeeded(pm, versionNode) } if (mustUpgrade) { - upgradeVersionNode(c, versionNode) + upgradeVersionNode(pm, versionNode, pm.pomFile) } return true @@ -38,7 +40,7 @@ abstract class AbstractSimpleCommand : io.github.pixee.maven.operator.Command { return false } - override fun execute(c: io.github.pixee.maven.operator.ProjectModel): Boolean = false + override fun execute(pm: ProjectModel): Boolean = false - override fun postProcess(c: io.github.pixee.maven.operator.ProjectModel): Boolean = false + override fun postProcess(c: ProjectModel): Boolean = false } \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/AbstractSimpleQueryCommand.kt b/src/main/java/io/github/pixee/maven/operator/AbstractQueryCommand.kt similarity index 81% rename from src/main/java/io/github/pixee/maven/operator/AbstractSimpleQueryCommand.kt rename to src/main/java/io/github/pixee/maven/operator/AbstractQueryCommand.kt index 0d5bf0517..b43bdbc38 100644 --- a/src/main/java/io/github/pixee/maven/operator/AbstractSimpleQueryCommand.kt +++ b/src/main/java/io/github/pixee/maven/operator/AbstractQueryCommand.kt @@ -15,7 +15,7 @@ import java.util.* * relying on dependency:tree mojo outputting into a text file - which might be cached. * */ -abstract class AbstractSimpleQueryCommand : io.github.pixee.maven.operator.AbstractSimpleCommand() { +abstract class AbstractQueryCommand : AbstractCommand() { /** * Generates a temporary file path used to store the output of the
dependency:tree
mojo * @@ -34,9 +34,9 @@ abstract class AbstractSimpleQueryCommand : io.github.pixee.maven.operator.Abstr /** * Given a POM URI, returns a File Object * - * @param c ProjectModel + * @param d POMDocument */ - protected fun getPomFilePath(c: io.github.pixee.maven.operator.ProjectModel): File = Paths.get(c.pomPath!!.toURI()).toFile() + protected fun getPomFilePath(d: POMDocument): File = Paths.get(d.pomPath!!.toURI()).toFile() /** * Abstract Method to extract dependencies @@ -45,20 +45,20 @@ abstract class AbstractSimpleQueryCommand : io.github.pixee.maven.operator.Abstr * @param pomFilePath Input Pom Path * @param c Project Model */ - abstract fun extractDependencyTree(outputPath: File, pomFilePath: File, c: io.github.pixee.maven.operator.ProjectModel) + abstract fun extractDependencyTree(outputPath: File, pomFilePath: File, c: ProjectModel) /** * Internal Holder Variable * * Todo: OF COURSE IT BREAKS THE PROTOCOL */ - internal var result: Collection? = null + internal var result: Collection? = null /** * We declare the main logic here - details are made in the child classes for now */ - override fun execute(c: io.github.pixee.maven.operator.ProjectModel): Boolean { - val pomFilePath = getPomFilePath(c) + override fun execute(pm: ProjectModel): Boolean { + val pomFilePath = getPomFilePath(pm.pomFile) val outputPath = getOutputPath(pomFilePath) @@ -67,8 +67,8 @@ abstract class AbstractSimpleQueryCommand : io.github.pixee.maven.operator.Abstr } try { - extractDependencyTree(outputPath, pomFilePath, c) - } catch (e: io.github.pixee.maven.operator.InvalidContextException) { + extractDependencyTree(outputPath, pomFilePath, pm) + } catch (e: InvalidContextException) { return false } @@ -98,7 +98,7 @@ abstract class AbstractSimpleQueryCommand : io.github.pixee.maven.operator.Abstr }.associate { (line, elements) -> val (groupId, artifactId, packaging, version, scope) = elements - line to io.github.pixee.maven.operator.Dependency( + line to Dependency( groupId = groupId, artifactId = artifactId, version = version, @@ -110,7 +110,7 @@ abstract class AbstractSimpleQueryCommand : io.github.pixee.maven.operator.Abstr protected fun buildInvocationRequest( outputPath: File, pomFilePath: File, - c: io.github.pixee.maven.operator.ProjectModel + c: ProjectModel ): InvocationRequest { val props = Properties(System.getProperties()).apply { //System.getProperties().forEach { t, u -> setProperty(t as String, u as String) } @@ -132,7 +132,7 @@ abstract class AbstractSimpleQueryCommand : io.github.pixee.maven.operator.Abstr properties = props - goals = listOf(io.github.pixee.maven.operator.AbstractSimpleQueryCommand.Companion.DEPENDENCY_TREE_MOJO_REFERENCE) + goals = listOf(DEPENDENCY_TREE_MOJO_REFERENCE) } return request @@ -163,7 +163,7 @@ abstract class AbstractSimpleQueryCommand : io.github.pixee.maven.operator.Abstr val inferredHome = File(SystemUtils.getUserHome(), ".m2") if (!(inferredHome.exists() && inferredHome.isDirectory)) { - io.github.pixee.maven.operator.AbstractSimpleQueryCommand.Companion.LOGGER.warn( + LOGGER.warn( "Inferred User Home - which does not exist or not a directory: {}", inferredHome ) @@ -193,8 +193,8 @@ abstract class AbstractSimpleQueryCommand : io.github.pixee.maven.operator.Abstr const val DEPENDENCY_TREE_MOJO_REFERENCE = "org.apache.maven.plugins:maven-dependency-plugin:3.3.0:tree" - val LOGGER: Logger = LoggerFactory.getLogger(io.github.pixee.maven.operator.AbstractSimpleQueryCommand::class.java) + val LOGGER: Logger = LoggerFactory.getLogger(AbstractQueryCommand::class.java) } - override fun postProcess(c: io.github.pixee.maven.operator.ProjectModel): Boolean = false + override fun postProcess(c: ProjectModel): Boolean = false } \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/Chain.kt b/src/main/java/io/github/pixee/maven/operator/Chain.kt index be71eb3e0..09d34f7fc 100644 --- a/src/main/java/io/github/pixee/maven/operator/Chain.kt +++ b/src/main/java/io/github/pixee/maven/operator/Chain.kt @@ -73,7 +73,16 @@ class Chain(vararg commands: Command) { * Returns a Pre-Configured Chain with the Defaults for Modifying a POM */ fun createForModify() = - Chain(CheckDependencyPresent, FormatCommand(), DiscardFormatCommand(), SimpleUpgrade, SimpleDependencyManagement, SimpleInsert) + Chain( + CheckDependencyPresent, + CheckParentPackaging, + FormatCommand(), + DiscardFormatCommand(), + CompositeDependencyManagement(), + SimpleUpgrade, + SimpleDependencyManagement, + SimpleInsert + ) /** * returns a pre-configured chain with the defaults for Querying diff --git a/src/main/java/io/github/pixee/maven/operator/CheckDependencyPresent.kt b/src/main/java/io/github/pixee/maven/operator/CheckDependencyPresent.kt index 912f11af3..777f76d39 100644 --- a/src/main/java/io/github/pixee/maven/operator/CheckDependencyPresent.kt +++ b/src/main/java/io/github/pixee/maven/operator/CheckDependencyPresent.kt @@ -3,12 +3,12 @@ package io.github.pixee.maven.operator /** * Guard Command Singleton use to validate required parameters */ -val CheckDependencyPresent = object : io.github.pixee.maven.operator.AbstractSimpleCommand() { - override fun execute(c: ProjectModel): Boolean { +val CheckDependencyPresent = object : AbstractCommand() { + override fun execute(pm: ProjectModel): Boolean { /** * CheckDependencyPresent requires a Dependency to be Present */ - if (null == c.dependency) + if (null == pm.dependency) throw MissingDependencyException("Dependency must be present for modify") return false diff --git a/src/main/java/io/github/pixee/maven/operator/CheckParentPackaging.kt b/src/main/java/io/github/pixee/maven/operator/CheckParentPackaging.kt new file mode 100644 index 000000000..7a44cf14d --- /dev/null +++ b/src/main/java/io/github/pixee/maven/operator/CheckParentPackaging.kt @@ -0,0 +1,54 @@ +package io.github.pixee.maven.operator + +import io.github.pixee.maven.operator.Util.selectXPathNodes +import org.dom4j.Element +import org.dom4j.Text + +/** + * Guard Command Singleton use to validate required parameters + */ +val CheckParentPackaging = object : AbstractCommand() { + fun packagingTypePredicate(d: POMDocument, packagingType: String): Boolean { + val elementText = + d.pomDocument.rootElement.selectXPathNodes("/m:project/m:packaging/text()") + .firstOrNull() + + if (elementText is Text) { + return elementText.text.equals(packagingType) + } + + return false + } + + override fun execute(pm: ProjectModel): Boolean { + val wrongParentPoms = pm.parentPomFiles.filterNot { packagingTypePredicate(it, "pom") } + + if (wrongParentPoms.isNotEmpty()) { + throw WrongDependencyTypeException("wrong packaging type for parentPom") + } + + if (pm.parentPomFiles.isNotEmpty()) { + // check main pom file has a inheritance to one of the members listed + if (!hasValidParentAndPackaging(pm.pomFile)) { + throw WrongDependencyTypeException("invalid parent/packaging combo for main pomfile") + } + } + + // todo: test a->b->c + + return false + } + + private fun hasValidParentAndPackaging(pomFile: POMDocument): Boolean { + val parentNode = pomFile.pomDocument.rootElement.selectXPathNodes("/m:project/m:parent") + .firstOrNull() as Element? ?: return false + + val packagingText = + (pomFile.pomDocument.rootElement.selectXPathNodes("/m:project/m:packaging/text()") + .firstOrNull() as Text?)?.text ?: "jar" + + @Suppress("UnnecessaryVariable") val validPackagingType = packagingText.endsWith("ar") + + return validPackagingType + } +} \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/Command.kt b/src/main/java/io/github/pixee/maven/operator/Command.kt index befa37c1d..776ae41b1 100644 --- a/src/main/java/io/github/pixee/maven/operator/Command.kt +++ b/src/main/java/io/github/pixee/maven/operator/Command.kt @@ -7,10 +7,10 @@ interface Command { /** * Given a context, performs an operation * - * @param c Context (Project Model) to use + * @param pm Context (Project Model) to use * @return true if the execution was successful *AND* the chain must end */ - fun execute(c: ProjectModel): Boolean + fun execute(pm: ProjectModel): Boolean /** * Post Processing, implementing a Filter Pattern diff --git a/src/main/java/io/github/pixee/maven/operator/CompositeDependencyManagement.kt b/src/main/java/io/github/pixee/maven/operator/CompositeDependencyManagement.kt new file mode 100644 index 000000000..ae85cbdd7 --- /dev/null +++ b/src/main/java/io/github/pixee/maven/operator/CompositeDependencyManagement.kt @@ -0,0 +1,123 @@ +package io.github.pixee.maven.operator + +import io.github.pixee.maven.operator.Util.addIndentedElement +import io.github.pixee.maven.operator.Util.selectXPathNodes +import org.dom4j.Element +import java.lang.IllegalStateException + +class CompositeDependencyManagement : AbstractCommand() { + override fun execute(pm: ProjectModel): Boolean { + /** + * Abort if not multi-pom + */ + if (pm.parentPomFiles.isEmpty()) { + return false + } + + var result = false + + /** + * TODO: Make it configurable / clear WHERE one should change it + */ + val parentPomFile = pm.parentPomFiles.last() + + // add dependencyManagement + + val dependencyManagementElement = + if (parentPomFile.resultPom.rootElement.elements("dependencyManagement").isEmpty()) { + parentPomFile.resultPom.rootElement.addIndentedElement( + parentPomFile, + "dependencyManagement" + ) + } else { + parentPomFile.resultPom.rootElement.element("dependencyManagement") + } + + val newDependencyManagementElement = modifyDependency( + parentPomFile, + Util.buildLookupExpressionForDependencyManagement(pm.dependency!!), + pm, + dependencyManagementElement, + dependencyManagementNode = true, + ) + + if (pm.useProperties) { + val newVersionNode = + newDependencyManagementElement?.addIndentedElement(parentPomFile, "version") + ?: throw IllegalStateException("newDependencyManagementElement is missing") + + val whereToUpgradeVersionProperty = parentPomFile + + Util.upgradeVersionNode(pm, newVersionNode, whereToUpgradeVersionProperty) + } + + // add dependency to pom - sans version + modifyDependency( + pm.pomFile, + Util.buildLookupExpressionForDependency(pm.dependency!!), + pm, + pm.pomFile.resultPom.rootElement, + dependencyManagementNode = false, + ) + + if (!result) { + result = pm.pomFile.dirty + } + + return result + } + + private fun modifyDependency( + pomFileToModify: POMDocument, + lookupExpressionForDependency: String, + c: ProjectModel, + parentElement: Element, + dependencyManagementNode: Boolean, + ): Element? { + val dependencyNodes = + pomFileToModify.resultPom.selectXPathNodes(lookupExpressionForDependency) + + if (1 == dependencyNodes.size) { + val versionNodes = dependencyNodes[0].selectXPathNodes("./m:version") + + if (1 == versionNodes.size) { + val versionNode = versionNodes.first() + + versionNode.parent.content().remove(versionNode) + + pomFileToModify.dirty = true + } + } else { + val dependenciesNode: Element = + if (null != parentElement.element("dependencies")) { + parentElement.element("dependencies") + } else { + parentElement.addIndentedElement( + pomFileToModify, + "dependencies" + ) + } + + val dependencyNode: Element = + dependenciesNode.addIndentedElement(pomFileToModify, "dependency") + + dependencyNode.addIndentedElement(pomFileToModify, "groupId").text = + c.dependency!!.groupId + dependencyNode.addIndentedElement(pomFileToModify, "artifactId").text = + c.dependency!!.artifactId + + if (dependencyManagementNode) { + if (!c.useProperties) { + dependencyNode.addIndentedElement(pomFileToModify, "version").text = + c.dependency!!.version!! + } + } + + pomFileToModify.dirty = true + + return dependencyNode + } + + return null + } +} \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/DiscardFormatCommand.kt b/src/main/java/io/github/pixee/maven/operator/DiscardFormatCommand.kt index 113f0f988..acb8dc87b 100644 --- a/src/main/java/io/github/pixee/maven/operator/DiscardFormatCommand.kt +++ b/src/main/java/io/github/pixee/maven/operator/DiscardFormatCommand.kt @@ -6,26 +6,36 @@ import org.xmlunit.builder.Input /** * Command Class to Short-Circuit/Discard Processing when no pom changes were made */ -class DiscardFormatCommand : io.github.pixee.maven.operator.AbstractSimpleCommand() { - override fun postProcess(c: ProjectModel): Boolean { - val originalDoc = Input.fromString(String(c.originalPom)).build() - val modifiedDoc = Input.fromString(c.resultPom.asXML()).build() +class DiscardFormatCommand : AbstractCommand() { + override fun postProcess(pm: ProjectModel): Boolean { + var mustSkip = false - val diff = DiffBuilder.compare(originalDoc).withTest(modifiedDoc) - .ignoreWhitespace() - .ignoreComments() - .ignoreElementContentWhitespace() - .checkForSimilar() - .build() + for (pomFile in pm.allPomFiles) { + val originalDoc = Input.fromString(String(pomFile.originalPom)).build() + val modifiedDoc = Input.fromString(pomFile.resultPom.asXML()).build() - val hasDifferences = diff.hasDifferences() + val diff = DiffBuilder.compare(originalDoc).withTest(modifiedDoc) + .ignoreWhitespace() + .ignoreComments() + .ignoreElementContentWhitespace() + .checkForSimilar() + .build() - if (! (c.modifiedByCommand || hasDifferences)) { - c.resultPomBytes = c.originalPom + val hasDifferences = diff.hasDifferences() - return true + if (!(pm.modifiedByCommand || hasDifferences)) { + pomFile.resultPomBytes = pomFile.originalPom + + mustSkip = true + } } - return super.postProcess(c) + /** + * Triggers early abandonment + */ + if (mustSkip) + return true + + return super.postProcess(pm) } } \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/FormatCommand.kt b/src/main/java/io/github/pixee/maven/operator/FormatCommand.kt index 444247158..38fab6f95 100644 --- a/src/main/java/io/github/pixee/maven/operator/FormatCommand.kt +++ b/src/main/java/io/github/pixee/maven/operator/FormatCommand.kt @@ -26,17 +26,7 @@ data class MatchData( * which are the only ones which are tricky to format (due to element and its attributes being freeform - thus formatting lost when serializing the DOM * and the PI being completely optional for the POM Document) */ -class FormatCommand : io.github.pixee.maven.operator.AbstractSimpleCommand() { - /** - * Preamble Contents are stored here - */ - private var preamble: String = "" - - /** - * Afterword - if needed - */ - private var suffix: String = "" - +class FormatCommand : AbstractCommand() { /** * StAX InputFactory */ @@ -47,17 +37,31 @@ class FormatCommand : io.github.pixee.maven.operator.AbstractSimpleCommand() { */ private val outputFactory = XMLOutputFactory.newInstance() - override fun execute(c: ProjectModel): Boolean { - parseXmlAndCharset(c) + override fun execute(pm: ProjectModel): Boolean { + for (pomFile in pm.allPomFiles) { + parseXmlAndCharset(pomFile) - parseLineEndings(c) - - c.endl = parseLineEndings(c) - c.indent = guessIndent(c) + pomFile.endl = parseLineEndings(pomFile) + pomFile.indent = guessIndent(pomFile) + } - return super.execute(c) + return super.execute(pm) } + /** + * This one is quite fun yet important. Let me explain: + * + * The DOM doesn't track records if empty elements are either `` or ``. Therefore we need to scan all ocurrences of + * singleton elements. + * + * Therefore we use a bitSet to keep track of each element and offset, scanning it forward + * when serializing we pick backwards and rewrite tags accordingly + * + * @param doc Raw Document Bytes + * @see RE_EMPTY_ELEMENT + * @return bitSet of + * + */ private fun elementBitSet(doc: ByteArray): BitSet { val result = BitSet() val eventReader = inputFactory.createXMLEventReader(doc.inputStream()) @@ -84,8 +88,17 @@ class FormatCommand : io.github.pixee.maven.operator.AbstractSimpleCommand() { return result } - private fun findSingleElementMatchesFrom(pomDocument: String) = - RE_EMPTY_ELEMENT.findAll(pomDocument).map { + /** + * Returns a reverse-ordered list of all the single element matches from the pom document + * raw string + * + * this is important so we can mix and match offsets and apply formatting accordingly + * + * @param xmlDocumentString Rendered POM Document Contents (string-formatted) + * @return map of (index, matchData object) reverse ordered + */ + private fun findSingleElementMatchesFrom(xmlDocumentString: String) = + RE_EMPTY_ELEMENT.findAll(xmlDocumentString).map { it.range.first to MatchData( range = it.range, content = it.value, @@ -97,11 +110,11 @@ class FormatCommand : io.github.pixee.maven.operator.AbstractSimpleCommand() { * Guesses the indent character (spaces / tabs) and length from the original document * formatting settings * - * @param c (project model) where it takes its input pom + * @param pomFile (project model) where it takes its input pom * @return indent string */ - private fun guessIndent(c: ProjectModel): String { - val eventReader = inputFactory.createXMLEventReader(c.originalPom.inputStream()) + private fun guessIndent(pomFile: POMDocument): String { + val eventReader = inputFactory.createXMLEventReader(pomFile.originalPom.inputStream()) val freqMap: MutableMap = mutableMapOf() val charFreqMap: MutableMap = mutableMapOf() @@ -165,19 +178,19 @@ class FormatCommand : io.github.pixee.maven.operator.AbstractSimpleCommand() { return indentString } - private fun parseLineEndings(c: ProjectModel): String { - val str = String(c.originalPom.inputStream().readBytes(), c.charset) + private fun parseLineEndings(pomFile: POMDocument): String { + val str = String(pomFile.originalPom.inputStream().readBytes(), pomFile.charset) return LINE_ENDINGS.associateWith { str.split(it).size } .maxBy { it.value } .key } - private fun parseXmlAndCharset(c: ProjectModel) { + private fun parseXmlAndCharset(pomFile: POMDocument) { /** * Performs a StAX Parsing to Grab the first element */ - val eventReader = inputFactory.createXMLEventReader(c.originalPom.inputStream()) + val eventReader = inputFactory.createXMLEventReader(pomFile.originalPom.inputStream()) var charset: Charset? = null @@ -200,7 +213,8 @@ class FormatCommand : io.github.pixee.maven.operator.AbstractSimpleCommand() { val offset = endElementEvent.location.characterOffset - preamble = c.originalPom.toString(c.charset).substring(0, offset) + pomFile.preamble = + pomFile.originalPom.toString(pomFile.charset).substring(0, offset) break } @@ -210,34 +224,56 @@ class FormatCommand : io.github.pixee.maven.operator.AbstractSimpleCommand() { } if (null == charset) { - val detectedCharsetName = UniversalDetector.detectCharset(c.originalPom.inputStream()) + val detectedCharsetName = + UniversalDetector.detectCharset(pomFile.originalPom.inputStream()) charset = Charset.forName(detectedCharsetName) } - c.charset = charset!! + pomFile.charset = charset!! - val lastLine = String(c.originalPom, c.charset) + val lastLine = String(pomFile.originalPom, pomFile.charset) val lastLineTrimmed = lastLine.trimEnd() - this.suffix = lastLine.substring(lastLineTrimmed.length) - + pomFile.suffix = lastLine.substring(lastLineTrimmed.length) } /** * When doing the opposite, render the XML using the optionally supplied encoding (defaults to UTF8 obviously) * but apply the original formatting as well */ - override fun postProcess(c: ProjectModel): Boolean { - var xmlRepresentation = c.resultPom.asXML().toString() + override fun postProcess(pm: ProjectModel): Boolean { + for (pomFile in pm.allPomFiles) { + /** + * Serializes it back + */ + val content = serializePomFile(pomFile) + + pomFile.resultPomBytes = content + } + + return super.postProcess(pm) + } + + /** + * Serialize a POM Document + * + * @param pom pom document + * @return bytes for the pom document + */ + private fun serializePomFile(pom: POMDocument): ByteArray { + // Generate a String representation. We'll need to patch it up and apply back + // differences we recored previously on the pom (see the pom member variables) + var xmlRepresentation = pom.resultPom.asXML().toString() - val originalElementMap = elementBitSet(c.originalPom) + val originalElementMap = elementBitSet(pom.originalPom) val targetElementMap = elementBitSet(xmlRepresentation.toByteArray()) // Let's find out the original empty elements from the original pom and store into a stack val elementsToReplace: MutableList = ArrayList().apply { - val matches = findSingleElementMatchesFrom(c.originalPom.toString(c.charset)).values + val matches = + findSingleElementMatchesFrom(pom.originalPom.toString(pom.charset)).values val filteredMatches = matches.filter { originalElementMap[it.range.first] } @@ -262,7 +298,7 @@ class FormatCommand : io.github.pixee.maven.operator.AbstractSimpleCommand() { */ val inputFactory = XMLInputFactory.newInstance() val eventReader = inputFactory.createXMLEventReader( - xmlRepresentation.toByteArray(c.charset).inputStream() + xmlRepresentation.toByteArray(pom.charset).inputStream() ) while (true) { @@ -277,7 +313,7 @@ class FormatCommand : io.github.pixee.maven.operator.AbstractSimpleCommand() { val offset = endElementEvent.location.characterOffset xmlRepresentation = - this.preamble + xmlRepresentation.substring(offset) + this.suffix + pom.preamble + xmlRepresentation.substring(offset) + pom.suffix break } @@ -290,11 +326,11 @@ class FormatCommand : io.github.pixee.maven.operator.AbstractSimpleCommand() { } /** - * Serializes it back + * Serializes it back from (string to ByteArray) */ - c.resultPomBytes = xmlRepresentation.toByteArray(c.charset) + val serializedContent = xmlRepresentation.toByteArray(pom.charset) - return super.postProcess(c) + return serializedContent } companion object { diff --git a/src/main/java/io/github/pixee/maven/operator/InvalidPathException.kt b/src/main/java/io/github/pixee/maven/operator/InvalidPathException.kt new file mode 100644 index 000000000..b9fe110e1 --- /dev/null +++ b/src/main/java/io/github/pixee/maven/operator/InvalidPathException.kt @@ -0,0 +1,10 @@ +package io.github.pixee.maven.operator + +import java.io.File +import java.io.IOException + +class InvalidPathException( + val parentPath: File, + val relativePath: String, + val loop: Boolean = false +) : IOException("Invalid Relative Path $relativePath (from ${parentPath.absolutePath}) (loops? ${loop})") \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/POMDocument.kt b/src/main/java/io/github/pixee/maven/operator/POMDocument.kt new file mode 100644 index 000000000..4afebb2ac --- /dev/null +++ b/src/main/java/io/github/pixee/maven/operator/POMDocument.kt @@ -0,0 +1,59 @@ +package io.github.pixee.maven.operator + +import org.dom4j.Document +import java.io.File +import java.net.URL +import java.nio.charset.Charset + +/** + * Data Class to Keep track of an entire POM File, including: + * + * Path (pomPath) + * + * DOM Contents (pomDocument) - original + * DOM Contents (resultPom) - modified + * + * Charset (ditto) + * Indent (ditto) + * Preamble (ditto) + * Suffix (ditto) + * Line Endings (endl) + * + * Original Content (originalPom) + * Modified Content (resultPomBytes) + */ +@Suppress("ArrayInDataClass") +data class POMDocument( + val originalPom: ByteArray, + val pomPath: URL?, + val pomDocument: Document, + var charset: Charset = Charset.defaultCharset(), + var endl: String = "\n", + var indent: String = " ", + var resultPomBytes: ByteArray = byteArrayOf(), + + /** + * Preamble Contents are stored here + */ + var preamble: String = "", + + /** + * Afterword - if needed + */ + var suffix: String = "", +) { + internal val file: File get() = File(this.pomPath!!.toURI()) + + val resultPom: Document = pomDocument.clone() as Document + + var dirty: Boolean = false + + override fun toString(): String { + return if (null == this.pomPath) { + "missing" + } else { + ("[POMDocument @ " + this.pomPath.toString() + "]") + } + } +} + diff --git a/src/main/java/io/github/pixee/maven/operator/POMDocumentFactory.kt b/src/main/java/io/github/pixee/maven/operator/POMDocumentFactory.kt new file mode 100644 index 000000000..4f5a74bce --- /dev/null +++ b/src/main/java/io/github/pixee/maven/operator/POMDocumentFactory.kt @@ -0,0 +1,36 @@ +package io.github.pixee.maven.operator + +import org.apache.commons.io.IOUtils +import org.dom4j.io.SAXReader +import java.io.File +import java.io.InputStream +import java.net.URL + +/** + * Factory for a POMDocument + */ +object POMDocumentFactory { + @JvmStatic + fun load(`is`: InputStream): POMDocument { + val originalPom: ByteArray = IOUtils.toByteArray(`is`) + val pomDocument = SAXReader().read(originalPom.inputStream())!! + + return POMDocument(originalPom = originalPom, pomDocument = pomDocument, pomPath = null) + } + + @JvmStatic + fun load(f: File) = + load(f.toURI().toURL()) + + @JvmStatic + fun load(url: URL): POMDocument { + val originalPom: ByteArray = IOUtils.toByteArray(url.openStream()) + + val saxReader = SAXReader() + + val pomDocument = saxReader.read(originalPom.inputStream()) + + return POMDocument(originalPom = originalPom, pomPath = url, pomDocument = pomDocument) + } + +} \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/POMOperator.kt b/src/main/java/io/github/pixee/maven/operator/POMOperator.kt index c8206c8b2..85c5e8578 100644 --- a/src/main/java/io/github/pixee/maven/operator/POMOperator.kt +++ b/src/main/java/io/github/pixee/maven/operator/POMOperator.kt @@ -21,7 +21,7 @@ object POMOperator { @JvmStatic fun queryDependency( projectModel: ProjectModel - ) = POMOperator.queryDependency(projectModel, emptyList()) + ) = queryDependency(projectModel, emptyList()) /** * Internal Use (package-wide) - Query for all the artifacts mentioned on a POM @@ -43,7 +43,7 @@ object POMOperator { chain.execute(projectModel) - val lastCommand = chain.commandList.filterIsInstance() + val lastCommand = chain.commandList.filterIsInstance() .lastOrNull { it.result != null } ?: return emptyList() diff --git a/src/main/java/io/github/pixee/maven/operator/POMScanner.kt b/src/main/java/io/github/pixee/maven/operator/POMScanner.kt new file mode 100644 index 000000000..59210198b --- /dev/null +++ b/src/main/java/io/github/pixee/maven/operator/POMScanner.kt @@ -0,0 +1,110 @@ +package io.github.pixee.maven.operator + +import org.dom4j.Element +import java.io.File +import java.net.URI +import java.nio.file.Path +import java.nio.file.Paths +import java.util.* +import kotlin.io.path.notExists + +object POMScanner { + private val RE_WINDOWS_PATH = Regex("""^\p{Alpha}:""") + + @JvmStatic + fun scanFrom(originalFile: File, topLevelDirectory: File): ProjectModelFactory { + val pomFile: POMDocument = POMDocumentFactory.load(originalFile) + val parentPomFiles: MutableList = arrayListOf() + + val pomFileQueue: Queue = LinkedList() + + val relativePathElement = + pomFile.pomDocument.rootElement.element("parent")?.element("relativePath") + + if (relativePathElement != null) { + pomFileQueue.add(relativePathElement) + } + + var lastFile : File = originalFile + + fun resolvePath(baseFile: File, relativePath: String) : Path { + var parentDir = baseFile + + if (parentDir.isFile) { + parentDir = parentDir.parentFile + } + + val result = File(File(parentDir, relativePath).toURI().normalize().path) + + lastFile = if (result.isDirectory) { + result + } else { + result.parentFile + } + + return Paths.get(result.absolutePath) + } + + val prevPaths : MutableSet = linkedSetOf() + + while (pomFileQueue.isNotEmpty()) { + val relativePathElement = pomFileQueue.poll() + + val relativePath = fixPomRelativePath(relativePathElement.text) + + if (!isRelative(relativePath)) + throw InvalidPathException(pomFile.file, relativePath) + + if (prevPaths.contains(relativePath)) { + throw InvalidPathException(pomFile.file, relativePath, loop=true) + } else { + prevPaths.add(relativePath) + } + + val newPath = resolvePath(lastFile, relativePath) + + if (newPath.notExists()) + throw InvalidPathException(pomFile.file, relativePath) + + if (!newPath.startsWith(topLevelDirectory.absolutePath)) + throw InvalidPathException(pomFile.file, relativePath) + + val newPomFile = POMDocumentFactory.load(newPath.toFile()) + + parentPomFiles.add(newPomFile) + + val newRelativePathElement = + newPomFile.pomDocument.rootElement.element("parent")?.element("relativePath") + + if (newRelativePathElement != null) { + pomFileQueue.add(newRelativePathElement) + } + } + + return ProjectModelFactory.loadFor( + pomFile = pomFile, + parentPomFiles = parentPomFiles + ) + } + + private fun fixPomRelativePath(text: String?): String { + if (null == text) + return "" + + val name = File(text).name + + if (-1 == name.indexOf(".")) { + return "$text/pom.xml" + } + + return text + } + + private fun isRelative(path: String): Boolean { + if (path.matches(RE_WINDOWS_PATH)) { + return false + } + + return !(path.startsWith("/") || path.startsWith("~")) + } +} diff --git a/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt b/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt index ecdcf0b90..8550b1041 100644 --- a/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt +++ b/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt @@ -1,10 +1,7 @@ package io.github.pixee.maven.operator import io.github.pixee.maven.operator.Util.selectXPathNodes -import org.dom4j.Document import org.dom4j.Element -import java.net.URL -import java.nio.charset.Charset /** * ProjectModel represents the input parameters for the chain @@ -12,52 +9,116 @@ import java.nio.charset.Charset * @todo consider resolution and also Topological Sort of Properties for cross-property reference */ class ProjectModel internal constructor( - val originalPom : ByteArray, - val pomPath: URL?, - val pomDocument: Document, + val pomFile: POMDocument, + + val parentPomFiles: List = emptyList(), + var dependency: Dependency?, val skipIfNewer: Boolean, val useProperties: Boolean, val activeProfiles: Set, val overrideIfAlreadyExists: Boolean, val queryType: QueryType = QueryType.NONE, - - var charset: Charset, - var endl: String, - var indent: String, ) { internal var modifiedByCommand = false - var resultPomBytes: ByteArray = byteArrayOf() + /** + * Involved POM Files + */ + val allPomFiles: Collection + get() = listOfNotNull( + pomFile, + *parentPomFiles.toTypedArray() + ) + + val resolvedProperties = + run { + val result: MutableMap = LinkedHashMap() + + allPomFiles + .reversed() // parent first, children later - thats why its reversed + .forEach { pomFile -> + val rootProperties = + propertiesDefinedOnPomDocument(pomFile) + + result.putAll(rootProperties) - internal val resultPom: Document = pomDocument.clone() as Document + val activatedProfiles = activeProfiles.filterNot { it.startsWith("!") } - val resolvedProperties: Map = + val newPropertiesFromProfiles = activatedProfiles.map { profileName -> + getPropertiesFromProfile(profileName, pomFile) + } + + newPropertiesFromProfiles.forEach { result.putAll(it) } + } + + result.toMap() + } + + val propertiesDefinedByFile: Map>> = run { - val rootProperties = - pomDocument.rootElement.elements("properties").flatMap { it.elements() } - .associate { - it.name to it.text + val result: MutableMap>> = LinkedHashMap() + + allPomFiles + .reversed() + .forEach { pomFile -> + val rootProperties = + propertiesDefinedOnPomDocument(pomFile) + + val tempProperties: MutableMap = LinkedHashMap() + + tempProperties.putAll(rootProperties) + + val activatedProfiles = activeProfiles.filterNot { it.startsWith("!") } + + val newPropertiesFromProfiles = activatedProfiles.map { profileName -> + getPropertiesFromProfile(profileName, pomFile) } - val result: MutableMap = LinkedHashMap() - result.putAll(rootProperties) - val activatedProfiles = activeProfiles.filterNot { it.startsWith("!") } - activatedProfiles.forEach { profileName -> - val expression = - "/m:project/m:profiles/m:profile[./m:id[text()='${profileName}']]/m:properties" - val propertiesElements = - pomDocument.selectXPathNodes(expression) - - val newPropertiesToAppend = - propertiesElements.filterIsInstance() - .flatMap { it.elements() } - .associate { - it.name to it.text + + newPropertiesFromProfiles.forEach { tempProperties.putAll(it) } + + tempProperties.entries.forEach { entry -> + if (!result.containsKey(entry.key)) { + result.put(entry.key, ArrayList()) } - result.putAll(newPropertiesToAppend) - } - result.toMap() + val definitionList = + result.get(entry.key) as MutableList> + + definitionList.add(entry.value to pomFile) + } + } + + result } + + private fun getPropertiesFromProfile( + profileName: String, + pomFile: POMDocument + ): Map { + val expression = + "/m:project/m:profiles/m:profile[./m:id[text()='${profileName}']]/m:properties" + val propertiesElements = + pomFile.pomDocument.selectXPathNodes(expression) + + val newPropertiesToAppend = + propertiesElements.filterIsInstance() + .flatMap { it.elements() } + .associate { + it.name to it.text + } + + return newPropertiesToAppend + } + + private fun propertiesDefinedOnPomDocument(pomFile: POMDocument): Map { + val rootProperties = + pomFile.pomDocument.rootElement.elements("properties") + .flatMap { it.elements() } + .associate { + it.name to it.text + } + return rootProperties + } } diff --git a/src/main/java/io/github/pixee/maven/operator/ProjectModelFactory.kt b/src/main/java/io/github/pixee/maven/operator/ProjectModelFactory.kt index e9183c400..90eede789 100644 --- a/src/main/java/io/github/pixee/maven/operator/ProjectModelFactory.kt +++ b/src/main/java/io/github/pixee/maven/operator/ProjectModelFactory.kt @@ -1,20 +1,15 @@ package io.github.pixee.maven.operator -import org.apache.commons.io.IOUtils -import org.dom4j.Document -import org.dom4j.io.SAXReader import java.io.File import java.io.InputStream import java.net.URL -import java.nio.charset.Charset /** * Builder Object for ProjectModel instances */ class ProjectModelFactory private constructor( - private val originalPom: ByteArray, - private var pomPath: URL?, - private var pomDocument: Document, + private var pomFile: POMDocument, + private var parentPomFiles: List = listOf(), private var dependency: Dependency? = null, private var skipIfNewer: Boolean = false, private var useProperties: Boolean = false, @@ -24,12 +19,23 @@ class ProjectModelFactory private constructor( ) { /** * Fluent Setter - * @param pomPath pomPath + * + * @param pomFile POM File */ - fun withPomPath(pomPath: URL): ProjectModelFactory = this.apply { - this.pomPath = pomPath + fun withPomFile(pomFile: POMDocument): ProjectModelFactory = this.apply { + this.pomFile = pomFile } + /** + * Fluent Setter + * + * @param parentPomFiles Parent POM Files + */ + fun withParentPomFiles(parentPomFiles: Collection): ProjectModelFactory = + this.apply { + this.parentPomFiles = listOf(*parentPomFiles.filterNotNull().toTypedArray()) + } + /** * Fluent Setter * @@ -81,29 +87,26 @@ class ProjectModelFactory private constructor( */ fun build(): ProjectModel { return ProjectModel( - originalPom = originalPom, - pomPath = pomPath, - pomDocument = pomDocument, + pomFile = pomFile, + parentPomFiles = parentPomFiles, dependency = dependency, skipIfNewer = skipIfNewer, useProperties = useProperties, activeProfiles = activeProfiles, overrideIfAlreadyExists = overrideIfAlreadyExists, - queryType = queryType, - charset = Charset.defaultCharset(), - endl = "", - indent = "", + queryType = queryType ) } + /** + * Mostly Delegates to POMDocumentFactory + */ companion object { @JvmStatic fun load(`is`: InputStream): ProjectModelFactory { - val originalPom: ByteArray = IOUtils.toByteArray(`is`) + val pomDocument = POMDocumentFactory.load(`is`) - val pomDocument = SAXReader().read(originalPom.inputStream())!! - - return ProjectModelFactory(pomPath = null, pomDocument = pomDocument, originalPom = originalPom) + return ProjectModelFactory(pomFile = pomDocument) } @JvmStatic @@ -112,13 +115,15 @@ class ProjectModelFactory private constructor( @JvmStatic fun load(url: URL): ProjectModelFactory { - val originalPom: ByteArray = IOUtils.toByteArray(url.openStream()) - - val saxReader = SAXReader() + val pomFile = POMDocumentFactory.load(url) - val pomDocument = saxReader.read(originalPom.inputStream()) - - return ProjectModelFactory(pomPath = url, pomDocument = pomDocument, originalPom = originalPom) + return ProjectModelFactory(pomFile = pomFile) } + + @JvmStatic + internal fun loadFor( + pomFile: POMDocument, + parentPomFiles: Collection, + ) = ProjectModelFactory(pomFile = pomFile, parentPomFiles = parentPomFiles.toList()) } } \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/QueryByEmbedder.kt b/src/main/java/io/github/pixee/maven/operator/QueryByEmbedder.kt index 7a80d0d72..973f06852 100644 --- a/src/main/java/io/github/pixee/maven/operator/QueryByEmbedder.kt +++ b/src/main/java/io/github/pixee/maven/operator/QueryByEmbedder.kt @@ -13,7 +13,7 @@ import java.io.PrintStream /** * Uses Maven Embedder to Implement */ -class QueryByEmbedder : io.github.pixee.maven.operator.AbstractSimpleQueryCommand() { +class QueryByEmbedder : AbstractQueryCommand() { /** * Runs the "dependency:tree" mojo - but using Embedder instead. */ diff --git a/src/main/java/io/github/pixee/maven/operator/QueryByInvoker.kt b/src/main/java/io/github/pixee/maven/operator/QueryByInvoker.kt index c5e44a6b2..a3fb973d2 100644 --- a/src/main/java/io/github/pixee/maven/operator/QueryByInvoker.kt +++ b/src/main/java/io/github/pixee/maven/operator/QueryByInvoker.kt @@ -4,7 +4,7 @@ import org.apache.maven.shared.invoker.DefaultInvoker import org.apache.maven.shared.invoker.InvocationRequest import java.io.File -class QueryByInvoker : io.github.pixee.maven.operator.AbstractSimpleQueryCommand() { +class QueryByInvoker : AbstractQueryCommand() { override fun extractDependencyTree( outputPath: File, @@ -13,7 +13,8 @@ class QueryByInvoker : io.github.pixee.maven.operator.AbstractSimpleQueryCommand ) { val invoker = DefaultInvoker() - val invocationRequest: InvocationRequest = buildInvocationRequest(outputPath, pomFilePath, c) + val invocationRequest: InvocationRequest = + buildInvocationRequest(outputPath, pomFilePath, c) val invocationResult = invoker.execute(invocationRequest) diff --git a/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt b/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt index ba43688ae..7cb2de578 100644 --- a/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt +++ b/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt @@ -29,7 +29,7 @@ import kotlin.io.path.toPath * TODO: Support Profiles / Environment Variables * Support Third Party / User-Supplied Repositories (right now it only supports central) */ -class QueryByResolver : io.github.pixee.maven.operator.AbstractSimpleQueryCommand() { +class QueryByResolver : AbstractQueryCommand() { private val localRepo = LocalRepository( File( System.getProperty("user.home"), @@ -55,7 +55,7 @@ class QueryByResolver : io.github.pixee.maven.operator.AbstractSimpleQueryComman } @Suppress("DEPRECATION") - override fun execute(c: ProjectModel): Boolean { + override fun execute(pm: ProjectModel): Boolean { /* * Aether's components implement org.eclipse.aether.spi.locator.Service to ease manual wiring and using the * prepopulated DefaultServiceLocator, we only need to register the repository connector and transporter @@ -106,11 +106,11 @@ class QueryByResolver : io.github.pixee.maven.operator.AbstractSimpleQueryComman val repositoryManager = DefaultRemoteRepositoryManager() val modelBuildingRequest = DefaultModelBuildingRequest().apply { - val pomFile = c.pomPath!!.toURI().toPath().toFile() + val pomFile = pm.pomFile.pomPath!!.toURI().toPath().toFile() - this.activeProfileIds = c.activeProfiles.filterNot { it.startsWith("!") }.toList() + this.activeProfileIds = pm.activeProfiles.filterNot { it.startsWith("!") }.toList() this.inactiveProfileIds = - c.activeProfiles.filter { it.startsWith("!") }.map { it.substring(1) }.toList() + pm.activeProfiles.filter { it.startsWith("!") }.map { it.substring(1) }.toList() this.userProperties = System.getProperties() this.systemProperties = System.getProperties() diff --git a/src/main/java/io/github/pixee/maven/operator/SimpleDependencyManagement.kt b/src/main/java/io/github/pixee/maven/operator/SimpleDependencyManagement.kt index 76dadadad..48b6366fa 100644 --- a/src/main/java/io/github/pixee/maven/operator/SimpleDependencyManagement.kt +++ b/src/main/java/io/github/pixee/maven/operator/SimpleDependencyManagement.kt @@ -3,11 +3,11 @@ package io.github.pixee.maven.operator import io.github.pixee.maven.operator.Util.buildLookupExpressionForDependencyManagement -val SimpleDependencyManagement = object : io.github.pixee.maven.operator.AbstractSimpleCommand() { - override fun execute(c: ProjectModel): Boolean { +val SimpleDependencyManagement = object : AbstractCommand() { + override fun execute(pm: ProjectModel): Boolean { val lookupExpression = - buildLookupExpressionForDependencyManagement(c.dependency!!) + buildLookupExpressionForDependencyManagement(pm.dependency!!) - return handleDependency(c, lookupExpression) + return handleDependency(pm, lookupExpression) } } \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/SimpleInsert.kt b/src/main/java/io/github/pixee/maven/operator/SimpleInsert.kt index 783865d5b..03c11d31f 100644 --- a/src/main/java/io/github/pixee/maven/operator/SimpleInsert.kt +++ b/src/main/java/io/github/pixee/maven/operator/SimpleInsert.kt @@ -1,51 +1,51 @@ package io.github.pixee.maven.operator import io.github.pixee.maven.operator.Util.addIndentedElement -import io.github.pixee.maven.operator.Util.findIndentLevel import io.github.pixee.maven.operator.Util.selectXPathNodes import io.github.pixee.maven.operator.Util.upgradeVersionNode -import org.apache.commons.lang3.StringUtils import org.dom4j.Element -import org.dom4j.Text -import org.dom4j.tree.DefaultText /** * Represents a POM Upgrade Strategy by simply adding a dependency/ section (and optionally a dependencyManagement/ section as well) */ val SimpleInsert = object : Command { - override fun execute(c: ProjectModel): Boolean { + override fun execute(pm: ProjectModel): Boolean { val dependencyManagementNodeList = - c.resultPom.selectXPathNodes("/m:project/m:dependencyManagement") + pm.pomFile.resultPom.selectXPathNodes("/m:project/m:dependencyManagement") val dependenciesNode = if (dependencyManagementNodeList.isEmpty()) { val newDependencyManagementNode = - c.resultPom.rootElement.addIndentedElement(c, "dependencyManagement") + pm.pomFile.resultPom.rootElement.addIndentedElement( + pm.pomFile, + "dependencyManagement" + ) val dependencyManagementNode = - newDependencyManagementNode.addIndentedElement(c, "dependencies") + newDependencyManagementNode.addIndentedElement(pm.pomFile, "dependencies") dependencyManagementNode } else { (dependencyManagementNodeList.first() as Element).element("dependencies") } - val dependencyNode = appendCoordinates(dependenciesNode, c) + val dependencyNode = appendCoordinates(dependenciesNode, pm) - val versionNode = dependencyNode.addIndentedElement(c, "version") + val versionNode = dependencyNode.addIndentedElement(pm.pomFile, "version") - upgradeVersionNode(c, versionNode) + upgradeVersionNode(pm, versionNode, pm.pomFile) - val dependenciesNodeList = c.resultPom.selectXPathNodes("//m:project/m:dependencies") + val dependenciesNodeList = + pm.pomFile.resultPom.selectXPathNodes("//m:project/m:dependencies") val rootDependencyNode: Element = if (dependenciesNodeList.isEmpty()) { - c.resultPom.rootElement.addIndentedElement(c, "dependencies") + pm.pomFile.resultPom.rootElement.addIndentedElement(pm.pomFile, "dependencies") } else if (dependenciesNodeList.size == 1) { dependenciesNodeList[0] as Element } else { throw IllegalStateException("More than one dependencies node") } - appendCoordinates(rootDependencyNode, c) + appendCoordinates(rootDependencyNode, pm) return true } @@ -57,15 +57,15 @@ val SimpleInsert = object : Command { dependenciesNode: Element, c: ProjectModel ): Element { - val dependencyNode = dependenciesNode.addIndentedElement(c, "dependency") + val dependencyNode = dependenciesNode.addIndentedElement(c.pomFile, "dependency") - val groupIdNode = dependencyNode.addIndentedElement(c, "groupId") + val groupIdNode = dependencyNode.addIndentedElement(c.pomFile, "groupId") val dep = c.dependency!! groupIdNode.text = dep.groupId - val artifactIdNode = dependencyNode.addIndentedElement(c, "artifactId") + val artifactIdNode = dependencyNode.addIndentedElement(c.pomFile, "artifactId") artifactIdNode.text = dep.artifactId diff --git a/src/main/java/io/github/pixee/maven/operator/SimpleUpgrade.kt b/src/main/java/io/github/pixee/maven/operator/SimpleUpgrade.kt index 6a4d130e7..7e268befa 100644 --- a/src/main/java/io/github/pixee/maven/operator/SimpleUpgrade.kt +++ b/src/main/java/io/github/pixee/maven/operator/SimpleUpgrade.kt @@ -6,11 +6,11 @@ import io.github.pixee.maven.operator.Util.buildLookupExpressionForDependency /** * Represents bumping an existing dependency/ */ -val SimpleUpgrade = object : io.github.pixee.maven.operator.AbstractSimpleCommand() { - override fun execute(c: ProjectModel): Boolean { +val SimpleUpgrade = object : AbstractCommand() { + override fun execute(pm: ProjectModel): Boolean { val lookupExpressionForDependency = - buildLookupExpressionForDependency(c.dependency!!) + buildLookupExpressionForDependency(pm.dependency!!) - return handleDependency(c, lookupExpressionForDependency) + return handleDependency(pm, lookupExpressionForDependency) } } \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/SupportCommand.kt b/src/main/java/io/github/pixee/maven/operator/SupportCommand.kt index b6e1c15ee..be9286d58 100644 --- a/src/main/java/io/github/pixee/maven/operator/SupportCommand.kt +++ b/src/main/java/io/github/pixee/maven/operator/SupportCommand.kt @@ -3,5 +3,4 @@ package io.github.pixee.maven.operator /** * Tag Interface to the chain to allow it to figure out whether things were modified */ -interface SupportCommand { -} \ No newline at end of file +interface SupportCommand \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/Util.kt b/src/main/java/io/github/pixee/maven/operator/Util.kt index 8088d31d3..85548d4d8 100644 --- a/src/main/java/io/github/pixee/maven/operator/Util.kt +++ b/src/main/java/io/github/pixee/maven/operator/Util.kt @@ -13,7 +13,7 @@ import org.dom4j.tree.DefaultText import org.jaxen.SimpleNamespaceContext import org.jaxen.XPath import org.jaxen.dom4j.Dom4jXPath -import java.io.* +import java.io.File /** @@ -24,18 +24,18 @@ object Util { * Extension Method that easily allows to add an element inside another while * retaining formatting * - * @param c ProjectModel / Context + * @param d ProjectModel / Context * @param name new element ("tag") name * @return created element inside `this` object, already indented after and (optionally) before */ - fun Element.addIndentedElement(c: ProjectModel, name: String): Element { + fun Element.addIndentedElement(d: POMDocument, name: String): Element { val contentList = this.content() val indentLevel = findIndentLevel(this) - val prefix = c.endl + StringUtils.repeat(c.indent, 1 + indentLevel) + val prefix = d.endl + StringUtils.repeat(d.indent, 1 + indentLevel) - val suffix = c.endl + StringUtils.repeat(c.indent, indentLevel) + val suffix = d.endl + StringUtils.repeat(d.indent, indentLevel) if (contentList.isNotEmpty() && contentList.last() is Text) { val lastElement = contentList.last() as Text @@ -51,6 +51,8 @@ object Util { contentList.add(DefaultText(suffix)) + d.dirty = true + return newElement } @@ -59,7 +61,7 @@ object Util { * * @return indent level */ - internal fun findIndentLevel(startingNode: Element): Int { + private fun findIndentLevel(startingNode: Element): Int { var level = 0 var node = startingNode @@ -80,21 +82,21 @@ object Util { /** * Upserts a given property */ - private fun upgradeProperty(c: ProjectModel, propertyName: String) { - if (null == c.resultPom.rootElement.element("properties")) { - c.resultPom.rootElement.addIndentedElement(c, "properties") + private fun upgradeProperty(c: ProjectModel, d: POMDocument, propertyName: String) { + if (null == d.resultPom.rootElement.element("properties")) { + d.resultPom.rootElement.addIndentedElement(d, "properties") } - val parentPropertyElement = c.resultPom.rootElement.element("properties") + val parentPropertyElement = d.resultPom.rootElement.element("properties") if (null == parentPropertyElement.element(propertyName)) { - parentPropertyElement.addIndentedElement(c, propertyName) + parentPropertyElement.addIndentedElement(d, propertyName) } else { if (!c.overrideIfAlreadyExists) { val propertyReferenceRE = Regex.fromLiteral("\${$propertyName}") val numberOfAllCurrentMatches = - propertyReferenceRE.findAll(c.pomDocument.asXML()).toList().size + propertyReferenceRE.findAll(d.resultPom.asXML()).toList().size if (numberOfAllCurrentMatches > 1) { throw IllegalStateException("Property $propertyName is already defined - and used more than once.") @@ -104,7 +106,11 @@ object Util { val propertyElement = parentPropertyElement.element(propertyName) - propertyElement.text = c.dependency!!.version + if (!(propertyElement.text ?: "").trim().equals(c.dependency!!.version)) { + propertyElement.text = c.dependency!!.version + + d.dirty = true + } } /** @@ -156,16 +162,23 @@ object Util { /** * Given a Version Node, upgrades a resulting POM */ - internal fun upgradeVersionNode(c: ProjectModel, versionNode: Element) { + internal fun upgradeVersionNode( + c: ProjectModel, + versionNode: Element, + pomDocumentHoldingProperty: POMDocument + ) { if (c.useProperties) { val propertyName = propertyName(c, versionNode) // define property - upgradeProperty(c, propertyName) + upgradeProperty(c, pomDocumentHoldingProperty, propertyName) versionNode.text = escapedPropertyName(propertyName) } else { - versionNode.text = c.dependency!!.version + if (!(versionNode.text ?: "").trim().equals(c.dependency!!.version)) { + pomDocumentHoldingProperty.dirty = true + versionNode.text = c.dependency!!.version + } } } @@ -254,7 +267,7 @@ object Util { val result = possiblePaths.findLast(isCliCallable) if (null == result) { - io.github.pixee.maven.operator.AbstractSimpleQueryCommand.LOGGER.warn( + AbstractQueryCommand.LOGGER.warn( "Unable to find mvn executable (execs: {}, path: {})", nativeExecutables.joinToString("/"), pathContentString diff --git a/src/main/java/io/github/pixee/maven/operator/WrongDependencyTypeException.kt b/src/main/java/io/github/pixee/maven/operator/WrongDependencyTypeException.kt new file mode 100644 index 000000000..9c13bbe89 --- /dev/null +++ b/src/main/java/io/github/pixee/maven/operator/WrongDependencyTypeException.kt @@ -0,0 +1,3 @@ +package io.github.pixee.maven.operator + +class WrongDependencyTypeException(message: String) : RuntimeException(message) diff --git a/src/test/java/io/github/pixee/maven/operator/test/AbstractTestBase.kt b/src/test/java/io/github/pixee/maven/operator/test/AbstractTestBase.kt index c537316d0..e95761867 100644 --- a/src/test/java/io/github/pixee/maven/operator/test/AbstractTestBase.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/AbstractTestBase.kt @@ -18,6 +18,10 @@ import java.net.URLDecoder open class AbstractTestBase { protected val LOGGER: Logger = LoggerFactory.getLogger(POMOperatorTest::class.java) + fun getResource(name: String) = this.javaClass.getResource(name)!! + + fun getResourceAsFile(name: String): File = File(getResource(name).toURI()) + /** * Implements a Given-When-Then idiom * @@ -54,7 +58,7 @@ open class AbstractTestBase { assertFalse( "Expected and outcome have differences", - getXmlDifferences(context.resultPom, outcome).hasDifferences() + getXmlDifferences(context.pomFile.resultPom, outcome).hasDifferences() ) } else { val resultFilePath = "src/test/resources/" + this.javaClass.`package`.name.replace( @@ -70,7 +74,7 @@ open class AbstractTestBase { LOGGER.warn("File $resultFilePath not found - writing results instead and ignorning assertions at all") - File(resultFilePath).writeBytes(context.resultPomBytes) + File(resultFilePath).writeBytes(context.pomFile.resultPomBytes) } return context diff --git a/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt b/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt index 9445614d3..1bab1c082 100644 --- a/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt @@ -54,11 +54,6 @@ class MassRepoIT { "apache/pulsar", pomPath = "pulsar-broker/pom.xml" ) to "commons-codec:commons-codec:1.14", - TestRepo( - "metersphere/metersphere", - branch = "main", - pomPath = "framework/eureka/pom.xml" - ) to "commons-lang3:commons-lang3:3.6", TestRepo( "apache/rocketmq", pomPath = "common/pom.xml" @@ -70,12 +65,6 @@ class MassRepoIT { TestRepo( "casbin/jcasbin", ) to "com.google.code.gson:gson:2.8.0", - /* - TestRepo( - "trinodb/trino", - pomPath = "core/trino-main/pom.xml" - ) to "org.apache.commons:commons-math3:3.6.0", - */ TestRepo( "bytedeco/javacv" ) to "org.jogamp.jocl:jocl-main:2.3.1", @@ -167,7 +156,7 @@ class MassRepoIT { val alternatePomFile = File(File(sampleRepo.cacheDir(), sampleRepo.pomPath).parent, "pom-modified.xml") - alternatePomFile.writeBytes(context.resultPomBytes) + alternatePomFile.writeBytes(context.pomFile.resultPomBytes) val finalDependencies = getDependenciesFrom(alternatePomFile.canonicalPath, sampleRepo.cacheDir()) diff --git a/src/test/java/io/github/pixee/maven/operator/test/POMOperatorMultipomTest.kt b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorMultipomTest.kt new file mode 100644 index 000000000..4ae17b0d0 --- /dev/null +++ b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorMultipomTest.kt @@ -0,0 +1,155 @@ +package io.github.pixee.maven.operator.test + +import com.google.common.io.Files +import io.github.pixee.maven.operator.* +import org.junit.Test +import java.io.File +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +class POMOperatorMultipomTest : AbstractTestBase() { + @Test(expected = WrongDependencyTypeException::class) + fun testWithParentAndChildMissingPackaging() { + val parentResource = getResource("parent-and-child-parent-broken.xml") + + val parentPomFiles = listOf(POMDocumentFactory.load(parentResource)) + + val parentPom = ProjectModelFactory.load( + parentResource, + ).withParentPomFiles(parentPomFiles) + + gwt( + "parent-and-child", + parentPom.withDependency(Dependency.fromString("org.dom4j:dom4j:2.0.3")) + ) + } + + @Test(expected = WrongDependencyTypeException::class) + fun testWithParentAndChildWrongType() { + val parentResource = getResource("parent-and-child-child-broken.xml") + + val parentPomFile = POMDocumentFactory.load(getResource("parent-and-child-parent.xml")) + + val parentPomFiles = listOf(parentPomFile) + + val parentPom = ProjectModelFactory.load( + parentResource, + ).withParentPomFiles(parentPomFiles) + + gwt( + "parent-and-child-wrong-type", + parentPom.withDependency(Dependency.fromString("org.dom4j:dom4j:2.0.3")) + ) + } + + @Test + fun testWithMultiplePomsBasicNoVersionProperty() { + val parentPomFile = getResource("sample-parent/pom.xml") + + val projectModelFactory = ProjectModelFactory + .load( + getResource("sample-child-with-relativepath.xml") + ) + .withParentPomFiles(listOf(POMDocumentFactory.load(parentPomFile))) + .withUseProperties(false) + + val result = gwt( + "multiple-pom-basic-no-version-property", + projectModelFactory.withDependency(Dependency.fromString("org.dom4j:dom4j:2.0.3")) + ) + + validateDepsFrom(result) + + assertTrue(result.allPomFiles.size == 2, "There should be two files") + assertTrue(result.allPomFiles.all { it.dirty }, "All files were modified") + } + + @Test + fun testWithMultiplePomsBasicWithVersionProperty() { + val parentPomFile = getResource("sample-parent/pom.xml") + + val sampleChild = getResource("sample-child-with-relativepath.xml") + + val parentPom = ProjectModelFactory.load( + sampleChild + ).withParentPomFiles(listOf(POMDocumentFactory.load(parentPomFile))) + .withUseProperties(true) + + val result = gwt( + "multiple-pom-basic-with-version-property", + parentPom.withDependency(Dependency.fromString("org.dom4j:dom4j:2.0.3")) + ) + + validateDepsFrom(result) + + assertTrue(result.allPomFiles.size == 2, "There should be two files") + assertTrue(result.allPomFiles.all { it.dirty }, "All files were modified") + + val parentPomString = String(result.parentPomFiles.first().resultPomBytes, Charsets.UTF_8) + val pomString = String(result.pomFile.resultPomBytes, Charsets.UTF_8) + + val version = result.dependency!!.version!! + + assertTrue( + parentPomString.contains("versions.dom4j>${version}"), + "Must contain property with version set on parent pom" + ) + assertFalse(pomString.contains(version), "Must not have reference to version on pom") + } + + fun validateDepsFrom(context: ProjectModel) { + val resultFiles = copyFiles(context) + + resultFiles.entries.forEach { + System.err.println("from ${it.key.pomPath} -> ${it.value}") + } + + val pomFile = resultFiles.entries.first().value + + val dependencies = POMOperator.queryDependency( + ProjectModelFactory.load(pomFile) + .withQueryType(QueryType.UNSAFE) + .build() + ) + + val foundDependency = dependencies.contains(context.dependency!!) + + assertTrue( + foundDependency, + "Dependency ${context.dependency!!} must be present in context $context ($dependencies)" + ) + } + + fun copyFiles(context: ProjectModel): Map { + var commonPath = File(context.pomFile.pomPath!!.toURI()).canonicalFile + + for (p in context.parentPomFiles) { + commonPath = File( + File(p.pomPath!!.toURI()).canonicalPath.toString() + .commonPrefixWith(commonPath.canonicalPath) + ) + } + + val commonPathLen = commonPath.parent.length + + val tmpOutputDir = Files.createTempDir() + + val result = context.allPomFiles.map { p -> + val pAsFile = File(p.pomPath!!.toURI()) + + val relPath = pAsFile.canonicalPath.substring(1 + commonPathLen) + + val targetPath = File(tmpOutputDir, relPath) + + if (!targetPath.parentFile.exists()) { + targetPath.parentFile.mkdirs() + } + + targetPath.writeBytes(p.resultPomBytes) + + p to targetPath + }.toMap() + + return result + } +} diff --git a/src/test/java/io/github/pixee/maven/operator/test/POMOperatorTest.kt b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorTest.kt index cd35742ab..84eedab54 100644 --- a/src/test/java/io/github/pixee/maven/operator/test/POMOperatorTest.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorTest.kt @@ -12,6 +12,7 @@ import org.junit.Test import org.xmlunit.diff.ComparisonType import java.io.File import java.nio.charset.Charset +import kotlin.test.assertFalse import kotlin.test.assertTrue /** @@ -20,7 +21,7 @@ import kotlin.test.assertTrue class POMOperatorTest : AbstractTestBase() { @Test(expected = DocumentException::class) fun testWithBrokenPom() { - val context = gwt( + gwt( "broken-pom", ProjectModelFactory.load( POMOperatorTest::class.java.getResource("broken-pom.xml")!!, @@ -49,11 +50,13 @@ class POMOperatorTest : AbstractTestBase() { .build() if (POMOperator.modify(projectModel)) { - val resultPomAsXml = String(projectModel.resultPomBytes) + assertTrue(projectModel.pomFile.dirty, "Original POM File is Dirty") + + val resultPomAsXml = String(projectModel.pomFile.resultPomBytes) LOGGER.debug("resultPomAsXml: {}", resultPomAsXml) - testPom.writeBytes(projectModel.resultPomBytes) + testPom.writeBytes(projectModel.pomFile.resultPomBytes) } else { throw IllegalStateException("Code that shouldn't be reached out at all") } @@ -92,11 +95,13 @@ class POMOperatorTest : AbstractTestBase() { ).withDependency(Dependency.fromString("org.dom4j:dom4j:2.0.3")) ) - val diff = getXmlDifferences(context.pomDocument, context.resultPom) + assertTrue(context.pomFile.dirty, "Original POM File is Dirty") + + val diff = getXmlDifferences(context.pomFile.pomDocument, context.pomFile.resultPom) assertThat("Document has differences", diff.hasDifferences()) - val textDiff = getTextDifferences(context.pomDocument, context.resultPom) + val textDiff = getTextDifferences(context.pomFile.pomDocument, context.pomFile.resultPom) LOGGER.debug("textDiff: {}", textDiff) @@ -122,7 +127,9 @@ class POMOperatorTest : AbstractTestBase() { ).withDependency(dependencyToUpgradeOnCaseThree).withSkipIfNewer(false) ) - val diff = getXmlDifferences(context.pomDocument, context.resultPom) + val diff = getXmlDifferences(context.pomFile.pomDocument, context.pomFile.resultPom) + + assertTrue(context.pomFile.dirty, "Original POM File is Dirty") assertThat("Document has differences", diff.hasDifferences()) assertThat("Document has a single difference", diff.differences.toList().size == 1) @@ -147,9 +154,11 @@ class POMOperatorTest : AbstractTestBase() { ).withDependency(dependencyToUpgrade).withSkipIfNewer(true) ) - val diff = getXmlDifferences(context.pomDocument, context.resultPom) + val diff = getXmlDifferences(context.pomFile.pomDocument, context.pomFile.resultPom) assertThat("Document has no differences", !diff.hasDifferences()) + + assertFalse(context.pomFile.dirty, "Original POM File is not Dirty") } @Test @@ -189,10 +198,12 @@ class POMOperatorTest : AbstractTestBase() { ).withDependency(dependencyToUpgrade) ) - val diff = getXmlDifferences(context.pomDocument, context.resultPom) + val diff = getXmlDifferences(context.pomFile.pomDocument, context.pomFile.resultPom) assertThat("Document has differences", diff.hasDifferences()) + assertTrue(context.pomFile.dirty, "Original POM File is Dirty") + val effectivePom = context.getEffectivePom() assertThat( @@ -214,7 +225,9 @@ class POMOperatorTest : AbstractTestBase() { ).withDependency(dependencyToUpgrade).withUseProperties(true) ) - val resultPomAsString = String(context.resultPomBytes) + assertTrue(context.pomFile.dirty, "Original POM File is Dirty") + + val resultPomAsString = String(context.pomFile.resultPomBytes) assertTrue( resultPomAsString.contains("
"), @@ -283,10 +298,12 @@ class POMOperatorTest : AbstractTestBase() { ).withDependency(dependencyToUpgrade).withUseProperties(true).withSkipIfNewer(true) ) - LOGGER.debug("original pom: {}", context.pomDocument.asXML()) - LOGGER.debug("resulting pom: {}", context.resultPom.asXML()) + LOGGER.debug("original pom: {}", context.pomFile.pomDocument.asXML()) + LOGGER.debug("resulting pom: {}", context.pomFile.resultPom.asXML()) - val diff = getXmlDifferences(context.pomDocument, context.resultPom) + assertTrue(context.pomFile.dirty, "Original POM File is Dirty") + + val diff = getXmlDifferences(context.pomFile.pomDocument, context.pomFile.resultPom) assertThat("Document has differences", diff.hasDifferences()) @@ -386,10 +403,12 @@ class POMOperatorTest : AbstractTestBase() { POMOperator.modify(context) - LOGGER.debug("original pom: {}", context.pomDocument.asXML()) - LOGGER.debug("resulting pom: {}", context.resultPom.asXML()) + assertTrue(context.pomFile.dirty, "Original POM File is Dirty") + + LOGGER.debug("original pom: {}", context.pomFile.pomDocument.asXML()) + LOGGER.debug("resulting pom: {}", context.pomFile.resultPom.asXML()) - val diff = getXmlDifferences(context.pomDocument, context.resultPom) + val diff = getXmlDifferences(context.pomFile.pomDocument, context.pomFile.resultPom) assertThat("Document has differences", diff.hasDifferences()) @@ -414,7 +433,9 @@ class POMOperatorTest : AbstractTestBase() { POMOperator.modify(context) - val resultPom = context.resultPomBytes.toString(Charset.defaultCharset()) + val resultPom = context.pomFile.resultPomBytes.toString(Charset.defaultCharset()) + + assertTrue(context.pomFile.dirty, "Original POM File is Dirty") // aldrin: uncomment this to check out formatting - useful for the next section // println(StringEscapeUtils.escapeJava(resultPom)) diff --git a/src/test/java/io/github/pixee/maven/operator/test/POMScannerTest.kt b/src/test/java/io/github/pixee/maven/operator/test/POMScannerTest.kt new file mode 100644 index 000000000..75250dc47 --- /dev/null +++ b/src/test/java/io/github/pixee/maven/operator/test/POMScannerTest.kt @@ -0,0 +1,83 @@ +package io.github.pixee.maven.operator.test + +import io.github.pixee.maven.operator.InvalidPathException +import io.github.pixee.maven.operator.POMScanner +import org.junit.Test +import java.io.File +import kotlin.test.assertTrue +import kotlin.test.fail + +class POMScannerTest: AbstractTestBase() { + val currentDirectory = File(System.getProperty("user.dir")) + + @Test + fun testBasic() { + val pomFile = getResourceAsFile("sample-child-with-relativepath.xml") + + val pmf = POMScanner.scanFrom(pomFile, currentDirectory) + } + + @Test(expected = InvalidPathException::class) + fun testTwoLevelsWithLoop() { + val pomFile = getResourceAsFile("sample-child-with-relativepath-and-two-levels.xml") + + val pmf = POMScanner.scanFrom(pomFile, currentDirectory) + } + + @Test + fun testTwoLevelsWithoutLoop() { + val pomFile = getResourceAsFile("sample-child-with-relativepath-and-two-levels-nonloop.xml") + + val pmf = POMScanner.scanFrom(pomFile, currentDirectory).build() + + assertTrue(pmf.parentPomFiles.size == 2, "There must be two parent pom files") + + val uniquePaths = pmf.allPomFiles.map { it.pomPath!!.toURI().normalize().toString() }.toSet() + + val uniquePathsAsString = uniquePaths.joinToString(" ") + + LOGGER.info("uniquePathsAsString: $uniquePathsAsString") + + assertTrue(uniquePaths.size == 3, "There must be three unique pom files referenced") + } + + @Test + fun testMultipleChildren() { + for (index in 1..3) { + val pomFile = getResourceAsFile("nested/child/pom/pom-$index-child.xml") + + val pm = POMScanner.scanFrom(pomFile, currentDirectory).build() + + assertTrue(pm.parentPomFiles.size == 2, "There must be two parent pom files") + + val uniquePaths = pm.allPomFiles.map { it.pomPath!!.toURI().normalize().toString() } + + val uniquePathsAsString = uniquePaths.joinToString(" ") + + LOGGER.info("uniquePathsAsString: $uniquePathsAsString") + + assertTrue(uniquePaths.size == 3, "There must be three unique pom files referenced") + } + } + + @Test + fun testInvalidRelativePaths() { + for (index in 1..4) { + val pomFile = getResourceAsFile("sample-child-with-broken-path-${index}.xml") + + try { + POMScanner.scanFrom(pomFile, currentDirectory) + + fail("Unreachable code") + } catch (e: Exception) { + LOGGER.info("Exception thrown: ", e) + + if (e is InvalidPathException) { + continue + } + + throw e + } + } + } +} \ No newline at end of file diff --git a/src/test/java/io/github/pixee/maven/operator/test/util.kt b/src/test/java/io/github/pixee/maven/operator/test/util.kt index 88ef5d71c..73a02680e 100644 --- a/src/test/java/io/github/pixee/maven/operator/test/util.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/util.kt @@ -18,7 +18,7 @@ internal fun ProjectModel.getRuntimeResolvedProperties(): Map = internal fun ProjectModel.getEffectivePom(): Document { val tmpInputFile = File.createTempFile("tmp-pom-orig", ".xml") - tmpInputFile.writeBytes(this.resultPomBytes) + tmpInputFile.writeBytes(this.pomFile.resultPomBytes) val tmpOutputFile = File.createTempFile("tmp-pom", ".xml") diff --git a/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-1-child.xml b/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-1-child.xml new file mode 100644 index 000000000..e4a3f45d9 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-1-child.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + + br.com.ingenieux + org-pom + 1 + ./pom-1.xml + + + pom-1-child + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-1.xml b/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-1.xml new file mode 100644 index 000000000..1381aa96c --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-1.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + + br.com.ingenieux + super-pom + 1 + ../../super/pom/pom.xml + + + org-pom + pom + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-2-child.xml b/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-2-child.xml new file mode 100644 index 000000000..777615260 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-2-child.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + + br.com.ingenieux + org-pom + 1 + ./pom-2.xml + + + pom-2-child + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-2.xml b/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-2.xml new file mode 100644 index 000000000..48050c8c6 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-2.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + + br.com.ingenieux + super-pom + 1 + ../../super/pom + + + org-pom + pom + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-3-child.xml b/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-3-child.xml new file mode 100644 index 000000000..4e887529c --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-3-child.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + + br.com.ingenieux + org-pom + 1 + ./pom-3.xml + + + pom-3-child + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-3.xml b/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-3.xml new file mode 100644 index 000000000..d64713cd7 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/nested/child/pom/pom-3.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + + br.com.ingenieux + super-pom + 1 + ../../super/pom/other-pom.xml + + + org-pom + pom + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/nested/super/pom/other-pom.xml b/src/test/resources/io/github/pixee/maven/operator/test/nested/super/pom/other-pom.xml new file mode 100644 index 000000000..5b9c4e081 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/nested/super/pom/other-pom.xml @@ -0,0 +1,13 @@ + + + 4.0.0 + + br.com.ingenieux + 1 + org-pom + + pom + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/nested/super/pom/pom.xml b/src/test/resources/io/github/pixee/maven/operator/test/nested/super/pom/pom.xml new file mode 100644 index 000000000..5b9c4e081 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/nested/super/pom/pom.xml @@ -0,0 +1,13 @@ + + + 4.0.0 + + br.com.ingenieux + 1 + org-pom + + pom + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/parent-and-child-child-broken.xml b/src/test/resources/io/github/pixee/maven/operator/test/parent-and-child-child-broken.xml new file mode 100644 index 000000000..cd59a5c84 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/parent-and-child-child-broken.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + + UTF-8 + 1.8 + 1.8 + 1.5.31 + + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/parent-and-child-parent-broken.xml b/src/test/resources/io/github/pixee/maven/operator/test/parent-and-child-parent-broken.xml new file mode 100644 index 000000000..c12b8458f --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/parent-and-child-parent-broken.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + + br.com.ingenieux + pom-operator + 1 + ./parent-and-child-parent.xml + + + pom-operator + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/parent-and-child-parent.xml b/src/test/resources/io/github/pixee/maven/operator/test/parent-and-child-parent.xml new file mode 100644 index 000000000..e27c9a221 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/parent-and-child-parent.xml @@ -0,0 +1,19 @@ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 1 + pom + + + UTF-8 + 1.8 + 1.8 + 1.5.31 + + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-basic-no-version-property-result.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-basic-no-version-property-result.xml new file mode 100644 index 000000000..3a98f80f1 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-basic-no-version-property-result.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + + + br.com.ingenieux + sample-parent + 1 + ./sample-parent + + + sample-child-with-relativepath + + + org.dom4j + dom4j + + + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-basic-result.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-basic-result.xml new file mode 100644 index 000000000..96bf62b22 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-basic-result.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + + br.com.ingenieux + sample-parent + 1 + ./sample-parent + + + sample-child-with-relativepath + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-basic-with-version-property-result.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-basic-with-version-property-result.xml new file mode 100644 index 000000000..3a98f80f1 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-basic-with-version-property-result.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + + + br.com.ingenieux + sample-parent + 1 + ./sample-parent + + + sample-child-with-relativepath + + + org.dom4j + dom4j + + + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/pom-with-parent-level-1.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-with-parent-level-1.xml new file mode 100644 index 000000000..d00aa1387 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/pom-with-parent-level-1.xml @@ -0,0 +1,13 @@ + + + 4.0.0 + + br.com.ingenieux + super-pom + 1 + + pom + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-1.xml b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-1.xml new file mode 100644 index 000000000..521078522 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-1.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + + br.com.ingenieux + sample-parent + 1 + ../../../../../../../../../../../../../sample-parent + + + sample-child-with-relativepath + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-2.xml b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-2.xml new file mode 100644 index 000000000..b0328f2ba --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-2.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + + br.com.ingenieux + sample-parent + 1 + / + + + sample-child-with-relativepath + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-3.xml b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-3.xml new file mode 100644 index 000000000..a8e03c78d --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-3.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + + br.com.ingenieux + sample-parent + 1 + C:/pom.xml + + + sample-child-with-relativepath + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-4.xml b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-4.xml new file mode 100644 index 000000000..e64b1c375 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-4.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + + br.com.ingenieux + sample-parent + 1 + + + + sample-child-with-relativepath + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-relativepath-2.xml b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-relativepath-2.xml new file mode 100644 index 000000000..0a50cdd82 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-relativepath-2.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + + br.com.ingenieux + sample-parent + 1 + ./sample-parent/other-pom.xml + + + sample-child-with-relativepath + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-relativepath-and-two-levels-nonloop.xml b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-relativepath-and-two-levels-nonloop.xml new file mode 100644 index 000000000..be5836456 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-relativepath-and-two-levels-nonloop.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + + br.com.ingenieux + org-pom + 1 + ./sample-parent/pom-with-parent-level-2-nonloop.xml + + + sample-child-with-relativepath + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-relativepath-and-two-levels.xml b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-relativepath-and-two-levels.xml new file mode 100644 index 000000000..6ee452f54 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-relativepath-and-two-levels.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + + br.com.ingenieux + org-pom + 1 + ./sample-parent/pom-with-parent-level-2.xml + + + sample-child-with-relativepath + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-relativepath.xml b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-relativepath.xml new file mode 100644 index 000000000..96bf62b22 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-relativepath.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + + br.com.ingenieux + sample-parent + 1 + ./sample-parent + + + sample-child-with-relativepath + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/sample-parent/other-pom.xml b/src/test/resources/io/github/pixee/maven/operator/test/sample-parent/other-pom.xml new file mode 100644 index 000000000..6127e53d8 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/sample-parent/other-pom.xml @@ -0,0 +1,13 @@ + + + 4.0.0 + + br.com.ingenieux + sample-parent + 1 + + pom + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom-with-parent-level-2-nonloop.xml b/src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom-with-parent-level-2-nonloop.xml new file mode 100644 index 000000000..a31f88775 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom-with-parent-level-2-nonloop.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + + br.com.ingenieux + super-pom + 1 + ../superpom-nonloop.xml + + + org-pom + + pom + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom-with-parent-level-2.xml b/src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom-with-parent-level-2.xml new file mode 100644 index 000000000..29b00a599 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom-with-parent-level-2.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + + br.com.ingenieux + super-pom + 1 + ../sample-child-with-relativepath-and-two-levels.xml + + + org-pom + + pom + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom.xml b/src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom.xml new file mode 100644 index 000000000..6127e53d8 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom.xml @@ -0,0 +1,13 @@ + + + 4.0.0 + + br.com.ingenieux + sample-parent + 1 + + pom + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/superpom-nonloop.xml b/src/test/resources/io/github/pixee/maven/operator/test/superpom-nonloop.xml new file mode 100644 index 000000000..d00aa1387 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/superpom-nonloop.xml @@ -0,0 +1,13 @@ + + + 4.0.0 + + br.com.ingenieux + super-pom + 1 + + pom + From 37178d47f87c8ee51a4c31cf3648965e39933b7f Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 28 Jun 2023 15:46:06 -0500 Subject: [PATCH 096/153] Generating Tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 13cdf4d3d..2e478b306 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.9-SNAPSHOT + 0.0.9 scm:git:${project.scm.url} From 92778fc4d7b3ca50d49c2e318141302994126796 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 28 Jun 2023 15:47:09 -0500 Subject: [PATCH 097/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index 392985c85..2099fff7a 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.github.pixee.maven.sample java-sample - 0.0.9-SNAPSHOT + 0.0.10-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index 2e478b306..a6dc2625e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.9 + 0.0.10-SNAPSHOT scm:git:${project.scm.url} From ef56353907ce044b5f8156e3c228260d138dc396 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 12 Jul 2023 12:24:10 -0500 Subject: [PATCH 098/153] Setting version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index feb217584..9c6a70f9e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.8 + 0.0.8-SNAPSHOT scm:git:${project.scm.url} From 14c2876630f1f8801b483acaacea1a71a5372976 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 12 Jul 2023 11:52:28 -0500 Subject: [PATCH 099/153] Allowing one to set a local repository path --- .../maven/operator/AbstractSimpleCommand.kt | 16 +++++ .../operator/AbstractSimpleQueryCommand.kt | 14 +++-- .../io/github/pixee/maven/operator/Chain.kt | 4 +- .../CheckLocalRepositoryDirCommand.kt | 18 ++++++ .../pixee/maven/operator/ProjectModel.kt | 3 + .../maven/operator/ProjectModelFactory.kt | 11 ++++ .../pixee/maven/operator/QueryByResolver.kt | 21 +++---- .../operator/test/POMOperatorQueryTest.kt | 58 ++++++++++++++++--- 8 files changed, 121 insertions(+), 24 deletions(-) create mode 100644 src/main/java/io/github/pixee/maven/operator/CheckLocalRepositoryDirCommand.kt diff --git a/src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt b/src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt index d2659fe8f..40541af5b 100644 --- a/src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt +++ b/src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt @@ -4,6 +4,7 @@ import io.github.pixee.maven.operator.Util.findOutIfUpgradeIsNeeded import io.github.pixee.maven.operator.Util.selectXPathNodes import io.github.pixee.maven.operator.Util.upgradeVersionNode import org.dom4j.Element +import java.io.File /** * Base implementation of Command - used by SimpleDependency and SimpleInsert @@ -41,4 +42,19 @@ abstract class AbstractSimpleCommand : io.github.pixee.maven.operator.Command { override fun execute(c: io.github.pixee.maven.operator.ProjectModel): Boolean = false override fun postProcess(c: io.github.pixee.maven.operator.ProjectModel): Boolean = false + protected fun getLocalRepositoryPath(pm: ProjectModel): File { + val localRepositoryPath: File = if (pm.repositoryPath != null) { + pm.repositoryPath + } else if (System.getenv("M2_REPO") != null) { + File(System.getenv("M2_REPO")) + } else if (System.getProperty("maven.repo.local") != null) { + File(System.getProperty("maven.repo.local")) + } else { + File( + System.getProperty("user.home"), + ".m2/repository" + ) + } + return localRepositoryPath + } } \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/AbstractSimpleQueryCommand.kt b/src/main/java/io/github/pixee/maven/operator/AbstractSimpleQueryCommand.kt index 0d5bf0517..0768c8155 100644 --- a/src/main/java/io/github/pixee/maven/operator/AbstractSimpleQueryCommand.kt +++ b/src/main/java/io/github/pixee/maven/operator/AbstractSimpleQueryCommand.kt @@ -36,7 +36,7 @@ abstract class AbstractSimpleQueryCommand : io.github.pixee.maven.operator.Abstr * * @param c ProjectModel */ - protected fun getPomFilePath(c: io.github.pixee.maven.operator.ProjectModel): File = Paths.get(c.pomPath!!.toURI()).toFile() + protected fun getPomFilePath(c: ProjectModel): File = Paths.get(c.pomPath!!.toURI()).toFile() /** * Abstract Method to extract dependencies @@ -45,7 +45,7 @@ abstract class AbstractSimpleQueryCommand : io.github.pixee.maven.operator.Abstr * @param pomFilePath Input Pom Path * @param c Project Model */ - abstract fun extractDependencyTree(outputPath: File, pomFilePath: File, c: io.github.pixee.maven.operator.ProjectModel) + abstract fun extractDependencyTree(outputPath: File, pomFilePath: File, c: ProjectModel) /** * Internal Holder Variable @@ -57,7 +57,7 @@ abstract class AbstractSimpleQueryCommand : io.github.pixee.maven.operator.Abstr /** * We declare the main logic here - details are made in the child classes for now */ - override fun execute(c: io.github.pixee.maven.operator.ProjectModel): Boolean { + override fun execute(c: ProjectModel): Boolean { val pomFilePath = getPomFilePath(c) val outputPath = getOutputPath(pomFilePath) @@ -110,11 +110,15 @@ abstract class AbstractSimpleQueryCommand : io.github.pixee.maven.operator.Abstr protected fun buildInvocationRequest( outputPath: File, pomFilePath: File, - c: io.github.pixee.maven.operator.ProjectModel + c: ProjectModel ): InvocationRequest { val props = Properties(System.getProperties()).apply { //System.getProperties().forEach { t, u -> setProperty(t as String, u as String) } setProperty("outputFile", outputPath.absolutePath) + + if (null != c.repositoryPath) { + setProperty("maven.repo.local", c.repositoryPath.absolutePath) + } } val request: InvocationRequest = DefaultInvocationRequest().apply { @@ -196,5 +200,5 @@ abstract class AbstractSimpleQueryCommand : io.github.pixee.maven.operator.Abstr val LOGGER: Logger = LoggerFactory.getLogger(io.github.pixee.maven.operator.AbstractSimpleQueryCommand::class.java) } - override fun postProcess(c: io.github.pixee.maven.operator.ProjectModel): Boolean = false + override fun postProcess(c: ProjectModel): Boolean = false } \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/Chain.kt b/src/main/java/io/github/pixee/maven/operator/Chain.kt index be71eb3e0..d665c9a0d 100644 --- a/src/main/java/io/github/pixee/maven/operator/Chain.kt +++ b/src/main/java/io/github/pixee/maven/operator/Chain.kt @@ -79,7 +79,7 @@ class Chain(vararg commands: Command) { * returns a pre-configured chain with the defaults for Querying */ fun createForQuery(queryType: QueryType = QueryType.SAFE): Chain { - val commands: List = AVAILABLE_QUERY_COMMANDS + val filteredCommands: List = AVAILABLE_QUERY_COMMANDS .filter { it.first == queryType }.mapNotNull { val commandClassName = "io.github.pixee.maven.operator.${it.second}" @@ -94,6 +94,8 @@ class Chain(vararg commands: Command) { } .toList() + val commands : List = listOf(CHECK_PARENT_DIR_COMMAND) + filteredCommands + if (commands.isEmpty()) throw IllegalStateException("Unable to load any available strategy for ${queryType.name}") diff --git a/src/main/java/io/github/pixee/maven/operator/CheckLocalRepositoryDirCommand.kt b/src/main/java/io/github/pixee/maven/operator/CheckLocalRepositoryDirCommand.kt new file mode 100644 index 000000000..7c3f08a64 --- /dev/null +++ b/src/main/java/io/github/pixee/maven/operator/CheckLocalRepositoryDirCommand.kt @@ -0,0 +1,18 @@ +package io.github.pixee.maven.operator + +import java.io.File + +val CHECK_PARENT_DIR_COMMAND = object : AbstractSimpleQueryCommand() { + override fun extractDependencyTree(outputPath: File, pomFilePath: File, c: ProjectModel) = + throw InvalidContextException() + + override fun execute(c: ProjectModel): Boolean { + val localRepositoryPath = getLocalRepositoryPath(c) + + if (!localRepositoryPath.exists()) { + localRepositoryPath.mkdirs() + } + + return false + } +} \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt b/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt index ecdcf0b90..c17bd882f 100644 --- a/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt +++ b/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt @@ -5,6 +5,7 @@ import org.dom4j.Document import org.dom4j.Element import java.net.URL import java.nio.charset.Charset +import java.io.File /** * ProjectModel represents the input parameters for the chain @@ -25,6 +26,8 @@ class ProjectModel internal constructor( var charset: Charset, var endl: String, var indent: String, + + val repositoryPath: File? = null, ) { internal var modifiedByCommand = false diff --git a/src/main/java/io/github/pixee/maven/operator/ProjectModelFactory.kt b/src/main/java/io/github/pixee/maven/operator/ProjectModelFactory.kt index e9183c400..942724f54 100644 --- a/src/main/java/io/github/pixee/maven/operator/ProjectModelFactory.kt +++ b/src/main/java/io/github/pixee/maven/operator/ProjectModelFactory.kt @@ -21,6 +21,7 @@ class ProjectModelFactory private constructor( private var activeProfiles: Set = emptySet(), private var overrideIfAlreadyExists: Boolean = false, private var queryType: QueryType = QueryType.NONE, + private var repositoryPath: File? = null, ) { /** * Fluent Setter @@ -76,6 +77,15 @@ class ProjectModelFactory private constructor( this.queryType = queryType } + /** + * Fluent Setter + * + * @param repositoryPath Repository Path + */ + fun withRepositoryPath(repositoryPath: File?) = this.apply { + this.repositoryPath = repositoryPath + } + /** * Fluent Setter */ @@ -90,6 +100,7 @@ class ProjectModelFactory private constructor( activeProfiles = activeProfiles, overrideIfAlreadyExists = overrideIfAlreadyExists, queryType = queryType, + repositoryPath = repositoryPath, charset = Charset.defaultCharset(), endl = "", indent = "", diff --git a/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt b/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt index ba43688ae..73fa16db6 100644 --- a/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt +++ b/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt @@ -29,17 +29,18 @@ import kotlin.io.path.toPath * TODO: Support Profiles / Environment Variables * Support Third Party / User-Supplied Repositories (right now it only supports central) */ -class QueryByResolver : io.github.pixee.maven.operator.AbstractSimpleQueryCommand() { - private val localRepo = LocalRepository( - File( - System.getProperty("user.home"), - ".m2/repository" - ).absolutePath - ) // "target/local-repo") - - private fun newRepositorySystemSession(system: RepositorySystem): DefaultRepositorySystemSession? { +class QueryByResolver : AbstractSimpleQueryCommand() { + private fun getLocalRepository(pm: ProjectModel): LocalRepository { + val localRepositoryPath: File = getLocalRepositoryPath(pm) + + return LocalRepository(localRepositoryPath.absolutePath) + } + + private fun newRepositorySystemSession(pm: ProjectModel, system: RepositorySystem): DefaultRepositorySystemSession? { val session = MavenRepositorySystemUtils.newSession() + val localRepo = getLocalRepository(pm) + session.localRepositoryManager = system.newLocalRepositoryManager(session, localRepo) return session @@ -99,7 +100,7 @@ class QueryByResolver : io.github.pixee.maven.operator.AbstractSimpleQueryComman val repositorySystem = locator.getService(org.eclipse.aether.RepositorySystem::class.java) - val session = newRepositorySystemSession(repositorySystem) + val session = newRepositorySystemSession(c, repositorySystem) val modelBuilder = DefaultModelBuilderFactory().newInstance() diff --git a/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt index 60af91fcf..0ff5cd83c 100644 --- a/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt @@ -1,17 +1,19 @@ package io.github.pixee.maven.operator.test import io.github.pixee.maven.operator.* +import junit.framework.TestCase.* import org.junit.Test import org.slf4j.Logger import org.slf4j.LoggerFactory -import kotlin.test.assertTrue +import java.io.File +import java.nio.file.Files class POMOperatorQueryTest { private val LOGGER: Logger = LoggerFactory.getLogger(POMOperatorTest::class.java) @Test fun testBasicQuery() { - QueryType.values().filterNot { it == QueryType.NONE } .forEach { queryType -> + QueryType.values().filterNot { it == QueryType.NONE }.forEach { queryType -> val context = ProjectModelFactory .load(this.javaClass.getResource("pom-1.xml")!!) @@ -22,7 +24,7 @@ class POMOperatorQueryTest { LOGGER.debug("Dependencies found: {}", dependencies) - assertTrue(dependencies.isNotEmpty(), "Dependencies are not empty") + assertTrue("Dependencies are not empty", dependencies.isNotEmpty()) } } @@ -36,7 +38,7 @@ class POMOperatorQueryTest { val dependencies = POMOperator.queryDependency(context) - assertTrue(dependencies.isEmpty(), "Dependencies are empty") + assertTrue("Dependencies are empty", dependencies.isEmpty()) } @Test(expected = IllegalStateException::class) @@ -49,7 +51,7 @@ class POMOperatorQueryTest { val dependencies = POMOperator.queryDependency(context) - assertTrue(dependencies.isEmpty(), "Dependencies are empty") + assertTrue("Dependencies are empty", dependencies.isEmpty()) } @Test @@ -58,7 +60,8 @@ class POMOperatorQueryTest { Chain.AVAILABLE_QUERY_COMMANDS.forEach { val commandClassName = "io.github.pixee.maven.operator.${it.second}" - val commandListOverride = listOf(Class.forName(commandClassName).newInstance() as Command) + val commandListOverride = + listOf(Class.forName(commandClassName).newInstance() as Command) val context = ProjectModelFactory @@ -66,10 +69,49 @@ class POMOperatorQueryTest { .withQueryType(QueryType.UNSAFE) .build() - val dependencies = POMOperator.queryDependency(context, commandList = commandListOverride) + val dependencies = + POMOperator.queryDependency(context, commandList = commandListOverride) - assertTrue(dependencies.isNotEmpty(), "Dependencies are not empty") + assertTrue("Dependencies are not empty", dependencies.isNotEmpty()) } } } + + + @Test + fun testTemporaryDirectory() { + QueryType.values().filterNot { it == QueryType.NONE }.forEach { queryType -> + val tempDirectory = File("/tmp/mvn-repo-" + System.currentTimeMillis() + ".dir") + + LOGGER.info("Using queryType: $queryType at $tempDirectory") + + assertFalse("Temp Directory does not exist initially", tempDirectory.exists()) + assertEquals( + "There must be no files", + tempDirectory.list()?.filter { File(it).isDirectory }?.size ?: 0, + 0, + ) + + val context = + ProjectModelFactory + .load(this.javaClass.getResource("pom-1.xml")!!) + .withQueryType(queryType) + .withRepositoryPath(tempDirectory) + .build() + + val dependencies = POMOperator.queryDependency(context) + + LOGGER.debug("Dependencies found: {}", dependencies) + + assertTrue("Dependencies are not empty", dependencies.isNotEmpty()) + + assertTrue("Temp Directory ends up existing", tempDirectory.exists()) + assertTrue("Temp Directory is a directory", tempDirectory.isDirectory) + assertEquals( + "There must be files", + tempDirectory.list().filter { File(it).isDirectory }.size, + 0 + ) + } + } } \ No newline at end of file From e97432f5f05f83db199592e30ffe817e0d20bb6b Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 12 Jul 2023 12:51:38 -0500 Subject: [PATCH 100/153] Fixing test --- .../pixee/maven/operator/AbstractSimpleQueryCommand.kt | 4 +++- .../java/io/github/pixee/maven/operator/test/MassRepoTest.kt | 5 ----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/io/github/pixee/maven/operator/AbstractSimpleQueryCommand.kt b/src/main/java/io/github/pixee/maven/operator/AbstractSimpleQueryCommand.kt index 0768c8155..9db2e7189 100644 --- a/src/main/java/io/github/pixee/maven/operator/AbstractSimpleQueryCommand.kt +++ b/src/main/java/io/github/pixee/maven/operator/AbstractSimpleQueryCommand.kt @@ -116,8 +116,10 @@ abstract class AbstractSimpleQueryCommand : io.github.pixee.maven.operator.Abstr //System.getProperties().forEach { t, u -> setProperty(t as String, u as String) } setProperty("outputFile", outputPath.absolutePath) + val localRepositoryPath = getLocalRepositoryPath(c).absolutePath + if (null != c.repositoryPath) { - setProperty("maven.repo.local", c.repositoryPath.absolutePath) + setProperty("maven.repo.local", localRepositoryPath) } } diff --git a/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt b/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt index 9445614d3..53d59fe9c 100644 --- a/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt @@ -54,11 +54,6 @@ class MassRepoIT { "apache/pulsar", pomPath = "pulsar-broker/pom.xml" ) to "commons-codec:commons-codec:1.14", - TestRepo( - "metersphere/metersphere", - branch = "main", - pomPath = "framework/eureka/pom.xml" - ) to "commons-lang3:commons-lang3:3.6", TestRepo( "apache/rocketmq", pomPath = "common/pom.xml" From c15a30aaa8c5897dd099f52df7be700a84086ebe Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 12 Jul 2023 12:55:02 -0500 Subject: [PATCH 101/153] Generating Tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9c6a70f9e..85d025001 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.8-SNAPSHOT + 0.0.8-localrepo-fix scm:git:${project.scm.url} From ebbae105acb1dc79b6a1c9ee1171279ab7dfd636 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 12 Jul 2023 13:25:05 -0500 Subject: [PATCH 102/153] Revert "Fixing test" This reverts commit e97432f5f05f83db199592e30ffe817e0d20bb6b. --- .../io/github/pixee/maven/operator/AbstractQueryCommand.kt | 4 +--- .../java/io/github/pixee/maven/operator/test/MassRepoTest.kt | 5 +++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/github/pixee/maven/operator/AbstractQueryCommand.kt b/src/main/java/io/github/pixee/maven/operator/AbstractQueryCommand.kt index b2ab7947c..1b6d0f3a7 100644 --- a/src/main/java/io/github/pixee/maven/operator/AbstractQueryCommand.kt +++ b/src/main/java/io/github/pixee/maven/operator/AbstractQueryCommand.kt @@ -117,10 +117,8 @@ abstract class AbstractQueryCommand : AbstractCommand() { //System.getProperties().forEach { t, u -> setProperty(t as String, u as String) } setProperty("outputFile", outputPath.absolutePath) - val localRepositoryPath = getLocalRepositoryPath(c).absolutePath - if (null != c.repositoryPath) { - setProperty("maven.repo.local", localRepositoryPath) + setProperty("maven.repo.local", c.repositoryPath.absolutePath) } } diff --git a/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt b/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt index 1bab1c082..de9c57042 100644 --- a/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt @@ -54,6 +54,11 @@ class MassRepoIT { "apache/pulsar", pomPath = "pulsar-broker/pom.xml" ) to "commons-codec:commons-codec:1.14", + TestRepo( + "metersphere/metersphere", + branch = "main", + pomPath = "framework/eureka/pom.xml" + ) to "commons-lang3:commons-lang3:3.6", TestRepo( "apache/rocketmq", pomPath = "common/pom.xml" From 083dba4a1dbb0cd1e3dfb670ff4e90b07c828312 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Sun, 16 Jul 2023 16:13:58 -0500 Subject: [PATCH 103/153] Allowing one to set a local repository path (#17) * Allowing one to set a local repository path * [no ci] Autogenerated JaCoCo coverage badge * Backporting and optimizing tests * [no ci] Autogenerated JaCoCo coverage badge * Allowing one to set a local repository path * Revert "Fixing test" This reverts commit e97432f5f05f83db199592e30ffe817e0d20bb6b. * [no ci] Autogenerated JaCoCo coverage badge --------- Co-authored-by: Jacoco Coverage Update Action --- .github/badges/branches.svg | 2 +- .github/badges/jacoco.svg | 2 +- .../pixee/maven/operator/AbstractCommand.kt | 16 +++-- .../maven/operator/AbstractQueryCommand.kt | 11 ++-- .../maven/operator/AbstractSimpleCommand.kt | 60 +++++++++++++++++++ .../io/github/pixee/maven/operator/Util.kt | 6 +- .../pixee/maven/operator/test/MassRepoTest.kt | 7 +-- .../operator/test/POMOperatorQueryTest.kt | 13 ++-- 8 files changed, 85 insertions(+), 32 deletions(-) create mode 100644 src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt diff --git a/.github/badges/branches.svg b/.github/badges/branches.svg index de17db21d..120ef8e56 100644 --- a/.github/badges/branches.svg +++ b/.github/badges/branches.svg @@ -1 +1 @@ -branches74.4% \ No newline at end of file +branches71.5% \ No newline at end of file diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index de2c1118a..34d158f7e 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage91.8% \ No newline at end of file +coverage89.7% \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/AbstractCommand.kt b/src/main/java/io/github/pixee/maven/operator/AbstractCommand.kt index 0c054cf7a..c70105712 100644 --- a/src/main/java/io/github/pixee/maven/operator/AbstractCommand.kt +++ b/src/main/java/io/github/pixee/maven/operator/AbstractCommand.kt @@ -46,18 +46,16 @@ abstract class AbstractCommand : Command { override fun postProcess(c: ProjectModel): Boolean = false protected fun getLocalRepositoryPath(pm: ProjectModel): File { - val localRepositoryPath: File = if (pm.repositoryPath != null) { - pm.repositoryPath - } else if (System.getenv("M2_REPO") != null) { - File(System.getenv("M2_REPO")) - } else if (System.getProperty("maven.repo.local") != null) { - File(System.getProperty("maven.repo.local")) - } else { - File( + val localRepositoryPath: File = when { + pm.repositoryPath != null -> pm.repositoryPath + System.getenv("M2_REPO") != null -> File(System.getenv("M2_REPO")) + System.getProperty("maven.repo.local") != null -> File(System.getProperty("maven.repo.local")) + else -> File( System.getProperty("user.home"), ".m2/repository" ) } + return localRepositoryPath } -} \ No newline at end of file +} diff --git a/src/main/java/io/github/pixee/maven/operator/AbstractQueryCommand.kt b/src/main/java/io/github/pixee/maven/operator/AbstractQueryCommand.kt index 1b6d0f3a7..ec1280a65 100644 --- a/src/main/java/io/github/pixee/maven/operator/AbstractQueryCommand.kt +++ b/src/main/java/io/github/pixee/maven/operator/AbstractQueryCommand.kt @@ -21,7 +21,7 @@ abstract class AbstractQueryCommand : AbstractCommand() { * * @param pomFilePath POM Original File Path */ - protected fun getOutputPath(pomFilePath: File): File { + private fun getOutputPath(pomFilePath: File): File { val basePath = pomFilePath.parentFile val outputBasename = "output-%08X.txt".format(pomFilePath.hashCode()) @@ -114,12 +114,11 @@ abstract class AbstractQueryCommand : AbstractCommand() { c: ProjectModel ): InvocationRequest { val props = Properties(System.getProperties()).apply { - //System.getProperties().forEach { t, u -> setProperty(t as String, u as String) } setProperty("outputFile", outputPath.absolutePath) - if (null != c.repositoryPath) { - setProperty("maven.repo.local", c.repositoryPath.absolutePath) - } + val localRepositoryPath = getLocalRepositoryPath(c).absolutePath + + setProperty("maven.repo.local", localRepositoryPath) } val request: InvocationRequest = DefaultInvocationRequest().apply { @@ -202,4 +201,4 @@ abstract class AbstractQueryCommand : AbstractCommand() { } override fun postProcess(c: ProjectModel): Boolean = false -} \ No newline at end of file +} diff --git a/src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt b/src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt new file mode 100644 index 000000000..425ab951b --- /dev/null +++ b/src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt @@ -0,0 +1,60 @@ +package io.github.pixee.maven.operator + +import io.github.pixee.maven.operator.Util.findOutIfUpgradeIsNeeded +import io.github.pixee.maven.operator.Util.selectXPathNodes +import io.github.pixee.maven.operator.Util.upgradeVersionNode +import org.dom4j.Element +import java.io.File + +/** + * Base implementation of Command - used by SimpleDependency and SimpleInsert + */ +abstract class AbstractSimpleCommand : io.github.pixee.maven.operator.Command { + /** + * Given a POM, locate its coordinates for a given dependency based on lookupExpression and figures out the upgrade + */ + protected fun handleDependency(c: io.github.pixee.maven.operator.ProjectModel, lookupExpression: String): Boolean { + val dependencyNodes = c.pomFile.resultPom.selectXPathNodes(lookupExpression) + + if (1 == dependencyNodes.size) { + val versionNodes = dependencyNodes[0].selectXPathNodes("./m:version") + + if (1 == versionNodes.size) { + val versionNode = versionNodes[0] as Element + + var mustUpgrade = true + + if (c.skipIfNewer) { + mustUpgrade = findOutIfUpgradeIsNeeded(c, versionNode) + } + + if (mustUpgrade) { + upgradeVersionNode(c, versionNode, c.pomFile) + } + + return true + } + } + + return false + } + + override fun execute(c: io.github.pixee.maven.operator.ProjectModel): Boolean = false + + override fun postProcess(c: io.github.pixee.maven.operator.ProjectModel): Boolean = false + protected fun getLocalRepositoryPath(pm: ProjectModel): File { + val localRepositoryPath: File = if (pm.repositoryPath != null) { + pm.repositoryPath + } else if (System.getenv("M2_REPO") != null) { + File(System.getenv("M2_REPO")) + } else if (System.getProperty("maven.repo.local") != null) { + File(System.getProperty("maven.repo.local")) + } else { + File( + System.getProperty("user.home"), + ".m2/repository" + ) + } + return localRepositoryPath + } +} \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/Util.kt b/src/main/java/io/github/pixee/maven/operator/Util.kt index 85548d4d8..3094a2973 100644 --- a/src/main/java/io/github/pixee/maven/operator/Util.kt +++ b/src/main/java/io/github/pixee/maven/operator/Util.kt @@ -13,6 +13,8 @@ import org.dom4j.tree.DefaultText import org.jaxen.SimpleNamespaceContext import org.jaxen.XPath import org.jaxen.dom4j.Dom4jXPath +import org.slf4j.Logger +import org.slf4j.LoggerFactory import java.io.File @@ -20,6 +22,8 @@ import java.io.File * Common Utilities */ object Util { + private val LOGGER: Logger = LoggerFactory.getLogger(Util::class.java) + /** * Extension Method that easily allows to add an element inside another while * retaining formatting @@ -267,7 +271,7 @@ object Util { val result = possiblePaths.findLast(isCliCallable) if (null == result) { - AbstractQueryCommand.LOGGER.warn( + LOGGER.warn( "Unable to find mvn executable (execs: {}, path: {})", nativeExecutables.joinToString("/"), pathContentString diff --git a/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt b/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt index de9c57042..0502231a6 100644 --- a/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt @@ -54,11 +54,6 @@ class MassRepoIT { "apache/pulsar", pomPath = "pulsar-broker/pom.xml" ) to "commons-codec:commons-codec:1.14", - TestRepo( - "metersphere/metersphere", - branch = "main", - pomPath = "framework/eureka/pom.xml" - ) to "commons-lang3:commons-lang3:3.6", TestRepo( "apache/rocketmq", pomPath = "common/pom.xml" @@ -231,4 +226,4 @@ class MassRepoIT { if (!TestRepo.BASE_CACHE_DIR.exists()) TestRepo.BASE_CACHE_DIR.mkdirs() } -} \ No newline at end of file +} diff --git a/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt index 0ff5cd83c..736cd46f2 100644 --- a/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt @@ -2,14 +2,16 @@ package io.github.pixee.maven.operator.test import io.github.pixee.maven.operator.* import junit.framework.TestCase.* +import org.junit.Assert.assertNotEquals import org.junit.Test import org.slf4j.Logger import org.slf4j.LoggerFactory import java.io.File -import java.nio.file.Files class POMOperatorQueryTest { - private val LOGGER: Logger = LoggerFactory.getLogger(POMOperatorTest::class.java) + companion object { + private val LOGGER: Logger = LoggerFactory.getLogger(POMOperatorTest::class.java) + } @Test fun testBasicQuery() { @@ -107,11 +109,6 @@ class POMOperatorQueryTest { assertTrue("Temp Directory ends up existing", tempDirectory.exists()) assertTrue("Temp Directory is a directory", tempDirectory.isDirectory) - assertEquals( - "There must be files", - tempDirectory.list().filter { File(it).isDirectory }.size, - 0 - ) } } -} \ No newline at end of file +} From c3865b10c065b89f60d56d29bd4fd65155a3e261 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Sun, 16 Jul 2023 16:16:20 -0500 Subject: [PATCH 104/153] Generating Tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a6dc2625e..5b391527d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.10-SNAPSHOT + 0.0.10 scm:git:${project.scm.url} From 919886ea8d7595b9b7308e039cd4c47d405eb763 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Sun, 16 Jul 2023 16:17:37 -0500 Subject: [PATCH 105/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index 2099fff7a..7df01d760 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.github.pixee.maven.sample java-sample - 0.0.10-SNAPSHOT + 0.0.11-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index 5b391527d..fb9330b52 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.10 + 0.0.11-SNAPSHOT scm:git:${project.scm.url} From 4c8e27955f2df0fa0bef6c82fc54a2146c194701 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 24 Jul 2023 13:20:27 -0500 Subject: [PATCH 106/153] Adds the 'offline' flag (#20) * Adds the 'offline' flag * [no ci] Autogenerated JaCoCo coverage badge * Removing import * Changes to POM Scanner * [no ci] Autogenerated JaCoCo coverage badge --------- Co-authored-by: Jacoco Coverage Update Action --- .github/badges/branches.svg | 2 +- .../maven/operator/AbstractQueryCommand.kt | 2 + .../github/pixee/maven/operator/POMScanner.kt | 6 +- .../pixee/maven/operator/ProjectModel.kt | 2 + .../maven/operator/ProjectModelFactory.kt | 11 + .../pixee/maven/operator/QueryByResolver.kt | 10 +- .../operator/test/POMOperatorQueryTest.kt | 214 +++++++++++++++++- .../maven/operator/test/POMScannerTest.kt | 23 +- .../test/pom-multiple-pom-parent-level-3.xml | 22 ++ .../test/pom-multiple-pom-parent-level-4.xml | 22 ++ .../sample-parent/pom-with-parent-level-3.xml | 18 ++ .../pom-with-parent-level-4.xml} | 6 +- 12 files changed, 330 insertions(+), 8 deletions(-) create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-parent-level-3.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-parent-level-4.xml create mode 100644 src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom-with-parent-level-3.xml rename src/test/resources/io/github/pixee/maven/operator/test/{sample-child-with-broken-path-4.xml => sample-parent/pom-with-parent-level-4.xml} (79%) diff --git a/.github/badges/branches.svg b/.github/badges/branches.svg index 120ef8e56..8b57303e6 100644 --- a/.github/badges/branches.svg +++ b/.github/badges/branches.svg @@ -1 +1 @@ -branches71.5% \ No newline at end of file +branches71.7% \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/AbstractQueryCommand.kt b/src/main/java/io/github/pixee/maven/operator/AbstractQueryCommand.kt index ec1280a65..1ca268161 100644 --- a/src/main/java/io/github/pixee/maven/operator/AbstractQueryCommand.kt +++ b/src/main/java/io/github/pixee/maven/operator/AbstractQueryCommand.kt @@ -134,6 +134,8 @@ abstract class AbstractQueryCommand : AbstractCommand() { profiles = c.activeProfiles.toList() isDebug = true + isOffline = c.offline + properties = props goals = listOf(DEPENDENCY_TREE_MOJO_REFERENCE) diff --git a/src/main/java/io/github/pixee/maven/operator/POMScanner.kt b/src/main/java/io/github/pixee/maven/operator/POMScanner.kt index 59210198b..966bbc6eb 100644 --- a/src/main/java/io/github/pixee/maven/operator/POMScanner.kt +++ b/src/main/java/io/github/pixee/maven/operator/POMScanner.kt @@ -21,7 +21,7 @@ object POMScanner { val relativePathElement = pomFile.pomDocument.rootElement.element("parent")?.element("relativePath") - if (relativePathElement != null) { + if (relativePathElement != null && relativePathElement.textTrim.isNotEmpty()) { pomFileQueue.add(relativePathElement) } @@ -50,6 +50,10 @@ object POMScanner { while (pomFileQueue.isNotEmpty()) { val relativePathElement = pomFileQueue.poll() + if (relativePathElement.textTrim.isEmpty()) { + break + } + val relativePath = fixPomRelativePath(relativePathElement.text) if (!isRelative(relativePath)) diff --git a/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt b/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt index 24104dd3b..2979ed08b 100644 --- a/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt +++ b/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt @@ -22,6 +22,8 @@ class ProjectModel internal constructor( val queryType: QueryType = QueryType.NONE, val repositoryPath: File? = null, + + val offline: Boolean = false, ) { internal var modifiedByCommand = false diff --git a/src/main/java/io/github/pixee/maven/operator/ProjectModelFactory.kt b/src/main/java/io/github/pixee/maven/operator/ProjectModelFactory.kt index 7a48717a1..80191385e 100644 --- a/src/main/java/io/github/pixee/maven/operator/ProjectModelFactory.kt +++ b/src/main/java/io/github/pixee/maven/operator/ProjectModelFactory.kt @@ -17,6 +17,7 @@ class ProjectModelFactory private constructor( private var overrideIfAlreadyExists: Boolean = false, private var queryType: QueryType = QueryType.NONE, private var repositoryPath: File? = null, + private var offline: Boolean = false, ) { /** * Fluent Setter @@ -92,6 +93,15 @@ class ProjectModelFactory private constructor( this.repositoryPath = repositoryPath } + /** + * Fluent Setter + * + * @param offline Offline + */ + fun withOffline(offline: Boolean) = this.apply { + this.offline = offline + } + /** * Fluent Setter */ @@ -106,6 +116,7 @@ class ProjectModelFactory private constructor( overrideIfAlreadyExists = overrideIfAlreadyExists, queryType = queryType, repositoryPath = repositoryPath, + offline = offline, ) } diff --git a/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt b/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt index fec78b43a..a9ced3c3c 100644 --- a/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt +++ b/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt @@ -95,12 +95,18 @@ class QueryByResolver : AbstractQueryCommand() { RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2/") .build() - val remoteRepositories = listOf(remoteRepository) + val remoteRepositories : List = + if (pm.offline) { + emptyList() + } else { + listOf(remoteRepository) + } val repositorySystem = locator.getService(org.eclipse.aether.RepositorySystem::class.java) - val session = newRepositorySystemSession(pm, repositorySystem) + val session = newRepositorySystemSession(pm, repositorySystem)!! + .setOffline(pm.offline) val modelBuilder = DefaultModelBuilderFactory().newInstance() diff --git a/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt index 736cd46f2..552e0b442 100644 --- a/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt @@ -2,11 +2,11 @@ package io.github.pixee.maven.operator.test import io.github.pixee.maven.operator.* import junit.framework.TestCase.* -import org.junit.Assert.assertNotEquals import org.junit.Test import org.slf4j.Logger import org.slf4j.LoggerFactory import java.io.File +import java.nio.file.Files class POMOperatorQueryTest { companion object { @@ -111,4 +111,216 @@ class POMOperatorQueryTest { assertTrue("Temp Directory is a directory", tempDirectory.isDirectory) } } + + @Test + fun testTemporaryDirectoryAndFullyOffline() { + QueryType.values().filterNot { it == QueryType.NONE }.filter { it == QueryType.SAFE } + .forEach { queryType -> + val tempDirectory = Files.createTempDirectory("mvn-repo").toFile() + + val context = + ProjectModelFactory + .load(this.javaClass.getResource("pom-1.xml")!!) + .withQueryType(queryType) + .withRepositoryPath(tempDirectory) + .withOffline(true) + .build() + + val dependencies = POMOperator.queryDependency(context) + + LOGGER.debug("Dependencies found: {}", dependencies) + + assertTrue("Dependencies are not empty", dependencies.isNotEmpty()) + } + } + + @Test + fun testOnSyntheticDependency() { + val tempDirectory = Files.createTempDirectory("mvn-repo").toFile() + + val tempPom = File(tempDirectory, "pom.xml").toPath() + + val randomName = "random-artifact-" + System.currentTimeMillis() + + Files.write(tempPom, """ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + + + dummyorg + ${randomName} + 2.1.3 + + + + + """.trimIndent().toByteArray()) + + val context = + ProjectModelFactory + .load(tempPom.toFile()) + .withQueryType(QueryType.SAFE) + .withRepositoryPath(tempDirectory) + .withOffline(true) + .build() + + val dependencies = POMOperator.queryDependency(context) + + LOGGER.debug("Dependencies found: {}", dependencies) + + assertTrue("Dependencies are not empty", dependencies.isNotEmpty()) + + assertTrue("Random name matches", dependencies.first().artifactId.equals(randomName)) + } + + @Test + fun testOnCompositeSyntheticDependency() { + val tempDirectory = Files.createTempDirectory("mvn-repo").toFile() + + val tempParentPom = File(tempDirectory, "pom-parent.xml").toPath() + val tempPom = File(tempDirectory, "pom.xml").toPath() + + val randomName = "random-artifact-" + System.currentTimeMillis() + + Files.write(tempParentPom, """ + + 4.0.0 + + somethingelse + br.com.ingenieux + 1 + + pom + + + + + dummyorg + managed-${randomName} + 1 + + + + + """.trim().toByteArray()) + + Files.write(tempPom, """ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + + somethingelse + br.com.ingenieux + 1 + ./pom-parent.xml + + + + + dummyorg + ${randomName} + 2.1.3 + + + dummyorg + managed-${randomName} + + + + + """.trim().toByteArray()) + + val context = + ProjectModelFactory + .load(tempPom.toFile()) + .withQueryType(QueryType.SAFE) + .withRepositoryPath(tempDirectory) + .withOffline(true) + .build() + + val dependencies = POMOperator.queryDependency(context) + + LOGGER.debug("Dependencies found: {}", dependencies) + + assertTrue("Dependencies are not empty", dependencies.isNotEmpty()) + + assertTrue("Random name matches", dependencies.first().artifactId.equals(randomName)) + } + + @Test + fun testOnCompositeSyntheticDependencyIncomplete() { + val tempDirectory = Files.createTempDirectory("mvn-repo").toFile() + + val tempPom = File(tempDirectory, "pom.xml").toPath() + + val randomName = "random-artifact-" + System.currentTimeMillis() + + Files.write(tempPom, """ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + + somethingelse + br.com.ingenieux + 1 + ./pom-parent.xml + + + + + dummyorg + ${randomName} + 2.1.3 + + + dummyorg + managed-${randomName} + + + + + """.trim().toByteArray()) + + val context = + ProjectModelFactory + .load(tempPom.toFile()) + .withQueryType(QueryType.SAFE) + .withRepositoryPath(tempDirectory) + .withOffline(true) + .build() + + val dependencies = POMOperator.queryDependency(context) + + LOGGER.debug("Dependencies found: {}", dependencies) + + assertTrue("Dependencies are empty", dependencies.isEmpty()) + } } diff --git a/src/test/java/io/github/pixee/maven/operator/test/POMScannerTest.kt b/src/test/java/io/github/pixee/maven/operator/test/POMScannerTest.kt index 75250dc47..b1f83c1a0 100644 --- a/src/test/java/io/github/pixee/maven/operator/test/POMScannerTest.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/POMScannerTest.kt @@ -62,7 +62,7 @@ class POMScannerTest: AbstractTestBase() { @Test fun testInvalidRelativePaths() { - for (index in 1..4) { + for (index in 1..3) { val pomFile = getResourceAsFile("sample-child-with-broken-path-${index}.xml") try { @@ -80,4 +80,25 @@ class POMScannerTest: AbstractTestBase() { } } } + + @Test + fun testWithRelativePathEmpty() { + for (index in 3..4) { + val pomFile = getResourceAsFile("pom-multiple-pom-parent-level-${index}.xml") + + try { + val pmf = POMScanner.scanFrom(pomFile, currentDirectory) + + assertTrue(pmf.build().parentPomFiles.isNotEmpty()) + } catch (e: InvalidPathException) { + LOGGER.info("Exception thrown: ", e) + + if (e is InvalidPathException) { + continue + } + + throw e + } + } + } } \ No newline at end of file diff --git a/src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-parent-level-3.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-parent-level-3.xml new file mode 100644 index 000000000..9548f8f86 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-parent-level-3.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + + + br.com.ingenieux + org-pom + 1 + ./sample-parent/pom-with-parent-level-3.xml + + + sample-child-with-relativepath + + + org.dom4j + dom4j + + + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-parent-level-4.xml b/src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-parent-level-4.xml new file mode 100644 index 000000000..adaa98907 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/pom-multiple-pom-parent-level-4.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + + + br.com.ingenieux + org-pom + 1 + ./sample-parent/pom-with-parent-level-4.xml + + + sample-child-with-relativepath + + + org.dom4j + dom4j + + + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom-with-parent-level-3.xml b/src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom-with-parent-level-3.xml new file mode 100644 index 000000000..806cf4242 --- /dev/null +++ b/src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom-with-parent-level-3.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + + br.com.ingenieux + super-pom + 1 + + + + org-pom + + pom + diff --git a/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-4.xml b/src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom-with-parent-level-4.xml similarity index 79% rename from src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-4.xml rename to src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom-with-parent-level-4.xml index e64b1c375..7eda1ec72 100644 --- a/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-4.xml +++ b/src/test/resources/io/github/pixee/maven/operator/test/sample-parent/pom-with-parent-level-4.xml @@ -7,10 +7,12 @@ br.com.ingenieux - sample-parent + super-pom 1 - sample-child-with-relativepath + org-pom + + pom From 4e71abb9c7c5686da76d9c4fb78059ba9378892a Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 24 Jul 2023 13:23:01 -0500 Subject: [PATCH 107/153] Generating Tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fb9330b52..cf52ae669 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.11-SNAPSHOT + 0.0.11 scm:git:${project.scm.url} From 3beae60ed74f63cb4ad301aa491bf01c7fa43b73 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 24 Jul 2023 13:24:16 -0500 Subject: [PATCH 108/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index 7df01d760..01acb47bf 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.github.pixee.maven.sample java-sample - 0.0.11-SNAPSHOT + 0.0.12-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index cf52ae669..3fc7bfbd9 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.11 + 0.0.12-SNAPSHOT scm:git:${project.scm.url} From 23129e88b07614298de5fb8a36b5e61b8c413cce Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Sun, 6 Aug 2023 12:45:23 -0500 Subject: [PATCH 109/153] Updates README (#19) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1e637196f..afcb56d0d 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ e.g. to generate version `0.0.2`: ``` (mvn versions:set -DnewVersion=0.0.3 && mvn clean package source:jar javadoc:jar deploy && git commit -am "Generating Tag" && git tag v0.0.3 && git push && git push --tags) -(V=0.0.4-SNAPSHOT mvn versions:set -DnewVersion=$V && (cd java-sample ; mvn versions:set -DnewVersion=$V && git commit -am "Generating development version" && git push)) +(export V='0.0.11-SNAPSHOT' ; mvn versions:set -DnewVersion=${V} && (cd java-sample ; mvn versions:set -DnewVersion=${V} && git commit -am "Generating development version" && git push)) ``` # TODO: From 5f63fdb8503aaf716a50f13fbd46afae0ad8a1d3 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 7 Aug 2023 15:49:10 -0500 Subject: [PATCH 110/153] Embedder-Based POM Scanner - and non-maven dependency resolution (#21) * Embedder-Based POM Scanner * [no ci] Autogenerated JaCoCo coverage badge * * Cleanup * Refactor common stuff into EmbedderFacade * Adds QueryByParsing * [no ci] Autogenerated JaCoCo coverage badge * * Handles * [no ci] Autogenerated JaCoCo coverage badge * Permissions * Fixing RE * [no ci] Autogenerated JaCoCo coverage badge --------- Co-authored-by: Jacoco Coverage Update Action --- .github/badges/branches.svg | 2 +- .github/badges/jacoco.svg | 2 +- .../maven/operator/AbstractSimpleCommand.kt | 60 ------- .../io/github/pixee/maven/operator/Chain.kt | 4 +- .../pixee/maven/operator/EmbedderFacade.kt | 146 ++++++++++++++++ .../github/pixee/maven/operator/POMScanner.kt | 46 ++++- .../pixee/maven/operator/ProjectModel.kt | 22 +-- .../pixee/maven/operator/QueryByParsing.kt | 165 ++++++++++++++++++ .../pixee/maven/operator/QueryByResolver.kt | 142 +++------------ .../operator/test/POMOperatorQueryTest.kt | 134 +++++++++++++- .../maven/operator/test/POMScannerTest.kt | 5 +- .../test/nested/super/pom/other-pom.xml | 2 +- .../test/sample-child-with-broken-path-1.xml | 2 +- 13 files changed, 520 insertions(+), 212 deletions(-) delete mode 100644 src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt create mode 100644 src/main/java/io/github/pixee/maven/operator/EmbedderFacade.kt create mode 100644 src/main/java/io/github/pixee/maven/operator/QueryByParsing.kt diff --git a/.github/badges/branches.svg b/.github/badges/branches.svg index 8b57303e6..1d4e5797d 100644 --- a/.github/badges/branches.svg +++ b/.github/badges/branches.svg @@ -1 +1 @@ -branches71.7% \ No newline at end of file +branches74% \ No newline at end of file diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index 34d158f7e..9681820dd 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage89.7% \ No newline at end of file +coverage90.7% \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt b/src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt deleted file mode 100644 index 425ab951b..000000000 --- a/src/main/java/io/github/pixee/maven/operator/AbstractSimpleCommand.kt +++ /dev/null @@ -1,60 +0,0 @@ -package io.github.pixee.maven.operator - -import io.github.pixee.maven.operator.Util.findOutIfUpgradeIsNeeded -import io.github.pixee.maven.operator.Util.selectXPathNodes -import io.github.pixee.maven.operator.Util.upgradeVersionNode -import org.dom4j.Element -import java.io.File - -/** - * Base implementation of Command - used by SimpleDependency and SimpleInsert - */ -abstract class AbstractSimpleCommand : io.github.pixee.maven.operator.Command { - /** - * Given a POM, locate its coordinates for a given dependency based on lookupExpression and figures out the upgrade - */ - protected fun handleDependency(c: io.github.pixee.maven.operator.ProjectModel, lookupExpression: String): Boolean { - val dependencyNodes = c.pomFile.resultPom.selectXPathNodes(lookupExpression) - - if (1 == dependencyNodes.size) { - val versionNodes = dependencyNodes[0].selectXPathNodes("./m:version") - - if (1 == versionNodes.size) { - val versionNode = versionNodes[0] as Element - - var mustUpgrade = true - - if (c.skipIfNewer) { - mustUpgrade = findOutIfUpgradeIsNeeded(c, versionNode) - } - - if (mustUpgrade) { - upgradeVersionNode(c, versionNode, c.pomFile) - } - - return true - } - } - - return false - } - - override fun execute(c: io.github.pixee.maven.operator.ProjectModel): Boolean = false - - override fun postProcess(c: io.github.pixee.maven.operator.ProjectModel): Boolean = false - protected fun getLocalRepositoryPath(pm: ProjectModel): File { - val localRepositoryPath: File = if (pm.repositoryPath != null) { - pm.repositoryPath - } else if (System.getenv("M2_REPO") != null) { - File(System.getenv("M2_REPO")) - } else if (System.getProperty("maven.repo.local") != null) { - File(System.getProperty("maven.repo.local")) - } else { - File( - System.getProperty("user.home"), - ".m2/repository" - ) - } - return localRepositoryPath - } -} \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/Chain.kt b/src/main/java/io/github/pixee/maven/operator/Chain.kt index 475d88e28..eeb6ad2ca 100644 --- a/src/main/java/io/github/pixee/maven/operator/Chain.kt +++ b/src/main/java/io/github/pixee/maven/operator/Chain.kt @@ -30,7 +30,7 @@ class Chain(vararg commands: Command) { done = nextCommand.execute(c) if (done) { - if (c.queryType == QueryType.NONE && (!(nextCommand is SupportCommand))) { + if (c.queryType == QueryType.NONE && (nextCommand !is SupportCommand)) { c.modifiedByCommand = true } @@ -66,6 +66,7 @@ class Chain(vararg commands: Command) { val AVAILABLE_QUERY_COMMANDS = listOf( QueryType.SAFE to "QueryByResolver", QueryType.SAFE to "QueryByEmbedder", + QueryType.SAFE to "QueryByParsing", QueryType.UNSAFE to "QueryByInvoker", ) @@ -93,7 +94,6 @@ class Chain(vararg commands: Command) { val commandClassName = "io.github.pixee.maven.operator.${it.second}" try { - @Suppress("DEPRECATION") Class.forName(commandClassName).newInstance() as Command } catch (e: Throwable) { LOGGER.warn("Creating class '{}': ", commandClassName, e) diff --git a/src/main/java/io/github/pixee/maven/operator/EmbedderFacade.kt b/src/main/java/io/github/pixee/maven/operator/EmbedderFacade.kt new file mode 100644 index 000000000..baa5b33c8 --- /dev/null +++ b/src/main/java/io/github/pixee/maven/operator/EmbedderFacade.kt @@ -0,0 +1,146 @@ +package io.github.pixee.maven.operator + +import org.apache.maven.model.building.* +import org.apache.maven.project.ProjectModelResolver +import org.apache.maven.repository.internal.MavenRepositorySystemUtils +import org.eclipse.aether.DefaultRepositorySystemSession +import org.eclipse.aether.RepositorySystem +import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory +import org.eclipse.aether.impl.DefaultServiceLocator +import org.eclipse.aether.internal.impl.DefaultRemoteRepositoryManager +import org.eclipse.aether.repository.LocalRepository +import org.eclipse.aether.repository.RemoteRepository +import org.eclipse.aether.spi.connector.RepositoryConnectorFactory +import org.eclipse.aether.spi.connector.transport.TransporterFactory +import org.eclipse.aether.transport.file.FileTransporterFactory +import org.eclipse.aether.transport.http.HttpTransporterFactory +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import java.io.File + +data class EmbedderFacadeRequest( + val offline: Boolean, + val localRepositoryPath: File? = null, + val pomFile: File?, + val activeProfileIds: Collection = emptyList(), + val inactiveProfileIds: Collection = emptyList(), +) + +data class EmbedderFacadeResponse( + val modelBuildingResult: ModelBuildingResult, + val session: DefaultRepositorySystemSession?, + val repositorySystem: RepositorySystem?, + val remoteRepositories: List = emptyList(), +) + +object EmbedderFacade { + // Embedder Impl + + fun invokeEmbedder(req: EmbedderFacadeRequest): EmbedderFacadeResponse { + val localRepoPath: File = when { + req.localRepositoryPath != null -> req.localRepositoryPath + System.getenv("M2_REPO") != null -> File(System.getenv("M2_REPO")) + System.getProperty("maven.repo.local") != null -> File(System.getProperty("maven.repo.local")) + else -> File( + System.getProperty("user.home"), + ".m2/repository" + ) + } + + val localRepository = LocalRepository(localRepoPath.absolutePath) + + val locator: DefaultServiceLocator = + MavenRepositorySystemUtils.newServiceLocator() + + locator.addService( + RepositoryConnectorFactory::class.java, + BasicRepositoryConnectorFactory::class.java + ) + + locator.addService( + TransporterFactory::class.java, + FileTransporterFactory::class.java + ) + + locator.addService( + TransporterFactory::class.java, + HttpTransporterFactory::class.java + ) + + locator.setErrorHandler(object : + DefaultServiceLocator.ErrorHandler() { + override fun serviceCreationFailed( + type: Class<*>?, + impl: Class<*>?, + exception: Throwable + ) { + LOGGER.error( + "Service creation failed for {} with implementation {}", + type, impl, exception + ) + } + }) + + val repositorySystem = locator.getService(RepositorySystem::class.java) + + val session = MavenRepositorySystemUtils.newSession() + + session.localRepositoryManager = + repositorySystem.newLocalRepositoryManager(session, localRepository) + + session.setOffline(req.offline) + + val modelBuilder = DefaultModelBuilderFactory().newInstance() + + val repositoryManager = DefaultRemoteRepositoryManager() + + val remoteRepository = + RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2/") + .build() + + val remoteRepositories = if (req.offline) { + emptyList() + } else { + listOf(remoteRepository) + } + + val modelBuildingRequest = DefaultModelBuildingRequest().apply { + this.userProperties = System.getProperties() + this.systemProperties = System.getProperties() + this.pomFile = req.pomFile!! + + this.isProcessPlugins = false + + this.modelSource = FileModelSource(pomFile) + + val modelResolver = ProjectModelResolver( + session, + null, + repositorySystem, + repositoryManager, + remoteRepositories, + null, + null + ) + + this.modelResolver = modelResolver + } + + val modelBuildingResult: ModelBuildingResult = try { + modelBuilder.build(modelBuildingRequest) + } catch (e: ModelBuildingException) { + LOGGER.warn("Oops: ", e) + + throw e + } + + return EmbedderFacadeResponse( + modelBuildingResult = modelBuildingResult, + session = session, + repositorySystem = repositorySystem, + remoteRepositories = remoteRepositories, + ) + } + + private val LOGGER: Logger = LoggerFactory.getLogger(EmbedderFacade::class.java) +} \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/POMScanner.kt b/src/main/java/io/github/pixee/maven/operator/POMScanner.kt index 966bbc6eb..919cb30c0 100644 --- a/src/main/java/io/github/pixee/maven/operator/POMScanner.kt +++ b/src/main/java/io/github/pixee/maven/operator/POMScanner.kt @@ -1,18 +1,36 @@ package io.github.pixee.maven.operator import org.dom4j.Element +import org.slf4j.Logger +import org.slf4j.LoggerFactory import java.io.File -import java.net.URI import java.nio.file.Path import java.nio.file.Paths import java.util.* import kotlin.io.path.notExists object POMScanner { + private val LOGGER: Logger = LoggerFactory.getLogger(POMScanner::class.java) + private val RE_WINDOWS_PATH = Regex("""^\p{Alpha}:""") @JvmStatic fun scanFrom(originalFile: File, topLevelDirectory: File): ProjectModelFactory { + val originalDocument = ProjectModelFactory.load(originalFile) + + val parentPoms: List = try { + getParentPoms(originalFile) + } catch (e: Exception) { + LOGGER.warn("While trying embedder: ", e) + + return legacyScanFrom(originalFile, topLevelDirectory) + } + + return originalDocument + .withParentPomFiles(parentPoms.map { POMDocumentFactory.load(it) }) + } + + private fun legacyScanFrom(originalFile: File, topLevelDirectory: File): ProjectModelFactory { val pomFile: POMDocument = POMDocumentFactory.load(originalFile) val parentPomFiles: MutableList = arrayListOf() @@ -25,9 +43,9 @@ object POMScanner { pomFileQueue.add(relativePathElement) } - var lastFile : File = originalFile + var lastFile: File = originalFile - fun resolvePath(baseFile: File, relativePath: String) : Path { + fun resolvePath(baseFile: File, relativePath: String): Path { var parentDir = baseFile if (parentDir.isFile) { @@ -45,7 +63,7 @@ object POMScanner { return Paths.get(result.absolutePath) } - val prevPaths : MutableSet = linkedSetOf() + val prevPaths: MutableSet = linkedSetOf() while (pomFileQueue.isNotEmpty()) { val relativePathElement = pomFileQueue.poll() @@ -60,7 +78,7 @@ object POMScanner { throw InvalidPathException(pomFile.file, relativePath) if (prevPaths.contains(relativePath)) { - throw InvalidPathException(pomFile.file, relativePath, loop=true) + throw InvalidPathException(pomFile.file, relativePath, loop = true) } else { prevPaths.add(relativePath) } @@ -111,4 +129,22 @@ object POMScanner { return !(path.startsWith("/") || path.startsWith("~")) } + + + private fun getParentPoms(originalFile: File): List { + val embedderFacadeResponse = EmbedderFacade.invokeEmbedder( + EmbedderFacadeRequest(offline = true, pomFile = originalFile) + ) + + val res = embedderFacadeResponse.modelBuildingResult + + val rawModels = res.modelIds.map { res.getRawModel(it) }.toList() + + val parentPoms: List = + if (rawModels.size > 1) { + rawModels.subList(1, rawModels.size).mapNotNull { it.pomFile }.toList() + } else + emptyList() + return parentPoms + } } diff --git a/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt b/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt index 2979ed08b..73709090b 100644 --- a/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt +++ b/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt @@ -84,11 +84,11 @@ class ProjectModel internal constructor( tempProperties.entries.forEach { entry -> if (!result.containsKey(entry.key)) { - result.put(entry.key, ArrayList()) + result[entry.key] = ArrayList() } val definitionList = - result.get(entry.key) as MutableList> + result[entry.key] as MutableList> definitionList.add(entry.value to pomFile) } @@ -116,14 +116,16 @@ class ProjectModel internal constructor( return newPropertiesToAppend } - private fun propertiesDefinedOnPomDocument(pomFile: POMDocument): Map { - val rootProperties = - pomFile.pomDocument.rootElement.elements("properties") - .flatMap { it.elements() } - .associate { - it.name to it.text - } - return rootProperties + companion object { + fun propertiesDefinedOnPomDocument(pomFile: POMDocument): Map { + val rootProperties = + pomFile.pomDocument.rootElement.elements("properties") + .flatMap { it.elements() } + .associate { + it.name to it.text + } + return rootProperties + } } } diff --git a/src/main/java/io/github/pixee/maven/operator/QueryByParsing.kt b/src/main/java/io/github/pixee/maven/operator/QueryByParsing.kt new file mode 100644 index 000000000..617ba48d9 --- /dev/null +++ b/src/main/java/io/github/pixee/maven/operator/QueryByParsing.kt @@ -0,0 +1,165 @@ +@file:Suppress("DEPRECATION") + +package io.github.pixee.maven.operator + +import org.apache.commons.lang3.builder.CompareToBuilder +import org.apache.commons.lang3.text.StrSubstitutor +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import java.io.File +import java.util.* + +/** + * this one is a bit more complex, as it intents to to a "best effort" attempt at parsing a pom + * focusing only on dependency right now, * without relying to any maven infrastructure at all + */ +class QueryByParsing : AbstractQueryCommand() { + override fun extractDependencyTree(outputPath: File, pomFilePath: File, c: ProjectModel) { + TODO("Not yet implemented") + } + + private val dependencies: MutableSet = LinkedHashSet() + + private val dependencyManagement: MutableSet = + TreeSet(object : Comparator { + override fun compare(o1: Dependency?, o2: Dependency?): Int { + if (o1 == o2) + return 0 + + if (o1 == null) + return 1 + + if (o2 == null) + return -1 + + return CompareToBuilder().append(o1.groupId, o2.groupId) + .append(o1.artifactId, o2.artifactId).toComparison() + } + }) + + private val properties: MutableMap = LinkedHashMap() + + private val strSubstitutor = StrSubstitutor(properties) + + override fun execute(pm: ProjectModel): Boolean { + /** + * Enlist all pom files given an hierarchy + */ + val pomFilesByHierarchy = pm.allPomFiles.reversed() + + for (pomDocument in pomFilesByHierarchy) { + updateProperties(pomDocument) + + updateDependencyManagement(pomDocument) + + updateDependencies(pomDocument) + } + + this.result = dependencies + + return true + } + + private fun updateDependencyManagement(pomDocument: POMDocument) { + val dependencyManagementDependenciesToAdd: Collection = + pomDocument.pomDocument.// + rootElement. // + element("dependencyManagement")?. // + element("dependencies")?. // + elements("dependency")?. // + map { dependencyElement -> + val groupId = dependencyElement.element("groupId").text + val artifactId = dependencyElement.element("artifactId").text + + val version = dependencyElement.element("version")?.text ?: "UNKNOWN" + + val classifier = dependencyElement.element("classifier")?.text + val packaging = dependencyElement.element("packaging")?.text + + val versionInterpolated = try { + strSubstitutor.replace(version) + } catch (e: java.lang.IllegalStateException) { + LOGGER.warn("while interpolating version", e) + + "UNKNOWN" + } + + Dependency(groupId, artifactId, versionInterpolated, classifier, packaging) + }?.toList() ?: emptyList() + + this.dependencyManagement.addAll(dependencyManagementDependenciesToAdd) + } + + fun lookForDependencyManagement(groupId: String, artifactId: String): Dependency? = + this.dependencyManagement.firstOrNull { it.groupId == groupId && it.artifactId == artifactId } + + private fun updateDependencies(pomDocument: POMDocument) { + val dependenciesToAdd: Collection = + pomDocument.pomDocument.// + rootElement. // + element("dependencies")?. // + elements("dependency")?. // + map { dependencyElement -> + val groupId = dependencyElement.element("groupId").text + val artifactId = dependencyElement.element("artifactId").text + + val versionElement = dependencyElement.element("version") + + val proposedDependency = lookForDependencyManagement(groupId, artifactId) + + if (versionElement == null && null != proposedDependency) { + proposedDependency + } else { + val version = versionElement?.text ?: "UNKNOWN" + + val classifier = dependencyElement.element("classifier")?.text + val packaging = dependencyElement.element("packaging")?.text + + val versionInterpolated = try { + strSubstitutor.replace(version) + } catch (e: java.lang.IllegalStateException) { + LOGGER.warn("while interpolating version", e) + + "UNKNOWN" + } + + Dependency(groupId, artifactId, versionInterpolated, classifier, packaging) + } + }?.toList() ?: emptyList() + + this.dependencies.addAll( + dependenciesToAdd + ) + } + + /** + * Updates the Properties member variable based on whats on the POMDocument + */ + private fun updateProperties(pomDocument: POMDocument) { + val propsDefined = ProjectModel.propertiesDefinedOnPomDocument(pomDocument) + + propsDefined.entries.filterNot { it.value.matches(RE_INTERPOLATION) } + .forEach { + properties[it.key] = it.value + } + + propsDefined.entries.filterNot { it.value.matches(RE_INTERPOLATION) } + .forEach { + val newValue = try { + strSubstitutor.replace(it.value) + } catch (e: IllegalStateException) { + LOGGER.warn("while replacing variables: ", e) + + it.value + } + + properties.put(it.key, it.value) + } + } + + companion object { + val RE_INTERPOLATION = Regex(""".*\$\{[\p{Alnum}.-_]+\}.*""") + + val logger: Logger = LoggerFactory.getLogger(QueryByParsing::class.java) + } +} \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt b/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt index a9ced3c3c..78e274f47 100644 --- a/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt +++ b/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt @@ -1,52 +1,20 @@ package io.github.pixee.maven.operator -import org.apache.maven.model.building.DefaultModelBuilderFactory -import org.apache.maven.model.building.DefaultModelBuildingRequest -import org.apache.maven.model.building.FileModelSource import org.apache.maven.model.building.ModelBuildingException -import org.apache.maven.project.ProjectModelResolver -import org.apache.maven.repository.internal.MavenRepositorySystemUtils -import org.eclipse.aether.DefaultRepositorySystemSession -import org.eclipse.aether.RepositorySystem import org.eclipse.aether.artifact.DefaultArtifact import org.eclipse.aether.collection.CollectRequest -import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory import org.eclipse.aether.graph.DependencyNode import org.eclipse.aether.graph.DependencyVisitor -import org.eclipse.aether.internal.impl.DefaultRemoteRepositoryManager -import org.eclipse.aether.repository.LocalRepository -import org.eclipse.aether.repository.RemoteRepository -import org.eclipse.aether.transport.file.FileTransporterFactory -import org.eclipse.aether.transport.http.HttpTransporterFactory import org.slf4j.Logger import org.slf4j.LoggerFactory import java.io.File -import kotlin.io.path.toPath /** * This is a resolver that actually embeds much of Maven Logic into that. * - * TODO: Support Profiles / Environment Variables - * Support Third Party / User-Supplied Repositories (right now it only supports central) + * Futurely TODO Support Third Party / User-Supplied Repositories (right now it only supports central) */ class QueryByResolver : AbstractQueryCommand() { - private fun getLocalRepository(pm: ProjectModel): LocalRepository { - val localRepositoryPath: File = getLocalRepositoryPath(pm) - - return LocalRepository(localRepositoryPath.absolutePath) - } - - private fun newRepositorySystemSession(pm: ProjectModel, system: RepositorySystem): DefaultRepositorySystemSession? { - val session = MavenRepositorySystemUtils.newSession() - - val localRepo = getLocalRepository(pm) - - session.localRepositoryManager = system.newLocalRepositoryManager(session, localRepo) - - return session - } - - companion object { private val LOGGER: Logger = LoggerFactory.getLogger(QueryByResolver::class.java) } @@ -55,99 +23,30 @@ class QueryByResolver : AbstractQueryCommand() { TODO("Not yet implemented") } - @Suppress("DEPRECATION") override fun execute(pm: ProjectModel): Boolean { - /* - * Aether's components implement org.eclipse.aether.spi.locator.Service to ease manual wiring and using the - * prepopulated DefaultServiceLocator, we only need to register the repository connector and transporter - * factories. - */ - val locator: org.eclipse.aether.impl.DefaultServiceLocator = - MavenRepositorySystemUtils.newServiceLocator() - locator.addService( - org.eclipse.aether.spi.connector.RepositoryConnectorFactory::class.java, - BasicRepositoryConnectorFactory::class.java - ) - locator.addService( - org.eclipse.aether.spi.connector.transport.TransporterFactory::class.java, - FileTransporterFactory::class.java + val req = EmbedderFacadeRequest( + offline = pm.offline, + pomFile = pm.pomFile.file, + localRepositoryPath = pm.repositoryPath, + activeProfileIds = pm.activeProfiles.filterNot { it.startsWith("!") }.toList(), + inactiveProfileIds = pm.activeProfiles.filter { it.startsWith("!") } + .map { it.substring(1) }.toList() ) - locator.addService( - org.eclipse.aether.spi.connector.transport.TransporterFactory::class.java, - HttpTransporterFactory::class.java - ) - - locator.setErrorHandler(object : - org.eclipse.aether.impl.DefaultServiceLocator.ErrorHandler() { - override fun serviceCreationFailed( - type: Class<*>?, - impl: Class<*>?, - exception: Throwable - ) { - LOGGER.error( - "Service creation failed for {} with implementation {}", - type, impl, exception - ) - } - }) - val remoteRepository = - RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2/") - .build() + this.result = emptyList() - val remoteRepositories : List = - if (pm.offline) { - emptyList() - } else { - listOf(remoteRepository) - } + val embedderFacadeResponse: EmbedderFacadeResponse - val repositorySystem = - locator.getService(org.eclipse.aether.RepositorySystem::class.java) - - val session = newRepositorySystemSession(pm, repositorySystem)!! - .setOffline(pm.offline) - - val modelBuilder = DefaultModelBuilderFactory().newInstance() - - val repositoryManager = DefaultRemoteRepositoryManager() - - val modelBuildingRequest = DefaultModelBuildingRequest().apply { - val pomFile = pm.pomFile.pomPath!!.toURI().toPath().toFile() - - this.activeProfileIds = pm.activeProfiles.filterNot { it.startsWith("!") }.toList() - this.inactiveProfileIds = - pm.activeProfiles.filter { it.startsWith("!") }.map { it.substring(1) }.toList() - - this.userProperties = System.getProperties() - this.systemProperties = System.getProperties() - this.pomFile = pomFile - - this.isProcessPlugins = false - - this.modelSource = FileModelSource(pomFile) - - val modelResolver = ProjectModelResolver( - session, - null, - repositorySystem, - repositoryManager, - remoteRepositories, - null, - null - ) - - this.modelResolver = modelResolver - } - - val res = try { - modelBuilder.build(modelBuildingRequest) - } catch (e: ModelBuildingException) { - LOGGER.warn("Oops: ", e) + try { + embedderFacadeResponse = EmbedderFacade.invokeEmbedder(req) + } catch (mbe: ModelBuildingException) { + LOGGER.warn("Oops:", mbe) return false } + val res = embedderFacadeResponse.modelBuildingResult + val dependencyToArtifact: (org.apache.maven.model.Dependency) -> org.eclipse.aether.graph.Dependency = { org.eclipse.aether.graph.Dependency( @@ -169,9 +68,13 @@ class QueryByResolver : AbstractQueryCommand() { res.effectiveModel.dependencyManagement?.dependencies?.map(dependencyToArtifact) ?.toList() ?: emptyList() - val collectRequest = CollectRequest(deps, managedDeps, remoteRepositories) + val collectRequest = + CollectRequest(deps, managedDeps, embedderFacadeResponse.remoteRepositories) - val collectResult = repositorySystem.collectDependencies(session, collectRequest) + val collectResult = embedderFacadeResponse.repositorySystem!!.collectDependencies( + embedderFacadeResponse.session, + collectRequest + ) val returnList: MutableList = mutableListOf() @@ -202,5 +105,4 @@ class QueryByResolver : AbstractQueryCommand() { return true } - } \ No newline at end of file diff --git a/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt index 552e0b442..e332ee394 100644 --- a/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt @@ -142,7 +142,8 @@ class POMOperatorQueryTest { val randomName = "random-artifact-" + System.currentTimeMillis() - Files.write(tempPom, """ + Files.write( + tempPom, """ - """.trimIndent().toByteArray()) + """.trimIndent().toByteArray() + ) val context = ProjectModelFactory @@ -191,7 +193,8 @@ class POMOperatorQueryTest { val randomName = "random-artifact-" + System.currentTimeMillis() - Files.write(tempParentPom, """ + Files.write( + tempParentPom, """ - """.trim().toByteArray()) + """.trim().toByteArray() + ) - Files.write(tempPom, """ + Files.write( + tempPom, """ - """.trim().toByteArray()) + """.trim().toByteArray() + ) val context = ProjectModelFactory @@ -268,14 +274,15 @@ class POMOperatorQueryTest { } @Test - fun testOnCompositeSyntheticDependencyIncomplete() { + fun testOnCompositeSyntheticDependencyIncompleteWithoutParsing() { val tempDirectory = Files.createTempDirectory("mvn-repo").toFile() val tempPom = File(tempDirectory, "pom.xml").toPath() val randomName = "random-artifact-" + System.currentTimeMillis() - Files.write(tempPom, """ + Files.write( + tempPom, """ - """.trim().toByteArray()) + """.trim().toByteArray() + ) val context = ProjectModelFactory @@ -317,10 +325,118 @@ class POMOperatorQueryTest { .withOffline(true) .build() + val dependencies = POMOperator.queryDependency( + context, + commandList = getCommandListFor("QueryByEmbedder", "QueryByResolver") + ) + + LOGGER.debug("Dependencies found: {}", dependencies) + + assertTrue("Dependencies are empty", dependencies.isEmpty()) + } + + @Test + fun testOnCompositeSyntheticDependencyIncompleteButWithParser() { + val tempDirectory = Files.createTempDirectory("mvn-repo").toFile() + + val tempPom = File(tempDirectory, "pom.xml").toPath() + + val randomName = "random-artifact-" + System.currentTimeMillis() + + Files.write( + tempPom, """ + + + 4.0.0 + + br.com.ingenieux + pom-operator + 0.0.1-SNAPSHOT + + + somethingelse + br.com.ingenieux + 1 + ./pom-parent.xml + + + + + + dummyorg + managed-${randomName} + 0.0.1 + + + + + + + dummyorg + ${randomName} + 2.1.3 + + + dummyorg + managed-${randomName} + + + + + """.trim().toByteArray() + ) + + val context = + ProjectModelFactory + .load(tempPom.toFile()) + .withQueryType(QueryType.SAFE) + .withRepositoryPath(tempDirectory) + .withOffline(true) + .build() + + val dependencies = + POMOperator.queryDependency(context, commandList = getCommandListFor("QueryByParsing")) + + LOGGER.debug("Dependencies found: {}", dependencies) + + assertTrue("Dependencies are empty", dependencies.isNotEmpty()) + + val foundDependencies = + dependencies.firstOrNull { it.version == "0.0.1" && it.artifactId.equals("managed-$randomName") } + + assertTrue("there's a dependencyManaged-version", foundDependencies != null) + } + + private fun getCommandListFor(vararg names: String): List = + names.map { + val commandClassName = "io.github.pixee.maven.operator.${it}" + + val commandInstance = + Class.forName(commandClassName).newInstance() as Command + + commandInstance + }.toList() + + @Test + fun testOfflineQueryResolution() { + val tempDirectory = Files.createTempDirectory("mvn-repo").toFile() + + val context = + ProjectModelFactory + .load(javaClass.getResource("nested/child/pom/pom-3-child.xml")) + .withQueryType(QueryType.SAFE) + .withRepositoryPath(tempDirectory) + .withOffline(true) + .build() + val dependencies = POMOperator.queryDependency(context) LOGGER.debug("Dependencies found: {}", dependencies) assertTrue("Dependencies are empty", dependencies.isEmpty()) + } } diff --git a/src/test/java/io/github/pixee/maven/operator/test/POMScannerTest.kt b/src/test/java/io/github/pixee/maven/operator/test/POMScannerTest.kt index b1f83c1a0..dad872ca2 100644 --- a/src/test/java/io/github/pixee/maven/operator/test/POMScannerTest.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/POMScannerTest.kt @@ -63,12 +63,13 @@ class POMScannerTest: AbstractTestBase() { @Test fun testInvalidRelativePaths() { for (index in 1..3) { - val pomFile = getResourceAsFile("sample-child-with-broken-path-${index}.xml") + val name = "sample-child-with-broken-path-${index}.xml" + val pomFile = getResourceAsFile(name) try { POMScanner.scanFrom(pomFile, currentDirectory) - fail("Unreachable code") + fail("Unreachable code for file: $name") } catch (e: Exception) { LOGGER.info("Exception thrown: ", e) diff --git a/src/test/resources/io/github/pixee/maven/operator/test/nested/super/pom/other-pom.xml b/src/test/resources/io/github/pixee/maven/operator/test/nested/super/pom/other-pom.xml index 5b9c4e081..59d61dcba 100644 --- a/src/test/resources/io/github/pixee/maven/operator/test/nested/super/pom/other-pom.xml +++ b/src/test/resources/io/github/pixee/maven/operator/test/nested/super/pom/other-pom.xml @@ -7,7 +7,7 @@ br.com.ingenieux 1 - org-pom + super-pom pom diff --git a/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-1.xml b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-1.xml index 521078522..5c8086521 100644 --- a/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-1.xml +++ b/src/test/resources/io/github/pixee/maven/operator/test/sample-child-with-broken-path-1.xml @@ -9,7 +9,7 @@ br.com.ingenieux sample-parent 1 - ../../../../../../../../../../../../../sample-parent + ../../../../../../../../../../../../../../../../../../sample-parent sample-child-with-relativepath From 3e4996305cd9fceae547441ba460a582541db184 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 7 Aug 2023 18:55:49 -0500 Subject: [PATCH 111/153] Generates javadoc (#23) * Generates javadoc * [no ci] Autogenerated JaCoCo coverage badge --------- Co-authored-by: Jacoco Coverage Update Action --- .github/badges/jacoco.svg | 2 +- pom.xml | 16 ++++++++++++++++ .../io/github/pixee/maven/operator/Dummy.java | 8 ++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 src/main/java/io/github/pixee/maven/operator/Dummy.java diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index 9681820dd..99a5dd41d 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage90.7% \ No newline at end of file +coverage90.6% \ No newline at end of file diff --git a/pom.xml b/pom.xml index 3fc7bfbd9..c190519d1 100644 --- a/pom.xml +++ b/pom.xml @@ -354,6 +354,22 @@ org.jacoco jacoco-maven-plugin + + org.apache.maven.plugins + maven-javadoc-plugin + 3.5.0 + + + + javadoc + jar + test-javadoc + test-jar + + package + + +
diff --git a/src/main/java/io/github/pixee/maven/operator/Dummy.java b/src/main/java/io/github/pixee/maven/operator/Dummy.java new file mode 100644 index 000000000..043d8542e --- /dev/null +++ b/src/main/java/io/github/pixee/maven/operator/Dummy.java @@ -0,0 +1,8 @@ +package io.github.pixee.maven.operator; + +/** + * This dummy class is for Javadoc-generating purposes only + */ +public class Dummy { + +} \ No newline at end of file From 8b8308bae649ef1ac51261ec2f528b64d36bf4a3 Mon Sep 17 00:00:00 2001 From: Arshan Dabirsiaghi Date: Mon, 7 Aug 2023 20:15:48 -0400 Subject: [PATCH 112/153] add MIT license (#22) --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..efdccf088 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Pixee + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 6e8957d5d244cf92c21bd8295049f85b312d53b1 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 7 Aug 2023 19:18:23 -0500 Subject: [PATCH 113/153] Generating Tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c190519d1..43d9e1f50 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.12-SNAPSHOT + 0.0.12 scm:git:${project.scm.url} From 3418a485f7611ef5af641f9dab41b3c2b2939e6b Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 7 Aug 2023 19:21:09 -0500 Subject: [PATCH 114/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index 01acb47bf..ce82e9d88 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.github.pixee.maven.sample java-sample - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index 43d9e1f50..efc819f86 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.12 + 0.0.13-SNAPSHOT scm:git:${project.scm.url} From 441e5f6f1c4f211db9d5a84d943df1d74adfb89b Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 7 Aug 2023 19:23:12 -0500 Subject: [PATCH 115/153] Generating Tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index efc819f86..6340b43f1 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.13-SNAPSHOT + 0.0.13 scm:git:${project.scm.url} From 4fba1f44279bc31a04ef72f696389483496f9e52 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 7 Aug 2023 19:23:49 -0500 Subject: [PATCH 116/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index ce82e9d88..43912d4f6 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.github.pixee.maven.sample java-sample - 0.0.13-SNAPSHOT + 0.0.14-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index 6340b43f1..166555fcb 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.13 + 0.0.14-SNAPSHOT scm:git:${project.scm.url} From 53bbed09f60def2fe9dd3204d305c0299fc4e5e1 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 7 Aug 2023 20:52:42 -0500 Subject: [PATCH 117/153] Prepare for rerelease (#24) --- .github/workflows/release.yml | 33 ++++---- pom.xml | 141 ++++++++++++++++++++++++++++------ 2 files changed, 135 insertions(+), 39 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 960c57a14..a071a7749 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,15 +2,15 @@ name: Create Release on Semantic Version Tag on: push: - branches: - - master + tags: + - "v*" env: M2_HOME: /opt/hostedtoolcache/maven/3.8.2 JAVA_HOME: /opt/hostedtoolcache/Java_Adopt_jdk/11.0.17-8 jobs: - pre-release: + release: runs-on: "ubuntu-latest" steps: @@ -22,22 +22,27 @@ jobs: with: java-version: '11' distribution: 'adopt' + server-id: ossrh + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD + gpg-private-key: ${{ secrets.OSSRH_GPG_SECRET_KEY }} + gpg-passphrase: MAVEN_GPG_PASSPHRASE - name: Set up Maven uses: stCarolas/setup-maven@v4.4 with: maven-version: 3.8.2 - - name: "Setting up Artifactory authentication" - uses: s4u/maven-settings-action@v2 - with: - servers: | - [ - {"id": "pixee-libs-release", "username": "${{ secrets.ARTIFACTORY_USER }}", "password": "${{ secrets.ARTIFACTORY_TOKEN }}"}, - {"id": "pixee-libs-snapshot", "username": "${{ secrets.ARTIFACTORY_USER }}", "password": "${{ secrets.ARTIFACTORY_TOKEN }}"} - ] - githubServer: false - - - name: Build with Maven + - name: "Publish to Maven Central" run: | mvn -N -B install + -Prelease \ + -X \ + --no-transfer-progress \ + --batch-mode \ + clean \ + deploy + env: + MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.OSSRH_GPG_SECRET_KEY_PASSPHRASE }} diff --git a/pom.xml b/pom.xml index 166555fcb..a77ce5953 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,39 @@ 0.0.14-SNAPSHOT - scm:git:${project.scm.url} - scm:git:${project.scm.url} - git@github.com:pixee/pom-operator.git + scm:git:git://github.com/pixee/pom-operator.git + scm:git:ssh://github.com:pixee/pom-operator.git + https://github.com/pixee/pom-operator/tree/master HEAD + + + + MIT License + http://www.opensource.org/licenses/mit-license.php + + + + + + ossrh + https://s01.oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + Aldrin Leal + pixee + https://pixee.ai/ + + + UTF-8 1.8 @@ -24,21 +51,12 @@ 2.5.3 1.9.2 3.8.6 + 2.9.1 + 1.6.13 + 2.2.1 + 3.0.1 - - - pixee-libs-release - a0cpnsoovnjqt-artifactory-primary-0-releases - https://pixee.jfrog.io/artifactory/mailman - - - pixee-libs-snapshot - a0cpnsoovnjqt-artifactory-primary-0-snapshots - https://pixee.jfrog.io/artifactory/mailman - - - com.offbytwo @@ -276,14 +294,6 @@ - - maven-release-plugin - ${maven-release-plugin.version} - - [ci skip] - @{project.version} - - org.jetbrains.kotlin kotlin-maven-plugin @@ -319,6 +329,53 @@ false + + org.apache.maven.plugins + maven-gpg-plugin + ${versions.maven-gpg-plugin} + + + org.apache.maven.plugins + maven-source-plugin + ${versions.maven-source-plugin} + + + attach-sources + + jar-no-fork + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + ${versions.nexus-staging-maven-plugin} + true + + ossrh + https://s01.oss.sonatype.org/ + true + + true + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${versions.maven-javadoc-plugin} + + + + javadoc + jar + test-javadoc + test-jar + + package + + + @@ -326,6 +383,7 @@ org.jetbrains.kotlin kotlin-maven-plugin + org.codehaus.mojo versions-maven-plugin @@ -350,6 +408,14 @@ + + org.apache.maven.plugins + maven-source-plugin + + + org.sonatype.plugins + nexus-staging-maven-plugin + org.jacoco jacoco-maven-plugin @@ -357,7 +423,6 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.5.0 @@ -414,5 +479,31 @@ + + release + + + + org.apache.maven.plugins + maven-gpg-plugin + + + sign-artifacts + verify + + sign + + + + --pinentry-mode + loopback + + + + + + + + From a8ba29022c471aba26257b14fbf62b7c5e454558 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 7 Aug 2023 20:56:25 -0500 Subject: [PATCH 118/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index 43912d4f6..1037fe7b1 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.github.pixee.maven.sample java-sample - 0.0.14-SNAPSHOT + 0.0.15-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index a77ce5953..8fc753080 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.14-SNAPSHOT + 0.0.15-SNAPSHOT scm:git:git://github.com/pixee/pom-operator.git From 6059eeaafe117b074f271920224bb62bebc67ff9 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 7 Aug 2023 21:08:40 -0500 Subject: [PATCH 119/153] Fixes workflows (#25) --- .github/workflows/release.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a071a7749..ff8116272 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -35,7 +35,7 @@ jobs: - name: "Publish to Maven Central" run: | - mvn -N -B install + mvn -N -B \ -Prelease \ -X \ --no-transfer-progress \ diff --git a/README.md b/README.md index afcb56d0d..ff4274fda 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ It implements a Chain of Responsibility strategy - each `Command` class attempts e.g. to generate version `0.0.2`: ``` -(mvn versions:set -DnewVersion=0.0.3 && mvn clean package source:jar javadoc:jar deploy && git commit -am "Generating Tag" && git tag v0.0.3 && git push && git push --tags) +(mvn versions:set -DnewVersion=0.0.3 && git commit -am "Generating Tag" && git tag v0.0.3 && git push && git push --tags) (export V='0.0.11-SNAPSHOT' ; mvn versions:set -DnewVersion=${V} && (cd java-sample ; mvn versions:set -DnewVersion=${V} && git commit -am "Generating development version" && git push)) ``` From cb22cbe2bf9a063cf828548b96378d53e61d0755 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 7 Aug 2023 21:09:31 -0500 Subject: [PATCH 120/153] Generating Tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8fc753080..1c7b9cd03 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.15-SNAPSHOT + 0.0.15 scm:git:git://github.com/pixee/pom-operator.git From 5210dfd4a1a3a87c30b1f523347b53850a71ec4a Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 7 Aug 2023 21:15:33 -0500 Subject: [PATCH 121/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index 1037fe7b1..02b7e67f7 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.github.pixee.maven.sample java-sample - 0.0.15-SNAPSHOT + 0.0.16-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index 1c7b9cd03..f513c8b1a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,13 @@ io.github.pixee.maven pom-operator - 0.0.15 + 0.0.16-SNAPSHOT + + POM Operator + + A Library for Parsing and Modifying POMS + + https://github.com/pixee/pom-operator scm:git:git://github.com/pixee/pom-operator.git From cf0596e12411b0b1eff07874f9df9d4b06f5cb61 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 7 Aug 2023 21:16:21 -0500 Subject: [PATCH 122/153] Generating Tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f513c8b1a..eb6a8847f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.16-SNAPSHOT + 0.0.16 POM Operator From 0e797aa98c02abc74c21ebac584eda6a24ad6f98 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 7 Aug 2023 21:16:53 -0500 Subject: [PATCH 123/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index 02b7e67f7..4fb29044f 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.github.pixee.maven.sample java-sample - 0.0.16-SNAPSHOT + 0.0.17-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index eb6a8847f..965ea142e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.16 + 0.0.17-SNAPSHOT POM Operator From 75cbb5cbcc157b716a1681f988ff9db6249c0f7a Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Mon, 7 Aug 2023 21:50:25 -0500 Subject: [PATCH 124/153] Generating Tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 965ea142e..3e723f452 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.17-SNAPSHOT + 0.0.17 POM Operator From 27b51fdfb2279e71adce9dfa61f1980afbda8598 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 16 Aug 2023 17:29:00 -0500 Subject: [PATCH 125/153] Improving test as well as reacting when dependency failures happen (#26) * Improving test as well as reacting when dependency failures happen * Warning --- java-sample/pom.xml | 2 +- pom.xml | 2 +- .../pixee/maven/operator/QueryByResolver.kt | 61 ++++---- .../pixee/maven/operator/test/MassRepoTest.kt | 133 +++++++++++++++--- 4 files changed, 147 insertions(+), 51 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index 4fb29044f..dffa250df 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.github.pixee.maven.sample java-sample - 0.0.17-SNAPSHOT + 0.0.18-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index 3e723f452..e3b181e54 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.17 + 0.0.18-SNAPSHOT POM Operator diff --git a/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt b/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt index 78e274f47..a54094f59 100644 --- a/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt +++ b/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt @@ -3,6 +3,7 @@ package io.github.pixee.maven.operator import org.apache.maven.model.building.ModelBuildingException import org.eclipse.aether.artifact.DefaultArtifact import org.eclipse.aether.collection.CollectRequest +import org.eclipse.aether.collection.DependencyCollectionException import org.eclipse.aether.graph.DependencyNode import org.eclipse.aether.graph.DependencyVisitor import org.slf4j.Logger @@ -71,38 +72,44 @@ class QueryByResolver : AbstractQueryCommand() { val collectRequest = CollectRequest(deps, managedDeps, embedderFacadeResponse.remoteRepositories) - val collectResult = embedderFacadeResponse.repositorySystem!!.collectDependencies( - embedderFacadeResponse.session, - collectRequest - ) - - val returnList: MutableList = mutableListOf() - - collectResult.root.accept(object : DependencyVisitor { - override fun visitEnter(node: DependencyNode?): Boolean { - node?.dependency?.apply { - returnList.add( - Dependency( - groupId = this.artifact.groupId, - artifactId = this.artifact.artifactId, - version = this.artifact.version, - classifier = this.artifact.classifier, - packaging = this.artifact.extension, - scope = this.scope, + return try { + val collectResult = embedderFacadeResponse.repositorySystem!!.collectDependencies( + embedderFacadeResponse.session, + collectRequest + ) + + val returnList: MutableList = mutableListOf() + + collectResult.root.accept(object : DependencyVisitor { + override fun visitEnter(node: DependencyNode?): Boolean { + node?.dependency?.apply { + returnList.add( + Dependency( + groupId = this.artifact.groupId, + artifactId = this.artifact.artifactId, + version = this.artifact.version, + classifier = this.artifact.classifier, + packaging = this.artifact.extension, + scope = this.scope, + ) ) - ) + } + + return true } - return true - } + override fun visitLeave(node: DependencyNode?): Boolean { + return true + } + }) - override fun visitLeave(node: DependencyNode?): Boolean { - return true - } - }) + this.result = returnList.toList() - this.result = returnList.toList() + return true + } catch (e: DependencyCollectionException) { + LOGGER.warn("while resolving: ", e) - return true + return false + } } } \ No newline at end of file diff --git a/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt b/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt index 0502231a6..25e2effc6 100644 --- a/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt +++ b/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt @@ -2,21 +2,26 @@ package io.github.pixee.maven.operator.test import io.github.pixee.maven.operator.Dependency import io.github.pixee.maven.operator.POMOperator +import io.github.pixee.maven.operator.POMScanner import io.github.pixee.maven.operator.ProjectModelFactory import io.github.pixee.maven.operator.Util.which import org.apache.commons.lang3.SystemUtils -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue +import org.junit.Assert.* import org.junit.Test import org.slf4j.Logger import org.slf4j.LoggerFactory import java.io.File +import java.lang.AssertionError +import java.lang.Exception data class TestRepo( val slug: String, val branch: String = "master", val pomPath: String = "pom.xml", val useProperties: Boolean = false, + val useScanner: Boolean = false, + val offline: Boolean = false, + val commitId: String? = null, ) { fun cacheDir() = BASE_CACHE_DIR.resolve("repo-%08X".format(slug.hashCode())) @@ -46,6 +51,35 @@ class MassRepoIT { */ private val repos = listOf( + TestRepo( + "WebGoat/WebGoat", + useProperties = true, + branch = "main", + useScanner = false, + commitId = "e75cfbeb110e3d3a2ca3c8fee2754992d89c419d", + pomPath = "webgoat-lessons/xxe/pom.xml", + ) to "io.github.pixee:java-security-toolkit:1.0.2", + TestRepo( + "WebGoat/WebGoat", + useProperties = true, + branch = "main", + useScanner = true, + offline = true, + pomPath = "webgoat-container/pom.xml" + ) to "io.github.pixee:java-security-toolkit:1.0.2", + TestRepo( + "WebGoat/WebGoat", + useProperties = true, + branch = "main", + useScanner = false, + pomPath = "webgoat-container/pom.xml" + ) to "io.github.pixee:java-security-toolkit:1.0.2", + TestRepo( + "WebGoat/WebGoat", + useProperties = true, + branch = "main", + pomPath = "webgoat-container/pom.xml" + ) to "io.github.pixee:java-security-toolkit:1.0.2", TestRepo( "CRRogo/vert.x", useProperties = true, @@ -107,6 +141,19 @@ class MassRepoIT { process.waitFor() } + + if (null != repo.commitId) { + val command = arrayOf("git", "checkout", repo.commitId) + + LOGGER.debug("Running command: ${command.joinToString(" ")}") + + val process = ProcessBuilder(*command) + .directory(repo.cacheDir()) + .inheritIO() + .start() + + process.waitFor() + } } /** @@ -124,7 +171,13 @@ class MassRepoIT { */ @Test fun testAllOthers() { - repos.forEach { testOnRepo(it.first, it.second) } + repos.forEachIndexed { n, pair -> + try { + testOnRepo(pair.first, pair.second) + } catch (e: Throwable) { + throw AssertionError("while trying example $n of $pair", e) + } + } } private fun testOnRepo( @@ -132,10 +185,11 @@ class MassRepoIT { dependencyToUpgradeString: String ) { LOGGER.info( - "Testing on repo {}, branch {} with dependency {}", + "Testing on repo {}, branch {} with dependency {} ({})", sampleRepo.slug, sampleRepo.branch, - dependencyToUpgradeString + dependencyToUpgradeString, + sampleRepo, ) checkoutOrResetCachedRepo(sampleRepo) @@ -145,40 +199,69 @@ class MassRepoIT { LOGGER.info("dependencies: {}", originalDependencies) val dependencyToUpgrade = Dependency.fromString(dependencyToUpgradeString) - val context = ProjectModelFactory.load(File(sampleRepo.cacheDir(), sampleRepo.pomPath)) + + val projectModelFactory = if (sampleRepo.useScanner) { + POMScanner.scanFrom( + File(sampleRepo.cacheDir(), sampleRepo.pomPath), + sampleRepo.cacheDir() + ) + } else { + ProjectModelFactory.Companion.load(File(sampleRepo.cacheDir(), sampleRepo.pomPath)) + } + + val context = projectModelFactory .withDependency(dependencyToUpgrade) .withSkipIfNewer(false) .withUseProperties(sampleRepo.useProperties) + .withOffline(sampleRepo.offline) .build() - POMOperator.modify(context) + val result = POMOperator.modify(context) - val alternatePomFile = - File(File(sampleRepo.cacheDir(), sampleRepo.pomPath).parent, "pom-modified.xml") - - alternatePomFile.writeBytes(context.pomFile.resultPomBytes) + context.allPomFiles.filter { it.dirty }.forEach { + it.file.writeBytes(it.resultPomBytes) + } val finalDependencies = - getDependenciesFrom(alternatePomFile.canonicalPath, sampleRepo.cacheDir()) + getDependenciesFrom(sampleRepo) LOGGER.info("dependencies: {}", finalDependencies) - val dependencyAsStringWithPackaging = dependencyToUpgrade.toString() + val queryFailed = "" == originalDependencies && "" == finalDependencies - assertFalse( - "Dependency should be originally missing", originalDependencies.contains( - dependencyAsStringWithPackaging + if (queryFailed) { + assertTrue("Must be modified even when query failed", result) + } else { + val dependencyAsStringWithPackaging = dependencyToUpgrade.toString() + + assertFalse( + "Dependency should be originally missing", originalDependencies.contains( + dependencyAsStringWithPackaging + ) ) - ) - assertTrue( - "New Dependency should be appearing", finalDependencies.contains( - dependencyAsStringWithPackaging + assertTrue( + "New Dependency should be appearing", finalDependencies.contains( + dependencyAsStringWithPackaging + ) ) - ) + } } - private fun getDependenciesFrom(repo: TestRepo): String = + private fun getDependenciesFrom(repo: TestRepo): String = try { getDependenciesFrom(repo.pomPath, repo.cacheDir()) + } catch (e: Exception) { + val pomFile = File(repo.cacheDir(), repo.pomPath) + + val dependencies = + POMOperator.queryDependency( + POMScanner.scanFrom(pomFile, repo.cacheDir()) + .withRepositoryPath(repo.cacheDir()) + .withOffline(false) + .build() + ) + + dependencies.joinToString("\n") + } private fun getDependenciesFrom(pomPath: String, dir: File): String { val outputFile = File.createTempFile("tmp-pom", ".txt") @@ -201,6 +284,9 @@ class MassRepoIT { "-DoutputFile=${outputFile.canonicalPath}" ) + LOGGER.debug("Running: " + command.joinToString(" ")) + LOGGER.debug("Dir: " + dir) + val process = ProcessBuilder(*command.toTypedArray()) .directory(dir) .inheritIO() @@ -208,6 +294,9 @@ class MassRepoIT { process.waitFor() + if (! outputFile.exists()) + return "" + val result = outputFile.readText() outputFile.delete() From fb2adb842d95c8ae5ffa503ba7353f065ea337cc Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 16 Aug 2023 17:30:04 -0500 Subject: [PATCH 126/153] Generating Tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e3b181e54..6bbcbb4ed 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.18-SNAPSHOT + 0.0.18 POM Operator From 6d9f7c53d38bdbcac7a9fde8b3374ba9e98f6f7c Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 16 Aug 2023 17:30:33 -0500 Subject: [PATCH 127/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index dffa250df..30dcf0b32 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.github.pixee.maven.sample java-sample - 0.0.18-SNAPSHOT + 0.0.19-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index 6bbcbb4ed..35afdfca8 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.18 + 0.0.19-SNAPSHOT POM Operator From 9d8170816f0eb23d606338b02cf8203cd8223e41 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 16 Aug 2023 20:18:34 -0500 Subject: [PATCH 128/153] Handles missing newDependencyManagement (#27) --- .../pixee/maven/operator/CompositeDependencyManagement.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/io/github/pixee/maven/operator/CompositeDependencyManagement.kt b/src/main/java/io/github/pixee/maven/operator/CompositeDependencyManagement.kt index ae85cbdd7..aa712ca95 100644 --- a/src/main/java/io/github/pixee/maven/operator/CompositeDependencyManagement.kt +++ b/src/main/java/io/github/pixee/maven/operator/CompositeDependencyManagement.kt @@ -87,6 +87,8 @@ class CompositeDependencyManagement : AbstractCommand() { pomFileToModify.dirty = true } + + return dependencyNodes[0] as Element } else { val dependenciesNode: Element = if (null != parentElement.element("dependencies")) { From b7a93f18493a3e840009db3d1d78e02f71850b50 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 16 Aug 2023 20:19:09 -0500 Subject: [PATCH 129/153] Generating Tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 35afdfca8..637c4d29d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.19-SNAPSHOT + 0.0.19 POM Operator From 0af2762f78f41bd6f3d3f2223a0fc03d50a7fedb Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Wed, 16 Aug 2023 20:19:45 -0500 Subject: [PATCH 130/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index 30dcf0b32..38034e72f 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.github.pixee.maven.sample java-sample - 0.0.19-SNAPSHOT + 0.0.20-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index 637c4d29d..415eaad89 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.19 + 0.0.20-SNAPSHOT POM Operator From d8d9bb87aa71fd99f8366ac98aa94dc3e59e92e1 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Thu, 17 Aug 2023 16:16:52 -0500 Subject: [PATCH 131/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index 38034e72f..4e5191325 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.github.pixee.maven.sample java-sample - 0.0.20-SNAPSHOT + 0.0.21-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index 415eaad89..3f48dce00 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.20-SNAPSHOT + 0.0.21-SNAPSHOT POM Operator From fdf90b47e417efc82f9267b5dc43c566efc1c582 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Thu, 17 Aug 2023 16:33:35 -0500 Subject: [PATCH 132/153] Generating Tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3f48dce00..fe26244c3 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.21-SNAPSHOT + 0.0.20 POM Operator From 3a473e94193c72d6b98d960a6898dc65258814fc Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Thu, 17 Aug 2023 17:02:26 -0500 Subject: [PATCH 133/153] Generating development version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fe26244c3..3f48dce00 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.20 + 0.0.21-SNAPSHOT POM Operator From 2ff13e9b9830b20c443847fc7d6a219718b1c809 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 18 Aug 2023 08:27:33 -0500 Subject: [PATCH 134/153] Fully offline resolution (#28) * Fully offline resolution * cleanup * [no ci] Autogenerated JaCoCo coverage badge --------- Co-authored-by: Jacoco Coverage Update Action --- .github/badges/jacoco.svg | 2 +- src/main/java/io/github/pixee/maven/operator/Chain.kt | 2 +- src/main/java/io/github/pixee/maven/operator/POMScanner.kt | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index 99a5dd41d..d17718247 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage90.6% \ No newline at end of file +coverage90.5% \ No newline at end of file diff --git a/src/main/java/io/github/pixee/maven/operator/Chain.kt b/src/main/java/io/github/pixee/maven/operator/Chain.kt index eeb6ad2ca..67bd4124f 100644 --- a/src/main/java/io/github/pixee/maven/operator/Chain.kt +++ b/src/main/java/io/github/pixee/maven/operator/Chain.kt @@ -65,8 +65,8 @@ class Chain(vararg commands: Command) { */ val AVAILABLE_QUERY_COMMANDS = listOf( QueryType.SAFE to "QueryByResolver", - QueryType.SAFE to "QueryByEmbedder", QueryType.SAFE to "QueryByParsing", + QueryType.UNSAFE to "QueryByEmbedder", QueryType.UNSAFE to "QueryByInvoker", ) diff --git a/src/main/java/io/github/pixee/maven/operator/POMScanner.kt b/src/main/java/io/github/pixee/maven/operator/POMScanner.kt index 919cb30c0..6634f40fb 100644 --- a/src/main/java/io/github/pixee/maven/operator/POMScanner.kt +++ b/src/main/java/io/github/pixee/maven/operator/POMScanner.kt @@ -30,7 +30,8 @@ object POMScanner { .withParentPomFiles(parentPoms.map { POMDocumentFactory.load(it) }) } - private fun legacyScanFrom(originalFile: File, topLevelDirectory: File): ProjectModelFactory { + @JvmStatic + fun legacyScanFrom(originalFile: File, topLevelDirectory: File): ProjectModelFactory { val pomFile: POMDocument = POMDocumentFactory.load(originalFile) val parentPomFiles: MutableList = arrayListOf() From 2aec194177a483700f964aed428c7009b017c03e Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 18 Aug 2023 08:28:01 -0500 Subject: [PATCH 135/153] Generating Tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3f48dce00..10f5809fd 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.21-SNAPSHOT + 0.0.21 POM Operator From c37a43fe75093920fcdb7717d74a76d3ddb55203 Mon Sep 17 00:00:00 2001 From: Aldrin Leal Date: Fri, 18 Aug 2023 08:28:18 -0500 Subject: [PATCH 136/153] Generating development version --- java-sample/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java-sample/pom.xml b/java-sample/pom.xml index 4e5191325..4e1578f04 100644 --- a/java-sample/pom.xml +++ b/java-sample/pom.xml @@ -7,7 +7,7 @@ io.github.pixee.maven.sample java-sample - 0.0.21-SNAPSHOT + 0.0.22-SNAPSHOT UTF-8 diff --git a/pom.xml b/pom.xml index 10f5809fd..614d27bf3 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.pixee.maven pom-operator - 0.0.21 + 0.0.22-SNAPSHOT POM Operator From 21903d01d397b61ffbe321161093c110b81e35be Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Wed, 16 Aug 2023 08:47:02 -0700 Subject: [PATCH 137/153] :fire: delete license from pom-operator as it is now released under codemodder-java license --- pom-operator/LICENSE | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 pom-operator/LICENSE diff --git a/pom-operator/LICENSE b/pom-operator/LICENSE deleted file mode 100644 index efdccf088..000000000 --- a/pom-operator/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Pixee - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. From c2bb3afd3f076a78ed956ac8b821d16d159b2902 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Thu, 24 Aug 2023 15:40:36 -0700 Subject: [PATCH 138/153] :construction: Add basic gradle build file --- pom-operator/build.gradle.kts | 51 +++++++++++++++++++++++++++++++++++ settings.gradle.kts | 1 + 2 files changed, 52 insertions(+) create mode 100644 pom-operator/build.gradle.kts diff --git a/pom-operator/build.gradle.kts b/pom-operator/build.gradle.kts new file mode 100644 index 000000000..75408e397 --- /dev/null +++ b/pom-operator/build.gradle.kts @@ -0,0 +1,51 @@ +plugins { + id("io.codemodder.base") + id("io.codemodder.java-library") + id("io.codemodder.maven-publish") +} + +dependencies { + api("com.offbytwo:docopt:0.6.0.20150202") + api("org.apache.commons:commons-lang3:3.12.0") + api("org.dom4j:dom4j:2.1.3") + api("jaxen:jaxen:1.2.0") + api("xerces:xercesImpl:2.12.2") + api("org.xmlunit:xmlunit-core:2.9.0") + api("org.xmlunit:xmlunit-assertj3:2.9.0") + api("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10") + api("com.github.zafarkhaja:java-semver:0.9.0") + api("commons-io:commons-io:2.11.0") + api("org.apache.maven.shared:maven-invoker:3.2.0") + api("com.google.inject:guice:5.1.0") + api("org.apache.maven:maven-embedder:3.8.6") { + exclude(group = "com.google.inject", module = "guice") + } + api("org.apache.maven:maven-compat:3.8.6") { + exclude(group = "com.google.inject", module = "guice") + } + api("org.apache.maven.resolver:maven-resolver-api:1.9.2") + api("org.apache.maven.resolver:maven-resolver-spi:1.9.2") + api("org.apache.maven.resolver:maven-resolver-util:1.9.2") + api("org.apache.maven.resolver:maven-resolver-impl:1.9.2") + api("org.apache.maven.resolver:maven-resolver-transport-file:1.9.2") + api("org.apache.maven.resolver:maven-resolver-transport-http:1.9.2") + api("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.2") + api("org.apache.maven:maven-resolver-provider:3.8.6") + api("org.apache.maven:maven-model-builder:3.8.6") + api("com.github.albfernandez:juniversalchardet:2.4.0") + testImplementation("org.slf4j:slf4j-simple:2.0.0") + testImplementation("fun.mike:diff-match-patch:0.0.2") + testImplementation("io.github.java-diff-utils:java-diff-utils:4.12") + testImplementation("org.hamcrest:hamcrest-all:1.3") + testImplementation("junit:junit:4.13.2") + testImplementation("org.jetbrains.kotlin:kotlin-test-junit:1.7.10") + compileOnly("org.slf4j:slf4j-api:2.0.0") +} + +// tasks.withType() { +// options.encoding = "UTF-8" +// } +// +// tasks.withType() { +// options.encoding = "UTF-8" +// } diff --git a/settings.gradle.kts b/settings.gradle.kts index 29dee6ed2..75ff1a075 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -47,3 +47,4 @@ include("plugins:codemodder-plugin-llm") include("plugins:codemodder-plugin-maven") include("plugins:codemodder-plugin-pmd") include("plugins:codemodder-plugin-semgrep") +include("pom-operator") From 674247b259abce0b5b0ae01597514bb73890a757 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Thu, 24 Aug 2023 15:41:07 -0700 Subject: [PATCH 139/153] :art: format files according to new repo rules --- .../io/github/pixee/maven/operator/Dummy.java | 8 ++----- .../operator/test/POMOperatorJavaIT.java | 23 +++++++------------ 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/Dummy.java b/pom-operator/src/main/java/io/github/pixee/maven/operator/Dummy.java index 043d8542e..1fd7d7581 100644 --- a/pom-operator/src/main/java/io/github/pixee/maven/operator/Dummy.java +++ b/pom-operator/src/main/java/io/github/pixee/maven/operator/Dummy.java @@ -1,8 +1,4 @@ package io.github.pixee.maven.operator; -/** - * This dummy class is for Javadoc-generating purposes only - */ -public class Dummy { - -} \ No newline at end of file +/** This dummy class is for Javadoc-generating purposes only */ +public class Dummy {} diff --git a/pom-operator/src/test/java/io/github/pixee/maven/operator/test/POMOperatorJavaIT.java b/pom-operator/src/test/java/io/github/pixee/maven/operator/test/POMOperatorJavaIT.java index 93005133d..db8caef52 100644 --- a/pom-operator/src/test/java/io/github/pixee/maven/operator/test/POMOperatorJavaIT.java +++ b/pom-operator/src/test/java/io/github/pixee/maven/operator/test/POMOperatorJavaIT.java @@ -1,31 +1,24 @@ package io.github.pixee.maven.operator.test; -import org.apache.commons.lang3.SystemUtils; -import org.junit.Test; +import static org.junit.Assert.assertEquals; +import io.github.pixee.maven.operator.Util; import java.util.Arrays; import java.util.List; - -import io.github.pixee.maven.operator.Util; - -import static org.junit.Assert.assertEquals; +import org.apache.commons.lang3.SystemUtils; +import org.junit.Test; public class POMOperatorJavaIT { @Test public void testJavaSample() throws Exception { String mvnAbsPath = Util.INSTANCE.which$pom_operator("mvn").getAbsolutePath(); - List argList = Arrays.asList( - mvnAbsPath, - "-B", - "-N", - "-f", - "java-sample/pom.xml", - "verify" - ); + List argList = + Arrays.asList(mvnAbsPath, "-B", "-N", "-f", "java-sample/pom.xml", "verify"); if (SystemUtils.IS_OS_WINDOWS) { - List newArgList = Arrays.asList(Util.INSTANCE.which$pom_operator("cmd").getAbsolutePath(), "/c"); + List newArgList = + Arrays.asList(Util.INSTANCE.which$pom_operator("cmd").getAbsolutePath(), "/c"); newArgList.addAll(argList); From 9c53ca1a6bf68f9bfcc5e9b25c236d109ed10ffb Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Thu, 24 Aug 2023 15:44:36 -0700 Subject: [PATCH 140/153] :truck: move and format kotlin files --- .../io/github/pixee/maven/operator/AbstractCommand.kt | 0 .../io/github/pixee/maven/operator/AbstractQueryCommand.kt | 0 .../main/{java => kotlin}/io/github/pixee/maven/operator/Chain.kt | 0 .../io/github/pixee/maven/operator/CheckDependencyPresent.kt | 0 .../github/pixee/maven/operator/CheckLocalRepositoryDirCommand.kt | 0 .../io/github/pixee/maven/operator/CheckParentPackaging.kt | 0 .../{java => kotlin}/io/github/pixee/maven/operator/Command.kt | 0 .../github/pixee/maven/operator/CompositeDependencyManagement.kt | 0 .../{java => kotlin}/io/github/pixee/maven/operator/Dependency.kt | 0 .../io/github/pixee/maven/operator/DiscardFormatCommand.kt | 0 .../io/github/pixee/maven/operator/EmbedderFacade.kt | 0 .../io/github/pixee/maven/operator/FormatCommand.kt | 0 .../io/github/pixee/maven/operator/InvalidContextException.kt | 0 .../io/github/pixee/maven/operator/InvalidPathException.kt | 0 .../io/github/pixee/maven/operator/MissingDependencyException.kt | 0 .../io/github/pixee/maven/operator/POMDocument.kt | 0 .../io/github/pixee/maven/operator/POMDocumentFactory.kt | 0 .../io/github/pixee/maven/operator/POMOperator.kt | 0 .../{java => kotlin}/io/github/pixee/maven/operator/POMScanner.kt | 0 .../io/github/pixee/maven/operator/ProjectModel.kt | 0 .../io/github/pixee/maven/operator/ProjectModelFactory.kt | 0 .../io/github/pixee/maven/operator/QueryByEmbedder.kt | 0 .../io/github/pixee/maven/operator/QueryByInvoker.kt | 0 .../io/github/pixee/maven/operator/QueryByParsing.kt | 0 .../io/github/pixee/maven/operator/QueryByResolver.kt | 0 .../{java => kotlin}/io/github/pixee/maven/operator/QueryType.kt | 0 .../io/github/pixee/maven/operator/SimpleDependencyManagement.kt | 0 .../io/github/pixee/maven/operator/SimpleInsert.kt | 0 .../io/github/pixee/maven/operator/SimpleUpgrade.kt | 0 .../io/github/pixee/maven/operator/SupportCommand.kt | 0 .../main/{java => kotlin}/io/github/pixee/maven/operator/Util.kt | 0 .../github/pixee/maven/operator/WrongDependencyTypeException.kt | 0 32 files changed, 0 insertions(+), 0 deletions(-) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/AbstractCommand.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/AbstractQueryCommand.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/Chain.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/CheckDependencyPresent.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/CheckLocalRepositoryDirCommand.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/CheckParentPackaging.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/Command.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/CompositeDependencyManagement.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/Dependency.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/DiscardFormatCommand.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/EmbedderFacade.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/FormatCommand.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/InvalidContextException.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/InvalidPathException.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/MissingDependencyException.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/POMDocument.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/POMDocumentFactory.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/POMOperator.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/POMScanner.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/ProjectModel.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/ProjectModelFactory.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/QueryByEmbedder.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/QueryByInvoker.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/QueryByParsing.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/QueryByResolver.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/QueryType.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/SimpleDependencyManagement.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/SimpleInsert.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/SimpleUpgrade.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/SupportCommand.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/Util.kt (100%) rename pom-operator/src/main/{java => kotlin}/io/github/pixee/maven/operator/WrongDependencyTypeException.kt (100%) diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/AbstractCommand.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/AbstractCommand.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/AbstractCommand.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/AbstractCommand.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/AbstractQueryCommand.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/AbstractQueryCommand.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/AbstractQueryCommand.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/AbstractQueryCommand.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/Chain.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/Chain.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/Chain.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/Chain.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/CheckDependencyPresent.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/CheckDependencyPresent.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/CheckDependencyPresent.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/CheckDependencyPresent.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/CheckLocalRepositoryDirCommand.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/CheckLocalRepositoryDirCommand.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/CheckLocalRepositoryDirCommand.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/CheckLocalRepositoryDirCommand.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/CheckParentPackaging.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/CheckParentPackaging.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/CheckParentPackaging.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/CheckParentPackaging.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/Command.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/Command.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/Command.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/Command.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/CompositeDependencyManagement.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/CompositeDependencyManagement.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/CompositeDependencyManagement.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/CompositeDependencyManagement.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/Dependency.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/Dependency.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/Dependency.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/Dependency.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/DiscardFormatCommand.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/DiscardFormatCommand.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/DiscardFormatCommand.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/DiscardFormatCommand.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/EmbedderFacade.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/EmbedderFacade.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/EmbedderFacade.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/EmbedderFacade.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/FormatCommand.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/FormatCommand.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/FormatCommand.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/FormatCommand.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/InvalidContextException.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/InvalidContextException.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/InvalidContextException.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/InvalidContextException.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/InvalidPathException.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/InvalidPathException.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/InvalidPathException.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/InvalidPathException.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/MissingDependencyException.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/MissingDependencyException.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/MissingDependencyException.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/MissingDependencyException.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/POMDocument.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/POMDocument.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/POMDocument.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/POMDocument.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/POMDocumentFactory.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/POMDocumentFactory.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/POMDocumentFactory.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/POMDocumentFactory.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/POMOperator.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/POMOperator.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/POMOperator.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/POMOperator.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/POMScanner.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/POMScanner.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/POMScanner.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/POMScanner.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/ProjectModel.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/ProjectModel.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/ProjectModel.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/ProjectModelFactory.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/ProjectModelFactory.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/ProjectModelFactory.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/ProjectModelFactory.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/QueryByEmbedder.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/QueryByEmbedder.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/QueryByEmbedder.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/QueryByEmbedder.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/QueryByInvoker.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/QueryByInvoker.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/QueryByInvoker.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/QueryByInvoker.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/QueryByParsing.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/QueryByParsing.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/QueryByParsing.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/QueryByParsing.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/QueryByResolver.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/QueryByResolver.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/QueryByResolver.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/QueryType.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/QueryType.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/QueryType.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/QueryType.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/SimpleDependencyManagement.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/SimpleDependencyManagement.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/SimpleDependencyManagement.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/SimpleDependencyManagement.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/SimpleInsert.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/SimpleInsert.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/SimpleInsert.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/SimpleInsert.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/SimpleUpgrade.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/SimpleUpgrade.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/SimpleUpgrade.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/SimpleUpgrade.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/SupportCommand.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/SupportCommand.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/SupportCommand.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/SupportCommand.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/Util.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/Util.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/Util.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/Util.kt diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/WrongDependencyTypeException.kt b/pom-operator/src/main/kotlin/io/github/pixee/maven/operator/WrongDependencyTypeException.kt similarity index 100% rename from pom-operator/src/main/java/io/github/pixee/maven/operator/WrongDependencyTypeException.kt rename to pom-operator/src/main/kotlin/io/github/pixee/maven/operator/WrongDependencyTypeException.kt From d3410b7bf4613702fad473b318836e306acd7ca8 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Wed, 16 Aug 2023 09:19:59 -0700 Subject: [PATCH 141/153] :truck: move kotlin test files to kotlin dir, add required kotlin test dependencies --- pom-operator/build.gradle.kts | 12 +++--------- .../pixee/maven/operator/test/AbstractTestBase.kt | 0 .../github/pixee/maven/operator/test/MassRepoTest.kt | 0 .../maven/operator/test/POMOperatorMultipomTest.kt | 0 .../maven/operator/test/POMOperatorQueryTest.kt | 0 .../pixee/maven/operator/test/POMOperatorTest.kt | 0 .../pixee/maven/operator/test/POMScannerTest.kt | 0 .../maven/operator/test/PropertyResolutionTest.kt | 0 .../io/github/pixee/maven/operator/test/util.kt | 0 9 files changed, 3 insertions(+), 9 deletions(-) rename pom-operator/src/test/{java => kotlin}/io/github/pixee/maven/operator/test/AbstractTestBase.kt (100%) rename pom-operator/src/test/{java => kotlin}/io/github/pixee/maven/operator/test/MassRepoTest.kt (100%) rename pom-operator/src/test/{java => kotlin}/io/github/pixee/maven/operator/test/POMOperatorMultipomTest.kt (100%) rename pom-operator/src/test/{java => kotlin}/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt (100%) rename pom-operator/src/test/{java => kotlin}/io/github/pixee/maven/operator/test/POMOperatorTest.kt (100%) rename pom-operator/src/test/{java => kotlin}/io/github/pixee/maven/operator/test/POMScannerTest.kt (100%) rename pom-operator/src/test/{java => kotlin}/io/github/pixee/maven/operator/test/PropertyResolutionTest.kt (100%) rename pom-operator/src/test/{java => kotlin}/io/github/pixee/maven/operator/test/util.kt (100%) diff --git a/pom-operator/build.gradle.kts b/pom-operator/build.gradle.kts index 75408e397..61af52a6c 100644 --- a/pom-operator/build.gradle.kts +++ b/pom-operator/build.gradle.kts @@ -38,14 +38,8 @@ dependencies { testImplementation("io.github.java-diff-utils:java-diff-utils:4.12") testImplementation("org.hamcrest:hamcrest-all:1.3") testImplementation("junit:junit:4.13.2") - testImplementation("org.jetbrains.kotlin:kotlin-test-junit:1.7.10") compileOnly("org.slf4j:slf4j-api:2.0.0") + testImplementation("org.jetbrains.kotlin:kotlin-test-junit5") + testImplementation("org.junit.jupiter:junit-jupiter-engine:5.9.2") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") } - -// tasks.withType() { -// options.encoding = "UTF-8" -// } -// -// tasks.withType() { -// options.encoding = "UTF-8" -// } diff --git a/pom-operator/src/test/java/io/github/pixee/maven/operator/test/AbstractTestBase.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/AbstractTestBase.kt similarity index 100% rename from pom-operator/src/test/java/io/github/pixee/maven/operator/test/AbstractTestBase.kt rename to pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/AbstractTestBase.kt diff --git a/pom-operator/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/MassRepoTest.kt similarity index 100% rename from pom-operator/src/test/java/io/github/pixee/maven/operator/test/MassRepoTest.kt rename to pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/MassRepoTest.kt diff --git a/pom-operator/src/test/java/io/github/pixee/maven/operator/test/POMOperatorMultipomTest.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorMultipomTest.kt similarity index 100% rename from pom-operator/src/test/java/io/github/pixee/maven/operator/test/POMOperatorMultipomTest.kt rename to pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorMultipomTest.kt diff --git a/pom-operator/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt similarity index 100% rename from pom-operator/src/test/java/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt rename to pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt diff --git a/pom-operator/src/test/java/io/github/pixee/maven/operator/test/POMOperatorTest.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorTest.kt similarity index 100% rename from pom-operator/src/test/java/io/github/pixee/maven/operator/test/POMOperatorTest.kt rename to pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorTest.kt diff --git a/pom-operator/src/test/java/io/github/pixee/maven/operator/test/POMScannerTest.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMScannerTest.kt similarity index 100% rename from pom-operator/src/test/java/io/github/pixee/maven/operator/test/POMScannerTest.kt rename to pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMScannerTest.kt diff --git a/pom-operator/src/test/java/io/github/pixee/maven/operator/test/PropertyResolutionTest.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/PropertyResolutionTest.kt similarity index 100% rename from pom-operator/src/test/java/io/github/pixee/maven/operator/test/PropertyResolutionTest.kt rename to pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/PropertyResolutionTest.kt diff --git a/pom-operator/src/test/java/io/github/pixee/maven/operator/test/util.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/util.kt similarity index 100% rename from pom-operator/src/test/java/io/github/pixee/maven/operator/test/util.kt rename to pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/util.kt From ddf1bd295a9f0fe2f9342e3b678279bc18027447 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Wed, 16 Aug 2023 10:22:20 -0700 Subject: [PATCH 142/153] Fix test suite for Gradle --- pom-operator/build.gradle.kts | 2 +- .../operator/test/POMOperatorJavaIT.java | 6 +-- .../maven/operator/test/AbstractTestBase.kt | 6 +-- .../pixee/maven/operator/test/MassRepoTest.kt | 19 ++++---- .../operator/test/POMOperatorMultipomTest.kt | 7 +-- .../operator/test/POMOperatorQueryTest.kt | 43 ++++++++++--------- .../maven/operator/test/POMOperatorTest.kt | 19 ++++---- .../maven/operator/test/POMScannerTest.kt | 7 +-- .../operator/test/PropertyResolutionTest.kt | 24 +++++------ .../github/pixee/maven/operator/test/util.kt | 4 +- 10 files changed, 73 insertions(+), 64 deletions(-) diff --git a/pom-operator/build.gradle.kts b/pom-operator/build.gradle.kts index 61af52a6c..1903b55f1 100644 --- a/pom-operator/build.gradle.kts +++ b/pom-operator/build.gradle.kts @@ -37,7 +37,7 @@ dependencies { testImplementation("fun.mike:diff-match-patch:0.0.2") testImplementation("io.github.java-diff-utils:java-diff-utils:4.12") testImplementation("org.hamcrest:hamcrest-all:1.3") - testImplementation("junit:junit:4.13.2") + testImplementation(testlibs.bundles.junit.jupiter) compileOnly("org.slf4j:slf4j-api:2.0.0") testImplementation("org.jetbrains.kotlin:kotlin-test-junit5") testImplementation("org.junit.jupiter:junit-jupiter-engine:5.9.2") diff --git a/pom-operator/src/test/java/io/github/pixee/maven/operator/test/POMOperatorJavaIT.java b/pom-operator/src/test/java/io/github/pixee/maven/operator/test/POMOperatorJavaIT.java index db8caef52..582f21ee4 100644 --- a/pom-operator/src/test/java/io/github/pixee/maven/operator/test/POMOperatorJavaIT.java +++ b/pom-operator/src/test/java/io/github/pixee/maven/operator/test/POMOperatorJavaIT.java @@ -1,12 +1,12 @@ package io.github.pixee.maven.operator.test; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import io.github.pixee.maven.operator.Util; import java.util.Arrays; import java.util.List; import org.apache.commons.lang3.SystemUtils; -import org.junit.Test; +import org.junit.jupiter.api.Test; public class POMOperatorJavaIT { @Test @@ -35,6 +35,6 @@ public void testJavaSample() throws Exception { int retCode = process.waitFor(); - assertEquals("Embedded execution must return zero", 0, retCode); + assertEquals(0, retCode, "Embedded execution must return zero"); } } diff --git a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/AbstractTestBase.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/AbstractTestBase.kt index e95761867..9424d3e6b 100644 --- a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/AbstractTestBase.kt +++ b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/AbstractTestBase.kt @@ -6,7 +6,7 @@ import io.github.pixee.maven.operator.ProjectModel import io.github.pixee.maven.operator.ProjectModelFactory import org.dom4j.Document import org.dom4j.io.SAXReader -import org.junit.Assert.assertFalse +import org.junit.jupiter.api.Assertions.assertFalse import org.slf4j.Logger import org.slf4j.LoggerFactory import org.xmlunit.builder.DiffBuilder @@ -57,8 +57,8 @@ open class AbstractTestBase { LOGGER.debug("context after: {}", context) assertFalse( - "Expected and outcome have differences", - getXmlDifferences(context.pomFile.resultPom, outcome).hasDifferences() + getXmlDifferences(context.pomFile.resultPom, outcome).hasDifferences(), + "Expected and outcome have differences" ) } else { val resultFilePath = "src/test/resources/" + this.javaClass.`package`.name.replace( diff --git a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/MassRepoTest.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/MassRepoTest.kt index 25e2effc6..7d3c41802 100644 --- a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/MassRepoTest.kt +++ b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/MassRepoTest.kt @@ -6,8 +6,9 @@ import io.github.pixee.maven.operator.POMScanner import io.github.pixee.maven.operator.ProjectModelFactory import io.github.pixee.maven.operator.Util.which import org.apache.commons.lang3.SystemUtils -import org.junit.Assert.* -import org.junit.Test +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test import org.slf4j.Logger import org.slf4j.LoggerFactory import java.io.File @@ -235,14 +236,16 @@ class MassRepoIT { val dependencyAsStringWithPackaging = dependencyToUpgrade.toString() assertFalse( - "Dependency should be originally missing", originalDependencies.contains( - dependencyAsStringWithPackaging - ) + originalDependencies.contains( + dependencyAsStringWithPackaging + ), + "Dependency should be originally missing" ) assertTrue( - "New Dependency should be appearing", finalDependencies.contains( - dependencyAsStringWithPackaging - ) + finalDependencies.contains( + dependencyAsStringWithPackaging + ), + "New Dependency should be appearing" ) } } diff --git a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorMultipomTest.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorMultipomTest.kt index 4ae17b0d0..d48a51e94 100644 --- a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorMultipomTest.kt +++ b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorMultipomTest.kt @@ -2,14 +2,15 @@ package io.github.pixee.maven.operator.test import com.google.common.io.Files import io.github.pixee.maven.operator.* -import org.junit.Test +import org.junit.jupiter.api.Test import java.io.File import kotlin.test.assertFalse import kotlin.test.assertTrue class POMOperatorMultipomTest : AbstractTestBase() { - @Test(expected = WrongDependencyTypeException::class) + @Test fun testWithParentAndChildMissingPackaging() { + // expected = WrongDependencyTypeException::class val parentResource = getResource("parent-and-child-parent-broken.xml") val parentPomFiles = listOf(POMDocumentFactory.load(parentResource)) @@ -24,7 +25,7 @@ class POMOperatorMultipomTest : AbstractTestBase() { ) } - @Test(expected = WrongDependencyTypeException::class) + @Test fun testWithParentAndChildWrongType() { val parentResource = getResource("parent-and-child-child-broken.xml") diff --git a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt index e332ee394..9b218b9ac 100644 --- a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt +++ b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt @@ -1,8 +1,8 @@ package io.github.pixee.maven.operator.test import io.github.pixee.maven.operator.* -import junit.framework.TestCase.* -import org.junit.Test +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test import org.slf4j.Logger import org.slf4j.LoggerFactory import java.io.File @@ -26,7 +26,7 @@ class POMOperatorQueryTest { LOGGER.debug("Dependencies found: {}", dependencies) - assertTrue("Dependencies are not empty", dependencies.isNotEmpty()) + assertTrue(dependencies.isNotEmpty(), "Dependencies are not empty") } } @@ -40,11 +40,12 @@ class POMOperatorQueryTest { val dependencies = POMOperator.queryDependency(context) - assertTrue("Dependencies are empty", dependencies.isEmpty()) + assertTrue(dependencies.isEmpty(), "Dependencies are empty") } - @Test(expected = IllegalStateException::class) + @Test fun testFailedUnsafeQuery() { + // expected = IllegalStateException::class val context = ProjectModelFactory .load(this.javaClass.getResource("pom-broken.xml")!!) @@ -53,7 +54,7 @@ class POMOperatorQueryTest { val dependencies = POMOperator.queryDependency(context) - assertTrue("Dependencies are empty", dependencies.isEmpty()) + assertTrue(dependencies.isEmpty(), "Dependencies are empty") } @Test @@ -74,7 +75,7 @@ class POMOperatorQueryTest { val dependencies = POMOperator.queryDependency(context, commandList = commandListOverride) - assertTrue("Dependencies are not empty", dependencies.isNotEmpty()) + assertTrue(dependencies.isNotEmpty(), "Dependencies are not empty") } } } @@ -87,11 +88,11 @@ class POMOperatorQueryTest { LOGGER.info("Using queryType: $queryType at $tempDirectory") - assertFalse("Temp Directory does not exist initially", tempDirectory.exists()) + assertFalse(tempDirectory.exists(), "Temp Directory does not exist initially") assertEquals( - "There must be no files", tempDirectory.list()?.filter { File(it).isDirectory }?.size ?: 0, 0, + "There must be no files" ) val context = @@ -105,10 +106,10 @@ class POMOperatorQueryTest { LOGGER.debug("Dependencies found: {}", dependencies) - assertTrue("Dependencies are not empty", dependencies.isNotEmpty()) + assertTrue(dependencies.isNotEmpty(), "Dependencies are not empty") - assertTrue("Temp Directory ends up existing", tempDirectory.exists()) - assertTrue("Temp Directory is a directory", tempDirectory.isDirectory) + assertTrue(tempDirectory.exists(), "Temp Directory ends up existing") + assertTrue(tempDirectory.isDirectory, "Temp Directory is a directory") } } @@ -130,7 +131,7 @@ class POMOperatorQueryTest { LOGGER.debug("Dependencies found: {}", dependencies) - assertTrue("Dependencies are not empty", dependencies.isNotEmpty()) + assertTrue(dependencies.isNotEmpty(), "Dependencies are not empty") } } @@ -179,9 +180,9 @@ class POMOperatorQueryTest { LOGGER.debug("Dependencies found: {}", dependencies) - assertTrue("Dependencies are not empty", dependencies.isNotEmpty()) + assertTrue(dependencies.isNotEmpty(), "Dependencies are not empty") - assertTrue("Random name matches", dependencies.first().artifactId.equals(randomName)) + assertTrue(dependencies.first().artifactId.equals(randomName), "Random name matches") } @Test @@ -268,9 +269,9 @@ class POMOperatorQueryTest { LOGGER.debug("Dependencies found: {}", dependencies) - assertTrue("Dependencies are not empty", dependencies.isNotEmpty()) + assertTrue(dependencies.isNotEmpty(), "Dependencies are not empty") - assertTrue("Random name matches", dependencies.first().artifactId.equals(randomName)) + assertTrue(dependencies.first().artifactId.equals(randomName), "Random name matches") } @Test @@ -332,7 +333,7 @@ class POMOperatorQueryTest { LOGGER.debug("Dependencies found: {}", dependencies) - assertTrue("Dependencies are empty", dependencies.isEmpty()) + assertTrue(dependencies.isEmpty(), "Dependencies are empty") } @Test @@ -402,12 +403,12 @@ class POMOperatorQueryTest { LOGGER.debug("Dependencies found: {}", dependencies) - assertTrue("Dependencies are empty", dependencies.isNotEmpty()) + assertTrue(dependencies.isNotEmpty(), "Dependencies are empty") val foundDependencies = dependencies.firstOrNull { it.version == "0.0.1" && it.artifactId.equals("managed-$randomName") } - assertTrue("there's a dependencyManaged-version", foundDependencies != null) + assertTrue(foundDependencies != null, "there's a dependencyManaged-version") } private fun getCommandListFor(vararg names: String): List = @@ -436,7 +437,7 @@ class POMOperatorQueryTest { LOGGER.debug("Dependencies found: {}", dependencies) - assertTrue("Dependencies are empty", dependencies.isEmpty()) + assertTrue(dependencies.isEmpty(), "Dependencies are empty") } } diff --git a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorTest.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorTest.kt index 84eedab54..c08aa5468 100644 --- a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorTest.kt +++ b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorTest.kt @@ -7,8 +7,8 @@ import io.github.pixee.maven.operator.Util.which import org.apache.commons.lang3.SystemUtils import org.dom4j.DocumentException import org.hamcrest.MatcherAssert.assertThat -import org.junit.Assert.assertEquals -import org.junit.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test import org.xmlunit.diff.ComparisonType import java.io.File import java.nio.charset.Charset @@ -19,8 +19,9 @@ import kotlin.test.assertTrue * Unit test for simple App. */ class POMOperatorTest : AbstractTestBase() { - @Test(expected = DocumentException::class) + @Test fun testWithBrokenPom() { + // expected = DocumentException::class gwt( "broken-pom", ProjectModelFactory.load( @@ -76,8 +77,9 @@ class POMOperatorTest : AbstractTestBase() { ) } - @Test(expected = MissingDependencyException::class) + @Test fun testWithDependencyMissing() { + // expected = MissingDependencyException::class gwt( "case-dependency-missing", ProjectModelFactory.load( @@ -318,14 +320,15 @@ class POMOperatorTest : AbstractTestBase() { ) assertEquals( - "Document changes a property called 'sample.version'", - differenceList.first().comparison.testDetails.xPath, - "/project[1]/properties[1]/sample.version[1]/text()[1]" + differenceList.first().comparison.testDetails.xPath, + "/project[1]/properties[1]/sample.version[1]/text()[1]", + "Document changes a property called 'sample.version'" ) } - @Test(expected = IllegalStateException::class) + @Test fun testCaseWithPropertyDefinedTwice() { + // expected = IllegalStateException::class val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "1.0.0") diff --git a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMScannerTest.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMScannerTest.kt index dad872ca2..23e9de9af 100644 --- a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMScannerTest.kt +++ b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMScannerTest.kt @@ -2,7 +2,7 @@ package io.github.pixee.maven.operator.test import io.github.pixee.maven.operator.InvalidPathException import io.github.pixee.maven.operator.POMScanner -import org.junit.Test +import org.junit.jupiter.api.Test import java.io.File import kotlin.test.assertTrue import kotlin.test.fail @@ -17,8 +17,9 @@ class POMScannerTest: AbstractTestBase() { val pmf = POMScanner.scanFrom(pomFile, currentDirectory) } - @Test(expected = InvalidPathException::class) + @Test fun testTwoLevelsWithLoop() { + // expected = InvalidPathException::class val pomFile = getResourceAsFile("sample-child-with-relativepath-and-two-levels.xml") val pmf = POMScanner.scanFrom(pomFile, currentDirectory) @@ -102,4 +103,4 @@ class POMScannerTest: AbstractTestBase() { } } } -} \ No newline at end of file +} diff --git a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/PropertyResolutionTest.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/PropertyResolutionTest.kt index a401b301d..2f7cc96ec 100644 --- a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/PropertyResolutionTest.kt +++ b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/PropertyResolutionTest.kt @@ -2,10 +2,10 @@ package io.github.pixee.maven.operator.test import io.github.pixee.maven.operator.Dependency import io.github.pixee.maven.operator.ProjectModelFactory -import junit.framework.TestCase.assertEquals -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue -import org.junit.Test +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -14,22 +14,22 @@ class PropertyResolutionTest { fun testPropertyResolutionWhenProfileIsDeactivatedForcefully() { val resolvedProperties = resolveWithProfiles("!test-profile") - assertFalse("foo property must not be there", resolvedProperties.contains("foo")) + Assertions.assertFalse(resolvedProperties.contains("foo"), "foo property must not be there") } @Test fun testPropertyResolutionWhenProfileIsMissing() { val resolvedProperties = resolveWithProfiles() - assertFalse("foo property must not be there", resolvedProperties.contains("foo")) + Assertions.assertFalse(resolvedProperties.contains("foo"), "foo property must not be there") } @Test fun testPropertyResolutionWhenProfileIsActivated() { val resolvedProperties = resolveWithProfiles("test-profile") - assertTrue("foo property must be there", resolvedProperties.contains("foo")) - assertEquals("foo property must be equal to 'bar'", resolvedProperties["foo"], "bar") + assertTrue(resolvedProperties.contains("foo"), "foo property must be there") + assertEquals(resolvedProperties["foo"], "bar", "foo property must be equal to 'bar'") } private fun resolveWithProfiles(vararg profilesToUse: String): Map { @@ -37,9 +37,9 @@ class PropertyResolutionTest { val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "2.0.2") val context = - ProjectModelFactory.load( - POMOperatorTest::class.java.getResource("pom-1.xml")!!, - ).withDependency(dependencyToUpgrade).withActiveProfiles(*profilesToUse).build() + ProjectModelFactory.load( + POMOperatorTest::class.java.getResource("pom-1.xml")!!, + ).withDependency(dependencyToUpgrade).withActiveProfiles(*profilesToUse).build() LOGGER.debug("Resolved Properties: {}", context.resolvedProperties) @@ -49,4 +49,4 @@ class PropertyResolutionTest { companion object { private val LOGGER: Logger = LoggerFactory.getLogger(POMOperatorTest::class.java) } -} \ No newline at end of file +} diff --git a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/util.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/util.kt index 73a02680e..43669f4f6 100644 --- a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/util.kt +++ b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/util.kt @@ -15,7 +15,7 @@ internal fun ProjectModel.getRuntimeResolvedProperties(): Map = it.name to it.text } -internal fun ProjectModel.getEffectivePom(): Document { +fun ProjectModel.getEffectivePom(): Document { val tmpInputFile = File.createTempFile("tmp-pom-orig", ".xml") tmpInputFile.writeBytes(this.pomFile.resultPomBytes) @@ -60,4 +60,4 @@ internal fun ProjectModel.getEffectivePom(): Document { throw IllegalStateException("Unexpected return code from maven: $retCode") return SAXReader().read(FileInputStream(tmpOutputFile)) -} \ No newline at end of file +} From c4d04651f23ea8a37d5c0f35615d52a2fae8b1e3 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Thu, 24 Aug 2023 15:53:32 -0700 Subject: [PATCH 143/153] :fire: delete pom xml --- pom-operator/pom.xml | 515 ------------------------------------------- 1 file changed, 515 deletions(-) delete mode 100644 pom-operator/pom.xml diff --git a/pom-operator/pom.xml b/pom-operator/pom.xml deleted file mode 100644 index 614d27bf3..000000000 --- a/pom-operator/pom.xml +++ /dev/null @@ -1,515 +0,0 @@ - - - 4.0.0 - - io.github.pixee.maven - pom-operator - 0.0.22-SNAPSHOT - - POM Operator - - A Library for Parsing and Modifying POMS - - https://github.com/pixee/pom-operator - - - scm:git:git://github.com/pixee/pom-operator.git - scm:git:ssh://github.com:pixee/pom-operator.git - https://github.com/pixee/pom-operator/tree/master - HEAD - - - - - - MIT License - http://www.opensource.org/licenses/mit-license.php - - - - - - ossrh - https://s01.oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ - - - - - - Aldrin Leal - pixee - https://pixee.ai/ - - - - - UTF-8 - 1.8 - 1.8 - 1.7.10 - 2.0.0 - 2.5.3 - 1.9.2 - 3.8.6 - 2.9.1 - 1.6.13 - 2.2.1 - 3.0.1 - - - - - com.offbytwo - docopt - 0.6.0.20150202 - - - org.apache.commons - commons-lang3 - 3.12.0 - - - org.dom4j - dom4j - 2.1.3 - - - jaxen - jaxen - 1.2.0 - - - org.slf4j - slf4j-api - ${slf4j.version} - provided - - - org.slf4j - slf4j-simple - ${slf4j.version} - test - - - xerces - xercesImpl - 2.12.2 - - - fun.mike - diff-match-patch - 0.0.2 - test - - - io.github.java-diff-utils - java-diff-utils - 4.12 - test - - - org.xmlunit - xmlunit-core - 2.9.0 - compile - - - org.xmlunit - xmlunit-assertj3 - 2.9.0 - compile - - - org.hamcrest - hamcrest-all - 1.3 - test - - - junit - junit - 4.13.2 - test - - - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - ${kotlin.version} - - - org.jetbrains.kotlin - kotlin-test-junit - ${kotlin.version} - test - - - com.github.zafarkhaja - java-semver - 0.9.0 - - - - commons-io - commons-io - 2.11.0 - - - org.apache.maven.shared - maven-invoker - 3.2.0 - compile - - - com.google.inject - guice - 5.1.0 - - - org.apache.maven - maven-embedder - ${versions.maven.core} - compile - - - com.google.inject - guice - - - - - org.apache.maven - maven-compat - ${versions.maven.core} - compile - - - org.apache.maven.resolver - maven-resolver-api - ${versions.maven.resolver} - - - org.apache.maven.resolver - maven-resolver-spi - ${versions.maven.resolver} - - - org.apache.maven.resolver - maven-resolver-util - ${versions.maven.resolver} - - - org.apache.maven.resolver - maven-resolver-impl - ${versions.maven.resolver} - - - org.apache.maven.resolver - maven-resolver-transport-file - ${versions.maven.resolver} - - - org.apache.maven.resolver - maven-resolver-transport-http - ${versions.maven.resolver} - - - org.apache.maven.resolver - maven-resolver-connector-basic - ${versions.maven.resolver} - - - org.apache.maven - maven-resolver-provider - ${versions.maven.core} - - - org.apache.maven - maven-model-builder - ${versions.maven.core} - - - com.github.albfernandez - juniversalchardet - 2.4.0 - - - - - - - - maven-clean-plugin - 3.1.0 - - - - maven-resources-plugin - 3.0.2 - - - maven-compiler-plugin - 3.8.0 - - - maven-surefire-plugin - 2.22.1 - - - maven-jar-plugin - 3.0.2 - - - maven-install-plugin - 2.5.2 - - - maven-deploy-plugin - 2.8.2 - - - - maven-site-plugin - 3.7.1 - - - maven-project-info-reports-plugin - 3.0.0 - - - org.jacoco - jacoco-maven-plugin - 0.8.7 - - - - prepare-agent - - - - generate-code-coverage-report - test - - report - - - - - - org.jetbrains.kotlin - kotlin-maven-plugin - ${kotlin.version} - - - compile - compile - - compile - - - - test-compile - test-compile - - test-compile - - - - - 1.8 - - - - org.codehaus.mojo - versions-maven-plugin - 2.14.2 - - false - true - true - false - - - - org.apache.maven.plugins - maven-gpg-plugin - ${versions.maven-gpg-plugin} - - - org.apache.maven.plugins - maven-source-plugin - ${versions.maven-source-plugin} - - - attach-sources - - jar-no-fork - - - - - - org.sonatype.plugins - nexus-staging-maven-plugin - ${versions.nexus-staging-maven-plugin} - true - - ossrh - https://s01.oss.sonatype.org/ - true - - true - - - - org.apache.maven.plugins - maven-javadoc-plugin - ${versions.maven-javadoc-plugin} - - - - javadoc - jar - test-javadoc - test-jar - - package - - - - - - - - org.jetbrains.kotlin - kotlin-maven-plugin - - - - org.codehaus.mojo - versions-maven-plugin - - - org.apache.maven.plugins - maven-compiler-plugin - - - compile - compile - - compile - - - - testCompile - test-compile - - testCompile - - - - - - org.apache.maven.plugins - maven-source-plugin - - - org.sonatype.plugins - nexus-staging-maven-plugin - - - org.jacoco - jacoco-maven-plugin - - - org.apache.maven.plugins - maven-javadoc-plugin - - - - javadoc - jar - test-javadoc - test-jar - - package - - - - - - - - - integration-testing - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - - org.apache.maven.plugins - maven-failsafe-plugin - 3.0.0-M7 - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - true - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - - integration-test - verify - - - - - - - - - release - - - - org.apache.maven.plugins - maven-gpg-plugin - - - sign-artifacts - verify - - sign - - - - --pinentry-mode - loopback - - - - - - - - - - From c734a7afadeb4a0535244db47c93a6aad015bca8 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Thu, 24 Aug 2023 15:53:53 -0700 Subject: [PATCH 144/153] :heavy_plus_sign: apply kotlin plugin --- pom-operator/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/pom-operator/build.gradle.kts b/pom-operator/build.gradle.kts index 1903b55f1..4cb15a09e 100644 --- a/pom-operator/build.gradle.kts +++ b/pom-operator/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("io.codemodder.base") id("io.codemodder.java-library") id("io.codemodder.maven-publish") + id("org.jetbrains.kotlin.jvm") version "1.8.20" } dependencies { From b6e08f7fa60fa7b37fcaf546fb83d41bf858def3 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Thu, 24 Aug 2023 15:56:42 -0700 Subject: [PATCH 145/153] :bug: fix order of assertTrue usage --- .../kotlin/io/github/pixee/maven/operator/test/MassRepoTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/MassRepoTest.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/MassRepoTest.kt index 7d3c41802..a0d42ccac 100644 --- a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/MassRepoTest.kt +++ b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/MassRepoTest.kt @@ -231,7 +231,7 @@ class MassRepoIT { val queryFailed = "" == originalDependencies && "" == finalDependencies if (queryFailed) { - assertTrue("Must be modified even when query failed", result) + assertTrue(result, "Must be modified even when query failed") } else { val dependencyAsStringWithPackaging = dependencyToUpgrade.toString() From da423ba1a6e0fd1271d4be8d37a841bdb708ce88 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Thu, 24 Aug 2023 16:41:28 -0700 Subject: [PATCH 146/153] :sparkles: setup maven for CI --- .github/workflows/checks.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 81afd7b7a..2ef138579 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -22,6 +22,14 @@ jobs: with: distribution: 'temurin' java-version: '17' + cache: maven + server-id: pixee + server-username: ORG_GRADLE_PROJECT_pixeeArtifactoryPassword + server-password: ORG_GRADLE_PROJECT_pixeeArtifactoryPassword + - name: Set up Maven + uses: stCarolas/setup-maven@v4.4 + with: + maven-version: 3.8.2 - uses: gradle/gradle-build-action@v2 with: arguments: check --stacktrace From 0478d39967a56ca2c4cf77a9041c49a4c094b0d6 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Thu, 24 Aug 2023 16:45:55 -0700 Subject: [PATCH 147/153] :bug: fix jfrog creds --- .github/workflows/checks.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 2ef138579..ac302b605 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -24,8 +24,8 @@ jobs: java-version: '17' cache: maven server-id: pixee - server-username: ORG_GRADLE_PROJECT_pixeeArtifactoryPassword - server-password: ORG_GRADLE_PROJECT_pixeeArtifactoryPassword + server-username: ${{ vars.PIXEE_ARTIFACTORY_USERNAME }} + server-password: ${{ secrets.PIXEE_ARTIFACTORY_PASSWORD }} - name: Set up Maven uses: stCarolas/setup-maven@v4.4 with: From b9c2f70d1461d310e95acfea6fdc82a36e5cd8cb Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Thu, 24 Aug 2023 18:26:27 -0700 Subject: [PATCH 148/153] :bug: fix test expectations --- .../maven/operator/test/POMOperatorTest.kt | 24 +++++++++++-------- .../maven/operator/test/POMScannerTest.kt | 4 ++-- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorTest.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorTest.kt index c08aa5468..a7ab08234 100644 --- a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorTest.kt +++ b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorTest.kt @@ -9,6 +9,7 @@ import org.dom4j.DocumentException import org.hamcrest.MatcherAssert.assertThat import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows import org.xmlunit.diff.ComparisonType import java.io.File import java.nio.charset.Charset @@ -21,13 +22,14 @@ import kotlin.test.assertTrue class POMOperatorTest : AbstractTestBase() { @Test fun testWithBrokenPom() { - // expected = DocumentException::class - gwt( - "broken-pom", - ProjectModelFactory.load( - POMOperatorTest::class.java.getResource("broken-pom.xml")!!, - ).withDependency(Dependency.fromString("org.dom4j:dom4j:2.0.3")) - ) + assertThrows { + gwt( + "broken-pom", + ProjectModelFactory.load( + POMOperatorTest::class.java.getResource("broken-pom.xml")!!, + ).withDependency(Dependency.fromString("org.dom4j:dom4j:2.0.3")) + ) + } } @Test @@ -79,13 +81,14 @@ class POMOperatorTest : AbstractTestBase() { @Test fun testWithDependencyMissing() { - // expected = MissingDependencyException::class + assertThrows { gwt( "case-dependency-missing", ProjectModelFactory.load( POMOperatorTest::class.java.getResource("pom-case-1.xml")!!, ) ) + } } @Test @@ -328,7 +331,6 @@ class POMOperatorTest : AbstractTestBase() { @Test fun testCaseWithPropertyDefinedTwice() { - // expected = IllegalStateException::class val dependencyToUpgrade = Dependency("org.dom4j", "dom4j", version = "1.0.0") @@ -369,7 +371,9 @@ class POMOperatorTest : AbstractTestBase() { .withOverrideIfAlreadyExists(false) .build() - POMOperator.modify(context) + assertThrows { + POMOperator.modify(context) + } } @Test diff --git a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMScannerTest.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMScannerTest.kt index 23e9de9af..c6eb2add1 100644 --- a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMScannerTest.kt +++ b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMScannerTest.kt @@ -3,6 +3,7 @@ package io.github.pixee.maven.operator.test import io.github.pixee.maven.operator.InvalidPathException import io.github.pixee.maven.operator.POMScanner import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows import java.io.File import kotlin.test.assertTrue import kotlin.test.fail @@ -19,10 +20,9 @@ class POMScannerTest: AbstractTestBase() { @Test fun testTwoLevelsWithLoop() { - // expected = InvalidPathException::class val pomFile = getResourceAsFile("sample-child-with-relativepath-and-two-levels.xml") - val pmf = POMScanner.scanFrom(pomFile, currentDirectory) + assertThrows { POMScanner.scanFrom(pomFile, currentDirectory) } } @Test From 49fe5c167bbc0386963f5176239a48bf7b3dbb2c Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Thu, 24 Aug 2023 18:33:30 -0700 Subject: [PATCH 149/153] :fire: remove dummy class --- .../src/main/java/io/github/pixee/maven/operator/Dummy.java | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 pom-operator/src/main/java/io/github/pixee/maven/operator/Dummy.java diff --git a/pom-operator/src/main/java/io/github/pixee/maven/operator/Dummy.java b/pom-operator/src/main/java/io/github/pixee/maven/operator/Dummy.java deleted file mode 100644 index 1fd7d7581..000000000 --- a/pom-operator/src/main/java/io/github/pixee/maven/operator/Dummy.java +++ /dev/null @@ -1,4 +0,0 @@ -package io.github.pixee.maven.operator; - -/** This dummy class is for Javadoc-generating purposes only */ -public class Dummy {} From caf967db0dafcab96649d22f596ca5a2ed110e71 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Thu, 24 Aug 2023 18:33:56 -0700 Subject: [PATCH 150/153] :recycle: make kotlin plugin --- gradle/build-plugins/build.gradle.kts | 1 + .../kotlin/io.codemodder.kotlin.gradle.kts | 22 +++++++++++++++++++ gradle/buildlibs.versions.toml | 1 + pom-operator/build.gradle.kts | 5 +---- 4 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 gradle/build-plugins/src/main/kotlin/io.codemodder.kotlin.gradle.kts diff --git a/gradle/build-plugins/build.gradle.kts b/gradle/build-plugins/build.gradle.kts index d9fd4b11c..c78f390fb 100644 --- a/gradle/build-plugins/build.gradle.kts +++ b/gradle/build-plugins/build.gradle.kts @@ -24,4 +24,5 @@ dependencies { implementation(buildlibs.spotless) implementation(buildlibs.nebula.publish.plugin) implementation(buildlibs.nebula.contacts.plugin) + implementation(buildlibs.kotlin) } diff --git a/gradle/build-plugins/src/main/kotlin/io.codemodder.kotlin.gradle.kts b/gradle/build-plugins/src/main/kotlin/io.codemodder.kotlin.gradle.kts new file mode 100644 index 000000000..edf2003bc --- /dev/null +++ b/gradle/build-plugins/src/main/kotlin/io.codemodder.kotlin.gradle.kts @@ -0,0 +1,22 @@ +import org.gradle.kotlin.dsl.version + +plugins { + id("io.codemodder.spotless") + id("org.jetbrains.kotlin.jvm") +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(17)) + } +} + +spotless { + java { + googleJavaFormat() + } +} + +tasks.withType(Test::class) { + useJUnitPlatform() +} diff --git a/gradle/buildlibs.versions.toml b/gradle/buildlibs.versions.toml index f9385bc61..d73324bf5 100644 --- a/gradle/buildlibs.versions.toml +++ b/gradle/buildlibs.versions.toml @@ -9,6 +9,7 @@ nebula-contacts-plugin = { module = "com.netflix.nebula.contacts:com.netflix.neb nebula-mavenscm-plugin = { module = "com.netflix.nebula.maven-scm:com.netflix.nebula.maven-scm.gradle.plugin", version = "20.3.0"} nebula-publish-plugin = { module = "com.netflix.nebula.maven-publish:com.netflix.nebula.maven-publish.gradle.plugin", version = "20.3.0"} spotless = { module = "com.diffplug.spotless:spotless-plugin-gradle", version.ref = "spotless" } +kotlin = { module = "org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin", version = "1.8.20"} [plugins] fileversioning = { id = "de.epitschke.gradle-file-versioning", version.ref = "fileversioning" } diff --git a/pom-operator/build.gradle.kts b/pom-operator/build.gradle.kts index 4cb15a09e..f7f78420d 100644 --- a/pom-operator/build.gradle.kts +++ b/pom-operator/build.gradle.kts @@ -1,8 +1,5 @@ plugins { - id("io.codemodder.base") - id("io.codemodder.java-library") - id("io.codemodder.maven-publish") - id("org.jetbrains.kotlin.jvm") version "1.8.20" + id("io.codemodder.kotlin") } dependencies { From 8a0b437de4c58772484572f2b1dcb862270d0cfe Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Thu, 24 Aug 2023 18:34:11 -0700 Subject: [PATCH 151/153] :bug: fix test --- .../operator/test/POMOperatorMultipomTest.kt | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorMultipomTest.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorMultipomTest.kt index d48a51e94..e05398cf0 100644 --- a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorMultipomTest.kt +++ b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorMultipomTest.kt @@ -3,6 +3,7 @@ package io.github.pixee.maven.operator.test import com.google.common.io.Files import io.github.pixee.maven.operator.* import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows import java.io.File import kotlin.test.assertFalse import kotlin.test.assertTrue @@ -10,7 +11,6 @@ import kotlin.test.assertTrue class POMOperatorMultipomTest : AbstractTestBase() { @Test fun testWithParentAndChildMissingPackaging() { - // expected = WrongDependencyTypeException::class val parentResource = getResource("parent-and-child-parent-broken.xml") val parentPomFiles = listOf(POMDocumentFactory.load(parentResource)) @@ -19,10 +19,12 @@ class POMOperatorMultipomTest : AbstractTestBase() { parentResource, ).withParentPomFiles(parentPomFiles) - gwt( - "parent-and-child", - parentPom.withDependency(Dependency.fromString("org.dom4j:dom4j:2.0.3")) - ) + assertThrows { + gwt( + "parent-and-child", + parentPom.withDependency(Dependency.fromString("org.dom4j:dom4j:2.0.3")) + ) + } } @Test @@ -37,10 +39,12 @@ class POMOperatorMultipomTest : AbstractTestBase() { parentResource, ).withParentPomFiles(parentPomFiles) - gwt( - "parent-and-child-wrong-type", - parentPom.withDependency(Dependency.fromString("org.dom4j:dom4j:2.0.3")) - ) + assertThrows { + gwt( + "parent-and-child-wrong-type", + parentPom.withDependency(Dependency.fromString("org.dom4j:dom4j:2.0.3")) + ) + } } @Test From 04676823499e8ca904c4759d42f86e536b904078 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Thu, 24 Aug 2023 18:37:49 -0700 Subject: [PATCH 152/153] :bug: add back in assertThrows --- .../pixee/maven/operator/test/POMOperatorQueryTest.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt index 9b218b9ac..cb079973d 100644 --- a/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt +++ b/pom-operator/src/test/kotlin/io/github/pixee/maven/operator/test/POMOperatorQueryTest.kt @@ -3,9 +3,11 @@ package io.github.pixee.maven.operator.test import io.github.pixee.maven.operator.* import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows import org.slf4j.Logger import org.slf4j.LoggerFactory import java.io.File +import java.lang.IllegalStateException import java.nio.file.Files class POMOperatorQueryTest { @@ -45,16 +47,13 @@ class POMOperatorQueryTest { @Test fun testFailedUnsafeQuery() { - // expected = IllegalStateException::class val context = ProjectModelFactory .load(this.javaClass.getResource("pom-broken.xml")!!) .withQueryType(QueryType.UNSAFE) .build() - val dependencies = POMOperator.queryDependency(context) - - assertTrue(dependencies.isEmpty(), "Dependencies are empty") + assertThrows { POMOperator.queryDependency(context) } } @Test From c8cd0e99ae87c4686db0c1c4fd78fa159e381b64 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Thu, 24 Aug 2023 18:42:28 -0700 Subject: [PATCH 153/153] :art: format kotlin plugin --- .../src/main/kotlin/io.codemodder.kotlin.gradle.kts | 2 -- 1 file changed, 2 deletions(-) diff --git a/gradle/build-plugins/src/main/kotlin/io.codemodder.kotlin.gradle.kts b/gradle/build-plugins/src/main/kotlin/io.codemodder.kotlin.gradle.kts index edf2003bc..f05d74fee 100644 --- a/gradle/build-plugins/src/main/kotlin/io.codemodder.kotlin.gradle.kts +++ b/gradle/build-plugins/src/main/kotlin/io.codemodder.kotlin.gradle.kts @@ -1,5 +1,3 @@ -import org.gradle.kotlin.dsl.version - plugins { id("io.codemodder.spotless") id("org.jetbrains.kotlin.jvm")