From ca78a669355785870403038481be09ffacb27cd4 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 6 Mar 2017 18:01:08 +0100 Subject: [PATCH] Added more pom updating --- .../cloud/release/PomParser.java | 50 +++---- .../cloud/release/PomReader.java | 44 ++++++ .../cloud/release/PomUpdater.java | 130 +++++++++++++++++ .../cloud/release/ProjectRepo.java | 15 ++ .../cloud/release/ReleaserApplication.java | 15 ++ .../cloud/release/SpringCloudConstants.java | 31 ++++ .../cloud/release/Versions.java | 44 ++++-- .../cloud/release/AcceptanceTests.java | 4 +- .../cloud/release/PomParserTests.java | 50 ++++--- .../cloud/release/PomReaderTests.java | 69 +++++++++ .../cloud/release/PomUpdaterTests.java | 132 ++++++++++++++++++ .../cloud/release/VersionsTests.java | 64 +++++++++ src/test/resources/projects/project/pom.xml | 41 ++++++ .../project/pom_matching_artifact.xml | 41 ++++++ .../projects/project/pom_matching_parent.xml | 41 ++++++ .../project/pom_matching_parent_v2.xml | 41 ++++++ .../project/pom_matching_properties.xml | 41 ++++++ .../{sample => spring-cloud-sleuth}/pom.xml | 0 .../spring-cloud-sleuth-core/pom.xml | 0 .../spring-cloud-sleuth-dependencies/pom.xml | 0 20 files changed, 797 insertions(+), 56 deletions(-) create mode 100644 src/main/java/org/springframework/cloud/release/PomReader.java create mode 100644 src/main/java/org/springframework/cloud/release/PomUpdater.java create mode 100644 src/main/java/org/springframework/cloud/release/SpringCloudConstants.java create mode 100644 src/test/java/org/springframework/cloud/release/PomReaderTests.java create mode 100644 src/test/java/org/springframework/cloud/release/PomUpdaterTests.java create mode 100644 src/test/java/org/springframework/cloud/release/VersionsTests.java create mode 100644 src/test/resources/projects/project/pom.xml create mode 100644 src/test/resources/projects/project/pom_matching_artifact.xml create mode 100644 src/test/resources/projects/project/pom_matching_parent.xml create mode 100644 src/test/resources/projects/project/pom_matching_parent_v2.xml create mode 100644 src/test/resources/projects/project/pom_matching_properties.xml rename src/test/resources/projects/{sample => spring-cloud-sleuth}/pom.xml (100%) rename src/test/resources/projects/{sample => spring-cloud-sleuth}/spring-cloud-sleuth-core/pom.xml (100%) rename src/test/resources/projects/{sample => spring-cloud-sleuth}/spring-cloud-sleuth-dependencies/pom.xml (100%) diff --git a/src/main/java/org/springframework/cloud/release/PomParser.java b/src/main/java/org/springframework/cloud/release/PomParser.java index 6b209c94..442234ab 100644 --- a/src/main/java/org/springframework/cloud/release/PomParser.java +++ b/src/main/java/org/springframework/cloud/release/PomParser.java @@ -1,9 +1,21 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * 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. + */ package org.springframework.cloud.release; import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.Reader; import java.lang.invoke.MethodHandles; import java.util.Map; import java.util.Set; @@ -14,8 +26,6 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import org.apache.maven.model.Model; -import org.apache.maven.model.io.xpp3.MavenXpp3Reader; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,9 +39,7 @@ class PomParser { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private static final String STARTER_POM = "spring-cloud-starter-parent/pom.xml"; - private static final String BOOT_STARTER_ARTIFACT_ID = "spring-boot-starter-parent"; private static final String DEPENDENCIES_POM = "spring-cloud-dependencies/pom.xml"; - private static final String CLOUD_DEPENDENCIES_ARTIFACT_ID = "spring-cloud-dependencies-parent"; private static final Pattern SC_VERSION_PATTERN = Pattern.compile("^(spring-cloud-.*)\\.version$"); private final File projectRootDir; @@ -49,12 +57,18 @@ class PomParser { this.dependenciesPom = dependenciesPom; } + Versions allVersions() { + Versions boot = bootVersion(); + Versions cloud = springCloudVersions(); + return new Versions(boot.bootVersion, cloud.scBuildVersion, cloud.projects); + } + Versions bootVersion() { Model model = pom(this.bootPom); String bootArtifactId = model.getParent().getArtifactId(); log.debug("Boot artifact id is equal to [{}]", bootArtifactId); - if (!BOOT_STARTER_ARTIFACT_ID.equals(bootArtifactId)) { - throw new IllegalStateException("The pom doesn't have a [" + BOOT_STARTER_ARTIFACT_ID + "] artifact id"); + if (!SpringCloudConstants.BOOT_STARTER_ARTIFACT_ID.equals(bootArtifactId)) { + throw new IllegalStateException("The pom doesn't have a [" + SpringCloudConstants.BOOT_STARTER_ARTIFACT_ID + "] artifact id"); } String bootVersion = model.getParent().getVersion(); log.debug("Boot version is equal to [{}]", bootVersion); @@ -75,9 +89,9 @@ class PomParser { Versions springCloudVersions() { Model model = pom(this.dependenciesPom); String buildArtifact = model.getParent().getArtifactId(); - log.debug("[{}] artifact id is equal to [{}]", CLOUD_DEPENDENCIES_ARTIFACT_ID, buildArtifact); - if (!CLOUD_DEPENDENCIES_ARTIFACT_ID.equals(buildArtifact)) { - throw new IllegalStateException("The pom doesn't have a [" + CLOUD_DEPENDENCIES_ARTIFACT_ID + "] artifact id"); + log.debug("[{}] artifact id is equal to [{}]", SpringCloudConstants.CLOUD_DEPENDENCIES_ARTIFACT_ID, buildArtifact); + if (!SpringCloudConstants.CLOUD_DEPENDENCIES_ARTIFACT_ID.equals(buildArtifact)) { + throw new IllegalStateException("The pom doesn't have a [" + SpringCloudConstants.CLOUD_DEPENDENCIES_ARTIFACT_ID + "] artifact id"); } String buildVersion = model.getParent().getVersion(); log.debug("Spring Cloud Build version is equal to [{}]", buildVersion); @@ -104,15 +118,3 @@ class PomParser { } } -class PomReader { - - Model readPom(File pom) { - try(Reader reader = new FileReader(pom)) { - MavenXpp3Reader xpp3Reader = new MavenXpp3Reader(); - return xpp3Reader.read(reader); - } - catch (XmlPullParserException | IOException e) { - throw new IllegalStateException("Failed to read file", e); - } - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/cloud/release/PomReader.java b/src/main/java/org/springframework/cloud/release/PomReader.java new file mode 100644 index 00000000..db33e7fe --- /dev/null +++ b/src/main/java/org/springframework/cloud/release/PomReader.java @@ -0,0 +1,44 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * 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. + */ +package org.springframework.cloud.release; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; + +import org.apache.maven.model.Model; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; + +/** + * @author Marcin Grzejszczak + */ +class PomReader { + + /** + * Returns a parsed POM + */ + Model readPom(File pom) { + try(Reader reader = new FileReader(pom)) { + MavenXpp3Reader xpp3Reader = new MavenXpp3Reader(); + return xpp3Reader.read(reader); + } + catch (XmlPullParserException | IOException e) { + throw new IllegalStateException("Failed to read file", e); + } + } +} diff --git a/src/main/java/org/springframework/cloud/release/PomUpdater.java b/src/main/java/org/springframework/cloud/release/PomUpdater.java new file mode 100644 index 00000000..881901d2 --- /dev/null +++ b/src/main/java/org/springframework/cloud/release/PomUpdater.java @@ -0,0 +1,130 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * 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. + */ +package org.springframework.cloud.release; + +import java.io.File; +import java.lang.invoke.MethodHandles; +import java.util.Properties; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.maven.model.Model; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.StringUtils; + +import static org.springframework.cloud.release.SpringCloudConstants.BUILD_ARTIFACT_ID; +import static org.springframework.cloud.release.SpringCloudConstants.CLOUD_DEPENDENCIES_ARTIFACT_ID; + +/** + * @author Marcin Grzejszczak + */ +class PomUpdater { + + private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + private final PomReader pomReader = new PomReader(); + + boolean shouldProjectBeUpdated(File rootPom, Versions versions) { + Model model = this.pomReader.readPom(rootPom); + if (!versions.shouldBeUpdated(model.getArtifactId())) { + log.info("Skipping project [{}] since it's not on the list of projects to update", model.getArtifactId()); + return false; + } + log.info("Project [{}] will have its dependencies updated", model.getArtifactId()); + return true; + } + + ModelWrapper updatePom(File pom, Versions versions) { + Model model = this.pomReader.readPom(pom); + boolean dirty = false; + if (isParentPom(model)) { + dirty = updateRootParentIfPossible(versions, model) || dirty ; + dirty = updateVersionIfPossible(versions, model) || dirty ; + } else { + dirty = updateParentVersionIfPossible(versions, model) || dirty; + } + dirty = updateProperties(versions, model) || dirty; + return new ModelWrapper(model, dirty); + } + + private boolean updateParentVersionIfPossible(Versions versions, Model model) { + String version = versions.versionForProject(model.getArtifactId()); + if (StringUtils.isEmpty(version)) { + log.warn("There was no version set for project [{}], skipping parent version setting", model.getArtifactId()); + return false; + } + log.info("Setting parent [{}] version to [{}]", model.getArtifactId(), version); + model.getParent().setVersion(version); + return true; + } + + 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 updateRootParentIfPossible(Versions versions, Model model) { + String parentArtifactId = model.getParent().getArtifactId(); + if (BUILD_ARTIFACT_ID.equals(parentArtifactId) || + CLOUD_DEPENDENCIES_ARTIFACT_ID.equals(parentArtifactId)) { + log.info("Setting version of parent to [{}]", parentArtifactId); + model.getParent().setVersion(versions.scBuildVersion); + return true; + } + log.warn("The parent pom should be referencing Spring Cloud Build but it's not. Won't update it"); + return false; + } + + private boolean updateVersionIfPossible(Versions versions, Model model) { + String version = versions.versionForProject(model.getArtifactId()); + if (StringUtils.isEmpty(version)) { + log.warn("There was no version set for project [{}], skipping version setting", model.getArtifactId()); + return false; + } + log.info("Setting [{}] version to [{}]", model.getArtifactId(), version); + model.setVersion(version); + return true; + } + + /** + * All child poms have a relative path to a parent folder. The parent one + * has an empty path. + */ + private boolean isParentPom(Model model) { + return StringUtils.isEmpty(model.getParent().getRelativePath()); + } +} + +class ModelWrapper { + final Model model; + final boolean dirty; + + ModelWrapper(Model model, boolean dirty) { + this.model = model; + this.dirty = dirty; + } +} \ No newline at end of file diff --git a/src/main/java/org/springframework/cloud/release/ProjectRepo.java b/src/main/java/org/springframework/cloud/release/ProjectRepo.java index d6add4aa..f09307e2 100644 --- a/src/main/java/org/springframework/cloud/release/ProjectRepo.java +++ b/src/main/java/org/springframework/cloud/release/ProjectRepo.java @@ -1,3 +1,18 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * 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. + */ package org.springframework.cloud.release; import java.io.File; diff --git a/src/main/java/org/springframework/cloud/release/ReleaserApplication.java b/src/main/java/org/springframework/cloud/release/ReleaserApplication.java index 0694bb57..dc1438e9 100644 --- a/src/main/java/org/springframework/cloud/release/ReleaserApplication.java +++ b/src/main/java/org/springframework/cloud/release/ReleaserApplication.java @@ -1,3 +1,18 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * 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. + */ package org.springframework.cloud.release; import org.springframework.boot.SpringApplication; diff --git a/src/main/java/org/springframework/cloud/release/SpringCloudConstants.java b/src/main/java/org/springframework/cloud/release/SpringCloudConstants.java new file mode 100644 index 00000000..21e703d7 --- /dev/null +++ b/src/main/java/org/springframework/cloud/release/SpringCloudConstants.java @@ -0,0 +1,31 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * 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. + */ + +package org.springframework.cloud.release; + +/** + * @author Marcin Grzejszczak + */ +final class SpringCloudConstants { + static final String BOOT_STARTER_ARTIFACT_ID = "spring-boot-starter-parent"; + static final String CLOUD_DEPENDENCIES_ARTIFACT_ID = "spring-cloud-dependencies-parent"; + static final String BUILD_ARTIFACT_ID = "spring-cloud-build"; + + private SpringCloudConstants() { + throw new IllegalStateException("Don't instantiate a utility class"); + } + +} diff --git a/src/main/java/org/springframework/cloud/release/Versions.java b/src/main/java/org/springframework/cloud/release/Versions.java index 2f01683f..02980b99 100644 --- a/src/main/java/org/springframework/cloud/release/Versions.java +++ b/src/main/java/org/springframework/cloud/release/Versions.java @@ -10,27 +10,49 @@ import java.util.Set; */ class Versions { - String boot; - String build; + private static final String SPRING_BOOT_PROJECT_NAME = "spring-boot"; + + String bootVersion; + String scBuildVersion; Set projects = new HashSet<>(); - Versions(String boot) { - this.boot = boot; + Versions(String bootVersion) { + this.bootVersion = bootVersion; + this.projects.add(new Project(SPRING_BOOT_PROJECT_NAME, bootVersion)); } - Versions(String build, Set projects) { - this.build = build; - this.projects = projects; + Versions(String scBuildVersion, Set projects) { + this.scBuildVersion = scBuildVersion; + this.projects.addAll(projects); } - Versions(String boot, String build, Set projects) { - this.boot = boot; - this.build = build; - this.projects = projects; + Versions(String bootVersion, String scBuildVersion, Set projects) { + this.bootVersion = bootVersion; + this.scBuildVersion = scBuildVersion; + this.projects.addAll(projects); + } + + String versionForProject(String projectName) { + return this.projects.stream() + .filter(project -> project.name.equals(projectName)) + .findFirst() + .orElse(Project.EMPTY_PROJECT) + .version; + } + + boolean shouldBeUpdated(String projectName) { + return this.projects.stream() + .anyMatch(project -> project.name.equals(projectName)); } } +/** + * @author Marcin Grzejszczak + */ class Project { + + static Project EMPTY_PROJECT = new Project("", ""); + final String name; final String version; diff --git a/src/test/java/org/springframework/cloud/release/AcceptanceTests.java b/src/test/java/org/springframework/cloud/release/AcceptanceTests.java index ce09ba97..c4f8a477 100644 --- a/src/test/java/org/springframework/cloud/release/AcceptanceTests.java +++ b/src/test/java/org/springframework/cloud/release/AcceptanceTests.java @@ -14,8 +14,8 @@ public class AcceptanceTests { - should parse spring-cloud-starter-parent/pom.xml and resolve: - Boot version (x) - should parse spring-cloud-dependencies/pom.xml and resolve: - - Project versions from properties - - Spring Cloud Build version from parent + - Project versions from properties (x) + - Spring Cloud Build version from parent (x) - should update the existing poms with the taken versions */ @Test diff --git a/src/test/java/org/springframework/cloud/release/PomParserTests.java b/src/test/java/org/springframework/cloud/release/PomParserTests.java index 27098b54..e83e2c1b 100644 --- a/src/test/java/org/springframework/cloud/release/PomParserTests.java +++ b/src/test/java/org/springframework/cloud/release/PomParserTests.java @@ -53,7 +53,7 @@ public class PomParserTests { public void should_populate_boot_version() { PomParser parser = new PomParser(this.springCloudReleaseProject); - String bootVersion = parser.bootVersion().boot; + String bootVersion = parser.bootVersion().bootVersion; then(bootVersion).isEqualTo("1.5.1.BUILD-SNAPSHOT"); } @@ -91,24 +91,36 @@ public class PomParserTests { Versions cloudVersions = parser.springCloudVersions(); - then(cloudVersions.build).isEqualTo("1.3.1.BUILD-SNAPSHOT"); - then(cloudVersions.projects) - .contains( - project("spring-cloud-aws", "1.2.0.BUILD-SNAPSHOT"), - project("spring-cloud-bus", "1.3.0.BUILD-SNAPSHOT"), - project("spring-cloud-contract", "1.1.0.BUILD-SNAPSHOT"), - project("spring-cloud-cloudfoundry", "1.1.0.BUILD-SNAPSHOT"), - project("spring-cloud-commons", "1.2.0.BUILD-SNAPSHOT"), - project("spring-cloud-config", "1.3.0.BUILD-SNAPSHOT"), - project("spring-cloud-netflix", "1.3.0.BUILD-SNAPSHOT"), - project("spring-cloud-security", "1.2.0.BUILD-SNAPSHOT"), - project("spring-cloud-consul", "1.2.0.BUILD-SNAPSHOT"), - project("spring-cloud-sleuth", "1.2.0.BUILD-SNAPSHOT"), - project("spring-cloud-stream", "Chelsea.BUILD-SNAPSHOT"), - project("spring-cloud-task", "1.1.2.BUILD-SNAPSHOT"), - project("spring-cloud-vault", "1.0.0.BUILD-SNAPSHOT"), - project("spring-cloud-zookeeper", "1.1.0.BUILD-SNAPSHOT") - ); + then(cloudVersions.scBuildVersion).isEqualTo("1.3.1.BUILD-SNAPSHOT"); + then(cloudVersions.projects).contains(allProjects()); + } + + @Test + public void should_populate_boot_and_cloud_version() { + PomParser parser = new PomParser(this.springCloudReleaseProject); + + Versions cloudVersions = parser.allVersions(); + + then(cloudVersions.bootVersion).isEqualTo("1.5.1.BUILD-SNAPSHOT"); + then(cloudVersions.scBuildVersion).isEqualTo("1.3.1.BUILD-SNAPSHOT"); + then(cloudVersions.projects).contains(allProjects()); + } + + private Project[] allProjects() { + return new Project[] { project("spring-cloud-aws", "1.2.0.BUILD-SNAPSHOT"), + project("spring-cloud-bus", "1.3.0.BUILD-SNAPSHOT"), + project("spring-cloud-contract", "1.1.0.BUILD-SNAPSHOT"), + project("spring-cloud-cloudfoundry", "1.1.0.BUILD-SNAPSHOT"), + project("spring-cloud-commons", "1.2.0.BUILD-SNAPSHOT"), + project("spring-cloud-config", "1.3.0.BUILD-SNAPSHOT"), + project("spring-cloud-netflix", "1.3.0.BUILD-SNAPSHOT"), + project("spring-cloud-security", "1.2.0.BUILD-SNAPSHOT"), + project("spring-cloud-consul", "1.2.0.BUILD-SNAPSHOT"), + project("spring-cloud-sleuth", "1.2.0.BUILD-SNAPSHOT"), + project("spring-cloud-stream", "Chelsea.BUILD-SNAPSHOT"), + project("spring-cloud-task", "1.1.2.BUILD-SNAPSHOT"), + project("spring-cloud-vault", "1.0.0.BUILD-SNAPSHOT"), + project("spring-cloud-zookeeper", "1.1.0.BUILD-SNAPSHOT") }; } Project project(String name, String value) { diff --git a/src/test/java/org/springframework/cloud/release/PomReaderTests.java b/src/test/java/org/springframework/cloud/release/PomReaderTests.java new file mode 100644 index 00000000..244aca0f --- /dev/null +++ b/src/test/java/org/springframework/cloud/release/PomReaderTests.java @@ -0,0 +1,69 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * 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. + */ + +package org.springframework.cloud.release; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +import org.apache.maven.model.Model; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.junit.Before; +import org.junit.Test; + +import static org.assertj.core.api.BDDAssertions.then; +import static org.assertj.core.api.BDDAssertions.thenThrownBy; + +/** + * @author Marcin Grzejszczak + */ +public class PomReaderTests { + + PomReader pomReader = new PomReader(); + File springCloudReleaseProject; + File licenseFile; + + @Before + public void setup() throws URISyntaxException { + URI scRelease = ProjectClonerTests.class.getResource("/projects/spring-cloud-release").toURI(); + this.springCloudReleaseProject = new File(scRelease.getPath(), "pom.xml"); + this.licenseFile = new File(scRelease.getPath(), "LICENSE.txt"); + } + + @Test + public void should_parse_a_valid_pom() { + Model pom = this.pomReader.readPom(this.springCloudReleaseProject); + + then(pom).isNotNull(); + then(pom.getArtifactId()).isEqualTo("spring-cloud-starter-build"); + } + + @Test + public void should_throw_exception_when_file_is_missing() { + thenThrownBy(() -> this.pomReader.readPom(new File("foo/bar"))) + .hasMessage("Failed to read file") + .hasCauseInstanceOf(IOException.class); + } + + @Test + public void should_throw_exception_when_file_is_invalid() { + thenThrownBy(() -> this.pomReader.readPom(this.licenseFile)) + .hasMessage("Failed to read file") + .hasCauseInstanceOf(XmlPullParserException.class); + } +} \ No newline at end of file diff --git a/src/test/java/org/springframework/cloud/release/PomUpdaterTests.java b/src/test/java/org/springframework/cloud/release/PomUpdaterTests.java new file mode 100644 index 00000000..c6fea2e1 --- /dev/null +++ b/src/test/java/org/springframework/cloud/release/PomUpdaterTests.java @@ -0,0 +1,132 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * 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. + */ + +package org.springframework.cloud.release; + +import java.io.File; +import java.net.URISyntaxException; +import java.util.HashSet; +import java.util.Set; + +import org.junit.Test; + +import static org.assertj.core.api.BDDAssertions.then; + +/** + * @author Marcin Grzejszczak + */ +public class PomUpdaterTests { + + Versions versions = new Versions("0.0.1", "0.0.2", projects()); + PomUpdater pomUpdater = new PomUpdater(); + + @Test + public void should_not_update_pom_when_project_is_not_on_the_versions_list() throws Exception { + File springCloudReleasePom = pom("/projects/spring-cloud-release"); + + then(this.pomUpdater.shouldProjectBeUpdated(springCloudReleasePom, this.versions)).isFalse(); + } + + @Test + public void should_update_pom_when_project_is_not_on_the_versions_list() throws Exception { + File springCloudSleuthPom = pom("/projects/spring-cloud-sleuth"); + + then(this.pomUpdater.shouldProjectBeUpdated(springCloudSleuthPom, this.versions)).isTrue(); + } + + @Test + public void should_not_update_the_model_if_no_changes_were_made() throws Exception { + File nonMatchingPom = pom("/projects/project"); + + ModelWrapper model = this.pomUpdater.updatePom(nonMatchingPom, this.versions); + + then(model.dirty).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.updatePom(matchingArtifactId, this.versions); + + then(model.dirty).isTrue(); + then(model.model.getVersion()).isEqualTo("0.0.3.BUILD-SNAPSHOT"); + then(model.model.getParent().getVersion()).isEqualTo("1.3.1.BUILD-SNAPSHOT"); + // 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_parent_is_matched_via_sc_build() throws Exception { + File matchingArtifactId = pom("/projects/project", "pom_matching_parent_v2.xml"); + + ModelWrapper model = this.pomUpdater.updatePom(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_parent_is_matched_via_sc_dependencies_parent() throws Exception { + File matchingArtifactId = pom("/projects/project", "pom_matching_parent.xml"); + + ModelWrapper model = this.pomUpdater.updatePom(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.updatePom(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"); + } + + Set projects() { + Set projects = new HashSet<>(); + projects.add(new Project("spring-cloud-sleuth", "0.0.3.BUILD-SNAPSHOT")); + projects.add(new Project("spring-cloud-vault", "0.0.4.BUILD-SNAPSHOT")); + return projects; + } + + private File pom(String relativePath) throws URISyntaxException { + return pom(relativePath, "pom.xml"); + } + + private File pom(String relativePath, String pomName) throws URISyntaxException { + return new File(new File(ProjectClonerTests.class.getResource(relativePath).toURI()), pomName); + } +} \ No newline at end of file diff --git a/src/test/java/org/springframework/cloud/release/VersionsTests.java b/src/test/java/org/springframework/cloud/release/VersionsTests.java new file mode 100644 index 00000000..ed7205e9 --- /dev/null +++ b/src/test/java/org/springframework/cloud/release/VersionsTests.java @@ -0,0 +1,64 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * 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. + */ + +package org.springframework.cloud.release; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.Test; + +import static org.assertj.core.api.BDDAssertions.then; + +/** + * @author Marcin Grzejszczak + */ +public class VersionsTests { + + Versions versions = new Versions("", projects()); + + @Test + public void should_add_boot_to_versions_when_version_is_created() { + then(new Versions("1.2.3.RELEASE").projects) + .containsExactly(new Project("spring-boot", "1.2.3.RELEASE")); + } + + @Test + public void should_return_true_when_project_is_on_the_list() { + then(this.versions.shouldBeUpdated("foo")).isTrue(); + } + + @Test + public void should_return_false_when_project_is_not_on_the_list() { + then(this.versions.shouldBeUpdated("missing")).isFalse(); + } + + @Test + public void should_return_version_for_present_project() { + then(this.versions.versionForProject("foo")).isEqualTo("bar"); + } + + @Test + public void should_return_empty_string_for_missing_project() { + then(this.versions.versionForProject("missing")).isEmpty(); + } + + Set projects() { + Set projects = new HashSet<>(); + projects.add(new Project("foo", "bar")); + return projects; + } +} \ No newline at end of file diff --git a/src/test/resources/projects/project/pom.xml b/src/test/resources/projects/project/pom.xml new file mode 100644 index 00000000..504000ba --- /dev/null +++ b/src/test/resources/projects/project/pom.xml @@ -0,0 +1,41 @@ + + + + + 4.0.0 + + foo + 1.2.0.BUILD-SNAPSHOT + pom + foo + foo + + + parentGroup + parentArtifactId + 1.3.1.BUILD-SNAPSHOT + + + + + + 1.3.1.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT + + diff --git a/src/test/resources/projects/project/pom_matching_artifact.xml b/src/test/resources/projects/project/pom_matching_artifact.xml new file mode 100644 index 00000000..d504aec8 --- /dev/null +++ b/src/test/resources/projects/project/pom_matching_artifact.xml @@ -0,0 +1,41 @@ + + + + + 4.0.0 + + spring-cloud-sleuth + 1.2.0.BUILD-SNAPSHOT + pom + foo + foo + + + parentGroup + parentArtifactId + 1.3.1.BUILD-SNAPSHOT + + + + + + 1.3.1.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT + + diff --git a/src/test/resources/projects/project/pom_matching_parent.xml b/src/test/resources/projects/project/pom_matching_parent.xml new file mode 100644 index 00000000..324497f5 --- /dev/null +++ b/src/test/resources/projects/project/pom_matching_parent.xml @@ -0,0 +1,41 @@ + + + + + 4.0.0 + + spring-cloud-sleuth + 1.2.0.BUILD-SNAPSHOT + pom + foo + foo + + + org.springframework.cloud + spring-cloud-build + 1.3.1.BUILD-SNAPSHOT + + + + + + 1.3.1.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT + + diff --git a/src/test/resources/projects/project/pom_matching_parent_v2.xml b/src/test/resources/projects/project/pom_matching_parent_v2.xml new file mode 100644 index 00000000..6445397c --- /dev/null +++ b/src/test/resources/projects/project/pom_matching_parent_v2.xml @@ -0,0 +1,41 @@ + + + + + 4.0.0 + + spring-cloud-sleuth + 1.2.0.BUILD-SNAPSHOT + pom + foo + foo + + + org.springframework.cloud + spring-cloud-dependencies-parent + 1.3.1.BUILD-SNAPSHOT + + + + + + 1.3.1.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT + + diff --git a/src/test/resources/projects/project/pom_matching_properties.xml b/src/test/resources/projects/project/pom_matching_properties.xml new file mode 100644 index 00000000..a59e3487 --- /dev/null +++ b/src/test/resources/projects/project/pom_matching_properties.xml @@ -0,0 +1,41 @@ + + + + + 4.0.0 + + spring-cloud-sleuth + 1.2.0.BUILD-SNAPSHOT + pom + foo + foo + + + org.springframework.cloud + spring-cloud-build + 1.3.1.BUILD-SNAPSHOT + + + + + + 1.3.1.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT + + diff --git a/src/test/resources/projects/sample/pom.xml b/src/test/resources/projects/spring-cloud-sleuth/pom.xml similarity index 100% rename from src/test/resources/projects/sample/pom.xml rename to src/test/resources/projects/spring-cloud-sleuth/pom.xml diff --git a/src/test/resources/projects/sample/spring-cloud-sleuth-core/pom.xml b/src/test/resources/projects/spring-cloud-sleuth/spring-cloud-sleuth-core/pom.xml similarity index 100% rename from src/test/resources/projects/sample/spring-cloud-sleuth-core/pom.xml rename to src/test/resources/projects/spring-cloud-sleuth/spring-cloud-sleuth-core/pom.xml diff --git a/src/test/resources/projects/sample/spring-cloud-sleuth-dependencies/pom.xml b/src/test/resources/projects/spring-cloud-sleuth/spring-cloud-sleuth-dependencies/pom.xml similarity index 100% rename from src/test/resources/projects/sample/spring-cloud-sleuth-dependencies/pom.xml rename to src/test/resources/projects/spring-cloud-sleuth/spring-cloud-sleuth-dependencies/pom.xml