Skip to content

Commit

Permalink
feat - Support resolving debug & release variant from Android Java pr…
Browse files Browse the repository at this point in the history
…oject (#173)
  • Loading branch information
Tanish-Ranjan authored Sep 5, 2024
1 parent 395b977 commit 3129d53
Show file tree
Hide file tree
Showing 34 changed files with 1,636 additions and 159 deletions.
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

0 comments on commit 3129d53

Please sign in to comment.