diff --git a/doc/changes/changes_4.3.1.md b/doc/changes/changes_4.3.1.md index 060fbe7f..026984d8 100644 --- a/doc/changes/changes_4.3.1.md +++ b/doc/changes/changes_4.3.1.md @@ -12,6 +12,7 @@ This release fixes vulnerability CVE-2024-31573 in `org.xmlunit:xmlunit-core:jar ## Bugfixes +* #571: Fixed failing version increment during dependency update * #567: Increased timeout for installing go-licenses ## Dependency Updates diff --git a/parent-pom/pom.xml b/parent-pom/pom.xml index 7958df57..5ca2a132 100644 --- a/parent-pom/pom.xml +++ b/parent-pom/pom.xml @@ -111,7 +111,7 @@ org.eclipse.jgit org.eclipse.jgit - + 6.7.0.202309050840-r @@ -292,8 +292,8 @@ org.slf4j:slf4j-jdk14:jar:*:* - - org.eclipse.jgit:org.eclipse.jgit:jar:*:6.8.0.202311291450-r + + org.eclipse.jgit:org.eclipse.jgit:jar:*:* diff --git a/project-keeper/src/main/java/com/exasol/projectkeeper/dependencyupdate/ProjectVersionIncrementor.java b/project-keeper/src/main/java/com/exasol/projectkeeper/dependencyupdate/ProjectVersionIncrementor.java index 8fa982df..d0a92fae 100644 --- a/project-keeper/src/main/java/com/exasol/projectkeeper/dependencyupdate/ProjectVersionIncrementor.java +++ b/project-keeper/src/main/java/com/exasol/projectkeeper/dependencyupdate/ProjectVersionIncrementor.java @@ -6,13 +6,14 @@ import java.time.*; import java.util.Objects; import java.util.Optional; +import java.util.stream.Stream; import org.w3c.dom.Document; import org.w3c.dom.Node; import com.exasol.errorreporting.ExaError; import com.exasol.projectkeeper.Logger; -import com.exasol.projectkeeper.shared.config.ProjectKeeperConfig; +import com.exasol.projectkeeper.shared.config.*; import com.exasol.projectkeeper.sources.analyze.generic.*; import com.exasol.projectkeeper.validators.changesfile.ChangesFile; import com.exasol.projectkeeper.validators.changesfile.ChangesFileIO; @@ -88,9 +89,7 @@ private LocalDate today() { String incrementProjectVersion() { final String nextVersion = getIncrementedVersion(currentProjectVersion); updatePomVersion(nextVersion); - if (usesReferenceCheckerPlugin()) { - updateReferences(); - } + sourcesUsingReferenceCheckerPlugin().forEach(this::updateReferences); return nextVersion; } @@ -102,14 +101,15 @@ private void updatePomVersion(final String nextVersion) { xmlFileIO.write(pom, path); } - private boolean usesReferenceCheckerPlugin() { - return config.getSources().stream().anyMatch(source -> source.getModules().contains(JAR_ARTIFACT)); + private Stream sourcesUsingReferenceCheckerPlugin() { + return config.getSources().stream().filter(source -> source.getModules().contains(JAR_ARTIFACT)); } - private void updateReferences() { - logger.info("Unify artifact references"); + private void updateReferences(final Source source) { + final Path moduleDir = projectDir.resolve(source.getPath()).getParent(); + logger.info("Unify artifact references in dir " + moduleDir + "..."); final ShellCommand command = MavenProcessBuilder.create().addArgument("artifact-reference-checker:unify") - .workingDir(projectDir).timeout(Duration.ofSeconds(30)).buildCommand(); + .workingDir(moduleDir).timeout(Duration.ofSeconds(30)).buildCommand(); commandExecutor.execute(command); } @@ -117,7 +117,7 @@ private void incrementVersion(final Path path, final Document pom, final String final Optional versionNode = findVersionNode(pom); if (versionNode.isEmpty()) { logger.warn(ExaError.messageBuilder("W-PK-CORE-196") - .message("No version node found in pom file {{pom file path}}.", path) + .message("No version element found in pom file {{pom file path}}.", path) .mitigation("Please update the version to {{next version}} manually.", nextVersion).toString()); return; } @@ -130,7 +130,13 @@ private void incrementVersion(final Path path, final Document pom, final String } private Optional findVersionNode(final Document pom) { - return xmlFileIO.runXPath(pom, "/project/version"); + final Optional versionNode = xmlFileIO.runXPath(pom, "/project/version"); + if (versionNode.isEmpty() || versionNode.get().getTextContent().equals("${revision}")) { + final Optional revisionElement = xmlFileIO.runXPath(pom, "/project/properties/revision"); + logger.info("Version element missing or refers to ${revision}, use revision property " + revisionElement); + return revisionElement; + } + return versionNode; } static String getIncrementedVersion(final String version) { @@ -139,6 +145,9 @@ static String getIncrementedVersion(final String version) { } private Path getPomPath() { + if (config.getVersionConfig() instanceof final VersionFromSource versionFromSource) { + return versionFromSource.getPathToPom(); + } return projectDir.resolve("pom.xml"); } } diff --git a/project-keeper/src/test/java/com/exasol/projectkeeper/dependencyupdate/ProjectVersionIncrementorTest.java b/project-keeper/src/test/java/com/exasol/projectkeeper/dependencyupdate/ProjectVersionIncrementorTest.java index a36cd1fe..935bce49 100644 --- a/project-keeper/src/test/java/com/exasol/projectkeeper/dependencyupdate/ProjectVersionIncrementorTest.java +++ b/project-keeper/src/test/java/com/exasol/projectkeeper/dependencyupdate/ProjectVersionIncrementorTest.java @@ -5,13 +5,13 @@ import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.same; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; import java.nio.file.Path; import java.time.*; import java.util.*; +import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; @@ -71,7 +71,7 @@ void incrementProjectVersionFailsForInconsistentVersionInPom() { final IllegalStateException exception = assertThrows(IllegalStateException.class, testee::incrementProjectVersion); assertThat(exception.getMessage(), - startsWith("E-PK-CORE-174: Inconsistent project version '1.2.2' found in pom '" + POM_PATH + Matchers.startsWith("E-PK-CORE-174: Inconsistent project version '1.2.2' found in pom '" + POM_PATH + "', expected '1.2.3'.")); } @@ -80,12 +80,16 @@ void incrementProjectVersionLogsWarningForMissingVersionElement() { simulatePomVersion(null); final ProjectVersionIncrementor testee = testee(configWithoutJarArtifact()); assertDoesNotThrow(testee::incrementProjectVersion); - verify(loggerMock).warn("W-PK-CORE-196: No version node found in pom file '" + POM_PATH + verify(loggerMock).warn("W-PK-CORE-196: No version element found in pom file '" + POM_PATH + "'. Please update the version to '1.2.4' manually."); } private void simulatePomVersion(final String version) { - when(xmlDocumentIOMock.read(POM_PATH)).thenReturn(pomModel); + simulatePomVersion(POM_PATH, version); + } + + private void simulatePomVersion(final Path pomPath, final String version) { + when(xmlDocumentIOMock.read(pomPath)).thenReturn(pomModel); if (version != null) { when(versionNode.getTextContent()).thenReturn(version); when(xmlDocumentIOMock.runXPath(same(pomModel), eq("/project/version"))) @@ -105,9 +109,67 @@ void incrementProjectVersion(final String currentVersion, final String expectedN verifyPomVersionUpdated(expectedNextVersion); } + @Test + void incrementProjectVersionInNonDefaultPom() { + final String currentVersion = "1.2.3"; + final String expectedNextVersion = "1.2.4"; + final Path subModulePom = Path.of("module/pom.xml"); + simulatePomVersion(subModulePom, currentVersion); + final String newVersion = testee(configWithVersionFromSource(subModulePom), currentVersion) + .incrementProjectVersion(); + assertThat(newVersion, equalTo(expectedNextVersion)); + verifyPomVersionUpdated(subModulePom, expectedNextVersion); + } + + @Test + void incrementProjectVersionInRevisionProperty() { + final String currentVersion = "1.2.3"; + final String expectedNextVersion = "1.2.4"; + simulatePomRevisionProperty(currentVersion); + final String newVersion = testee(configWithoutJarArtifact(), currentVersion).incrementProjectVersion(); + assertThat(newVersion, equalTo(expectedNextVersion)); + verifyPomVersionUpdated(expectedNextVersion); + } + + @Test + void incrementProjectVersionLogsWarningForMissingRevisionPropertyElement() { + simulatePomRevisionProperty(null); + final ProjectVersionIncrementor testee = testee(configWithoutJarArtifact()); + assertDoesNotThrow(testee::incrementProjectVersion); + verify(loggerMock).warn("W-PK-CORE-196: No version element found in pom file '" + POM_PATH + + "'. Please update the version to '1.2.4' manually."); + } + + private void simulatePomRevisionProperty(final String version) { + when(xmlDocumentIOMock.read(POM_PATH)).thenReturn(pomModel); + final Node projectVersionNode = createNode("${revision}"); + if (version != null) { + when(versionNode.getTextContent()).thenReturn(version); + when(xmlDocumentIOMock.runXPath(same(pomModel), eq("/project/version"))) + .thenReturn(Optional.of(projectVersionNode)); + when(xmlDocumentIOMock.runXPath(same(pomModel), eq("/project/properties/revision"))) + .thenReturn(Optional.of(versionNode)); + } else { + when(xmlDocumentIOMock.runXPath(same(pomModel), eq("/project/version"))) + .thenReturn(Optional.of(projectVersionNode)); + when(xmlDocumentIOMock.runXPath(same(pomModel), eq("/project/properties/revision"))) + .thenReturn(Optional.empty()); + } + } + + private Node createNode(final String textContent) { + final Node revisionNode = mock(Node.class); + when(revisionNode.getTextContent()).thenReturn(textContent); + return revisionNode; + } + private void verifyPomVersionUpdated(final String expectedNextVersion) { + verifyPomVersionUpdated(POM_PATH, expectedNextVersion); + } + + private void verifyPomVersionUpdated(final Path pomPath, final String expectedNextVersion) { verify(versionNode).setTextContent(expectedNextVersion); - verify(xmlDocumentIOMock).write(same(pomModel), eq(POM_PATH)); + verify(xmlDocumentIOMock).write(same(pomModel), eq(pomPath)); } @Test @@ -122,8 +184,8 @@ void incrementProjectVersionWithJarArtifactUpdatesReferences() { private void assertMavenExecuted(final String... mavenArguments) { final ShellCommand command = getExecutedCommand(); assertThat(command.workingDir().get(), equalTo(PROJECT_DIR)); - assertThat(command.commandline(), - contains(startsWith("mvn"), equalTo("--batch-mode"), equalTo("artifact-reference-checker:unify"))); + assertThat(command.commandline(), contains(Matchers.startsWith("mvn"), equalTo("--batch-mode"), + equalTo("artifact-reference-checker:unify"))); } private ShellCommand getExecutedCommand() { @@ -146,11 +208,17 @@ private ProjectVersionIncrementor testee(final ProjectKeeperConfig config, final } private ProjectKeeperConfig configWithJarArtifact() { - return ProjectKeeperConfig.builder() - .sources(List.of(Source.builder().modules(Set.of(ProjectKeeperModule.JAR_ARTIFACT)).build())).build(); + return ProjectKeeperConfig.builder().sources(List.of( + Source.builder().path(Path.of("pom.xml")).modules(Set.of(ProjectKeeperModule.JAR_ARTIFACT)).build())) + .build(); } private ProjectKeeperConfig configWithoutJarArtifact() { return ProjectKeeperConfig.builder().sources(List.of(Source.builder().modules(Set.of()).build())).build(); } + + private ProjectKeeperConfig configWithVersionFromSource(final Path pom) { + return ProjectKeeperConfig.builder().sources(List.of(Source.builder().build())) + .versionConfig(new VersionFromSource(pom)).build(); + } }