diff --git a/initializr-web/src/main/java/io/spring/initializr/web/support/SpringBootMetadataReader.java b/initializr-web/src/main/java/io/spring/initializr/web/support/SpringBootMetadataReader.java index e519fa16..48e51845 100644 --- a/initializr-web/src/main/java/io/spring/initializr/web/support/SpringBootMetadataReader.java +++ b/initializr-web/src/main/java/io/spring/initializr/web/support/SpringBootMetadataReader.java @@ -23,6 +23,9 @@ import java.util.List; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; +import io.spring.initializr.generator.version.Version; +import io.spring.initializr.generator.version.Version.Qualifier; +import io.spring.initializr.generator.version.VersionParser; import io.spring.initializr.metadata.DefaultMetadataElement; import org.springframework.web.client.RestTemplate; @@ -56,14 +59,53 @@ class SpringBootMetadataReader { ArrayNode releases = (ArrayNode) this.content.get("projectReleases"); List list = new ArrayList<>(); for (JsonNode node : releases) { - DefaultMetadataElement version = new DefaultMetadataElement(); - version.setId(node.get("version").textValue()); - String name = node.get("versionDisplayName").textValue(); - version.setName(node.get("snapshot").booleanValue() ? name + " (SNAPSHOT)" : name); - version.setDefault(node.get("current").booleanValue()); - list.add(version); + DefaultMetadataElement versionMetadata = parseVersionMetadata(node); + if (versionMetadata != null) { + list.add(versionMetadata); + } } return list; } + private DefaultMetadataElement parseVersionMetadata(JsonNode node) { + String versionId = node.get("version").textValue(); + Version version = VersionParser.DEFAULT.safeParse(versionId); + if (version == null) { + return null; + } + DefaultMetadataElement versionMetadata = new DefaultMetadataElement(); + versionMetadata.setId(versionId); + versionMetadata.setName(determineDisplayName(version)); + versionMetadata.setDefault(node.get("current").booleanValue()); + return versionMetadata; + } + + private String determineDisplayName(Version version) { + StringBuilder sb = new StringBuilder(); + sb.append(version.getMajor()).append(".").append(version.getMinor()).append(".").append(version.getPatch()); + if (version.getQualifier() != null) { + sb.append(determineSuffix(version.getQualifier())); + } + return sb.toString(); + } + + private String determineSuffix(Qualifier qualifier) { + String id = qualifier.getId(); + if (id.equals("RELEASE")) { + return ""; + } + StringBuilder sb = new StringBuilder(" ("); + if (id.contains("SNAPSHOT")) { + sb.append("SNAPSHOT"); + } + else { + sb.append(id); + if (qualifier.getVersion() != null) { + sb.append(qualifier.getVersion()); + } + } + sb.append(")"); + return sb.toString(); + } + } diff --git a/initializr-web/src/test/java/io/spring/initializr/web/support/DefaultInitializrMetadataUpdateStrategyTests.java b/initializr-web/src/test/java/io/spring/initializr/web/support/DefaultInitializrMetadataUpdateStrategyTests.java index f9540938..54b2f734 100755 --- a/initializr-web/src/test/java/io/spring/initializr/web/support/DefaultInitializrMetadataUpdateStrategyTests.java +++ b/initializr-web/src/test/java/io/spring/initializr/web/support/DefaultInitializrMetadataUpdateStrategyTests.java @@ -70,7 +70,7 @@ class DefaultInitializrMetadataUpdateStrategyTests { assertThat(updatedMetadata.getBootVersions()).isNotNull(); List updatedBootVersions = updatedMetadata.getBootVersions().getContent(); assertThat(updatedBootVersions).hasSize(5); - assertBootVersion(updatedBootVersions.get(0), "2.5.0-M1", false); + assertBootVersion(updatedBootVersions.get(0), "2.5.0 (M1)", false); assertBootVersion(updatedBootVersions.get(1), "2.4.1 (SNAPSHOT)", false); assertBootVersion(updatedBootVersions.get(2), "2.4.0", true); assertBootVersion(updatedBootVersions.get(3), "2.3.8 (SNAPSHOT)", false); @@ -91,7 +91,7 @@ class DefaultInitializrMetadataUpdateStrategyTests { assertThat(updatedMetadata.getBootVersions()).isNotNull(); List updatedBootVersions = updatedMetadata.getBootVersions().getContent(); assertThat(updatedBootVersions).hasSize(5); - assertBootVersion(updatedBootVersions.get(0), "2.5.0-M1", true); + assertBootVersion(updatedBootVersions.get(0), "2.5.0 (M1)", true); assertBootVersion(updatedBootVersions.get(1), "2.4.1 (SNAPSHOT)", false); assertBootVersion(updatedBootVersions.get(2), "2.4.0", false); assertBootVersion(updatedBootVersions.get(3), "2.3.8 (SNAPSHOT)", false); diff --git a/initializr-web/src/test/java/io/spring/initializr/web/support/SpringBootMetadataReaderTests.java b/initializr-web/src/test/java/io/spring/initializr/web/support/SpringBootMetadataReaderTests.java index 83133b07..68535988 100755 --- a/initializr-web/src/test/java/io/spring/initializr/web/support/SpringBootMetadataReaderTests.java +++ b/initializr-web/src/test/java/io/spring/initializr/web/support/SpringBootMetadataReaderTests.java @@ -57,7 +57,7 @@ class SpringBootMetadataReaderTests { List versions = new SpringBootMetadataReader(this.objectMapper, this.restTemplate, this.metadata.getConfiguration().getEnv().getSpringBootMetadataUrl()).getBootVersions(); assertThat(versions).hasSize(5); - assertSpringBootVersion(versions.get(0), "2.5.0-M1", "2.5.0-M1", false); + assertSpringBootVersion(versions.get(0), "2.5.0-M1", "2.5.0 (M1)", false); assertSpringBootVersion(versions.get(1), "2.4.1-SNAPSHOT", "2.4.1 (SNAPSHOT)", false); assertSpringBootVersion(versions.get(2), "2.4.0", "2.4.0", true); assertSpringBootVersion(versions.get(3), "2.3.8.BUILD-SNAPSHOT", "2.3.8 (SNAPSHOT)", false); @@ -65,6 +65,18 @@ class SpringBootMetadataReaderTests { this.server.verify(); } + @Test + void readAvailableVersionsWithInvalidVersion() throws IOException { + this.server.expect(requestTo("https://spring.io/project_metadata/spring-boot")).andRespond(withSuccess( + new ClassPathResource("metadata/sagan/spring-boot-invalid-version.json"), MediaType.APPLICATION_JSON)); + List versions = new SpringBootMetadataReader(this.objectMapper, this.restTemplate, + this.metadata.getConfiguration().getEnv().getSpringBootMetadataUrl()).getBootVersions(); + assertThat(versions).hasSize(2); + assertSpringBootVersion(versions.get(0), "2.5.0-M1", "2.5.0 (M1)", false); + assertSpringBootVersion(versions.get(1), "2.4.0", "2.4.0", true); + this.server.verify(); + } + private void assertSpringBootVersion(DefaultMetadataElement actual, String id, String name, boolean defaultVersion) { assertThat(actual.getId()).isEqualTo(id); diff --git a/initializr-web/src/test/resources/metadata/sagan/spring-boot-invalid-version.json b/initializr-web/src/test/resources/metadata/sagan/spring-boot-invalid-version.json new file mode 100644 index 00000000..7479422a --- /dev/null +++ b/initializr-web/src/test/resources/metadata/sagan/spring-boot-invalid-version.json @@ -0,0 +1,66 @@ +{ + "id": "spring-boot", + "name": "Spring Boot", + "repoUrl": "https://github.com/spring-projects/spring-boot", + "siteUrl": "https://projects.spring.io/spring-boot", + "category": "active", + "stackOverflowTags": "spring-boot", + "projectReleases": [ + { + "releaseStatus": "SNAPSHOT", + "refDocUrl": "https://docs.spring.io/spring-boot/docs/2.5.0-M1/reference/htmlsingle/", + "apiDocUrl": "https://docs.spring.io/spring-boot/docs/2.5.0-M1/api/", + "groupId": "org.springframework.boot", + "artifactId": "spring-boot", + "repository": { + "id": "spring-milestones", + "name": "Spring Milestones", + "url": "https://repo.spring.io/libs-milestone", + "snapshotsEnabled": false + }, + "preRelease": true, + "generalAvailability": false, + "versionDisplayName": "2.5.0-M1", + "current": false, + "snapshot": false, + "version": "2.5.0-M1" + }, + { + "releaseStatus": "SNAPSHOT", + "refDocUrl": "https://docs.spring.io/spring-boot/docs/2.4.1-SNAPSHOT/reference/htmlsingle/", + "apiDocUrl": "https://docs.spring.io/spring-boot/docs/2.4.1-SNAPSHOT/api/", + "groupId": "org.springframework.boot", + "artifactId": "spring-boot", + "repository": { + "id": "spring-snapshots", + "name": "Spring Snapshots", + "url": "https://repo.spring.io/libs-snapshot", + "snapshotsEnabled": true + }, + "preRelease": false, + "generalAvailability": false, + "versionDisplayName": "2.4.1", + "current": false, + "snapshot": true, + "version": "Not a valid version" + }, + { + "releaseStatus": "GENERAL_AVAILABILITY", + "refDocUrl": "https://docs.spring.io/spring-boot/docs/2.4.0/reference/htmlsingle/", + "apiDocUrl": "https://docs.spring.io/spring-boot/docs/2.4.0/api/", + "groupId": "org.springframework.boot", + "artifactId": "spring-boot", + "repository": null, + "preRelease": false, + "generalAvailability": true, + "versionDisplayName": "2.4.0", + "current": true, + "snapshot": false, + "version": "2.4.0" + } + ], + "aggregator": false, + "stackOverflowTagList": [ + "spring-boot" + ] +} \ No newline at end of file