Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle different project dependency configs #107

Merged
merged 1 commit into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
import java.io.Serializable;

/**
* Represents a project dependency.
* Represents a build target dependency.
* In Java this is a project:sourceset dependency on a project:sourceset.
*/
public interface GradleProjectDependency extends Serializable {
public interface BuildTargetDependency extends Serializable {
public String getProjectPath();

public String getSourceSetName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public interface GradleSourceSet extends Serializable {
/**
* Project dependencies.
*/
public Set<GradleProjectDependency> getProjectDependencies();
public Set<BuildTargetDependency> getBuildTargetDependencies();

/**
* has tests defined.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

package com.microsoft.java.bs.gradle.model.impl;

import java.util.Objects;

import com.microsoft.java.bs.gradle.model.BuildTargetDependency;
import com.microsoft.java.bs.gradle.model.GradleSourceSet;

/**
* Default implementation of {@link BuildTargetDependency}.
*/
public class DefaultBuildTargetDependency implements BuildTargetDependency {
private static final long serialVersionUID = 1L;

private String projectPath;

private String sourceSetName;

public DefaultBuildTargetDependency(String projectPath, String sourceSetName) {
this.projectPath = projectPath;
this.sourceSetName = sourceSetName;
}

public DefaultBuildTargetDependency(GradleSourceSet sourceSet) {
this(sourceSet.getProjectPath(), sourceSet.getSourceSetName());
}


/**
* Copy constructor.
*
* @param buildTargetDependency the other instance to copy from.
*/
public DefaultBuildTargetDependency(BuildTargetDependency buildTargetDependency) {
this.projectPath = buildTargetDependency.getProjectPath();
this.sourceSetName = buildTargetDependency.getSourceSetName();
}

public String getProjectPath() {
return projectPath;
}

public void setProjectPath(String projectPath) {
this.projectPath = projectPath;
}

public String getSourceSetName() {
return sourceSetName;
}

public void setSourceSetName(String sourceSetName) {
this.sourceSetName = sourceSetName;
}

@Override
public int hashCode() {
return Objects.hash(projectPath, sourceSetName);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
DefaultBuildTargetDependency other = (DefaultBuildTargetDependency) obj;
return Objects.equals(projectPath, other.projectPath)
&& Objects.equals(sourceSetName, other.sourceSetName);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import java.util.stream.Collectors;

import com.microsoft.java.bs.gradle.model.GradleModuleDependency;
import com.microsoft.java.bs.gradle.model.GradleProjectDependency;
import com.microsoft.java.bs.gradle.model.BuildTargetDependency;
import com.microsoft.java.bs.gradle.model.GradleSourceSet;

/**
Expand Down Expand Up @@ -59,7 +59,7 @@ public class DefaultGradleSourceSet implements GradleSourceSet {

private Set<GradleModuleDependency> moduleDependencies;

private Set<GradleProjectDependency> projectDependencies;
private Set<BuildTargetDependency> buildTargetDependencies;

private boolean hasTests;

Expand Down Expand Up @@ -92,8 +92,8 @@ public DefaultGradleSourceSet(GradleSourceSet gradleSourceSet) {
this.compilerArgs = gradleSourceSet.getCompilerArgs();
this.moduleDependencies = gradleSourceSet.getModuleDependencies().stream()
.map(DefaultGradleModuleDependency::new).collect(Collectors.toSet());
this.projectDependencies = gradleSourceSet.getProjectDependencies().stream()
.map(DefaultGradleProjectDependency::new).collect(Collectors.toSet());
this.buildTargetDependencies = gradleSourceSet.getBuildTargetDependencies().stream()
.map(DefaultBuildTargetDependency::new).collect(Collectors.toSet());
this.hasTests = gradleSourceSet.hasTests();
}

Expand Down Expand Up @@ -257,12 +257,12 @@ public void setModuleDependencies(Set<GradleModuleDependency> moduleDependencies
this.moduleDependencies = moduleDependencies;
}

public Set<GradleProjectDependency> getProjectDependencies() {
return projectDependencies;
public Set<BuildTargetDependency> getBuildTargetDependencies() {
return buildTargetDependencies;
}

public void setProjectDependencies(Set<GradleProjectDependency> projectDependencies) {
this.projectDependencies = projectDependencies;
public void setBuildTargetDependencies(Set<BuildTargetDependency> buildTargetDependencies) {
this.buildTargetDependencies = buildTargetDependencies;
}

public boolean hasTests() {
Expand All @@ -280,7 +280,7 @@ public int hashCode() {
generatedSourceDirs, sourceOutputDir, compileClasspath,
resourceDirs, resourceOutputDir, javaHome, javaVersion,
gradleVersion, sourceCompatibility, targetCompatibility,
compilerArgs, moduleDependencies, projectDependencies,
compilerArgs, moduleDependencies, buildTargetDependencies,
hasTests);
}

Expand Down Expand Up @@ -316,7 +316,7 @@ public boolean equals(Object obj) {
&& Objects.equals(targetCompatibility, other.targetCompatibility)
&& Objects.equals(compilerArgs, other.compilerArgs)
&& Objects.equals(moduleDependencies, other.moduleDependencies)
&& Objects.equals(projectDependencies, other.projectDependencies)
&& Objects.equals(buildTargetDependencies, other.buildTargetDependencies)
&& hasTests == other.hasTests;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.LinkedList;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
Expand All @@ -25,24 +24,29 @@
import java.util.stream.Stream;

import org.gradle.api.Project;
import org.gradle.api.file.CopySpec;
import org.gradle.api.file.Directory;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.SourceDirectorySet;
import org.gradle.api.internal.tasks.compile.DefaultJavaCompileSpec;
import org.gradle.api.internal.tasks.compile.JavaCompilerArgumentsBuilder;
import org.gradle.api.internal.file.copy.DefaultCopySpec;
import org.gradle.api.plugins.JavaPluginExtension;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.TaskCollection;
import org.gradle.api.tasks.bundling.AbstractArchiveTask;
import org.gradle.api.tasks.compile.CompileOptions;
import org.gradle.api.tasks.compile.JavaCompile;
import org.gradle.api.tasks.testing.Test;
import org.gradle.plugins.ide.internal.tooling.java.DefaultInstalledJdk;
import org.gradle.tooling.provider.model.ToolingModelBuilder;
import org.gradle.util.GradleVersion;

import com.microsoft.java.bs.gradle.model.BuildTargetDependency;
import com.microsoft.java.bs.gradle.model.GradleSourceSet;
import com.microsoft.java.bs.gradle.model.GradleSourceSets;
import com.microsoft.java.bs.gradle.model.impl.DefaultBuildTargetDependency;
import com.microsoft.java.bs.gradle.model.impl.DefaultGradleSourceSet;
import com.microsoft.java.bs.gradle.model.impl.DefaultGradleSourceSets;
import com.microsoft.java.bs.gradle.plugin.dependency.DependencyCollector;
Expand Down Expand Up @@ -156,13 +160,69 @@ public Object buildAll(String modelName, Project rootProject) {
}
}

// map all output dirs to their source sets
Map<File, DefaultGradleSourceSet> outputsToSourceSet = new HashMap<>();
for (DefaultGradleSourceSet sourceSet : sourceSetMap.values()) {
if (sourceSet.getSourceOutputDir() != null) {
outputsToSourceSet.put(sourceSet.getSourceOutputDir(), sourceSet);
}
if (sourceSet.getResourceOutputDir() != null) {
outputsToSourceSet.put(sourceSet.getResourceOutputDir(), sourceSet);
}
}
// map all output jars to their source sets
for (Project project : allProject) {

SourceSetContainer sourceSets = getSourceSetContainer(project);
if (sourceSets == null || sourceSets.isEmpty()) {
continue;
}

// dependencies
// get all archive tasks for this project and find the dirs that are included in the archive
TaskCollection<AbstractArchiveTask> archiveTasks =
project.getTasks().withType(AbstractArchiveTask.class);
for (AbstractArchiveTask archiveTask : archiveTasks) {
Set<Object> archiveSourcePaths = getArchiveSourcePaths(archiveTask.getRootSpec());
for (Object sourcePath : archiveSourcePaths) {
sourceSets.forEach(sourceSet -> {
DefaultGradleSourceSet gradleSourceSet = sourceSetMap.get(sourceSet);
if (gradleSourceSet == null) {
return;
}

if (sourceSet.getOutput().equals(sourcePath)) {
File archiveFile;
if (GradleVersion.current().compareTo(GradleVersion.version("5.1")) >= 0) {
archiveFile = archiveTask.getArchiveFile().get().getAsFile();
} else {
archiveFile = archiveTask.getArchivePath();
}
outputsToSourceSet.put(archiveFile, gradleSourceSet);
}
});
}
}
}

// match any classpath entries to other project's output dirs/jars to create dependencies
for (DefaultGradleSourceSet sourceSet : sourceSetMap.values()) {
Set<BuildTargetDependency> dependencies = new HashSet<>();
for (File file : sourceSet.getCompileClasspath()) {
DefaultGradleSourceSet otherSourceSet = outputsToSourceSet.get(file);
if (otherSourceSet != null) {
dependencies.add(new DefaultBuildTargetDependency(otherSourceSet));
}
}
sourceSet.setBuildTargetDependencies(dependencies);
}

for (Project project : allProject) {
SourceSetContainer sourceSets = getSourceSetContainer(project);
if (sourceSets == null || sourceSets.isEmpty()) {
continue;
}

// module dependencies
sourceSets.forEach(sourceSet -> {
DefaultGradleSourceSet gradleSourceSet = sourceSetMap.get(sourceSet);
if (gradleSourceSet == null) {
Expand All @@ -172,7 +232,6 @@ public Object buildAll(String modelName, Project rootProject) {
exclusionFromDependencies);
collector.collectByConfigurationNames(getClasspathConfigurationNames(sourceSet));
gradleSourceSet.setModuleDependencies(collector.getModuleDependencies());
gradleSourceSet.setProjectDependencies(collector.getProjectDependencies());
});
}

Expand Down Expand Up @@ -207,6 +266,36 @@ private String createUniqueDisplayName(DefaultGradleSourceSet sourceSet,
return usedName;
}

private Set<Object> getArchiveSourcePaths(CopySpec copySpec) {
Set<Object> sourcePaths = new HashSet<>();
if (copySpec instanceof DefaultCopySpec) {
DefaultCopySpec defaultCopySpec = (DefaultCopySpec) copySpec;
sourcePaths.addAll(defaultCopySpec.getSourcePaths());
// DefaultCopySpec#getChildren changed from Iterable to Collection
if (GradleVersion.current().compareTo(GradleVersion.version("6.2")) >= 0) {
jdneo marked this conversation as resolved.
Show resolved Hide resolved
for (CopySpec child : defaultCopySpec.getChildren()) {
sourcePaths.addAll(getArchiveSourcePaths(child));
}
} else {
try {
Method getChildren = defaultCopySpec.getClass().getMethod("getChildren");
Object children = getChildren.invoke(defaultCopySpec);
if (children instanceof Iterable) {
for (Object child : (Iterable<?>) children) {
if (child instanceof CopySpec) {
sourcePaths.addAll(getArchiveSourcePaths((CopySpec) child));
}
}
}
} catch (NoSuchMethodException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException e) {
// cannot get archive information
}
}
}
return sourcePaths;
}

private SourceSetContainer getSourceSetContainer(Project project) {
if (!project.getPlugins().hasPlugin("java")) {
return null;
Expand Down
Loading
Loading