Skip to content

Commit

Permalink
Add depth to tooling model deps, move fromToolingModel to tooling model
Browse files Browse the repository at this point in the history
  • Loading branch information
jkschneider committed Feb 20, 2024
1 parent 3953c65 commit 2b066d7
Show file tree
Hide file tree
Showing 18 changed files with 248 additions and 215 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,4 @@ public class FeaturePreview implements Serializable {

@Nullable
Boolean enabled;

static FeaturePreview fromToolingModel(org.openrewrite.gradle.toolingapi.FeaturePreview toolingFeaturePreview) {
return new FeaturePreview(
toolingFeaturePreview.getName(),
toolingFeaturePreview.isActive(),
toolingFeaturePreview.isEnabled()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,16 @@
import lombok.experimental.NonFinal;
import org.openrewrite.internal.StringUtils;
import org.openrewrite.internal.lang.Nullable;
import org.openrewrite.maven.tree.*;
import org.openrewrite.maven.tree.Dependency;
import org.openrewrite.maven.tree.ResolvedDependency;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.Collections.emptyList;

@SuppressWarnings("unused")
@Value
@With
public class GradleDependencyConfiguration implements Serializable {

/**
* The name of the dependency configuration. Unique within a given project.
*/
Expand Down Expand Up @@ -61,10 +58,15 @@ public class GradleDependencyConfiguration implements Serializable {
* The list of direct dependencies resolved for this configuration.
*/
List<ResolvedDependency> directResolved;

/**
* The list of all dependencies resolved for this configuration, including transitive dependencies.
*/
List<ResolvedDependency> resolved;
public List<ResolvedDependency> getResolved() {
List<ResolvedDependency> resolved = new ArrayList<>(directResolved);
Set<ResolvedDependency> alreadyResolved = new HashSet<>();
return resolveTransitiveDependencies(resolved, alreadyResolved);
}

/**
* The type of exception thrown when attempting to resolve this configuration. null if no exception was thrown.
Expand Down Expand Up @@ -103,139 +105,36 @@ public List<GradleDependencyConfiguration> allExtendsFrom() {

@Nullable
public Dependency findRequestedDependency(String groupId, String artifactId) {
return requested.stream()
.filter(d -> StringUtils.matchesGlob(d.getGav().getGroupId(), groupId) &&
StringUtils.matchesGlob(d.getGav().getArtifactId(), artifactId))
.findFirst()
.orElse(null);
for (Dependency d : requested) {
if (StringUtils.matchesGlob(d.getGav().getGroupId(), groupId) &&
StringUtils.matchesGlob(d.getGav().getArtifactId(), artifactId)) {
return d;
}
}
return null;
}

@Nullable
public ResolvedDependency findResolvedDependency(String groupId, String artifactId) {
return resolved.stream()
.map(d -> d.findDependency(groupId, artifactId))
.filter(Objects::nonNull)
.findFirst()
.orElse(null);
}

@SuppressWarnings("DuplicatedCode")
public static Map<String, GradleDependencyConfiguration> fromToolingModel(Map<String, org.openrewrite.gradle.toolingapi.GradleDependencyConfiguration> toolingConfigurations) {
Map<String, GradleDependencyConfiguration> results = new HashMap<>();
List<org.openrewrite.gradle.toolingapi.GradleDependencyConfiguration> configurations = new ArrayList<>(toolingConfigurations.values());
for (org.openrewrite.gradle.toolingapi.GradleDependencyConfiguration toolingConfiguration : configurations) {
GradleDependencyConfiguration configuration = fromToolingModel(toolingConfiguration);
results.put(configuration.getName(), configuration);
}

// Record the relationships between dependency configurations
for (org.openrewrite.gradle.toolingapi.GradleDependencyConfiguration conf : configurations) {
if (conf.getExtendsFrom().isEmpty()) {
continue;
}
GradleDependencyConfiguration dc = results.get(conf.getName());
if (dc != null) {
List<GradleDependencyConfiguration> extendsFrom = conf.getExtendsFrom().stream()
.map(it -> results.get(it.getName()))
.collect(Collectors.toList());
dc.unsafeSetExtendsFrom(extendsFrom);
for (ResolvedDependency d : directResolved) {
ResolvedDependency dependency = d.findDependency(groupId, artifactId);
if (dependency != null) {
return dependency;
}
}
return results;
return null;
}

private static GradleDependencyConfiguration fromToolingModel(org.openrewrite.gradle.toolingapi.GradleDependencyConfiguration config) {
List<ResolvedDependency> direct = config.getResolved().stream().map(GradleDependencyConfiguration::fromToolingModel)
.collect(Collectors.toList());
List<ResolvedDependency> transitive = resolveTransitiveDependencies(direct, new LinkedHashSet<>());
return new GradleDependencyConfiguration(
config.getName(),
config.getDescription(),
config.isTransitive(),
config.isCanBeResolved(),
config.isCanBeConsumed(),
emptyList(),
config.getRequested().stream().map(GradleDependencyConfiguration::fromToolingModel)
.collect(Collectors.toList()),
direct,
transitive,
null,
null
);
public void unsafeSetExtendsFrom(List<GradleDependencyConfiguration> extendsFrom) {
this.extendsFrom = extendsFrom;
}

/**
* Recursively resolve all transitive dependencies for the given list of resolved dependencies.
*
* @param resolved The list of resolved dependencies to resolve transitive dependencies for.
* @param alreadyResolved A set of dependencies that have already been resolved. This is used to prevent infinite recursion.
* @return A list of all transitive dependencies for the given list of resolved dependencies.
*/
static List<ResolvedDependency> resolveTransitiveDependencies(List<ResolvedDependency> resolved, Set<ResolvedDependency> alreadyResolved) {
private static List<ResolvedDependency> resolveTransitiveDependencies(List<ResolvedDependency> resolved, Set<ResolvedDependency> alreadyResolved) {
for (ResolvedDependency dependency : resolved) {
if (alreadyResolved.add(dependency)) {
alreadyResolved.addAll(resolveTransitiveDependencies(dependency.getDependencies(), alreadyResolved));
}
}
return new ArrayList<>(alreadyResolved);
}

void unsafeSetExtendsFrom(List<GradleDependencyConfiguration> extendsFrom) {
this.extendsFrom = extendsFrom;
}

private static ResolvedDependency fromToolingModel(org.openrewrite.gradle.toolingapi.ResolvedDependency dep) {
return fromToolingModel0(dep, new HashMap<>());
}

private static ResolvedDependency fromToolingModel0(org.openrewrite.gradle.toolingapi.ResolvedDependency dep,
Map<ResolvedGroupArtifactVersion, ResolvedDependency> resolvedCache) {
ResolvedGroupArtifactVersion gav = fromToolingModel(dep.getGav());
ResolvedDependency resolvedDependency = resolvedCache.get(gav);
if (resolvedDependency != null) {
return resolvedDependency;
}
List<ResolvedDependency> deps = new ArrayList<>(dep.getDependencies().size());
resolvedDependency = resolvedCache.computeIfAbsent(
gav,
k -> ResolvedDependency.builder()
.repository(GradleProject.fromToolingModel(dep.getRepository()))
.gav(gav)
.requested(fromToolingModel(dep.getRequested()))
.dependencies(deps)
.licenses(emptyList())
// Setting depth to "0" everywhere isn't accurate, but this saves memory and
// depth isn't meaningful for Gradle conflict resolution the way it is for Maven.
.depth(0)
.build()
);
dep.getDependencies().stream()
.map(d -> fromToolingModel0(d, resolvedCache))
.forEach(deps::add);
return resolvedDependency;
}

private static Dependency fromToolingModel(org.openrewrite.gradle.toolingapi.Dependency dep) {
return Dependency.builder()
.gav(fromToolingModel(dep.getGav()))
.scope(dep.getScope())
.type(dep.getType())
.exclusions(dep.getExclusions().stream()
.map(GradleDependencyConfiguration::fromToolingModel)
.collect(Collectors.toList()))
.optional(dep.getOptional())
.build();
}

private static GroupArtifact fromToolingModel(org.openrewrite.gradle.toolingapi.GroupArtifact ga) {
return new GroupArtifact(ga.getGroupId(), ga.getArtifactId());
}

private static GroupArtifactVersion fromToolingModel(org.openrewrite.gradle.toolingapi.GroupArtifactVersion gav) {
return new GroupArtifactVersion(gav.getGroupId(), gav.getArtifactId(), gav.getVersion());
}

private static ResolvedGroupArtifactVersion fromToolingModel(org.openrewrite.gradle.toolingapi.ResolvedGroupArtifactVersion gav) {
return new ResolvedGroupArtifactVersion(null, gav.getGroupId(), gav.getArtifactId(), gav.getVersion(), gav.getDatedSnapshotVersion());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,4 @@ public class GradlePluginDescriptor implements Serializable {
*/
@Nullable
String id;

public static GradlePluginDescriptor fromToolingModel(org.openrewrite.gradle.toolingapi.GradlePluginDescriptor desc) {
return new GradlePluginDescriptor(desc.getFullyQualifiedClassName(), desc.getId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;


/**
Expand All @@ -36,16 +35,22 @@
public class GradleProject implements Marker, Serializable {
@With
UUID id;

@With
String name;

@With
String path;

@With
List<GradlePluginDescriptor> plugins;

@With
List<MavenRepository> mavenRepositories;

@With
List<MavenRepository> mavenPluginRepositories;

Map<String, GradleDependencyConfiguration> nameToConfiguration;

public List<MavenRepository> getMavenPluginRepositories() {
Expand All @@ -72,7 +77,7 @@ public List<GradleDependencyConfiguration> getConfigurations() {
* |> testCompileClasspath
* |> testRuntimeClasspath
* </pre>
*
* <p>
* When querying "implementation" with transitive is false this function will return [compileClasspath, runtimeClasspath, testImplementation].
* When transitive is true this function will also return [testCompileClasspath, testRuntimeClasspath].
*/
Expand Down Expand Up @@ -124,39 +129,4 @@ public GradleProject withNameToConfiguration(Map<String, GradleDependencyConfigu
configurations
);
}

public static GradleProject fromToolingModel(org.openrewrite.gradle.toolingapi.GradleProject project) {
return new GradleProject(
UUID.randomUUID(),
project.getName(),
project.getPath(),
project.getPlugins().stream()
.map(GradlePluginDescriptor::fromToolingModel)
.collect(Collectors.toList()),
project.getMavenRepositories().stream()
.map(GradleProject::fromToolingModel)
.collect(Collectors.toList()),
project.getMavenPluginRepositories().stream()
.map(GradleProject::fromToolingModel)
.collect(Collectors.toList()),
GradleDependencyConfiguration.fromToolingModel(project.getNameToConfiguration())
);
}

@Nullable
static MavenRepository fromToolingModel(@Nullable org.openrewrite.gradle.toolingapi.MavenRepository mavenRepository) {
if (mavenRepository == null) {
return null;
}
return new MavenRepository(
mavenRepository.getId(),
mavenRepository.getUri(),
mavenRepository.getReleases(),
mavenRepository.getSnapshots(),
mavenRepository.isKnownToExist(),
mavenRepository.getUsername(),
mavenRepository.getPassword(),
mavenRepository.getDeriveMetadataIfMissing()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@

import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;
import static org.openrewrite.gradle.marker.GradleDependencyConfiguration.resolveTransitiveDependencies;
import static org.openrewrite.gradle.marker.GradleSettingsBuilder.GRADLE_PLUGIN_PORTAL;

public final class GradleProjectBuilder {
Expand Down Expand Up @@ -193,13 +192,12 @@ private static Map<String, GradleDependencyConfiguration> dependencyConfiguratio
} else {
resolved = emptyList();
}
List<org.openrewrite.maven.tree.ResolvedDependency> transitive = resolveTransitiveDependencies(resolved, new LinkedHashSet<>());
GradleDependencyConfiguration dc = new GradleDependencyConfiguration(conf.getName(), conf.getDescription(),
conf.isTransitive(), conf.isCanBeResolved(), conf.isCanBeConsumed(), emptyList(), requested, resolved, transitive, exceptionType, exceptionMessage);
conf.isTransitive(), conf.isCanBeResolved(), conf.isCanBeConsumed(), emptyList(), requested, resolved, exceptionType, exceptionMessage);
results.put(conf.getName(), dc);
} catch (Exception e) {
GradleDependencyConfiguration dc = new GradleDependencyConfiguration(conf.getName(), conf.getDescription(),
conf.isTransitive(), conf.isCanBeResolved(), conf.isCanBeConsumed(), emptyList(), emptyList(), emptyList(), emptyList(), e.getClass().getName(), e.getMessage());
conf.isTransitive(), conf.isCanBeResolved(), conf.isCanBeConsumed(), emptyList(), emptyList(), emptyList(), e.getClass().getName(), e.getMessage());
results.put(conf.getName(), dc);
}
}
Expand Down Expand Up @@ -235,7 +233,6 @@ private static org.openrewrite.maven.tree.Dependency dependency(Dependency dep,
);
}


private static List<org.openrewrite.maven.tree.ResolvedDependency> resolved(
Map<GroupArtifact, org.openrewrite.maven.tree.Dependency> gaToRequested,
Map<GroupArtifact, ResolvedDependency> gaToResolved) {
Expand Down Expand Up @@ -294,9 +291,7 @@ private static org.openrewrite.maven.tree.ResolvedDependency resolved(
ResolvedGroupArtifactVersion resolvedGav = resolvedGroupArtifactVersion(dep);
org.openrewrite.maven.tree.ResolvedDependency resolvedDependency = resolvedCache.get(resolvedGav);
if (resolvedDependency == null) {

List<org.openrewrite.maven.tree.ResolvedDependency> dependencies = new ArrayList<>();

resolvedDependency = org.openrewrite.maven.tree.ResolvedDependency.builder()
.gav(resolvedGav)
.requested(dependency(dep))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
import org.openrewrite.maven.tree.MavenRepository;

import java.io.Serializable;
import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

@Value
Expand All @@ -44,25 +47,4 @@ public Set<FeaturePreview> getActiveFeatures() {
.filter(FeaturePreview::isActive)
.collect(Collectors.toSet());
}

public static GradleSettings fromToolingModel(org.openrewrite.gradle.toolingapi.GradleSettings settings) {
return new GradleSettings(
UUID.randomUUID(),
settings.getPluginRepositories().stream()
.map(GradleProject::fromToolingModel)
.collect(Collectors.toList()),
settings.getPlugins().stream()
.map(GradlePluginDescriptor::fromToolingModel)
.collect(Collectors.toList()),
fromToolingModel(settings.getFeaturePreviews())
);
}

private static Map<String, FeaturePreview> fromToolingModel(Map<String, org.openrewrite.gradle.toolingapi.FeaturePreview> toolingFeaturePreviews) {
Map<String, FeaturePreview> results = new HashMap<>();
for (Map.Entry<String, org.openrewrite.gradle.toolingapi.FeaturePreview> featurePreviewEntry : toolingFeaturePreviews.entrySet()) {
results.put(featurePreviewEntry.getKey(), FeaturePreview.fromToolingModel(featurePreviewEntry.getValue()));
}
return results;
}
}

0 comments on commit 2b066d7

Please sign in to comment.