diff --git a/.github/workflows/changelog-print.yml b/.github/workflows/changelog-print.yml index 184608f0b1..86040e0f71 100644 --- a/.github/workflows/changelog-print.yml +++ b/.github/workflows/changelog-print.yml @@ -14,6 +14,6 @@ jobs: with: java-version: 21 distribution: 'temurin' - - name: gradle caching + - name: Setup Gradle 🐘 uses: gradle/actions/setup-gradle@v5 - run: ./gradlew changelogPrint diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0282bddf72..7bd02c30d9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,6 @@ on: push: branches: [main, release] workflow_dispatch: - concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -19,34 +18,35 @@ jobs: buildcacheuser: ${{ secrets.BUILDCACHE_USER }} buildcachepass: ${{ secrets.BUILDCACHE_PASS }} steps: - - name: Checkout + - name: Checkout Code ðŸ“Ĩ uses: actions/checkout@v6 with: fetch-depth: 0 - uses: actions/setup-java@v5 with: - distribution: "temurin" + distribution: temurin java-version: 21 - - name: gradle caching + - name: Setup Gradle 🐘 uses: gradle/actions/setup-gradle@v5 - name: Spotless âœĻ - run: ./gradlew spotlessCheck + run: ./gradlew clean spotlessCheck + - name: Error Prone 🚧 + run: ./gradlew clean assemble + - name: Test Classes ⚙ïļ + run: ./gradlew clean testClasses - name: Rewrite â™ŧïļ - run: ./gradlew rewriteDryRun - - name: assemble testClasses - run: ./gradlew assemble testClasses + run: ./gradlew clean rewriteDryRun build: + name: Build 🏗ïļ needs: sanity-check strategy: fail-fast: false matrix: kind: [maven, gradle] - # Test on the latest Java version once Gradle & Maven support it. - jre: [17, 21, 24] + jre: [17, 21, 24] # test on the latest Java version once Gradle & Maven support it. os: [ubuntu-latest, windows-latest] include: - # npm on linux only (crazy slow on windows) - - kind: npm + - kind: npm # npm on linux only (crazy slow on windows). jre: 17 os: ubuntu-latest - kind: shfmt @@ -58,66 +58,64 @@ jobs: os: ubuntu-latest runs-on: ${{ matrix.os }} steps: - - name: Checkout + - name: Checkout Code ðŸ“Ĩ uses: actions/checkout@v6 - uses: actions/setup-java@v5 with: - distribution: "temurin" + distribution: temurin java-version: ${{ matrix.jre }} - - name: gradle caching + - name: Setup Gradle 🐘 uses: gradle/actions/setup-gradle@v5 - - name: build (maven-only) + - name: Build Maven ðŸŠķ if: matrix.kind == 'maven' - run: ./gradlew :plugin-maven:build -x spotlessCheck -x rewriteDryRun - - name: build (everything-but-maven) + run: ./gradlew :plugin-maven:build -x spotlessCheck + - name: Build Gradle 🐘 if: matrix.kind == 'gradle' - run: ./gradlew build -x spotlessCheck -x rewriteDryRun -PSPOTLESS_EXCLUDE_MAVEN=true - - name: test npm + run: ./gradlew build -PSPOTLESS_EXCLUDE_MAVEN=true -x spotlessCheck + - name: Test npm 📊 if: matrix.kind == 'npm' run: ./gradlew testNpm - - name: Setup go + - name: Setup Go if: matrix.kind == 'shfmt' uses: actions/setup-go@v6 with: - go-version: 'stable' - - name: Install shfmt + go-version: stable + - name: Install shfmt ðŸ“Ĩ if: matrix.kind == 'shfmt' - run: | - go install mvdan.cc/sh/v3/cmd/shfmt@${{ matrix.shfmt-version }} - - name: Test shfmt + run: go install mvdan.cc/sh/v3/cmd/shfmt@${{ matrix.shfmt-version }} + - name: Test shfmt 📊 if: matrix.kind == 'shfmt' run: ./gradlew testShfmt - - name: Test idea + - name: Test IDEA 📊 if: matrix.kind == 'idea' run: | download_link=$(curl https://data.services.jetbrains.com/products/releases\?code\=IIC\&latest\=true\&type\=release | jq -r '.IIC[0].downloads.linux.link') - curl --location "$download_link" -o idea.tar.gz + curl --location $download_link -o idea.tar.gz tar -xf idea.tar.gz cd idea-IC* export PATH=${PATH}:$(pwd)/bin cd .. ./gradlew testIdea - - name: junit result + - name: Junit Report 📋 uses: mikepenz/action-junit-report@v6 - if: always() # always run even if the previous step fails + if: always() # always run even if the previous step fails. with: check_name: JUnit ${{ matrix.kind }} ${{ matrix.jre }} ${{ matrix.os }} report_paths: '*/build/test-results/*/TEST-*.xml' check_retries: true - - # Status check that is required in branch protection rules. - final-status: + complete: # this check is required in branch protection rules. + name: Complete ✅ needs: - sanity-check - build runs-on: ubuntu-latest if: always() steps: - - name: Check + - name: Check ðŸĶ‰ run: | results=$(tr -d '\n' <<< '${{ toJSON(needs.*.result) }}') - if ! grep -q -v -E '(failure|cancelled)' <<< "$results"; then - echo "One or more required jobs failed" + if ! grep -q -v -E '(failure|cancelled)' <<< $results; then + echo ❌ One or more required jobs failed. exit 1 fi - echo "All required jobs completed successfully." + echo ✅ All required jobs completed successfully. diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 9f8f931c62..1c54de5741 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -36,7 +36,7 @@ jobs: # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection steps: - - name: Checkout repository + - name: Checkout Code ðŸ“Ĩ uses: actions/checkout@v6 with: # We must fetch at least the immediate parents so that if this is @@ -54,7 +54,7 @@ jobs: with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. + # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. # queries: ./path/to/local/query, your-org/your-repo/queries@main diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 31e4dd2711..ff5824a20a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -42,7 +42,7 @@ jobs: with: java-version: 21 distribution: 'temurin' - - name: gradle caching + - name: Setup Gradle 🐘 uses: gradle/actions/setup-gradle@v5 - name: git fetch origin main run: git fetch origin main diff --git a/README.md b/README.md index 064509f3f5..59edbdd2cd 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Spotless can format <antlr | c | c# | c++ | css | flow | graphql | groovy | h You probably want one of the links below: -## [❇ïļ Spotless for Gradle](plugin-gradle) (with integrations for [VS Code](https://marketplace.visualstudio.com/items?itemName=richardwillis.vscode-spotless-gradle) and [IntelliJ](https://plugins.jetbrains.com/plugin/18321-spotless-gradle)) +## [âœĻïļ Spotless for Gradle](plugin-gradle) (with integrations for [VS Code](https://marketplace.visualstudio.com/items?itemName=richardwillis.vscode-spotless-gradle) and [IntelliJ](https://plugins.jetbrains.com/plugin/18321-spotless-gradle)) ```console user@machine repo % ./gradlew build @@ -25,7 +25,7 @@ user@machine repo % ./gradlew build BUILD SUCCESSFUL ``` -## [❇ïļ Spotless for Maven](plugin-maven) +## [âœĻïļ Spotless for Maven](plugin-maven) ```console user@machine repo % mvn spotless:check @@ -40,7 +40,7 @@ user@machine repo % mvn spotless:check [INFO] BUILD SUCCESS ``` -## [❇ïļ Spotless for SBT (external for now)](https://github.com/moznion/sbt-spotless) +## [âœĻïļ Spotless for SBT (external for now)](https://github.com/moznion/sbt-spotless) ## [Other build systems](CONTRIBUTING.md#how-to-add-a-new-plugin-for-a-build-system) ## How it works (for potential contributors) diff --git a/rewrite.yml b/rewrite.yml index d318e9bce3..5cfe4964ed 100644 --- a/rewrite.yml +++ b/rewrite.yml @@ -7,13 +7,18 @@ recipeList: - org.openrewrite.gradle.EnableGradleBuildCache - org.openrewrite.gradle.EnableGradleParallelExecution - org.openrewrite.gradle.GradleBestPractices + - org.openrewrite.hcl.format.RemoveTrailingWhitespace - org.openrewrite.java.RemoveUnusedImports + - org.openrewrite.java.ShortenFullyQualifiedTypeReferences + - org.openrewrite.java.SimplifySingleElementAnnotation + - org.openrewrite.java.format.EmptyNewlineAtEndOfFile - org.openrewrite.java.format.NormalizeFormat - org.openrewrite.java.format.NormalizeLineBreaks + - org.openrewrite.java.format.PadEmptyForLoopComponents - org.openrewrite.java.format.RemoveTrailingWhitespace - org.openrewrite.java.migrate.UpgradeToJava17 + - org.openrewrite.java.migrate.lang.JavaLangAPIs - org.openrewrite.java.migrate.lang.StringRulesRecipes - - org.openrewrite.java.migrate.util.JavaLangAPIs - org.openrewrite.java.migrate.util.JavaUtilAPIs - org.openrewrite.java.migrate.util.MigrateInflaterDeflaterToClose - org.openrewrite.java.migrate.util.ReplaceStreamCollectWithToList @@ -22,19 +27,32 @@ recipeList: - org.openrewrite.java.recipes.RecipeTestingBestPractices - org.openrewrite.java.security.JavaSecurityBestPractices - org.openrewrite.staticanalysis.BufferedWriterCreationRecipes + - org.openrewrite.staticanalysis.ChainStringBuilderAppendCalls - org.openrewrite.staticanalysis.CommonStaticAnalysis + - org.openrewrite.staticanalysis.CustomImportOrder + - org.openrewrite.staticanalysis.DefaultComesLast + - org.openrewrite.staticanalysis.EmptyBlock - org.openrewrite.staticanalysis.EqualsAvoidsNull + - org.openrewrite.staticanalysis.ExplicitInitialization + - org.openrewrite.staticanalysis.FallThrough + - org.openrewrite.staticanalysis.FinalizePrivateFields + - org.openrewrite.staticanalysis.ForLoopControlVariablePostfixOperators + - org.openrewrite.staticanalysis.HideUtilityClassConstructor - org.openrewrite.staticanalysis.JavaApiBestPractices - org.openrewrite.staticanalysis.LowercasePackage - org.openrewrite.staticanalysis.MissingOverrideAnnotation - org.openrewrite.staticanalysis.ModifierOrder + - org.openrewrite.staticanalysis.NeedBraces - org.openrewrite.staticanalysis.NoFinalizer - org.openrewrite.staticanalysis.NoToStringOnStringType - org.openrewrite.staticanalysis.NoValueOfOnStringType - org.openrewrite.staticanalysis.RemoveUnusedLocalVariables - org.openrewrite.staticanalysis.RemoveUnusedPrivateFields - org.openrewrite.staticanalysis.RemoveUnusedPrivateMethods + - org.openrewrite.staticanalysis.ReplaceStringBuilderWithString + - org.openrewrite.staticanalysis.ReplaceThreadRunWithThreadStart - org.openrewrite.staticanalysis.SimplifyTernaryRecipes + - org.openrewrite.staticanalysis.TypecastParenPad - org.openrewrite.staticanalysis.URLEqualsHashCodeRecipes - org.openrewrite.staticanalysis.UnnecessaryCloseInTryWithResources - org.openrewrite.staticanalysis.UnnecessaryExplicitTypeArguments diff --git a/testlib/src/main/java/com/diffplug/spotless/ReflectionUtil.java b/testlib/src/main/java/com/diffplug/spotless/ReflectionUtil.java deleted file mode 100644 index 1590b08311..0000000000 --- a/testlib/src/main/java/com/diffplug/spotless/ReflectionUtil.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2016-2025 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.spotless; - -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.Parameter; -import java.util.Arrays; -import java.util.Iterator; - -/** - * Utilities for dumping class info, helpful for - * debugging reflection code. Probably easiest to - * just copy-paste these methods where you need - * them. - */ -public class ReflectionUtil { - public static void dumpAllInfo(String name, Object obj) { - System.out.println(name + " of type " + obj.getClass()); - for (Method method : obj.getClass().getMethods()) { - dumpMethod(method); - } - } - - public static void dumpMethod(Method method) { - System.out.print(Modifier.toString(method.getModifiers())); - System.out.print(" " + method.getReturnType()); - System.out.print(" " + method.getName() + "("); - Iterator paramIter = Arrays.asList(method.getParameters()).iterator(); - while (paramIter.hasNext()) { - Parameter param = paramIter.next(); - - System.out.print(param.getType().getName()); - if (paramIter.hasNext()) { - System.out.print(", "); - } - } - System.out.println(")"); - } -} diff --git a/testlib/src/main/java/com/diffplug/spotless/TestProvisioner.java b/testlib/src/main/java/com/diffplug/spotless/TestProvisioner.java index 55558f9b37..2cae4b63ae 100644 --- a/testlib/src/main/java/com/diffplug/spotless/TestProvisioner.java +++ b/testlib/src/main/java/com/diffplug/spotless/TestProvisioner.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 DiffPlug + * Copyright 2026 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,33 @@ */ package com.diffplug.spotless; +import static com.diffplug.common.base.Errors.asRuntime; +import static com.diffplug.common.base.StandardSystemProperty.USER_DIR; +import static com.diffplug.common.base.StandardSystemProperty.USER_HOME; +import static com.diffplug.common.base.Suppliers.memoize; +import static com.diffplug.common.collect.ImmutableSet.copyOf; +import static com.diffplug.common.io.Files.asByteSink; +import static com.diffplug.common.io.Files.asByteSource; +import static com.diffplug.common.io.Files.createParentDirs; +import static com.diffplug.common.io.Files.createTempDir; +import static java.nio.file.Files.walk; +import static java.nio.file.Path.of; +import static java.util.Comparator.reverseOrder; +import static java.util.Objects.requireNonNull; +import static org.gradle.api.attributes.Bundling.BUNDLING_ATTRIBUTE; +import static org.gradle.api.attributes.Bundling.EXTERNAL; +import static org.gradle.api.attributes.Category.CATEGORY_ATTRIBUTE; +import static org.gradle.api.attributes.Category.LIBRARY; +import static org.gradle.api.attributes.java.TargetJvmEnvironment.STANDARD_JVM; +import static org.gradle.api.attributes.java.TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE; +import static org.gradle.testfixtures.ProjectBuilder.builder; + import java.io.File; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.nio.file.Path; -import java.util.Comparator; +import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; @@ -34,125 +55,134 @@ import org.gradle.api.attributes.Bundling; import org.gradle.api.attributes.Category; import org.gradle.api.attributes.java.TargetJvmEnvironment; -import org.gradle.testfixtures.ProjectBuilder; -import com.diffplug.common.base.Errors; -import com.diffplug.common.base.StandardSystemProperty; -import com.diffplug.common.base.Suppliers; import com.diffplug.common.collect.ImmutableSet; -import com.diffplug.common.io.Files; -public class TestProvisioner { - public static Project gradleProject(File dir) { - File userHome = new File(StandardSystemProperty.USER_HOME.value()); - return ProjectBuilder.builder() - .withGradleUserHomeDir(new File(userHome, ".gradle")) - .withProjectDir(dir) +public final class TestProvisioner { + + private static final String MAVEN_CENTRAL_CACHE = "build/tmp/testprovisioner.mavenCentral.cache"; + private static final String TEST_LIB = "testlib"; + private static final Provisioner PROVISIONER = memoize( + () -> resolveAndCache(() -> createWithRepositories(RepositoryHandler::mavenCentral))).get(); + + private TestProvisioner() {} + + public static Project gradleProject(File projectDir) { + return builder() + .withGradleUserHomeDir(new File(requireNonNull(USER_HOME.value()), ".gradle")) + .withProjectDir(projectDir) .build(); } /** - * Creates a Provisioner for the given repositories. - *

