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 4f48a5ed74..39003aab27 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 @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 DiffPlug + * Copyright 2016-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; -import java.util.Optional; import java.util.Properties; import com.diffplug.common.base.Errors; @@ -157,7 +156,7 @@ public static class State implements Serializable { /** State constructor expects that all passed items are not modified afterwards */ protected State(String formatterVersion, String formatterStepExt, Provisioner jarProvisioner, List dependencies, Iterable settingsFiles) throws IOException { - this.jarState = JarState.withoutTransitives(dependencies, jarProvisioner); + this.jarState = JarState.from(dependencies, jarProvisioner, false); this.settingsFiles = FileSignature.signAsList(settingsFiles); this.formatterStepExt = formatterStepExt; semanticVersion = convertEclipseVersion(formatterVersion); @@ -187,12 +186,6 @@ public Properties getPreferences() { return preferences.getProperties(); } - /** Returns first coordinate from sorted set that starts with a given prefix.*/ - public Optional getMavenCoordinate(String prefix) { - return jarState.getMavenCoordinates().stream() - .filter(coordinate -> coordinate.startsWith(prefix)).findFirst(); - } - /** * Load class based on the given configuration of JAR provider and Maven coordinates. * Different class loader instances are provided in the following scenarios: diff --git a/lib/src/main/java/com/diffplug/spotless/JarState.java b/lib/src/main/java/com/diffplug/spotless/JarState.java index 48686c49f8..d0a3908413 100644 --- a/lib/src/main/java/com/diffplug/spotless/JarState.java +++ b/lib/src/main/java/com/diffplug/spotless/JarState.java @@ -25,7 +25,6 @@ import java.util.NoSuchElementException; import java.util.Objects; import java.util.Set; -import java.util.TreeSet; import java.util.stream.Collectors; /** @@ -38,46 +37,43 @@ */ public final class JarState implements Serializable { private static final long serialVersionUID = 1L; - - @Deprecated - private final Set mavenCoordinates; private final FileSignature fileSignature; - private JarState(Collection mavenCoordinates, FileSignature fileSignature) { - this.mavenCoordinates = new TreeSet<>(mavenCoordinates); + private JarState(FileSignature fileSignature) { this.fileSignature = fileSignature; } /** 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); + public static JarState from(Object dependency, Provisioner provisioner) throws IOException { + final Collection mavenCoordinates; + if (dependency instanceof Collection) { + mavenCoordinates = (Collection) dependency; + } else { + mavenCoordinates = Collections.singletonList(dependency); + } + return from(mavenCoordinates, provisioner); } /** Provisions the given maven coordinates and their transitive dependencies. */ - public static JarState from(Collection mavenCoordinates, Provisioner provisioner) throws IOException { - 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); + public static JarState from(Collection dependencies, Provisioner provisioner) throws IOException { + return from(dependencies, provisioner, true); } - private static JarState provisionWithTransitives(boolean withTransitives, Collection mavenCoordinates, Provisioner provisioner) throws IOException { - Objects.requireNonNull(mavenCoordinates, "mavenCoordinates"); + public static JarState from(Collection dependencies, Provisioner provisioner, boolean withTransitives) throws IOException { + Objects.requireNonNull(dependencies, "dependencies"); Objects.requireNonNull(provisioner, "provisioner"); - Set jars = provisioner.provisionWithTransitives(withTransitives, mavenCoordinates); + Set jars = provisioner.provisionWithTransitives(withTransitives, dependencies); if (jars.isEmpty()) { - throw new NoSuchElementException("Resolved to an empty result: " + mavenCoordinates.stream().collect(Collectors.joining(", "))); + throw new NoSuchElementException("Resolved to an empty result: " + dependencies.stream().map(Object::toString).collect(Collectors.joining(", "))); } FileSignature fileSignature = FileSignature.signAsSet(jars); - return new JarState(mavenCoordinates, fileSignature); + return new JarState(fileSignature); } /** Wraps the given collection of a files as a JarState, maintaining the order in the Collection. */ public static JarState preserveOrder(Collection jars) throws IOException { FileSignature fileSignature = FileSignature.signAsList(jars); - return new JarState(Collections.emptySet(), fileSignature); + return new JarState(fileSignature); } URL[] jarUrls() { @@ -107,10 +103,4 @@ public ClassLoader getClassLoader() { public ClassLoader getClassLoader(Serializable key) { return SpotlessCache.instance().classloader(key, this); } - - /** Returns unmodifiable view on sorted Maven coordinates */ - @Deprecated - public Set getMavenCoordinates() { - return Collections.unmodifiableSet(mavenCoordinates); - } } diff --git a/lib/src/main/java/com/diffplug/spotless/Provisioner.java b/lib/src/main/java/com/diffplug/spotless/Provisioner.java index 259cac5a7c..ab7488e7bf 100644 --- a/lib/src/main/java/com/diffplug/spotless/Provisioner.java +++ b/lib/src/main/java/com/diffplug/spotless/Provisioner.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package com.diffplug.spotless; import java.io.File; -import java.util.Arrays; import java.util.Collection; import java.util.Set; @@ -25,17 +24,10 @@ * Spotless' dependencies minimal. */ public interface Provisioner { - /** - * 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 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 optionally their transitive dependencies. + * the specified coordinates and optionally their transitive dependencies. */ - public Set provisionWithTransitives(boolean withTransitives, Collection mavenCoordinates); + Set provisionWithTransitives(boolean withTransitives, Collection dependencies); } 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 288cc10c72..7ac3646430 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 @@ -65,8 +65,8 @@ static class DedupingProvisioner implements Provisioner { } @Override - public Set provisionWithTransitives(boolean withTransitives, Collection mavenCoordinates) { - Request req = new Request(withTransitives, mavenCoordinates); + public Set provisionWithTransitives(boolean withTransitives, Collection dependencies) { + Request req = new Request(withTransitives, dependencies); Set result; synchronized (cache) { result = cache.get(req); @@ -77,7 +77,7 @@ public Set provisionWithTransitives(boolean withTransitives, Collection provisionWithTransitives(boolean withTransitives, Collection { - Request req = new Request(withTransitives, mavenCoordinates); + final Provisioner cachedOnly = (withTransitives, dependencies) -> { + Request req = new Request(withTransitives, dependencies); Set result; synchronized (cache) { result = cache.get(req); @@ -95,7 +95,7 @@ public Set provisionWithTransitives(boolean withTransitives, Collection { + return (withTransitives, deps) -> { try { Configuration config = configurations.create("spotless" - + new Request(withTransitives, mavenCoords).hashCode()); - mavenCoords.stream() + + new Request(withTransitives, deps).hashCode()); + deps.stream() .map(dependencies::create) .forEach(config.getDependencies()::add); - config.setDescription(mavenCoords.toString()); + config.setDescription(deps.toString()); config.setTransitive(withTransitives); config.setCanBeConsumed(false); config.setVisible(false); @@ -134,7 +134,7 @@ private static Provisioner forConfigurationContainer(Project project, Configurat throw new GradleException(String.format( "You need to add a repository containing the '%s' artifact in '%sbuild.gradle'.%n" + "E.g.: 'repositories { mavenCentral() }'", - mavenCoords, projName), e); + deps, projName), e); } }; } @@ -144,16 +144,16 @@ private static Provisioner forConfigurationContainer(Project project, Configurat /** Models a request to the provisioner. */ private static class Request { final boolean withTransitives; - final ImmutableList mavenCoords; + final ImmutableList dependencies; - public Request(boolean withTransitives, Collection mavenCoords) { + public Request(boolean withTransitives, Collection dependencies) { this.withTransitives = withTransitives; - this.mavenCoords = ImmutableList.copyOf(mavenCoords); + this.dependencies = ImmutableList.copyOf(dependencies); } @Override public int hashCode() { - return withTransitives ? mavenCoords.hashCode() : ~mavenCoords.hashCode(); + return withTransitives ? dependencies.hashCode() : ~dependencies.hashCode(); } @Override @@ -162,7 +162,7 @@ public boolean equals(Object obj) { return true; } else if (obj instanceof Request) { Request o = (Request) obj; - return o.withTransitives == withTransitives && o.mavenCoords.equals(mavenCoords); + return o.withTransitives == withTransitives && o.dependencies.equals(dependencies); } else { return false; } @@ -170,7 +170,7 @@ public boolean equals(Object obj) { @Override public String toString() { - String coords = mavenCoords.toString(); + String coords = dependencies.toString(); StringBuilder builder = new StringBuilder(); builder.append(coords, 1, coords.length() - 1); // strip off [] if (withTransitives) { diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GradleProvisionerTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GradleProvisionerTest.java new file mode 100644 index 0000000000..f2fbc85d88 --- /dev/null +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GradleProvisionerTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2023 DiffPlug + * + * 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 com.diffplug.gradle.spotless; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class GradleProvisionerTest extends GradleIntegrationHarness { + private static final String JUPITER_COORDINATE = "'" + "org.junit.jupiter:junit-jupiter:5.10.0" + "'"; + private static final String JUPITER_TRANSITIVE = "junit-jupiter-params-5.10.0.jar, junit-jupiter-engine-5.10.0.jar, junit-jupiter-api-5.10.0.jar, junit-platform-engine-1.10.0.jar, junit-platform-commons-1.10.0.jar, junit-jupiter-5.10.0.jar, opentest4j-1.3.0.jar"; + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void canResolveMavenCoordinates(boolean withTransitives) throws IOException { + String output = resolveDepsResult(withTransitives, JUPITER_COORDINATE); + assertThat(output).contains(withTransitives ? JUPITER_TRANSITIVE : "junit-jupiter-5.10.0.jar"); + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void canResolveLocalProject(boolean withTransitives) throws IOException { + setFile("settings.gradle").toLines("include 'sub'"); + setFile("sub/build.gradle").toLines( + "plugins {", + " id 'java'", + "}", + "repositories { mavenCentral() }", + "dependencies {", + " implementation " + JUPITER_COORDINATE, + "}"); + String output = resolveDepsResult(withTransitives, "project(':sub')"); + assertThat(output).contains(withTransitives ? JUPITER_TRANSITIVE : "sub.jar"); + } + + private String resolveDepsResult(boolean withTransitives, Object dep) throws IOException { + setFile("build.gradle").toLines( + "import com.diffplug.gradle.spotless.GradleProvisioner", + "plugins {", + " id 'com.diffplug.spotless'", + "}", + "repositories { mavenCentral() }", + "tasks.register('resolveDeps') {", + " def files = GradleProvisioner.forProject(project)", + String.format(".provisionWithTransitives(%s, [%s])", withTransitives, dep), + " println files.collect { it.getName() }.join(', ')", + "}"); + return gradleRunner().withArguments("resolveDeps").build().getOutput(); + } +} 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 d0c8cb729a..fd792dc57e 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 @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 DiffPlug + * Copyright 2016-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,13 +60,13 @@ public ArtifactResolver(RepositorySystem repositorySystem, RepositorySystemSessi * 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) { + public Set resolve(boolean withTransitives, Collection mavenCoordinates) { Collection excludeTransitive = new ArrayList(1); if (!withTransitives) { excludeTransitive.add(EXCLUDE_ALL_TRANSITIVES); } List dependencies = mavenCoordinates.stream() - .map(coordinateString -> new DefaultArtifact(coordinateString)) + .map(coordinate -> new DefaultArtifact(coordinate.toString())) .map(artifact -> new Dependency(artifact, null, null, excludeTransitive)) .collect(toList()); CollectRequest collectRequest = new CollectRequest(dependencies, null, repositories); diff --git a/testlib/src/main/java/com/diffplug/spotless/TestProvisioner.java b/testlib/src/main/java/com/diffplug/spotless/TestProvisioner.java index 7c7b7b67f7..bae2582279 100644 --- a/testlib/src/main/java/com/diffplug/spotless/TestProvisioner.java +++ b/testlib/src/main/java/com/diffplug/spotless/TestProvisioner.java @@ -63,13 +63,13 @@ private static Provisioner createWithRepositories(Consumer re File tempDir = Files.createTempDir(); Project project = TestProvisioner.gradleProject(tempDir); repoConfig.accept(project.getRepositories()); - return (withTransitives, mavenCoords) -> { - Dependency[] deps = mavenCoords.stream() + return (withTransitives, dependencies) -> { + Dependency[] deps = dependencies.stream() .map(project.getDependencies()::create) .toArray(Dependency[]::new); Configuration config = project.getConfigurations().detachedConfiguration(deps); config.setTransitive(withTransitives); - config.setDescription(mavenCoords.toString()); + config.setDescription(dependencies.toString()); config.attributes(attr -> { attr.attribute(Category.CATEGORY_ATTRIBUTE, project.getObjects().named(Category.class, Category.LIBRARY)); attr.attribute(Bundling.BUNDLING_ATTRIBUTE, project.getObjects().named(Bundling.class, Bundling.EXTERNAL)); @@ -100,10 +100,10 @@ private static Provisioner caching(String name, Supplier input) { File testlib = new File(spotlessDir, "testlib"); File cacheFile = new File(testlib, "build/tmp/testprovisioner." + name + ".cache"); - Map, ImmutableSet> cached; + Map, ImmutableSet> cached; if (cacheFile.exists()) { try (ObjectInputStream inputStream = new ObjectInputStream(Files.asByteSource(cacheFile).openBufferedStream())) { - cached = (Map, ImmutableSet>) inputStream.readObject(); + cached = (Map, ImmutableSet>) inputStream.readObject(); } catch (IOException | ClassNotFoundException e) { throw Errors.asRuntime(e); } @@ -115,15 +115,15 @@ private static Provisioner caching(String name, Supplier input) { throw Errors.asRuntime(e); } } - return (withTransitives, mavenCoordsRaw) -> { - ImmutableSet mavenCoords = ImmutableSet.copyOf(mavenCoordsRaw); + return (withTransitives, depsRaw) -> { + ImmutableSet deps = ImmutableSet.copyOf(depsRaw); synchronized (TestProvisioner.class) { - ImmutableSet result = cached.get(mavenCoords); + ImmutableSet result = cached.get(deps); // double-check that depcache pruning hasn't removed them since our cache cached them boolean needsToBeSet = result == null || !result.stream().allMatch(file -> file.exists() && file.isFile() && file.length() > 0); if (needsToBeSet) { - result = ImmutableSet.copyOf(input.get().provisionWithTransitives(withTransitives, mavenCoords)); - cached.put(mavenCoords, result); + result = ImmutableSet.copyOf(input.get().provisionWithTransitives(withTransitives, deps)); + cached.put(deps, result); try (ObjectOutputStream outputStream = new ObjectOutputStream(Files.asByteSink(cacheFile).openBufferedStream())) { outputStream.writeObject(cached); } catch (IOException e) { diff --git a/testlib/src/test/java/com/diffplug/spotless/ProvisionerTest.java b/testlib/src/test/java/com/diffplug/spotless/ProvisionerTest.java index e3616a5844..2caf9fb7f3 100644 --- a/testlib/src/test/java/com/diffplug/spotless/ProvisionerTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/ProvisionerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 DiffPlug + * Copyright 2016-2023 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,8 @@ package com.diffplug.spotless; import java.io.File; -import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.stream.Collectors; import org.assertj.core.api.Assertions; @@ -25,12 +26,10 @@ class ProvisionerTest { @Test void testManipulation() { - Provisioner provisioner = (withTransitives, deps) -> deps.stream().map(File::new).collect(Collectors.toSet()); - Assertions.assertThat(provisioner.provisionWithTransitives(true, "a")) + Provisioner provisioner = (withTransitives, deps) -> deps.stream().map(Object::toString).map(File::new).collect(Collectors.toSet()); + Assertions.assertThat(provisioner.provisionWithTransitives(true, Collections.singleton("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"))) + Assertions.assertThat(provisioner.provisionWithTransitives(true, List.of("a", "a"))) .containsExactlyInAnyOrder(new File("a")); } }