diff --git a/CHANGES.md b/CHANGES.md index 6d506cd2e2..7d8b17c664 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,8 @@ This document is intended for Spotless developers. We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`). ## [Unreleased] +### Fixed +- `P2Provisioner` now passes cache directory overrides directly to Solstice. ([#2944](https://github.com/diffplug/spotless/pull/2944)) ### Changes - `Formatter` no longer recomputes line-ending normalization (`LineEnding.toUnix`) a second time for every formatter step that changes content, removing redundant O(n) work from the core formatting loop. ([#2934](https://github.com/diffplug/spotless/pull/2934)) diff --git a/lib-extra/src/main/java/com/diffplug/spotless/extra/P2Provisioner.java b/lib-extra/src/main/java/com/diffplug/spotless/extra/P2Provisioner.java index 1a3997dc3c..3ce9486476 100644 --- a/lib-extra/src/main/java/com/diffplug/spotless/extra/P2Provisioner.java +++ b/lib-extra/src/main/java/com/diffplug/spotless/extra/P2Provisioner.java @@ -42,7 +42,7 @@ public interface P2Provisioner { * * @param modelWrapper wrapper around P2Model describing repositories and plugins to install * @param mavenProvisioner provisioner for Maven dependencies (some P2 bundles are on Maven Central) - * @param cacheDirectory optional cache directory override + * @param cacheDirectory optional cache directory override passed directly to Solstice * @return ordered list of JAR files forming the classpath */ List provisionP2Dependencies( @@ -55,7 +55,7 @@ static P2Provisioner createDefault() { return (modelWrapper, mavenProvisioner, cacheDirectory) -> { try { if (cacheDirectory != null) { - CacheLocations.override_p2data = cacheDirectory.toPath().resolve("dev/equo/p2-data").toFile(); + CacheLocations.override_p2data = cacheDirectory; } P2Model model = modelWrapper.unwrap(); P2QueryResult query = model.query(P2ClientCache.PREFER_OFFLINE, P2QueryCache.ALLOW); diff --git a/lib/src/main/java/com/diffplug/spotless/Formatter.java b/lib/src/main/java/com/diffplug/spotless/Formatter.java index 71eba72204..d63dc41234 100644 --- a/lib/src/main/java/com/diffplug/spotless/Formatter.java +++ b/lib/src/main/java/com/diffplug/spotless/Formatter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 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. diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index 4393e93660..d67921b9b8 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -3,6 +3,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `3.27.0`). ## [Unreleased] +### Added +- Add `cacheDirectory(...)` to `eclipse()`, `eclipseCdt()`, and `greclipse()`; the default P2 cache is `$GRADLE_USER_HOME/caches/p2-data`. ([#2944](https://github.com/diffplug/spotless/pull/2944)) ### Changes - Improved formatting performance by eliminating redundant per-step line-ending normalization in the core formatter loop. ([#2934](https://github.com/diffplug/spotless/pull/2934)) diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/BaseGroovyExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/BaseGroovyExtension.java index d38649b73e..25da9a4e85 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/BaseGroovyExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/BaseGroovyExtension.java @@ -92,5 +92,19 @@ public GrEclipseConfig withP2Mirrors(Map mirrors) { extension.replaceStep(builder.build()); return this; } + + /** + * Overrides the directory used to cache the P2 dependencies fetched by + * Equo/Solstice. Defaults to {@code $GRADLE_USER_HOME/caches/p2-data}. + * + *

Useful when the default location is not writable, or when you want to + * place the cache elsewhere. + */ + public GrEclipseConfig cacheDirectory(Object cacheDirectory) { + Objects.requireNonNull(cacheDirectory); + builder.setCacheDirectory(extension.getProject().file(cacheDirectory)); + extension.replaceStep(builder.build()); + return this; + } } } diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/CppExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/CppExtension.java index fbbf65fd9d..6bbc8d0bea 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/CppExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/CppExtension.java @@ -19,6 +19,7 @@ import java.util.List; import java.util.Map; +import java.util.Objects; import javax.inject.Inject; @@ -81,6 +82,20 @@ public EclipseConfig withP2Mirrors(Map mirrors) { replaceStep(builder.build()); return this; } + + /** + * Overrides the directory used to cache the P2 dependencies fetched by + * Equo/Solstice. Defaults to {@code $GRADLE_USER_HOME/caches/p2-data}. + * + *

Useful when the default location is not writable, or when you want to + * place the cache elsewhere. + */ + public EclipseConfig cacheDirectory(Object cacheDirectory) { + Objects.requireNonNull(cacheDirectory); + builder.setCacheDirectory(getProject().file(cacheDirectory)); + replaceStep(builder.build()); + return this; + } } @Override 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 060e62c541..52196faf83 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 @@ -61,7 +61,7 @@ public DedupingProvisioner dedupingProvisioner(Project project) { public DedupingP2Provisioner dedupingP2Provisioner(Project project) { return switch (this) { - case ROOT_PROJECT, ROOT_BUILDSCRIPT -> new DedupingP2Provisioner(P2Provisioner.createDefault()); + case ROOT_PROJECT, ROOT_BUILDSCRIPT -> new DedupingP2Provisioner(P2Provisioner.createDefault(), defaultP2CacheDirectory(project)); default -> throw Unhandled.enumException(this); }; } @@ -156,6 +156,10 @@ private static Provisioner forConfigurationContainer(Project project, Configurat private static final Logger LOGGER = LoggerFactory.getLogger(GradleProvisioner.class); + static File defaultP2CacheDirectory(Project project) { + return new File(project.getGradle().getGradleUserHomeDir(), "caches/p2-data"); + } + /** Models a request to the provisioner. */ private static class Request { final boolean withTransitives; @@ -199,9 +203,15 @@ public String toString() { static class DedupingP2Provisioner implements P2Provisioner { private final Map> cache = new HashMap<>(); private final P2Provisioner p2Provisioner; + @Nullable private final File defaultCacheDirectory; public DedupingP2Provisioner(P2Provisioner p2Provisioner) { + this(p2Provisioner, null); + } + + public DedupingP2Provisioner(P2Provisioner p2Provisioner, @Nullable File defaultCacheDirectory) { this.p2Provisioner = p2Provisioner; + this.defaultCacheDirectory = defaultCacheDirectory; } @Override @@ -210,33 +220,35 @@ public synchronized List provisionP2Dependencies( Provisioner mavenProvisioner, @Nullable File cacheDirectory) throws IOException { + File effectiveCacheDirectory = effectiveCacheDirectory(cacheDirectory); P2Request req = new P2Request( List.copyOf(modelWrapper.getP2Repos()), List.copyOf(modelWrapper.getInstallList()), Set.copyOf(modelWrapper.getFilterNames()), List.copyOf(modelWrapper.getPureMaven()), modelWrapper.isUseMavenCentral(), - cacheDirectory); + effectiveCacheDirectory); List result = cache.get(req); if (result != null) { return result; } - result = p2Provisioner.provisionP2Dependencies(modelWrapper, mavenProvisioner, cacheDirectory); + result = p2Provisioner.provisionP2Dependencies(modelWrapper, mavenProvisioner, effectiveCacheDirectory); cache.put(req, List.copyOf(result)); return result; } /** A child P2Provisioner which retrieves cached elements only. */ final P2Provisioner cachedOnly = (modelWrapper, mavenProvisioner, cacheDirectory) -> { + File effectiveCacheDirectory = effectiveCacheDirectory(cacheDirectory); P2Request req = new P2Request( List.copyOf(modelWrapper.getP2Repos()), List.copyOf(modelWrapper.getInstallList()), Set.copyOf(modelWrapper.getFilterNames()), List.copyOf(modelWrapper.getPureMaven()), modelWrapper.isUseMavenCentral(), - cacheDirectory); + effectiveCacheDirectory); List result; synchronized (cache) { result = cache.get(req); @@ -247,6 +259,10 @@ public synchronized List provisionP2Dependencies( throw new GradleException("P2 dependencies not predeclared. Add Eclipse formatter configuration to the `spotlessPredeclare` block in the root project."); }; + @Nullable private File effectiveCacheDirectory(@Nullable File cacheDirectory) { + return cacheDirectory != null ? cacheDirectory : defaultCacheDirectory; + } + /** * Cache key capturing all P2Model state that affects query results. * Based on P2Model fields from equo-ide: diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java index a6a6ce1e5d..4ea13c261d 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/JavaExtension.java @@ -385,6 +385,20 @@ public EclipseConfig withP2Mirrors(Map mirrors) { return this; } + /** + * Overrides the directory used to cache the P2 dependencies fetched by + * Equo/Solstice. Defaults to {@code $GRADLE_USER_HOME/caches/p2-data}. + * + *

Useful when the default location is not writable, or when you want to + * place the cache elsewhere. + */ + public EclipseConfig cacheDirectory(Object cacheDirectory) { + Objects.requireNonNull(cacheDirectory); + builder.setCacheDirectory(getProject().file(cacheDirectory)); + replaceStep(builder.build()); + return this; + } + } /** Removes newlines between type annotations and types. */ diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskService.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskService.java index 0aa7b596a7..90f282d873 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskService.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskService.java @@ -85,7 +85,7 @@ P2Provisioner p2ProvisionerFor(SpotlessExtension spotless) { return predeclaredP2Provisioner.cachedOnly; } else { return p2Provisioner.computeIfAbsent(spotless.project.getPath(), - unused -> new GradleProvisioner.DedupingP2Provisioner(P2Provisioner.createDefault())); + unused -> new GradleProvisioner.DedupingP2Provisioner(P2Provisioner.createDefault(), GradleProvisioner.defaultP2CacheDirectory(spotless.project))); } } } 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 index 830050bd26..1d3a366b03 100644 --- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GradleProvisionerTest.java +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GradleProvisionerTest.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.stream.Stream; @@ -262,6 +263,72 @@ void cachedOnlyCacheHitReturnsResult() throws IOException { assertThat(result).isNotEmpty(); } + @Test + void defaultCacheDirectoryUsedWhenNoOverride() throws IOException { + AtomicReference capturedCacheDirectory = new AtomicReference<>(); + File defaultCacheDirectory = new File("gradle-home/caches/p2-data"); + P2Provisioner underlying = (modelWrapper, mavenProvisioner, cacheDirectory) -> { + capturedCacheDirectory.set(cacheDirectory); + return List.of(new File("/mock/p2.jar")); + }; + GradleProvisioner.DedupingP2Provisioner deduping = new GradleProvisioner.DedupingP2Provisioner(underlying, defaultCacheDirectory); + + P2ModelWrapper model = createMockModel( + List.of("https://download.eclipse.org/eclipse/updates/4.26/"), + List.of("org.eclipse.jdt.core"), + Set.of(), + List.of(), + true, + null); + + deduping.provisionP2Dependencies(model, mockProvisioner(), null); + + assertThat(capturedCacheDirectory.get()).isEqualTo(defaultCacheDirectory); + } + + @Test + void explicitCacheDirectoryOverridesDefault() throws IOException { + AtomicReference capturedCacheDirectory = new AtomicReference<>(); + File defaultCacheDirectory = new File("gradle-home/caches/p2-data"); + File explicitCacheDirectory = new File("project/.spotless-p2"); + P2Provisioner underlying = (modelWrapper, mavenProvisioner, cacheDirectory) -> { + capturedCacheDirectory.set(cacheDirectory); + return List.of(new File("/mock/p2.jar")); + }; + GradleProvisioner.DedupingP2Provisioner deduping = new GradleProvisioner.DedupingP2Provisioner(underlying, defaultCacheDirectory); + + P2ModelWrapper model = createMockModel( + List.of("https://download.eclipse.org/eclipse/updates/4.26/"), + List.of("org.eclipse.jdt.core"), + Set.of(), + List.of(), + true, + null); + + deduping.provisionP2Dependencies(model, mockProvisioner(), explicitCacheDirectory); + + assertThat(capturedCacheDirectory.get()).isEqualTo(explicitCacheDirectory); + } + + @Test + void cachedOnlyUsesDefaultCacheDirectoryForLookup() throws IOException { + File defaultCacheDirectory = new File("gradle-home/caches/p2-data"); + P2Provisioner underlying = mockP2Provisioner(new AtomicInteger(0)); + GradleProvisioner.DedupingP2Provisioner deduping = new GradleProvisioner.DedupingP2Provisioner(underlying, defaultCacheDirectory); + + P2ModelWrapper model = createMockModel( + List.of("https://download.eclipse.org/eclipse/updates/4.26/"), + List.of("org.eclipse.jdt.core"), + Set.of(), + List.of(), + true, + null); + + deduping.provisionP2Dependencies(model, mockProvisioner(), null); + + assertThat(deduping.cachedOnly.provisionP2Dependencies(model, mockProvisioner(), null)).isNotEmpty(); + } + @Test void cachedOnlyCacheMissThrowsException() { P2Provisioner underlying = mockP2Provisioner(new AtomicInteger(0)); diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index e8db904b02..ac3336e865 100644 --- a/plugin-maven/CHANGES.md +++ b/plugin-maven/CHANGES.md @@ -3,8 +3,11 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`). ## [Unreleased] +### Added +- Add `` to ``, ``, and `` for the Equo/Solstice P2 cache. ([#2944](https://github.com/diffplug/spotless/pull/2944)) ### Fixed - `spotless:apply` no longer aborts on the first file with lints; it now formats all files and reports a single aggregated lint failure across every file, matching the Gradle plugin's behavior. ([#2937](https://github.com/diffplug/spotless/pull/2937)) +- `` and `` now default P2 data to the Maven local repository. ([#2944](https://github.com/diffplug/spotless/pull/2944)) ### Changes - Improved formatting performance by eliminating redundant per-step line-ending normalization in the core formatter loop. ([#2934](https://github.com/diffplug/spotless/pull/2934)) diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepFactory.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepFactory.java index 4642f17de5..875980cda2 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepFactory.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/FormatterStepFactory.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. @@ -15,6 +15,8 @@ */ package com.diffplug.spotless.maven; +import java.io.File; + import org.eclipse.aether.RepositorySystemSession; import com.diffplug.spotless.FormatterStep; @@ -26,4 +28,8 @@ public interface FormatterStepFactory { default void init(RepositorySystemSession repositorySystemSession) { // nothing } + + static File defaultP2CacheDirectory(RepositorySystemSession repositorySystemSession) { + return new File(repositorySystemSession.getLocalRepository().getBasedir(), "dev/equo/p2-data"); + } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/cpp/EclipseCdt.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/cpp/EclipseCdt.java index 6709e78116..6e7796972c 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/cpp/EclipseCdt.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/cpp/EclipseCdt.java @@ -21,6 +21,7 @@ import java.util.List; import org.apache.maven.plugins.annotations.Parameter; +import org.eclipse.aether.RepositorySystemSession; import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.extra.EquoBasedStepBuilder; @@ -40,6 +41,9 @@ public class EclipseCdt implements FormatterStepFactory { @Parameter private List p2Mirrors = new ArrayList<>(); + @Parameter + private File cacheDirectory; + @Override public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) { EquoBasedStepBuilder eclipseConfig = EclipseCdtFormatterStep.createBuilder(stepConfig.getProvisioner(), stepConfig.getP2Provisioner()); @@ -49,6 +53,16 @@ public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) { eclipseConfig.setPreferences(Arrays.asList(settingsFile)); } eclipseConfig.setP2Mirrors(p2Mirrors); + if (cacheDirectory != null) { + eclipseConfig.setCacheDirectory(cacheDirectory); + } return eclipseConfig.build(); } + + @Override + public void init(RepositorySystemSession repositorySystemSession) { + if (cacheDirectory == null) { + cacheDirectory = FormatterStepFactory.defaultP2CacheDirectory(repositorySystemSession); + } + } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/groovy/GrEclipse.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/groovy/GrEclipse.java index 613a624c01..9cbf0b7760 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/groovy/GrEclipse.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/groovy/GrEclipse.java @@ -21,6 +21,7 @@ import java.util.List; import org.apache.maven.plugins.annotations.Parameter; +import org.eclipse.aether.RepositorySystemSession; import com.diffplug.spotless.FormatterStep; import com.diffplug.spotless.extra.EquoBasedStepBuilder; @@ -40,6 +41,9 @@ public class GrEclipse implements FormatterStepFactory { @Parameter private List p2Mirrors = new ArrayList<>(); + @Parameter + private File cacheDirectory; + @Override public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) { EquoBasedStepBuilder grEclipseConfig = GrEclipseFormatterStep.createBuilder(stepConfig.getProvisioner(), stepConfig.getP2Provisioner()); @@ -49,6 +53,16 @@ public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) { grEclipseConfig.setPreferences(Arrays.asList(settingsFile)); } grEclipseConfig.setP2Mirrors(p2Mirrors); + if (cacheDirectory != null) { + grEclipseConfig.setCacheDirectory(cacheDirectory); + } return grEclipseConfig.build(); } + + @Override + public void init(RepositorySystemSession repositorySystemSession) { + if (cacheDirectory == null) { + cacheDirectory = FormatterStepFactory.defaultP2CacheDirectory(repositorySystemSession); + } + } } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Eclipse.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Eclipse.java index 4d3df28cd7..094828c173 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Eclipse.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/java/Eclipse.java @@ -55,6 +55,7 @@ public class Eclipse implements FormatterStepFactory { @Parameter private Boolean sortMembersVisibilityOrderEnabled = false; + @Parameter private File cacheDirectory; @Override @@ -84,14 +85,13 @@ public FormatterStep newFormatterStep(FormatterStepConfig stepConfig) { if (sortMembersVisibilityOrderEnabled != null) { eclipseConfig.sortMembersVisibilityOrderEnabled(sortMembersVisibilityOrderEnabled); } - if (cacheDirectory != null) { - eclipseConfig.setCacheDirectory(cacheDirectory); - } return eclipseConfig.build(); } @Override public void init(RepositorySystemSession repositorySystemSession) { - this.cacheDirectory = repositorySystemSession.getLocalRepository().getBasedir(); + if (cacheDirectory == null) { + cacheDirectory = FormatterStepFactory.defaultP2CacheDirectory(repositorySystemSession); + } } } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/FormatterStepFactoryTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/FormatterStepFactoryTest.java new file mode 100644 index 0000000000..ff98996431 --- /dev/null +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/FormatterStepFactoryTest.java @@ -0,0 +1,137 @@ +/* + * 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. + * 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.maven; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.lang.reflect.Field; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.repository.LocalRepository; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.maven.cpp.EclipseCdt; +import com.diffplug.spotless.maven.groovy.GrEclipse; +import com.diffplug.spotless.maven.java.Eclipse; + +class FormatterStepFactoryTest { + @TempDir + Path tempDir; + + @Test + void defaultP2CacheDirectoryUsesMavenLocalRepository() { + File localRepository = tempDir.resolve("local-repo").toFile(); + + assertThat(FormatterStepFactory.defaultP2CacheDirectory(repositorySystemSession(localRepository))) + .isEqualTo(new File(localRepository, "dev/equo/p2-data")); + } + + @Test + void eclipseUsesConfiguredCacheDirectory() throws Exception { + assertUsesConfiguredCacheDirectory(new Eclipse()); + } + + @Test + void grEclipseUsesConfiguredCacheDirectory() throws Exception { + assertUsesConfiguredCacheDirectory(new GrEclipse()); + } + + @Test + void eclipseCdtUsesConfiguredCacheDirectory() throws Exception { + assertUsesConfiguredCacheDirectory(new EclipseCdt()); + } + + @Test + void eclipseUsesDefaultCacheDirectory() throws Exception { + assertUsesDefaultCacheDirectory(new Eclipse()); + } + + @Test + void grEclipseUsesDefaultCacheDirectory() throws Exception { + assertUsesDefaultCacheDirectory(new GrEclipse()); + } + + @Test + void eclipseCdtUsesDefaultCacheDirectory() throws Exception { + assertUsesDefaultCacheDirectory(new EclipseCdt()); + } + + private void assertUsesConfiguredCacheDirectory(FormatterStepFactory factory) throws Exception { + File configuredCacheDirectory = tempDir.resolve("configured-p2-cache").toFile(); + Field cacheDirectory = cacheDirectoryField(factory); + cacheDirectory.set(factory, configuredCacheDirectory); + + factory.init(repositorySystemSession(tempDir.resolve("local-repo").toFile())); + + assertP2ProvisionerReceives(factory, configuredCacheDirectory); + } + + private void assertUsesDefaultCacheDirectory(FormatterStepFactory factory) throws Exception { + File localRepository = tempDir.resolve("local-repo").toFile(); + File defaultCacheDirectory = new File(localRepository, "dev/equo/p2-data"); + + factory.init(repositorySystemSession(localRepository)); + + assertP2ProvisionerReceives(factory, defaultCacheDirectory); + } + + private void assertP2ProvisionerReceives(FormatterStepFactory factory, File expectedCacheDirectory) throws Exception { + AtomicReference actualCacheDirectory = new AtomicReference<>(); + File fakeJar = tempDir.resolve("fake.jar").toFile(); + Files.write(fakeJar.toPath(), new byte[]{0}); + + FormatterStep step = factory.newFormatterStep(new FormatterStepConfig( + UTF_8, + "", + Optional.empty(), + (withTransitives, mavenCoordinates) -> Set.of(), + (modelWrapper, mavenProvisioner, cacheDirectory) -> { + actualCacheDirectory.set(cacheDirectory); + return List.of(fakeJar); + }, + null, + Optional.empty(), + Optional.empty())); + + int unused = step.hashCode(); + + assertThat(actualCacheDirectory.get()).isEqualTo(expectedCacheDirectory); + } + + private Field cacheDirectoryField(FormatterStepFactory factory) throws NoSuchFieldException { + Field cacheDirectory = factory.getClass().getDeclaredField("cacheDirectory"); + cacheDirectory.setAccessible(true); + return cacheDirectory; + } + + private RepositorySystemSession repositorySystemSession(File localRepository) { + RepositorySystemSession repositorySystemSession = mock(); + when(repositorySystemSession.getLocalRepository()).thenReturn(new LocalRepository(localRepository)); + return repositorySystemSession; + } +}