- * The first time a project is created, there are ~7 seconds of configuration - * which will go away for all subsequent runs. - *

- * Every call to resolve will take about 1 second, even when all artifacts are resolved. + * Creates a Provisioner for the mavenCentral repo. */ - private static Provisioner createWithRepositories(Consumer repoConfig) { - // Running this takes ~3 seconds the first time it is called. Probably because of classloading. - File tempDir = Files.createTempDir(); - Project project = TestProvisioner.gradleProject(tempDir); - repoConfig.accept(project.getRepositories()); - 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()); - 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)); - // Add this attribute for resolving Guava dependency, see https://github.com/google/guava/issues/6801. - attr.attribute(TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.getObjects().named(TargetJvmEnvironment.class, TargetJvmEnvironment.STANDARD_JVM)); - }); - try { - return config.resolve(); - } catch (ResolveException e) { - /* Provide Maven coordinates in exception message instead of static string 'detachedConfiguration' */ - throw new RuntimeException("Error resolving configuration: " + config.getDescription(), e); - } finally { - // delete the temp dir - try { - java.nio.file.Files.walk(tempDir.toPath()) - .sorted(Comparator.reverseOrder()) - .map(Path::toFile) - .forEach(File::delete); + public static Provisioner mavenCentral() { + return PROVISIONER; + } + + /** + * Creates a Provisioner which will cache the result of previous calls. + */ + private static Provisioner resolveAndCache(Supplier delegate) { + var cacheFile = new File(new File(new File(requireNonNull(USER_DIR.value())).getParentFile(), TEST_LIB), MAVEN_CENTRAL_CACHE); + return (withTransitives, rawCoords) -> resolveAndCache( + delegate, + withTransitives, + loadCache(cacheFile), + copyOf(rawCoords), + cacheFile); + } + + private static ImmutableSet resolveAndCache(Supplier delegate, + boolean withTransitives, + Map, ImmutableSet> artifactCache, + ImmutableSet mavenCoords, + File cacheFile) { + synchronized (TestProvisioner.class) { + var cachedFiles = artifactCache.get(mavenCoords); + var cacheValid = cachedFiles != null && + cachedFiles.stream().allMatch(f -> f.exists() && f.isFile() && f.length() > 0); + if (!cacheValid) { + cachedFiles = copyOf(delegate.get().provisionWithTransitives(withTransitives, mavenCoords)); + artifactCache.put(mavenCoords, cachedFiles); + try (var out = new ObjectOutputStream(asByteSink(cacheFile).openBufferedStream())) { + out.writeObject(artifactCache); } catch (IOException e) { - throw Errors.asRuntime(e); + throw asRuntime(e); } } - }; + return cachedFiles; + } } - /** Creates a Provisioner which will cache the result of previous calls. */ @SuppressWarnings("unchecked") - private static Provisioner caching(String name, Supplier input) { - File spotlessDir = new File(StandardSystemProperty.USER_DIR.value()).getParentFile(); - File testlib = new File(spotlessDir, "testlib"); - File cacheFile = new File(testlib, "build/tmp/testprovisioner." + name + ".cache"); - - Map, ImmutableSet> cached; + private static Map, ImmutableSet> loadCache(File cacheFile) { if (cacheFile.exists()) { - try (ObjectInputStream inputStream = new ObjectInputStream(Files.asByteSource(cacheFile).openBufferedStream())) { - cached = (Map, ImmutableSet>) inputStream.readObject(); + try (var in = new ObjectInputStream(asByteSource(cacheFile).openBufferedStream())) { + return (Map, ImmutableSet>) in.readObject(); } catch (IOException | ClassNotFoundException e) { - throw Errors.asRuntime(e); - } - } else { - cached = new HashMap<>(); - try { - Files.createParentDirs(cacheFile); - } catch (IOException e) { - throw Errors.asRuntime(e); + throw asRuntime(e); } } - return (withTransitives, mavenCoordsRaw) -> { - ImmutableSet mavenCoords = ImmutableSet.copyOf(mavenCoordsRaw); - synchronized (TestProvisioner.class) { - ImmutableSet result = cached.get(mavenCoords); - // 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); - try (ObjectOutputStream outputStream = new ObjectOutputStream(Files.asByteSink(cacheFile).openBufferedStream())) { - outputStream.writeObject(cached); - } catch (IOException e) { - throw Errors.asRuntime(e); - } - } - return result; - } - }; + try { + createParentDirs(cacheFile); + return new HashMap<>(); + } catch (IOException e) { + throw asRuntime(e); + } } - /** Creates a Provisioner for the mavenCentral repo. */ - public static Provisioner mavenCentral() { - return MAVEN_CENTRAL.get(); + /** + * Creates a Provisioner for the given repositories. + */ + private static Provisioner createWithRepositories(Consumer repositoryConfigurer) { + return createProvisioner(repositoryConfigurer, gradleProject(createTempDir())); } - private static final Supplier MAVEN_CENTRAL = Suppliers.memoize(() -> caching("mavenCentral", () -> createWithRepositories(RepositoryHandler::mavenCentral))); - - /** Creates a Provisioner for the local maven repo for development purpose. */ - public static Provisioner mavenLocal() { - return createWithRepositories(RepositoryHandler::mavenLocal); + private static Provisioner createProvisioner(Consumer repositoryConfigurer, Project project) { + repositoryConfigurer.accept(project.getRepositories()); + return (withTransitives, mavenCoords) -> { + var configuration = applyAttributes(project + .getConfigurations() + .detachedConfiguration(mavenCoords + .stream() + .map(project.getDependencies()::create) + .toArray(Dependency[]::new)), + withTransitives, + mavenCoords, + project); + try { + return configuration.resolve(); + } catch (ResolveException e) { + throw new RuntimeException("Error resolving configuration: " + configuration.getDescription(), e); + } finally { + try (var paths = walk(of(project.getPath()))) { + paths.sorted(reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); + } catch (IOException ignored) {} + } + }; } - /** Creates a Provisioner for the Sonatype snapshots maven repo for development purpose. */ - public static Provisioner snapshots() { - return createWithRepositories(repo -> repo.maven(setup -> setup.setUrl("https://oss.sonatype.org/content/repositories/snapshots"))); + private static Configuration applyAttributes(Configuration configuration, + boolean withTransitives, + Collection mavenCoords, + Project project) { + configuration.setTransitive(withTransitives); + configuration.setDescription(mavenCoords.toString()); + configuration.attributes(attrs -> { + attrs.attribute( + CATEGORY_ATTRIBUTE, + project.getObjects().named(Category.class, LIBRARY)); + attrs.attribute( + BUNDLING_ATTRIBUTE, + project.getObjects().named(Bundling.class, EXTERNAL)); + attrs.attribute( + TARGET_JVM_ENVIRONMENT_ATTRIBUTE, + project.getObjects().named(TargetJvmEnvironment.class, STANDARD_JVM)); + }); + return configuration; } - } diff --git a/testlib/src/test/java/com/diffplug/spotless/PaddedCellTest.java b/testlib/src/test/java/com/diffplug/spotless/PaddedCellTest.java index 2820aadeef..1a62c62097 100644 --- a/testlib/src/test/java/com/diffplug/spotless/PaddedCellTest.java +++ b/testlib/src/test/java/com/diffplug/spotless/PaddedCellTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 DiffPlug + * Copyright 2016-2026 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -116,7 +116,7 @@ void diverging() throws IOException { void cycleOrder() { BiConsumer testCase = (unorderedStr, canonical) -> { List unordered = Arrays.asList(unorderedStr.split(",")); - for (int i = 0; i < unordered.size(); ++i) { + for (int i = 0; i < unordered.size(); i++) { // try every rotation of the list Collections.rotate(unordered, 1); PaddedCell result = CYCLE.create(rootFolder, unordered);