diff --git a/CHANGES.md b/CHANGES.md index af3112797b..3a562b8f3b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ You might be looking for: ### Version 1.15.0-SNAPSHOT - TBD (javadoc [lib](https://diffplug.github.io/spotless/javadoc/spotless-lib/snapshot/) [lib-extra](https://diffplug.github.io/spotless/javadoc/spotless-lib-extra/snapshot/), [snapshot repo](https://oss.sonatype.org/content/repositories/snapshots/com/diffplug/spotless/)) +* Extended dependency provisioner to exclude transitives on request ([#297](https://github.com/diffplug/spotless/pull/297)).This prevents unnecessary downloads of unused transitive dependencies for Eclipse based formatter steps. * Updated default groovy-eclipse from 4.8.0 to 4.8.1 ([#288](https://github.com/diffplug/spotless/pull/288)). New version is based on [Groovy-Eclipse 3.0.0](https://github.com/groovy/groovy-eclipse/wiki/3.0.0-Release-Notes). * Integrated Eclipse WTP formatter ([#290](https://github.com/diffplug/spotless/pull/290)) * Updated JSR305 annotation from 3.0.0 to 3.0.2 ([#274](https://github.com/diffplug/spotless/pull/274)) diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/EclipseBasedStepBuilder.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/EclipseBasedStepBuilder.java index 5cb1dbd9f2..5ce6a6d6e9 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/EclipseBasedStepBuilder.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/EclipseBasedStepBuilder.java @@ -152,7 +152,7 @@ public static class State implements Serializable { /** State constructor expects that all passed items are not modified afterwards */ protected State(String formatterStepExt, Provisioner jarProvisioner, List dependencies, Iterable settingsFiles) throws IOException { - this.jarState = JarState.from(dependencies, jarProvisioner); + this.jarState = JarState.withoutTransitives(dependencies, jarProvisioner); this.settingsFiles = FileSignature.signAsList(settingsFiles); this.formatterStepExt = formatterStepExt; } diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.7.3a.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.7.3a.lockfile index 538073263f..2aae28f4ba 100644 --- a/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.7.3a.lockfile +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/eclipse_wtp_formatters/v4.7.3a.lockfile @@ -17,10 +17,8 @@ org.eclipse.platform:org.eclipse.equinox.app:1.3.500 org.eclipse.platform:org.eclipse.equinox.common:3.10.0 org.eclipse.platform:org.eclipse.equinox.preferences:3.7.100 org.eclipse.platform:org.eclipse.equinox.registry:3.8.0 -#Spotless currently loads all transitive dependencies. -#jface requires platform specific JARs (not used by formatter), which are not hosted via M2. -#org.eclipse.platform:org.eclipse.jface.text:3.13.0 -#org.eclipse.platform:org.eclipse.jface:3.14.0 +org.eclipse.platform:org.eclipse.jface.text:3.13.0 +org.eclipse.platform:org.eclipse.jface:3.14.0 org.eclipse.platform:org.eclipse.osgi.services:3.7.0 org.eclipse.platform:org.eclipse.osgi:3.13.0 org.eclipse.platform:org.eclipse.text:3.6.300 diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.8.0.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.8.0.lockfile index bda127d96f..1cda67e29c 100644 --- a/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.8.0.lockfile +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.8.0.lockfile @@ -12,9 +12,7 @@ org.eclipse.platform:org.eclipse.equinox.app:1.3.500 org.eclipse.platform:org.eclipse.equinox.common:3.10.0 org.eclipse.platform:org.eclipse.equinox.preferences:3.7.100 org.eclipse.platform:org.eclipse.equinox.registry:3.8.0 -#Spotless currently loads all transitive dependencies. -#jface requires platform specific JARs (not used by formatter), which are not hosted via M2. -#org.eclipse.platform:org.eclipse.jface.text:3.13.0 -#org.eclipse.platform:org.eclipse.jface:3.14.0 +org.eclipse.platform:org.eclipse.jface.text:3.13.0 +org.eclipse.platform:org.eclipse.jface:3.14.0 org.eclipse.platform:org.eclipse.osgi:3.13.0 org.eclipse.platform:org.eclipse.text:3.6.300 \ No newline at end of file diff --git a/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.8.1.lockfile b/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.8.1.lockfile index e1bcf464d5..952bcd326b 100644 --- a/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.8.1.lockfile +++ b/lib-extra/src/main/resources/com/diffplug/spotless/extra/groovy_eclipse_formatter/v4.8.1.lockfile @@ -12,9 +12,7 @@ org.eclipse.platform:org.eclipse.equinox.app:1.3.500 org.eclipse.platform:org.eclipse.equinox.common:3.10.0 org.eclipse.platform:org.eclipse.equinox.preferences:3.7.100 org.eclipse.platform:org.eclipse.equinox.registry:3.8.0 -#Spotless currently loads all transitive dependencies. -#jface requires platform specific JARs (not used by formatter), which are not hosted via M2. -#org.eclipse.platform:org.eclipse.jface.text:3.13.0 -#org.eclipse.platform:org.eclipse.jface:3.14.0 +org.eclipse.platform:org.eclipse.jface.text:3.13.0 +org.eclipse.platform:org.eclipse.jface:3.14.0 org.eclipse.platform:org.eclipse.osgi:3.13.0 org.eclipse.platform:org.eclipse.text:3.6.300 \ No newline at end of file diff --git a/lib/src/main/java/com/diffplug/spotless/JarState.java b/lib/src/main/java/com/diffplug/spotless/JarState.java index faaaa43ca3..2b7d15e527 100644 --- a/lib/src/main/java/com/diffplug/spotless/JarState.java +++ b/lib/src/main/java/com/diffplug/spotless/JarState.java @@ -54,24 +54,37 @@ public final class JarState implements Serializable { @SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED") private final transient Set jars; + @Deprecated // internal public JarState(String mavenCoordinate, FileSignature fileSignature, Set jars) { this(Arrays.asList(mavenCoordinate), fileSignature, jars); } + @Deprecated // internal public JarState(Collection mavenCoordinates, FileSignature fileSignature, Set jars) { this.mavenCoordinates = new TreeSet(mavenCoordinates); this.fileSignature = fileSignature; this.jars = jars; } + /** Provisions the given maven coordinate and its transitive dependencies. */ public static JarState from(String mavenCoordinate, Provisioner provisioner) throws IOException { return from(Collections.singletonList(mavenCoordinate), provisioner); } + /** Provisions the given maven coordinates and their transitive dependencies. */ public static JarState from(Collection mavenCoordinates, Provisioner provisioner) throws IOException { - Objects.requireNonNull(provisioner, "provisioner"); + return provisionWithTransitives(true, mavenCoordinates, provisioner); + } + + /** Provisions the given maven coordinates without their transitive dependencies. */ + public static JarState withoutTransitives(Collection mavenCoordinates, Provisioner provisioner) throws IOException { + return provisionWithTransitives(false, mavenCoordinates, provisioner); + } + + private static JarState provisionWithTransitives(boolean withTransitives, Collection mavenCoordinates, Provisioner provisioner) throws IOException { Objects.requireNonNull(mavenCoordinates, "mavenCoordinates"); - Set jars = provisioner.provisionWithDependencies(mavenCoordinates); + Objects.requireNonNull(provisioner, "provisioner"); + Set jars = provisioner.provisionWithTransitives(withTransitives, mavenCoordinates); if (jars.isEmpty()) { throw new NoSuchElementException("Resolved to an empty result: " + mavenCoordinates.stream().collect(Collectors.joining(", "))); } diff --git a/lib/src/main/java/com/diffplug/spotless/Provisioner.java b/lib/src/main/java/com/diffplug/spotless/Provisioner.java index 6da15c010a..cb39e7f993 100644 --- a/lib/src/main/java/com/diffplug/spotless/Provisioner.java +++ b/lib/src/main/java/com/diffplug/spotless/Provisioner.java @@ -25,17 +25,30 @@ * Spotless' dependencies minimal. */ public interface Provisioner { + + /** Method interface has been extended to {@link Provisioner#provisionWithTransitives(boolean, Collection)}. */ + @Deprecated + public default Set provisionWithDependencies(Collection mavenCoordinates) { + return provisionWithTransitives(true, mavenCoordinates); + } + + /** Method interface has been extended to {@link Provisioner#provisionWithTransitives(boolean, String...)}. */ + @Deprecated + public default Set provisionWithDependencies(String... mavenCoordinates) { + return provisionWithDependencies(Arrays.asList(mavenCoordinates)); + } + /** - * Given a set of maven coordinates, returns a set of jars which - * include all of the specified coordinates and their dependencies. + * Given a set of Maven coordinates, returns a set of jars which include all + * of the specified coordinates and optionally their transitive dependencies. */ - public Set provisionWithDependencies(Collection mavenCoordinates); + public default Set provisionWithTransitives(boolean withTransitives, String... mavenCoordinates) { + return provisionWithTransitives(withTransitives, Arrays.asList(mavenCoordinates)); + } /** - * Given a set of maven coordinates, returns a set of jars which - * include all of the specified coordinates and their dependencies. + * Given a set of Maven coordinates, returns a set of jars which include all + * of the specified coordinates and optionally their transitive dependencies. */ - public default Set provisionWithDependencies(String... mavenCoordinates) { - return provisionWithDependencies(Arrays.asList(mavenCoordinates)); - } + public Set provisionWithTransitives(boolean withTransitives, Collection mavenCoordinates); } diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleProvisioner.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleProvisioner.java index a2793f8e47..1e902f881f 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleProvisioner.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/GradleProvisioner.java @@ -32,13 +32,14 @@ private GradleProvisioner() {} public static Provisioner fromProject(Project project) { Objects.requireNonNull(project); - return mavenCoords -> { + return (withTransitives, mavenCoords) -> { try { Dependency[] deps = mavenCoords.stream() .map(project.getBuildscript().getDependencies()::create) .toArray(Dependency[]::new); Configuration config = project.getRootProject().getBuildscript().getConfigurations().detachedConfiguration(deps); config.setDescription(mavenCoords.toString()); + config.setTransitive(withTransitives); return config.resolve(); } catch (Exception e) { logger.log(Level.SEVERE, @@ -53,4 +54,5 @@ public static Provisioner fromProject(Project project) { } private static final Logger logger = Logger.getLogger(GradleProvisioner.class.getName()); + } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/ArtifactResolver.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/ArtifactResolver.java index bf1379e0d5..379bf25cff 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/ArtifactResolver.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/ArtifactResolver.java @@ -41,7 +41,8 @@ public class ArtifactResolver { - private static final DependencyFilter ACCEPT_ALL_FILTER = (node, parents) -> true; + private static final DependencyFilter ACCEPT_ALL = (node, parents) -> true; + private static final DependencyFilter FILTER_TRANSITIVES = (node, parents) -> parents.size() <= 1; private final RepositorySystem repositorySystem; private final RepositorySystemSession session; @@ -56,19 +57,28 @@ public ArtifactResolver(RepositorySystem repositorySystem, RepositorySystemSessi this.log = Objects.requireNonNull(log); } - /** Use {@link ArtifactResolver#resolve(Collection) instead.} */ + /** Use {@link ArtifactResolver#resolve(boolean, Collection)) instead.} */ @Deprecated public Set resolve(String mavenCoordinate) { - return resolve(Arrays.asList(mavenCoordinate)); + return resolve(true, Arrays.asList(mavenCoordinate)); } - public Set resolve(Collection mavenCoordinate) { - List dependencies = mavenCoordinate.stream() + /** + * Given a set of maven coordinates, returns a set of jars which include all + * of the specified coordinates and optionally their transitive dependencies. + */ + public Set resolve(boolean withTransitives, Collection mavenCoordinates) { + List dependencies = mavenCoordinates.stream() .map(coordinateString -> new DefaultArtifact(coordinateString)) .map(artifact -> new Dependency(artifact, null)) .collect(toList()); - CollectRequest collectRequest = new CollectRequest((Dependency) null, dependencies, repositories); - DependencyRequest dependencyRequest = new DependencyRequest(collectRequest, ACCEPT_ALL_FILTER); + CollectRequest collectRequest = new CollectRequest(dependencies, null, repositories); + DependencyRequest dependencyRequest; + if (withTransitives) { + dependencyRequest = new DependencyRequest(collectRequest, ACCEPT_ALL); + } else { + dependencyRequest = new DependencyRequest(collectRequest, FILTER_TRANSITIVES); + } DependencyResult dependencyResult = resolveDependencies(dependencyRequest); diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/MavenProvisioner.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/MavenProvisioner.java index 5da8e792f7..2ce571a09d 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/MavenProvisioner.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/MavenProvisioner.java @@ -24,5 +24,4 @@ private MavenProvisioner() {} public static Provisioner create(ArtifactResolver artifactResolver) { return artifactResolver::resolve; } - } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenProvisionerTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenProvisionerTest.java index ad077c99e4..c5d6201f0d 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenProvisionerTest.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenProvisionerTest.java @@ -20,7 +20,7 @@ public class MavenProvisionerTest extends MavenIntegrationTest { @Test - public void testMultipleDependencies() throws Exception { + public void testMultipleDependenciesExcludingTransitives() throws Exception { writePomWithJavaSteps( "", " 4.8.0", @@ -30,7 +30,7 @@ public void testMultipleDependencies() throws Exception { } @Test - public void testSingleDependency() throws Exception { + public void testSingleDependencyIncludingTransitives() throws Exception { writePomWithJavaSteps( "", " 1.2", diff --git a/testlib/src/main/java/com/diffplug/spotless/TestProvisioner.java b/testlib/src/main/java/com/diffplug/spotless/TestProvisioner.java index f2ccfe731a..e5852d7c56 100644 --- a/testlib/src/main/java/com/diffplug/spotless/TestProvisioner.java +++ b/testlib/src/main/java/com/diffplug/spotless/TestProvisioner.java @@ -52,11 +52,12 @@ private static Supplier createLazyWithRepositories(Consumer { Project project = ProjectBuilder.builder().build(); repoConfig.accept(project.getRepositories()); - return mavenCoords -> { + return (withTransitives, mavenCoords) -> { Dependency[] deps = mavenCoords.stream() .map(project.getDependencies()::create) .toArray(Dependency[]::new); Configuration config = project.getConfigurations().detachedConfiguration(deps); + config.setTransitive(withTransitives); config.setDescription(mavenCoords.toString()); try { return config.resolve(); @@ -85,11 +86,11 @@ private static Provisioner caching(String name, Supplier input) { } else { cached = new HashMap<>(); } - return mavenCoords -> { + return (withTransitives, mavenCoords) -> { Box wasChanged = Box.of(false); ImmutableSet result = cached.computeIfAbsent(ImmutableSet.copyOf(mavenCoords), coords -> { wasChanged.set(true); - return ImmutableSet.copyOf(input.get().provisionWithDependencies(coords)); + return ImmutableSet.copyOf(input.get().provisionWithTransitives(withTransitives, coords)); }); if (wasChanged.get()) { try (ObjectOutputStream outputStream = new ObjectOutputStream(Files.asByteSink(cacheFile).openBufferedStream())) { diff --git a/testlib/src/test/java/com/diffplug/spotless/ProvisionerTest.java b/testlib/src/test/java/com/diffplug/spotless/ProvisionerTest.java index 1c7f8ea376..adc26b5318 100644 --- a/testlib/src/test/java/com/diffplug/spotless/ProvisionerTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/ProvisionerTest.java @@ -24,8 +24,9 @@ public class ProvisionerTest { @Test - public void testManipulation() { - Provisioner provisioner = deps -> deps.stream().map(File::new).collect(Collectors.toSet()); + @Deprecated + public void testManipulationDeprecated() { + Provisioner provisioner = (withTransitives, deps) -> deps.stream().map(File::new).collect(Collectors.toSet()); Assertions.assertThat(provisioner.provisionWithDependencies("a")) .containsExactlyInAnyOrder(new File("a")); Assertions.assertThat(provisioner.provisionWithDependencies("a", "a")) @@ -33,4 +34,15 @@ public void testManipulation() { Assertions.assertThat(provisioner.provisionWithDependencies(Arrays.asList("a", "a"))) .containsExactlyInAnyOrder(new File("a")); } + + @Test + public void testManipulation() { + Provisioner provisioner = (withTransitives, deps) -> deps.stream().map(File::new).collect(Collectors.toSet()); + Assertions.assertThat(provisioner.provisionWithTransitives(true, "a")) + .containsExactlyInAnyOrder(new File("a")); + Assertions.assertThat(provisioner.provisionWithTransitives(true, "a", "a")) + .containsExactlyInAnyOrder(new File("a")); + Assertions.assertThat(provisioner.provisionWithTransitives(true, Arrays.asList("a", "a"))) + .containsExactlyInAnyOrder(new File("a")); + } }