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

feat - Support resolving debug & release variant from Android Java project #173

Merged
merged 15 commits into from
Sep 5, 2024
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 @@ -86,9 +86,9 @@ public interface GradleSourceSet extends Serializable {
Set<File> getSourceOutputDirs();

/**
* The resource output directory of this source set.
* The resource output directories of this source set.
*/
public File getResourceOutputDir();
public Set<File> getResourceOutputDirs();

/**
* Any archive files created from the output of this source set to the output dirs.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ private Collection<GradleBuild> fetchIncludedBuilds(BuildController buildControl
Map<String, GradleBuild> builds = new HashMap<>();
GradleBuild build = buildController.getBuildModel();
String rootProjectName = build.getRootProject().getName();
fetchIncludedBuilds(buildController, build, builds, rootProjectName);
fetchIncludedBuilds(build, builds, rootProjectName);
return builds.values();
}

private void fetchIncludedBuilds(BuildController buildController, GradleBuild build,
Map<String, GradleBuild> builds, String rootProjectName) {
private void fetchIncludedBuilds(GradleBuild build, Map<String,
GradleBuild> builds, String rootProjectName) {
if (builds.containsKey(rootProjectName)) {
return;
}
Expand All @@ -75,7 +75,7 @@ private void fetchIncludedBuilds(BuildController buildController, GradleBuild bu
if (moreBuilds != null) {
for (GradleBuild includedBuild : moreBuilds) {
String includedBuildName = includedBuild.getRootProject().getName();
fetchIncludedBuilds(buildController, includedBuild, builds, includedBuildName);
fetchIncludedBuilds(includedBuild, builds, includedBuildName);
}
}
}
Expand All @@ -87,7 +87,7 @@ private void fetchIncludedBuilds(BuildController buildController, GradleBuild bu
* @param builds The Gradle build models representing the build and included builds.
*/
private List<GradleSourceSet> fetchModels(BuildController buildController,
Collection<GradleBuild> builds) {
Collection<GradleBuild> builds) {

List<GetSourceSetAction> projectActions = new ArrayList<>();
for (GradleBuild build : builds) {
Expand All @@ -101,7 +101,7 @@ private List<GradleSourceSet> fetchModels(BuildController buildController,
// populate source set dependencies.
List<GradleSourceSet> sourceSets = buildController.run(projectActions).stream()
.flatMap(ss -> ss.getGradleSourceSets().stream())
.map(ss -> new DefaultGradleSourceSet(ss))
.map(DefaultGradleSourceSet::new)
.collect(Collectors.toList());

populateInterProjectInfo(sourceSets);
Expand Down Expand Up @@ -140,8 +140,10 @@ private void populateInterProjectInfo(List<GradleSourceSet> sourceSets) {
outputsToSourceSet.put(file, sourceSet);
}
}
if (sourceSet.getResourceOutputDir() != null) {
outputsToSourceSet.put(sourceSet.getResourceOutputDir(), sourceSet);
if (sourceSet.getResourceOutputDirs() != null) {
for (File file : sourceSet.getResourceOutputDirs()) {
outputsToSourceSet.put(file, sourceSet);
}
}
if (sourceSet.getArchiveOutputFiles() != null) {
for (Map.Entry<File, List<File>> archive : sourceSet.getArchiveOutputFiles().entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public class DefaultGradleSourceSet implements GradleSourceSet {

private Set<File> resourceDirs;

private File resourceOutputDir;
private Set<File> resourceOutputDirs;

private Map<File, List<File>> archiveOutputFiles;

Expand Down Expand Up @@ -85,7 +85,7 @@ public DefaultGradleSourceSet(GradleSourceSet gradleSourceSet) {
this.generatedSourceDirs = gradleSourceSet.getGeneratedSourceDirs();
this.sourceOutputDirs = gradleSourceSet.getSourceOutputDirs();
this.resourceDirs = gradleSourceSet.getResourceDirs();
this.resourceOutputDir = gradleSourceSet.getResourceOutputDir();
this.resourceOutputDirs = gradleSourceSet.getResourceOutputDirs();
this.archiveOutputFiles = gradleSourceSet.getArchiveOutputFiles();
this.compileClasspath = gradleSourceSet.getCompileClasspath();
this.moduleDependencies = gradleSourceSet.getModuleDependencies().stream()
Expand Down Expand Up @@ -234,12 +234,12 @@ public void setResourceDirs(Set<File> resourceDirs) {
}

@Override
public File getResourceOutputDir() {
return resourceOutputDir;
public Set<File> getResourceOutputDirs() {
return resourceOutputDirs;
}

public void setResourceOutputDir(File resourceOutputDir) {
this.resourceOutputDir = resourceOutputDir;
public void setResourceOutputDirs(Set<File> resourceOutputDirs) {
this.resourceOutputDirs = resourceOutputDirs;
}

@Override
Expand Down Expand Up @@ -300,7 +300,7 @@ public void setExtensions(Map<String, LanguageExtension> extensions) {
public int hashCode() {
return Objects.hash(gradleVersion, displayName, projectName, projectPath,
projectDir, rootDir, sourceSetName, classesTaskName, cleanTaskName, taskNames, sourceDirs,
generatedSourceDirs, sourceOutputDirs, resourceDirs, resourceOutputDir, archiveOutputFiles,
generatedSourceDirs, sourceOutputDirs, resourceDirs, resourceOutputDirs, archiveOutputFiles,
compileClasspath, moduleDependencies, buildTargetDependencies,
hasTests, extensions);
}
Expand Down Expand Up @@ -331,7 +331,7 @@ public boolean equals(Object obj) {
&& Objects.equals(generatedSourceDirs, other.generatedSourceDirs)
&& Objects.equals(sourceOutputDirs, other.sourceOutputDirs)
&& Objects.equals(resourceDirs, other.resourceDirs)
&& Objects.equals(resourceOutputDir, other.resourceOutputDir)
&& Objects.equals(resourceOutputDirs, other.resourceOutputDirs)
&& Objects.equals(archiveOutputFiles, other.archiveOutputFiles)
&& Objects.equals(compileClasspath, other.compileClasspath)
&& Objects.equals(moduleDependencies, other.moduleDependencies)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import java.util.Set;
import java.util.stream.Collectors;

import com.microsoft.java.bs.gradle.plugin.utils.AndroidUtils;
import com.microsoft.java.bs.gradle.plugin.utils.SourceSetUtils;
import org.gradle.api.GradleException;
import org.gradle.api.Project;
import org.gradle.api.Task;
Expand All @@ -33,7 +35,6 @@
import com.microsoft.java.bs.gradle.model.GradleSourceSet;
import com.microsoft.java.bs.gradle.model.GradleSourceSets;
import com.microsoft.java.bs.gradle.model.LanguageExtension;
import com.microsoft.java.bs.gradle.model.SupportedLanguages;
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 All @@ -47,17 +48,25 @@ public boolean canBuild(String modelName) {
return modelName.equals(GradleSourceSets.class.getName());
}

@SuppressWarnings("NullableProblems")
@Override
public Object buildAll(String modelName, Project project) {
// mapping Gradle source set to our customized model.
List<GradleSourceSet> sourceSets = getSourceSetContainer(project).stream()
.map(ss -> getSourceSet(project, ss)).collect(Collectors.toList());
List<GradleSourceSet> sourceSets;

// Fetch source sets depending on the project type
if (AndroidUtils.isAndroidProject(project)) {
sourceSets = AndroidUtils.getBuildVariantsAsGradleSourceSets(project);
} else {
sourceSets = getSourceSetContainer(project).stream()
.map(ss -> getSourceSet(project, ss)).collect(Collectors.toList());
}

excludeSourceDirsFromModules(sourceSets);

return new DefaultGradleSourceSets(sourceSets);
}

private DefaultGradleSourceSet getSourceSet(Project project, SourceSet sourceSet) {
DefaultGradleSourceSet gradleSourceSet = new DefaultGradleSourceSet();
// dependencies are populated by the GradleSourceSetsAction. Make sure not null.
Expand All @@ -69,13 +78,14 @@ private DefaultGradleSourceSet getSourceSet(Project project, SourceSet sourceSet
gradleSourceSet.setProjectDir(project.getProjectDir());
gradleSourceSet.setRootDir(project.getRootDir());
gradleSourceSet.setSourceSetName(sourceSet.getName());
String classesTaskName = getFullTaskName(projectPath, sourceSet.getClassesTaskName());
String classesTaskName =
SourceSetUtils.getFullTaskName(projectPath, sourceSet.getClassesTaskName());
gradleSourceSet.setClassesTaskName(classesTaskName);
String cleanTaskName = getFullTaskName(projectPath, "clean");
String cleanTaskName = SourceSetUtils.getFullTaskName(projectPath, "clean");
gradleSourceSet.setCleanTaskName(cleanTaskName);
Set<String> taskNames = new HashSet<>();
gradleSourceSet.setTaskNames(taskNames);
String projectName = stripPathPrefix(projectPath);
String projectName = SourceSetUtils.stripPathPrefix(projectPath);
if (projectName.isEmpty()) {
projectName = project.getName();
}
Expand All @@ -90,11 +100,13 @@ private DefaultGradleSourceSet getSourceSet(Project project, SourceSet sourceSet
Set<File> srcDirs = new HashSet<>();
Set<File> generatedSrcDirs = new HashSet<>();
Set<File> sourceOutputDirs = new HashSet<>();
for (LanguageModelBuilder languageModelBuilder : getSupportedLanguages()) {
for (LanguageModelBuilder languageModelBuilder
: SourceSetUtils.getSupportedLanguageModelBuilders()) {
LanguageExtension extension = languageModelBuilder.getExtensionFor(project, sourceSet,
gradleSourceSet.getModuleDependencies());
if (extension != null) {
String compileTaskName = getFullTaskName(projectPath, extension.getCompileTaskName());
String compileTaskName =
SourceSetUtils.getFullTaskName(projectPath, extension.getCompileTaskName());
taskNames.add(compileTaskName);

srcDirs.addAll(extension.getSourceDirs());
Expand Down Expand Up @@ -124,16 +136,18 @@ private DefaultGradleSourceSet getSourceSet(Project project, SourceSet sourceSet

// resource output dir
File resourceOutputDir = sourceSet.getOutput().getResourcesDir();
Set<File> resourceOutputDirs = new HashSet<>();
if (resourceOutputDir != null) {
gradleSourceSet.setResourceOutputDir(resourceOutputDir);
resourceOutputDirs.add(resourceOutputDir);
}
gradleSourceSet.setResourceOutputDirs(resourceOutputDirs);

// archive output dirs
Map<File, List<File>> archiveOutputFiles = getArchiveOutputFiles(project, sourceSet);
gradleSourceSet.setArchiveOutputFiles(archiveOutputFiles);

// tests
if (sourceOutputDirs != null) {
if (!sourceOutputDirs.isEmpty()) {
Set<Test> testTasks = tasksWithType(project, Test.class);
for (Test testTask : testTasks) {
if (GradleVersion.current().compareTo(GradleVersion.version("4.0")) >= 0) {
Expand Down Expand Up @@ -161,7 +175,7 @@ private DefaultGradleSourceSet getSourceSet(Project project, SourceSet sourceSet
break;
}
} catch (NoSuchMethodException | SecurityException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException e) {
| IllegalArgumentException | InvocationTargetException e) {
// ignore
}
}
Expand All @@ -171,22 +185,6 @@ private DefaultGradleSourceSet getSourceSet(Project project, SourceSet sourceSet
return gradleSourceSet;
}

private List<LanguageModelBuilder> getSupportedLanguages() {
List<LanguageModelBuilder> results = new LinkedList<>();
String supportedLanguagesProps = System.getProperty("bsp.gradle.supportedLanguages");
if (supportedLanguagesProps != null) {
String[] supportedLanguages = supportedLanguagesProps.split(",");
for (String language : supportedLanguages) {
if (language.equalsIgnoreCase(SupportedLanguages.JAVA.getBspName())) {
results.add(new JavaLanguageModelBuilder());
} else if (language.equalsIgnoreCase(SupportedLanguages.SCALA.getBspName())) {
results.add(new ScalaLanguageModelBuilder());
}
}
}
return results;
}

private <T extends Task> Set<T> tasksWithType(Project project, Class<T> clazz) {
// Gradle gives concurrentmodification exceptions if multiple threads resolve
// the tasks concurrently, which happens on multi-project builds
Expand All @@ -199,6 +197,7 @@ private <T extends Task> Set<T> tasksWithType(Project project, Class<T> clazz) {
* get all archive tasks for this project and maintain the archive file
* to source set mapping.
*/
@SuppressWarnings("deprecation")
private Map<File, List<File>> getArchiveOutputFiles(Project project, SourceSet sourceSet) {
// get all archive tasks for this project and find the dirs that are included in the archive
Set<AbstractArchiveTask> archiveTasks = tasksWithType(project, AbstractArchiveTask.class);
Expand All @@ -213,8 +212,7 @@ private Map<File, List<File>> getArchiveOutputFiles(Project project, SourceSet s
} else {
archiveFile = archiveTask.getArchivePath();
}
List<File> sourceSetOutputs = new LinkedList<>();
sourceSetOutputs.addAll(sourceSet.getOutput().getFiles());
List<File> sourceSetOutputs = new LinkedList<>(sourceSet.getOutput().getFiles());
archiveOutputFiles.put(archiveFile, sourceSetOutputs);
}
}
Expand Down Expand Up @@ -243,8 +241,8 @@ private void excludeSourceDirsFromModules(List<GradleSourceSet> sourceSets) {
if (sourceSet.getSourceOutputDirs() != null) {
exclusions.addAll(sourceSet.getSourceOutputDirs());
}
if (sourceSet.getResourceOutputDir() != null) {
exclusions.add(sourceSet.getResourceOutputDir());
if (sourceSet.getResourceOutputDirs() != null) {
exclusions.addAll(sourceSet.getResourceOutputDirs());
}
if (sourceSet.getArchiveOutputFiles() != null) {
exclusions.addAll(sourceSet.getArchiveOutputFiles().keySet());
Expand All @@ -256,7 +254,7 @@ private void excludeSourceDirsFromModules(List<GradleSourceSet> sourceSets) {
for (GradleSourceSet sourceSet : sourceSets) {
Set<GradleModuleDependency> filteredModuleDependencies = sourceSet.getModuleDependencies()
.stream().filter(mod -> mod.getArtifacts()
.stream().anyMatch(art -> !exclusionUris.contains(art.getUri())))
.stream().anyMatch(art -> !exclusionUris.contains(art.getUri())))
.collect(Collectors.toSet());
if (sourceSet instanceof DefaultGradleSourceSet) {
((DefaultGradleSourceSet) sourceSet).setModuleDependencies(filteredModuleDependencies);
Expand All @@ -267,7 +265,7 @@ private void excludeSourceDirsFromModules(List<GradleSourceSet> sourceSets) {
private Collection<SourceSet> getSourceSetContainer(Project project) {
if (GradleVersion.current().compareTo(GradleVersion.version("5.0")) >= 0) {
SourceSetContainer sourceSetContainer = project.getExtensions()
.findByType(SourceSetContainer.class);
.findByType(SourceSetContainer.class);
if (sourceSetContainer != null) {
return sourceSetContainer;
}
Expand All @@ -287,37 +285,12 @@ private Collection<SourceSet> getSourceSetContainer(Project project) {
return (SourceSetContainer) getSourceSetsMethod.invoke(pluginConvention);
}
} catch (NoSuchMethodException | SecurityException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException e) {
| IllegalArgumentException | InvocationTargetException e) {
// ignore
}
return new LinkedList<>();
}

/**
* Return a project task name - [project path]:[task].
*/
private String getFullTaskName(String modulePath, String taskName) {
if (taskName == null) {
return null;
}
if (taskName.isEmpty()) {
return taskName;
}

if (modulePath == null || modulePath.equals(":")) {
// must be prefixed with ":" as taskPaths are reported back like that in progress messages
return ":" + taskName;
}
return modulePath + ":" + taskName;
}

private String stripPathPrefix(String projectPath) {
if (projectPath.startsWith(":")) {
return projectPath.substring(1);
}
return projectPath;
}

private Set<Object> getArchiveSourcePaths(CopySpec copySpec) {
Set<Object> sourcePaths = new HashSet<>();
if (copySpec instanceof DefaultCopySpec) {
Expand All @@ -340,7 +313,7 @@ private Set<Object> getArchiveSourcePaths(CopySpec copySpec) {
}
}
} catch (NoSuchMethodException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException e) {
| IllegalArgumentException | InvocationTargetException e) {
// cannot get archive information
}
}
Expand Down
Loading
Loading