From e612aab3a889d3bcf12a90efca38b71a4f3a71ed Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 12 Feb 2018 15:49:48 +0100 Subject: [PATCH] Improve dependency order in generated build Closes gh-601 --- .../generator/ProjectGenerator.java | 30 ++++++++++++++++++- .../generator/ProjectGeneratorTests.java | 30 ++++++++++++++----- .../test/generator/GradleBuildAssert.java | 7 ++++- 3 files changed, 58 insertions(+), 9 deletions(-) diff --git a/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectGenerator.java b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectGenerator.java index ccb5fc66..920afc96 100644 --- a/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectGenerator.java +++ b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectGenerator.java @@ -689,10 +689,38 @@ public class ProjectGenerator { private static List filterDependencies(List dependencies, String scope) { return dependencies.stream().filter(dep -> scope.equals(dep.getScope())) - .sorted(Comparator.comparing(MetadataElement::getId)) + .sorted(DependencyComparator.INSTANCE) .collect(Collectors.toList()); } + private static class DependencyComparator implements Comparator { + + private static final DependencyComparator INSTANCE = new DependencyComparator(); + + @Override + public int compare(Dependency o1, Dependency o2) { + if (isSpringBootDependency(o1) && isSpringBootDependency(o2)) { + return o1.getArtifactId().compareTo(o2.getArtifactId()); + } + if (isSpringBootDependency(o1)) { + return -1; + } + if (isSpringBootDependency(o2)) { + return 1; + } + int group = o1.getGroupId().compareTo(o2.getGroupId()); + if (group != 0) { + return group; + } + return o1.getArtifactId().compareTo(o2.getArtifactId()); + } + + private boolean isSpringBootDependency(Dependency dependency) { + return dependency.getGroupId().startsWith("org.springframework.boot"); + } + + } + private static class Imports { private final List statements = new ArrayList<>(); diff --git a/initializr-generator/src/test/java/io/spring/initializr/generator/ProjectGeneratorTests.java b/initializr-generator/src/test/java/io/spring/initializr/generator/ProjectGeneratorTests.java index d3526655..52cd0e81 100644 --- a/initializr-generator/src/test/java/io/spring/initializr/generator/ProjectGeneratorTests.java +++ b/initializr-generator/src/test/java/io/spring/initializr/generator/ProjectGeneratorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -34,8 +34,7 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; -import static org.hamcrest.CoreMatchers.containsString; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; /** @@ -817,6 +816,23 @@ public class ProjectGeneratorTests extends AbstractProjectGeneratorTests { .equalsTo(new ClassPathResource("project/gradle/gitignore.gen")); } + @Test + public void dependencyOrderSpringBootTakesPrecedence() { + Dependency depOne = Dependency.withId("one", "org.acme", "first", "1.2.3"); + Dependency depTwo = Dependency.withId("two", "com.example", "second", "1.2.3"); + InitializrMetadata metadata = InitializrMetadataTestBuilder.withDefaults() + .addDependencyGroup("core", "web", "security", "data-jpa") + .addDependencyGroup("sample", depOne, depTwo).build(); + applyMetadata(metadata); + ProjectRequest request = createProjectRequest("one", "web", "two", "data-jpa"); + assertThat(generateGradleBuild(request).getGradleBuild()) + .containsSequence( + "compile('org.springframework.boot:spring-boot-starter-data-jpa')", + "compile('org.springframework.boot:spring-boot-starter-web')", + "compile('com.example:second:1.2.3')", + "compile('org.acme:first:1.2.3')"); + } + @Test public void invalidProjectTypeMavenPom() { ProjectRequest request = createProjectRequest("web"); @@ -843,7 +859,7 @@ public class ProjectGeneratorTests extends AbstractProjectGeneratorTests { fail("Should have failed to generate project"); } catch (InvalidProjectRequestException ex) { - assertThat(ex.getMessage(), containsString("foo-bar")); + assertThat(ex.getMessage()).contains("foo-bar"); verifyProjectFailedEventFor(request, ex); } } @@ -857,7 +873,7 @@ public class ProjectGeneratorTests extends AbstractProjectGeneratorTests { fail("Should have failed to generate project"); } catch (InvalidProjectRequestException ex) { - assertThat(ex.getMessage(), containsString("foo-bar")); + assertThat(ex.getMessage()).contains("foo-bar"); verifyProjectFailedEventFor(request, ex); } } @@ -871,7 +887,7 @@ public class ProjectGeneratorTests extends AbstractProjectGeneratorTests { fail("Should have failed to generate project"); } catch (InvalidProjectRequestException ex) { - assertThat(ex.getMessage(), containsString("foo-bar")); + assertThat(ex.getMessage()).contains("foo-bar"); verifyProjectFailedEventFor(request, ex); } } @@ -885,7 +901,7 @@ public class ProjectGeneratorTests extends AbstractProjectGeneratorTests { fail("Should have failed to generate project"); } catch (InvalidProjectRequestException ex) { - assertThat(ex.getMessage(), containsString("foo-bar")); + assertThat(ex.getMessage()).contains("foo-bar"); verifyProjectFailedEventFor(request, ex); } } diff --git a/initializr-generator/src/test/java/io/spring/initializr/test/generator/GradleBuildAssert.java b/initializr-generator/src/test/java/io/spring/initializr/test/generator/GradleBuildAssert.java index d8c1a0ca..0f9601dc 100644 --- a/initializr-generator/src/test/java/io/spring/initializr/test/generator/GradleBuildAssert.java +++ b/initializr-generator/src/test/java/io/spring/initializr/test/generator/GradleBuildAssert.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -77,4 +77,9 @@ public class GradleBuildAssert { content.contains(expression)); return this; } + + public String getGradleBuild() { + return this.content; + } + }