Skip to content

Commit 50ddbb4

Browse files
committed
chore: initial impl for maven provisioner (WIP)
1 parent 483ab5e commit 50ddbb4

4 files changed

Lines changed: 167 additions & 1 deletion

File tree

gradle/libs.versions.toml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ classgraph = "4.8.180"
55
diff-utils = "1.3.0"
66
durian = "1.2.0"
77
junit = "5.8.1"
8+
maven-resolver = "2.0.13"
9+
maven-resolver-transport-http = "1.9.24"
10+
maven-settings = "3.9.11"
811
mockito = "5.17.0"
912
native-include-cleanThat = "2.23"
1013
native-include-googleJavaFormat = "1.27.0"
@@ -28,6 +31,14 @@ durian-io = { module = "com.diffplug.durian:durian-io", version.ref = "durian" }
2831
durian-collect = { module = "com.diffplug.durian:durian-collect", version.ref = "durian" }
2932
junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" }
3033
junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" }
34+
maven-resolver-api = { module = "org.apache.maven.resolver:maven-resolver-api", version.ref = "maven-resolver" }
35+
maven-resolver-spi = { module = "org.apache.maven.resolver:maven-resolver-spi", version.ref = "maven-resolver" }
36+
maven-resolver-util = { module = "org.apache.maven.resolver:maven-resolver-util", version.ref = "maven-resolver" }
37+
maven-resolver-impl = { module = "org.apache.maven.resolver:maven-resolver-impl", version.ref = "maven-resolver" }
38+
maven-resolver-connector-basic = { module = "org.apache.maven.resolver:maven-resolver-connector-basic", version.ref = "maven-resolver" }
39+
maven-resolver-transport-http = { module = "org.apache.maven.resolver:maven-resolver-transport-http", version.ref = "maven-resolver-transport-http" }
40+
maven-settings = { module = "org.apache.maven:maven-settings", version.ref = "maven-settings" }
41+
maven-settings-builder = { module = "org.apache.maven:maven-settings-builder", version.ref = "maven-settings" }
3142
mockito = { module = "org.mockito:mockito-core", version.ref = "mockito" }
3243
native-include-cleanThat = { module = "io.github.solven-eu.cleanthat:java", version.ref = "native-include-cleanThat" }
3344
native-include-googleJavaFormat = { module = "com.google.googlejavaformat:google-java-format", version.ref = "native-include-googleJavaFormat" }
@@ -44,6 +55,16 @@ spotless-plugin-gradle = { module = "com.diffplug.spotless:spotless-plugin-gradl
4455

4556
[bundles]
4657
durian-libs = ["durian-core", "durian-io", "durian-collect"]
58+
maven-resolver-libs = [
59+
"maven-resolver-api",
60+
"maven-resolver-spi",
61+
"maven-resolver-util",
62+
"maven-resolver-impl",
63+
"maven-resolver-connector-basic",
64+
"maven-resolver-transport-http",
65+
"maven-settings",
66+
"maven-settings-builder"
67+
]
4768
native-includes = [
4869
"native-include-cleanThat",
4970
"native-include-googleJavaFormat",

provisioner/build.gradle

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
plugins {
2+
id 'buildlogic.java-library-conventions'
3+
}
4+
5+
version = rootProject.version
6+
7+
dependencies {
8+
//
9+
// implementation libs.bundles.maven.resolver.libs
10+
11+
implementation( platform("org.apache.maven:maven-resolver-provider:3.9.11"))
12+
implementation( "org.apache.maven:maven-resolver-provider")
13+
implementation "org.apache.maven.resolver:maven-resolver-api"
14+
implementation "org.apache.maven.resolver:maven-resolver-spi"
15+
implementation "org.apache.maven.resolver:maven-resolver-util"
16+
implementation "org.apache.maven.resolver:maven-resolver-impl"
17+
implementation "org.apache.maven.resolver:maven-resolver-connector-basic"
18+
implementation "org.apache.maven.resolver:maven-resolver-transport-file"
19+
implementation "org.apache.maven.resolver:maven-resolver-transport-http"
20+
21+
implementation libs.bundles.spotless.libs
22+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package com.diffplug.spotless.cli.provisioner;
2+
3+
import com.diffplug.spotless.Provisioner;
4+
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
5+
import org.eclipse.aether.DefaultRepositorySystemSession;
6+
import org.eclipse.aether.RepositorySystem;
7+
import org.eclipse.aether.RepositorySystemSession;
8+
import org.eclipse.aether.artifact.Artifact;
9+
import org.eclipse.aether.artifact.DefaultArtifact;
10+
import org.eclipse.aether.collection.CollectRequest;
11+
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
12+
import org.eclipse.aether.graph.Dependency;
13+
import org.eclipse.aether.impl.DefaultServiceLocator;
14+
import org.eclipse.aether.repository.LocalRepository;
15+
import org.eclipse.aether.repository.RemoteRepository;
16+
import org.eclipse.aether.resolution.ArtifactRequest;
17+
import org.eclipse.aether.resolution.ArtifactResult;
18+
import org.eclipse.aether.resolution.DependencyRequest;
19+
import org.eclipse.aether.resolution.DependencyResult;
20+
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
21+
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
22+
import org.eclipse.aether.transport.http.HttpTransporterFactory;
23+
import org.eclipse.aether.util.artifact.JavaScopes;
24+
import org.eclipse.aether.util.filter.DependencyFilterUtils;
25+
26+
import java.io.File;
27+
import java.nio.file.Path;
28+
import java.util.Collection;
29+
import java.util.LinkedHashSet;
30+
import java.util.List;
31+
import java.util.Set;
32+
33+
public class DynamicMavenResolverPublisher implements Provisioner {
34+
35+
public static final List<RemoteRepository> DEFAULT_REMOTE_REPOSITORIES = List.of(
36+
new RemoteRepository.Builder("central", "default", "https://repo1.maven.org/maven2/").build()
37+
);
38+
39+
public static final Path DEFAULT_LOCAL_MAVEN_REPO = defaultLocalMavenRepo();
40+
41+
private final List<RemoteRepository> remoteRepositories;
42+
43+
private final Path localMavenRepo;
44+
45+
public DynamicMavenResolverPublisher(List<RemoteRepository> remoteRepositories, Path localMavenRepo) {
46+
this.remoteRepositories = remoteRepositories;
47+
this.localMavenRepo = localMavenRepo;
48+
}
49+
50+
private static Path defaultLocalMavenRepo() {
51+
// 1) Respect standard Maven override if present
52+
String explicit = System.getProperty("maven.repo.local");
53+
if (explicit != null && !explicit.isBlank()) {
54+
return Path.of(explicit);
55+
}
56+
57+
// 2) Maven's default: ${user.home}/.m2/repository
58+
String userHome = System.getProperty("user.home");
59+
return Path.of(userHome, ".m2", "repository");
60+
}
61+
62+
private RepositorySystem newRepositorySystem() {
63+
DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
64+
locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
65+
locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
66+
return locator.getService(RepositorySystem.class);
67+
}
68+
69+
private RepositorySystemSession newSession(RepositorySystem system) {
70+
DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
71+
LocalRepository localRepo = new LocalRepository(localMavenRepo.toFile());
72+
session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
73+
return session;
74+
}
75+
76+
@Override
77+
public Set<File> provisionWithTransitives(boolean withTransitives, Collection<String> mavenCoordinates) {
78+
RepositorySystem repositorySystem = newRepositorySystem();
79+
RepositorySystemSession repositorySystemSession = newSession(repositorySystem);
80+
Set<File> jarFiles = new LinkedHashSet<>();
81+
82+
for (String coord : mavenCoordinates) {
83+
Artifact artifact = new DefaultArtifact(coord);
84+
85+
try {
86+
if (withTransitives) {
87+
// Resolve full dependency graph
88+
CollectRequest collectRequest = new CollectRequest();
89+
collectRequest.setRoot(new Dependency(artifact, JavaScopes.RUNTIME));
90+
remoteRepositories.forEach(collectRequest::addRepository);
91+
92+
DependencyRequest dependencyRequest =
93+
new DependencyRequest(collectRequest, DependencyFilterUtils.classpathFilter(JavaScopes.RUNTIME));
94+
95+
DependencyResult result = repositorySystem.resolveDependencies(repositorySystemSession, dependencyRequest);
96+
97+
result.getArtifactResults().forEach(r -> {
98+
File f = r.getArtifact().getFile();
99+
if (f != null) jarFiles.add(f);
100+
});
101+
102+
} else {
103+
// Resolve just the main artifact
104+
ArtifactRequest request = new ArtifactRequest();
105+
request.setArtifact(artifact);
106+
remoteRepositories.forEach(request::addRepository);
107+
108+
ArtifactResult result = repositorySystem.resolveArtifact(repositorySystemSession, request);
109+
jarFiles.add(result.getArtifact().getFile());
110+
}
111+
112+
} catch (Exception e) {
113+
throw new RuntimeException("Failed to resolve: " + coord, e);
114+
}
115+
}
116+
117+
return jarFiles;
118+
}
119+
120+
}

settings.gradle

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,7 @@ plugins {
3434
}
3535

3636
rootProject.name = 'spotless-cli'
37-
include('app', 'testlib')
37+
38+
include 'app'
39+
include 'testlib'
40+
include 'provisioner'

0 commit comments

Comments
 (0)