From 2d297480498bb7ffa7cc8ec462b3eb6d0e65827c Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 7 Mar 2017 13:00:32 +0100 Subject: [PATCH] Updated code to use Maven Version Plugin --- releaser-core/pom.xml | 10 +- .../cloud/release/internal/PomUpdater.java | 286 ++++++++++++++---- .../release/internal/ProjectUpdater.java | 8 +- .../cloud/release/internal/Versions.java | 14 +- .../release/internal/PomUpdaterTests.java | 99 +++--- .../internal/VersionChangeAssertions.java | 58 ++++ .../cloud/release/internal/VersionsTests.java | 25 +- .../project/pom_matching_parent_v2.xml | 2 +- 8 files changed, 374 insertions(+), 128 deletions(-) create mode 100644 releaser-core/src/test/java/org/springframework/cloud/release/internal/VersionChangeAssertions.java diff --git a/releaser-core/pom.xml b/releaser-core/pom.xml index e938a055..7d9c0bd6 100644 --- a/releaser-core/pom.xml +++ b/releaser-core/pom.xml @@ -4,7 +4,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.springframework.cloud releaser-core 0.0.1.BUILD-SNAPSHOT jar @@ -35,7 +34,14 @@ org.apache.maven maven-model - 3.3.9 + + + 2.2.1 + + + org.codehaus.mojo + versions-maven-plugin + 2.3 org.springframework.boot diff --git a/releaser-core/src/main/java/org/springframework/cloud/release/internal/PomUpdater.java b/releaser-core/src/main/java/org/springframework/cloud/release/internal/PomUpdater.java index 5f912e74..893fc0ab 100644 --- a/releaser-core/src/main/java/org/springframework/cloud/release/internal/PomUpdater.java +++ b/releaser-core/src/main/java/org/springframework/cloud/release/internal/PomUpdater.java @@ -15,16 +15,25 @@ */ package org.springframework.cloud.release.internal; +import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; -import java.io.IOException; -import java.io.Writer; import java.lang.invoke.MethodHandles; +import java.util.ArrayList; +import java.util.List; import java.util.Properties; -import java.util.concurrent.atomic.AtomicBoolean; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; import org.apache.maven.model.Model; -import org.apache.maven.model.io.xpp3.MavenXpp3Writer; +import org.apache.maven.plugin.logging.Log; +import org.codehaus.mojo.versions.api.PomHelper; +import org.codehaus.mojo.versions.change.AbstractVersionChanger; +import org.codehaus.mojo.versions.change.VersionChange; +import org.codehaus.mojo.versions.change.VersionChanger; +import org.codehaus.mojo.versions.change.VersionChangerFactory; +import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; +import org.codehaus.stax2.XMLInputFactory2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.StringUtils; @@ -53,33 +62,29 @@ class PomUpdater { if (!versions.shouldBeUpdated(model.getArtifactId())) { log.info("Skipping project [{}] since it's not on the list of projects to update", model.getArtifactId()); return false; - } else if (versions.versionAlreadySet(model.getArtifactId(), model.getVersion())) { - log.info("Version has already been set. The project shouldn't be updated."); - return false; } log.info("Project [{}] will have its dependencies updated", model.getArtifactId()); return true; } ModelWrapper readModel(File pom) { - return new ModelWrapper(this.pomReader.readPom(pom), false); + return new ModelWrapper(this.pomReader.readPom(pom)); } /** * Updates the root / child module model * - * @param rootProjectName - name of the artifactId of the root project + * @param rootProject - root project model * @param pom - file with the pom * @param versions - versions to update * @return updated model */ - ModelWrapper updateModel(String rootProjectName, File pom, Versions versions) { + ModelWrapper updateModel(ModelWrapper rootProject, File pom, Versions versions) { Model model = this.pomReader.readPom(pom); - boolean dirty = false; - dirty = updateParentIfPossible(rootProjectName, versions, model) || dirty ; - dirty = updateVersionIfPossible(rootProjectName, versions, model) || dirty ; - dirty = updateProperties(versions, model) || dirty; - return new ModelWrapper(model, dirty); + List sourceChanges = new ArrayList<>(); + sourceChanges = updateParentIfPossible(rootProject, versions, model, sourceChanges); + sourceChanges = updateVersionIfPossible(rootProject, versions, model, sourceChanges); + return new ModelWrapper(model, sourceChanges, versions); } /** @@ -88,85 +93,256 @@ class PomUpdater { * * @return - the pom file */ - File overwritePomIfDirty(ModelWrapper wrapper, File pom) { - if (wrapper.dirty) { + File overwritePomIfDirty(ModelWrapper wrapper, Versions versions, File pom) { + if (wrapper.isDirty()) { log.debug("There were changes in the pom so file will be overridden"); - this.pomWriter.write(wrapper.model, pom); + this.pomWriter.write(wrapper, versions, pom); log.info("Successfully stored [{}]", pom); } return pom; } - - private boolean updateProperties(Versions versions, Model model) { - final AtomicBoolean atomicBoolean = new AtomicBoolean(); - versions.projects - .forEach(project -> { - Properties properties = model.getProperties(); - String projectVersionKey = project.name + ".version"; - if (properties.containsKey(projectVersionKey)) { - Object previous = properties.setProperty(projectVersionKey, project.version); - log.info("Updated property [{}] => [{}]. Previous version [{}]", - projectVersionKey, project.version, previous); - atomicBoolean.set(true); - } - }); - return atomicBoolean.get(); - } - - private boolean updateParentIfPossible(String rootProjectName, Versions versions, Model model) { + private List updateParentIfPossible(ModelWrapper wrapper, Versions versions, + Model model, List sourceChanges) { + String rootProjectName = wrapper.projectName(); + List changes = new ArrayList<>(sourceChanges); if (model.getParent() == null || StringUtils.isEmpty(model.getParent().getVersion())) { - return false; + return changes; } + String parentGroupId = model.getParent().getGroupId(); String parentArtifactId = model.getParent().getArtifactId(); + String oldVersion = model.getParent().getVersion(); String version = versions.versionForProject(parentArtifactId); if (StringUtils.isEmpty(version)) { if (StringUtils.hasText(model.getParent().getRelativePath())) { version = versions.versionForProject(rootProjectName); } else { log.warn("There is no info on the [{}] version", model.getArtifactId()); - return false; + return changes; } } - log.info("Setting version of parent [{}] to [{}] for module [{}]", parentArtifactId, version, model.getArtifactId()); - model.getParent().setVersion(version); - return true; + log.info("Setting version of parent [{}] to [{}] for module [{}]", parentArtifactId, + version, model.getArtifactId()); + changes.add(new VersionChange(parentGroupId, parentArtifactId, oldVersion, version)); + return changes; } - private boolean updateVersionIfPossible(String rootProjectName, Versions versions, Model model) { + private List updateVersionIfPossible(ModelWrapper wrapper, Versions versions, + Model model, List sourceChanges) { + String rootProjectName = wrapper.projectName(); + List changes = new ArrayList<>(sourceChanges); + String parentGroupId = groupId(model); + String parentArtifactId = model.getArtifactId(); + String oldVersion = model.getVersion(); String version = versions.versionForProject(rootProjectName); if (StringUtils.isEmpty(version) || StringUtils.isEmpty(model.getVersion())) { log.warn("There was no version set for project [{}], skipping version setting for module [{}]", rootProjectName, model.getArtifactId()); - return false; + return changes; } log.info("Setting [{}] version to [{}]", model.getArtifactId(), version); - model.setVersion(version); - return true; + changes.add(new VersionChange(parentGroupId, parentArtifactId, oldVersion, version)); + return changes; + } + + private String groupId(Model model) { + if (StringUtils.hasText(model.getGroupId())) { + return model.getGroupId(); + } + if (model.getParent() != null) { + return model.getParent().getGroupId(); + } + return ""; } } class ModelWrapper { final Model model; - final boolean dirty; + final Versions versions; + final List sourceChanges = new ArrayList<>(); - ModelWrapper(Model model, boolean dirty) { + ModelWrapper(Model model, List sourceChanges, Versions versions) { this.model = model; - this.dirty = dirty; + this.versions = versions; + this.sourceChanges.addAll(sourceChanges); + } + + ModelWrapper(Model model) { + this.model = model; + this.versions = Versions.EMPTY_VERSION; } String projectName() { return this.model.getArtifactId(); } + + boolean isDirty() { + return !this.sourceChanges.isEmpty() || this.versions.shouldSetProperty(this.model.getProperties()); + } } class PomWriter { - void write(Model model, File pom) { - try(Writer writer = new FileWriter(pom)) { - MavenXpp3Writer pomWriter = new MavenXpp3Writer(); - pomWriter.write(writer, model); - } - catch (IOException e) { - throw new IllegalStateException("Failed to write file", e); + + private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + void write(ModelWrapper wrapper, Versions versions, File pom) { + try { + VersionChangerFactory versionChangerFactory = new VersionChangerFactory(); + StringBuilder input = PomHelper.readXmlFile(pom); + ModifiedPomXMLEventReader parsedPom = newModifiedPomXER(input); + versionChangerFactory.setPom(parsedPom); + LoggerToMavenLog loggerToMavenLog = new LoggerToMavenLog(PomWriter.log); + versionChangerFactory.setLog(loggerToMavenLog); + versionChangerFactory.setModel(wrapper.model); + log.info("Applying version / parent / plugin / project changes to the pom [{}]", pom); + VersionChanger changer = versionChangerFactory.newVersionChanger( true, + true, true, true); + for (VersionChange versionChange : wrapper.sourceChanges) { + changer.apply(versionChange); + } + log.info("Applying properties changes to the pom [{}]", pom); + new PropertyVersionChanger(wrapper, versions, parsedPom, loggerToMavenLog) + .apply(null); + try (BufferedWriter bw = new BufferedWriter(new FileWriter(pom))) { + bw.write(input.toString()); + } + log.info("Flushed changes to the pom file [{}]", pom); + } catch (Exception e) { + log.error("Exception occurred while trying to apply changes to the POM", e); } } + + /** + * Creates a {@link org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader} from a StringBuilder. + * + * @param input The XML to read and modify. + * @return The {@link org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader}. + */ + private ModifiedPomXMLEventReader newModifiedPomXER(StringBuilder input) { + ModifiedPomXMLEventReader newPom = null; + try { + XMLInputFactory inputFactory = XMLInputFactory2.newInstance(); + inputFactory.setProperty(XMLInputFactory2.P_PRESERVE_LOCATION, Boolean.TRUE); + newPom = new ModifiedPomXMLEventReader(input, inputFactory); + } + catch (XMLStreamException e) { + log.error("Exception occurred while trying to parse pom", e); + } + return newPom; + } +} + +class PropertyVersionChanger extends AbstractVersionChanger { + + private final Versions versions; + private final Log log; + + public PropertyVersionChanger(ModelWrapper wrapper, Versions versions, ModifiedPomXMLEventReader pom, Log log) { + super(wrapper.model, pom, log); + this.versions = versions; + this.log = log; + } + + @Override public void apply(final VersionChange versionChange) throws XMLStreamException { + this.versions.projects + .stream() + .filter(project -> { + Properties properties = getModel().getProperties(); + String projectVersionKey = propertyName(project); + return properties.containsKey(projectVersionKey); + }) + .forEach(project -> { + String propertyName = propertyName(project); + if (setPropertyVersion(propertyName, project.version)) { + info(" Updating property " + propertyName); + info(" to version " + project.version); + } + }); + } + + private String propertyName(Project project) { + return project.name + ".version"; + } + + private boolean setPropertyVersion(String propertyName, String version) { + try { + return PomHelper.setPropertyVersion(getPom(), null, propertyName, version); + } + catch (XMLStreamException e) { + this.log.error("Exception occurred while trying to set property version", e); + return false; + } + } +} + +class LoggerToMavenLog implements Log { + + private final Logger logger; + + LoggerToMavenLog(Logger logger) { + this.logger = logger; + } + + @Override public boolean isDebugEnabled() { + return this.logger.isDebugEnabled(); + } + + @Override public void debug(CharSequence content) { + this.logger.debug(content.toString()); + } + + @Override public void debug(CharSequence content, Throwable error) { + this.logger.debug(content.toString(), error); + } + + @Override public void debug(Throwable error) { + this.debug("Exception occurred", error); + } + + @Override public boolean isInfoEnabled() { + return this.logger.isInfoEnabled(); + } + + @Override public void info(CharSequence content) { + this.logger.info(content.toString()); + } + + @Override public void info(CharSequence content, Throwable error) { + this.logger.info(content.toString(), error); + } + + @Override public void info(Throwable error) { + this.info("Exception occurred", error); + } + + @Override public boolean isWarnEnabled() { + return this.logger.isWarnEnabled(); + } + + @Override public void warn(CharSequence content) { + this.logger.warn(content.toString()); + } + + @Override public void warn(CharSequence content, Throwable error) { + this.logger.warn(content.toString(), error); + } + + @Override public void warn(Throwable error) { + this.warn("Exception occurred", error); + } + + @Override public boolean isErrorEnabled() { + return this.logger.isErrorEnabled(); + } + + @Override public void error(CharSequence content) { + this.logger.error(content.toString()); + } + + @Override public void error(CharSequence content, Throwable error) { + this.logger.error(content.toString(), error); + } + + @Override public void error(Throwable error) { + this.error("Exception occurred", error); + } } \ No newline at end of file diff --git a/releaser-core/src/main/java/org/springframework/cloud/release/internal/ProjectUpdater.java b/releaser-core/src/main/java/org/springframework/cloud/release/internal/ProjectUpdater.java index 77f7769b..6f48dd66 100644 --- a/releaser-core/src/main/java/org/springframework/cloud/release/internal/ProjectUpdater.java +++ b/releaser-core/src/main/java/org/springframework/cloud/release/internal/ProjectUpdater.java @@ -42,8 +42,8 @@ public class ProjectUpdater { File clonedScRelease = this.gitProjectRepo.cloneProject( URI.create(this.properties.getSpringCloudReleaseGitUrl())); this.gitProjectRepo.checkout(clonedScRelease, this.properties.getBranch()); - SCReleasePomParser SCReleasePomParser = new SCReleasePomParser(clonedScRelease); - Versions versions = SCReleasePomParser.allVersions(); + SCReleasePomParser sCReleasePomParser = new SCReleasePomParser(clonedScRelease); + Versions versions = sCReleasePomParser.allVersions(); if (!this.pomUpdater.shouldProjectBeUpdated(projectRoot, versions)) { log.info("Skipping project updating"); return; @@ -80,8 +80,8 @@ public class ProjectUpdater { public FileVisitResult visitFile(Path path, BasicFileAttributes attr) { File file = path.toFile(); if (POM_XML.equals(file.getName())) { - ModelWrapper model = this.pomUpdater.updateModel(this.rootPom.projectName(), file, this.versions); - this.pomUpdater.overwritePomIfDirty(model, file); + ModelWrapper model = this.pomUpdater.updateModel(this.rootPom, file, this.versions); + this.pomUpdater.overwritePomIfDirty(model, this.versions, file); } return FileVisitResult.CONTINUE; } diff --git a/releaser-core/src/main/java/org/springframework/cloud/release/internal/Versions.java b/releaser-core/src/main/java/org/springframework/cloud/release/internal/Versions.java index 44e4c88e..7cf6baec 100644 --- a/releaser-core/src/main/java/org/springframework/cloud/release/internal/Versions.java +++ b/releaser-core/src/main/java/org/springframework/cloud/release/internal/Versions.java @@ -1,11 +1,12 @@ package org.springframework.cloud.release.internal; +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; + import static org.springframework.cloud.release.internal.SpringCloudConstants.BUILD_ARTIFACT_ID; import static org.springframework.cloud.release.internal.SpringCloudConstants.CLOUD_DEPENDENCIES_ARTIFACT_ID; -import java.util.HashSet; -import java.util.Set; - /** * Represents versions taken out from Spring Cloud Release pom * @@ -14,6 +15,7 @@ import java.util.Set; class Versions { private static final String SPRING_BOOT_PROJECT_NAME = "spring-boot"; + static final Versions EMPTY_VERSION = new Versions(""); String bootVersion; String scBuildVersion; @@ -52,9 +54,9 @@ class Versions { .anyMatch(project -> project.name.equals(projectName)); } - boolean versionAlreadySet(String projectName, String version) { - String versionForProject = versionForProject(projectName); - return version.equals(versionForProject); + boolean shouldSetProperty(Properties properties) { + return this.projects.stream() + .anyMatch(project -> properties.containsKey(project.name + ".version")); } } diff --git a/releaser-core/src/test/java/org/springframework/cloud/release/internal/PomUpdaterTests.java b/releaser-core/src/test/java/org/springframework/cloud/release/internal/PomUpdaterTests.java index c006669a..2bd74fdb 100644 --- a/releaser-core/src/test/java/org/springframework/cloud/release/internal/PomUpdaterTests.java +++ b/releaser-core/src/test/java/org/springframework/cloud/release/internal/PomUpdaterTests.java @@ -16,8 +16,6 @@ package org.springframework.cloud.release.internal; -import static org.assertj.core.api.BDDAssertions.then; - import java.io.File; import java.io.IOException; import java.net.URISyntaxException; @@ -25,12 +23,15 @@ import java.nio.file.Files; import java.util.HashSet; import java.util.Set; +import org.apache.maven.model.Model; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.springframework.util.FileSystemUtils; +import static org.springframework.cloud.release.internal.VersionChangeAssertions.then; + /** * @author Marcin Grzejszczak */ @@ -64,68 +65,44 @@ public class PomUpdaterTests { public void should_not_update_the_model_if_no_changes_were_made() throws Exception { File nonMatchingPom = pom("/projects/project"); - ModelWrapper model = this.pomUpdater.updateModel("foo", nonMatchingPom, this.versions); + ModelWrapper model = this.pomUpdater.updateModel(model("foo"), nonMatchingPom, this.versions); - then(model.dirty).isFalse(); + then(model.isDirty()).isFalse(); } @Test public void should_update_the_model_if_only_artifact_id_is_matched_in_the_root_pom() throws Exception { File matchingArtifactId = pom("/projects/project", "pom_matching_artifact.xml"); - ModelWrapper model = this.pomUpdater.updateModel("spring-cloud-sleuth", matchingArtifactId, this.versions); + ModelWrapper model = this.pomUpdater.updateModel(model("spring-cloud-sleuth"), matchingArtifactId, this.versions); - then(model.dirty).isTrue(); - then(model.model.getVersion()).isEqualTo("0.0.3.BUILD-SNAPSHOT"); - // the rest is the same - then(model.model.getParent().getVersion()).isEqualTo("1.3.1.BUILD-SNAPSHOT"); - then(model.model.getProperties()) - .containsEntry("spring-cloud-foo.version", "1.3.1.BUILD-SNAPSHOT") - .containsEntry("foo.version", "1.2.0.BUILD-SNAPSHOT"); + then(model.isDirty()).isTrue(); + then(new ListOfChanges(model)) + .newParentVersionIsEqualTo("parentGroup", "spring-cloud-sleuth", "0.0.3.BUILD-SNAPSHOT"); } @Test public void should_update_the_model_if_parent_is_matched_via_sc_build() throws Exception { File matchingArtifactId = pom("/projects/project", "pom_matching_parent_v2.xml"); - ModelWrapper model = this.pomUpdater.updateModel("spring-cloud-sleuth", matchingArtifactId, this.versions); + ModelWrapper model = this.pomUpdater.updateModel(model("spring-cloud-sleuth"), matchingArtifactId, this.versions); - then(model.dirty).isTrue(); - then(model.model.getVersion()).isEqualTo("0.0.3.BUILD-SNAPSHOT"); - then(model.model.getParent().getVersion()).isEqualTo("0.0.2"); - // the rest is the same - then(model.model.getProperties()) - .containsEntry("spring-cloud-foo.version", "1.3.1.BUILD-SNAPSHOT") - .containsEntry("foo.version", "1.2.0.BUILD-SNAPSHOT"); + then(model.isDirty()).isTrue(); + then(new ListOfChanges(model)) + .newParentVersionIsEqualTo("org.springframework.cloud", "spring-cloud-sleuth", "0.0.3.BUILD-SNAPSHOT") + .newParentVersionIsEqualTo("org.springframework.cloud", "spring-cloud-build", "0.0.2"); } @Test public void should_update_the_model_if_parent_is_matched_via_sc_dependencies_parent() throws Exception { File matchingArtifactId = pom("/projects/project", "pom_matching_parent.xml"); - ModelWrapper model = this.pomUpdater.updateModel("spring-cloud-sleuth", matchingArtifactId, this.versions); + ModelWrapper model = this.pomUpdater.updateModel(model("spring-cloud-sleuth"), matchingArtifactId, this.versions); - then(model.dirty).isTrue(); - then(model.model.getVersion()).isEqualTo("0.0.3.BUILD-SNAPSHOT"); - then(model.model.getParent().getVersion()).isEqualTo("0.0.2"); - // the rest is the same - then(model.model.getProperties()) - .containsEntry("spring-cloud-foo.version", "1.3.1.BUILD-SNAPSHOT") - .containsEntry("foo.version", "1.2.0.BUILD-SNAPSHOT"); - } - - @Test - public void should_update_the_model_if_properties_are_matched() throws Exception { - File matchingArtifactId = pom("/projects/project", "pom_matching_properties.xml"); - - ModelWrapper model = this.pomUpdater.updateModel("spring-cloud-sleuth", matchingArtifactId, this.versions); - - then(model.dirty).isTrue(); - then(model.model.getVersion()).isEqualTo("0.0.3.BUILD-SNAPSHOT"); - then(model.model.getParent().getVersion()).isEqualTo("0.0.2"); - then(model.model.getProperties()) - .containsEntry("spring-cloud-sleuth.version", "0.0.3.BUILD-SNAPSHOT") - .containsEntry("spring-cloud-vault.version", "0.0.4.BUILD-SNAPSHOT"); + then(model.isDirty()).isTrue(); + then(new ListOfChanges(model)) + .newParentVersionIsEqualTo("org.springframework.cloud", "spring-cloud-sleuth", "0.0.3.BUILD-SNAPSHOT") + .newParentVersionIsEqualTo("org.springframework.cloud", "spring-cloud-build", "0.0.2"); } @Test @@ -146,10 +123,11 @@ public class PomUpdaterTests { public void should_update_the_child_model_if_parent_is_matched_via_sc_build() throws Exception { File matchingArtifactId = pom("/projects/project/children", "pom_matching_parent_v2.xml"); - ModelWrapper model = this.pomUpdater.updateModel("spring-cloud-sleuth", matchingArtifactId, this.versions); + ModelWrapper model = this.pomUpdater.updateModel(model("spring-cloud-sleuth"), matchingArtifactId, this.versions); - then(model.dirty).isTrue(); - then(model.model.getParent().getVersion()).isEqualTo("0.0.3.BUILD-SNAPSHOT"); + then(model.isDirty()).isTrue(); + then(new ListOfChanges(model)) + .newParentVersionIsEqualTo("org.springframework.cloud", "spring-cloud-sleuth", "0.0.3.BUILD-SNAPSHOT"); // the rest is the same then(model.model.getProperties()) .containsEntry("spring-cloud-foo.version", "1.3.1.BUILD-SNAPSHOT") @@ -160,10 +138,11 @@ public class PomUpdaterTests { public void should_update_the_child_model_if_parent_is_matched_via_sc_dependencies_parent() throws Exception { File matchingArtifactId = pom("/projects/project/children", "pom_matching_parent.xml"); - ModelWrapper model = this.pomUpdater.updateModel("spring-cloud-sleuth", matchingArtifactId, this.versions); + ModelWrapper model = this.pomUpdater.updateModel(model("spring-cloud-sleuth"), matchingArtifactId, this.versions); - then(model.dirty).isTrue(); - then(model.model.getParent().getVersion()).isEqualTo("0.0.3.BUILD-SNAPSHOT"); + then(model.isDirty()).isTrue(); + then(new ListOfChanges(model)) + .newParentVersionIsEqualTo("org.springframework.cloud", "spring-cloud-sleuth", "0.0.3.BUILD-SNAPSHOT"); // the rest is the same then(model.model.getProperties()) .containsEntry("spring-cloud-foo.version", "1.3.1.BUILD-SNAPSHOT") @@ -174,13 +153,11 @@ public class PomUpdaterTests { public void should_update_the_child_model_if_properties_are_matched() throws Exception { File matchingArtifactId = pom("/projects/project/children", "pom_matching_properties.xml"); - ModelWrapper model = this.pomUpdater.updateModel("spring-cloud-sleuth", matchingArtifactId, this.versions); + ModelWrapper model = this.pomUpdater.updateModel(model("spring-cloud-sleuth"), matchingArtifactId, this.versions); - then(model.dirty).isTrue(); - then(model.model.getParent().getVersion()).isEqualTo("0.0.3.BUILD-SNAPSHOT"); - then(model.model.getProperties()) - .containsEntry("spring-cloud-sleuth.version", "0.0.3.BUILD-SNAPSHOT") - .containsEntry("spring-cloud-vault.version", "0.0.4.BUILD-SNAPSHOT"); + then(model.isDirty()).isTrue(); + then(new ListOfChanges(model)) + .newParentVersionIsEqualTo("org.springframework.cloud", "spring-cloud-sleuth", "0.0.3.BUILD-SNAPSHOT"); } @Test @@ -188,9 +165,9 @@ public class PomUpdaterTests { FileSystemUtils.copyRecursively(file("/projects/project"), this.temporaryFolder); File beforeProcessing = pom("/projects/project/children", "pom_matching_properties.xml"); File afterProcessing = new File(this.temporaryFolder, "/children/pom_matching_properties.xml"); - ModelWrapper model = this.pomUpdater.updateModel("spring-cloud-sleuth", afterProcessing, this.versions); + ModelWrapper model = this.pomUpdater.updateModel(model("spring-cloud-sleuth"), afterProcessing, this.versions); - File processedPom = this.pomUpdater.overwritePomIfDirty(model, afterProcessing); + File processedPom = this.pomUpdater.overwritePomIfDirty(model, Versions.EMPTY_VERSION, afterProcessing); then(processedPom).isSameAs(afterProcessing); String processedPomText = asString(processedPom); @@ -203,9 +180,9 @@ public class PomUpdaterTests { FileSystemUtils.copyRecursively(file("/projects/project"), this.temporaryFolder); File beforeProcessing = pom("/projects/project/"); File afterProcessing = new File(this.temporaryFolder, "/pom.xml"); - ModelWrapper model = this.pomUpdater.updateModel("foo", afterProcessing, this.versions); + ModelWrapper model = this.pomUpdater.updateModel(model("foo"), afterProcessing, this.versions); - File processedPom = this.pomUpdater.overwritePomIfDirty(model, afterProcessing); + File processedPom = this.pomUpdater.overwritePomIfDirty(model, Versions.EMPTY_VERSION, afterProcessing); then(processedPom).isSameAs(afterProcessing); then(asString(processedPom)).isEqualTo(asString(beforeProcessing)); @@ -218,6 +195,12 @@ public class PomUpdaterTests { return projects; } + private ModelWrapper model(String projectName) { + Model parent = new Model(); + parent.setArtifactId(projectName); + return new ModelWrapper(parent); + } + private File file(String relativePath) throws URISyntaxException { return new File(GitProjectRepoTests.class.getResource(relativePath).toURI()); } diff --git a/releaser-core/src/test/java/org/springframework/cloud/release/internal/VersionChangeAssertions.java b/releaser-core/src/test/java/org/springframework/cloud/release/internal/VersionChangeAssertions.java new file mode 100644 index 00000000..280e941a --- /dev/null +++ b/releaser-core/src/test/java/org/springframework/cloud/release/internal/VersionChangeAssertions.java @@ -0,0 +1,58 @@ +package org.springframework.cloud.release.internal; + +import java.util.ArrayList; +import java.util.List; + +import org.assertj.core.api.AbstractAssert; +import org.assertj.core.api.BDDAssertions; +import org.codehaus.mojo.versions.change.VersionChange; + +/** + * @author Marcin Grzejszczak + */ +class VersionChangeAssertions extends BDDAssertions { + + public static VersionChangeAssert then(ListOfChanges actual) { + return assertThat(actual); + } + + public static VersionChangeAssert assertThat(ListOfChanges actual) { + return new VersionChangeAssert(actual); + } + +} + +class ListOfChanges { + + final List changes; + + ListOfChanges(ModelWrapper model) { + this.changes = new ArrayList<>(model.sourceChanges); + } +} + +class VersionChangeAssert extends + AbstractAssert { + + public VersionChangeAssert(ListOfChanges actual) { + super(actual, VersionChangeAssert.class); + } + + VersionChangeAssert newParentVersionIsEqualTo(String groupId, String artifactId, String newVersion) { + boolean matches = false; + for (VersionChange change : actual.changes) { + if (newVersion.equals(change.getNewVersion()) + && groupId.equals(change.getGroupId()) + && artifactId.equals(change.getArtifactId())) { + matches = true; + break; + } + } + if (matches) { + return this; + } + failWithMessage("There is no change with that parent coordinates"); + return this; + } +} + diff --git a/releaser-core/src/test/java/org/springframework/cloud/release/internal/VersionsTests.java b/releaser-core/src/test/java/org/springframework/cloud/release/internal/VersionsTests.java index fd6f3b69..7b04c5e4 100644 --- a/releaser-core/src/test/java/org/springframework/cloud/release/internal/VersionsTests.java +++ b/releaser-core/src/test/java/org/springframework/cloud/release/internal/VersionsTests.java @@ -17,11 +17,10 @@ package org.springframework.cloud.release.internal; import java.util.HashSet; +import java.util.Properties; import java.util.Set; import org.junit.Test; -import org.springframework.cloud.release.internal.Project; -import org.springframework.cloud.release.internal.Versions; import static org.assertj.core.api.BDDAssertions.then; @@ -58,9 +57,31 @@ public class VersionsTests { then(this.versions.versionForProject("missing")).isEmpty(); } + @Test + public void should_return_true_if_properties_contains_project_key() { + then(this.versions.shouldSetProperty(validProps())).isTrue(); + } + + @Test + public void should_return_False_if_properties_does_not_contain_project_key() { + then(this.versions.shouldSetProperty(missingProps())).isFalse(); + } + Set projects() { Set projects = new HashSet<>(); projects.add(new Project("foo", "bar")); return projects; } + + Properties validProps() { + Properties properties = new Properties(); + properties.setProperty("foo.version", "1.0.0"); + return properties; + } + + Properties missingProps() { + Properties properties = new Properties(); + properties.setProperty("missing.version", "1.0.0"); + return properties; + } } \ No newline at end of file diff --git a/releaser-core/src/test/resources/projects/project/pom_matching_parent_v2.xml b/releaser-core/src/test/resources/projects/project/pom_matching_parent_v2.xml index 6445397c..324497f5 100644 --- a/releaser-core/src/test/resources/projects/project/pom_matching_parent_v2.xml +++ b/releaser-core/src/test/resources/projects/project/pom_matching_parent_v2.xml @@ -28,7 +28,7 @@ org.springframework.cloud - spring-cloud-dependencies-parent + spring-cloud-build 1.3.1.BUILD-SNAPSHOT