Gradle: fix dependencies scope merge

IDEA-117556 Gradle custom provided configuration added with compile scope
IDEA-117601 Gradle integration ignores scopes.TEST.plus in build.gradle
This commit is contained in:
Vladislav.Soroka
2013-12-09 17:12:49 +04:00
parent b636208169
commit f80d6920dc
7 changed files with 155 additions and 16 deletions
@@ -481,16 +481,16 @@ public class ExternalSystemUtil {
DataNode<ProjectData> externalProject = task.getExternalProject();
if(externalProject != null) {
Set<String> myExternalModulePaths = ContainerUtil.newHashSet();
Set<String> externalModulePaths = ContainerUtil.newHashSet();
Collection<DataNode<ModuleData>> moduleNodes = ExternalSystemApiUtil.findAll(externalProject, ProjectKeys.MODULE);
for (DataNode<ModuleData> node : moduleNodes) {
myExternalModulePaths.add(node.getData().getLinkedExternalProjectPath());
externalModulePaths.add(node.getData().getLinkedExternalProjectPath());
}
String projectPath = externalProject.getData().getLinkedExternalProjectPath();
ExternalProjectSettings linkedProjectSettings = manager.getSettingsProvider().fun(project).getLinkedProjectSettings(projectPath);
if (linkedProjectSettings != null) {
linkedProjectSettings.setModules(myExternalModulePaths);
linkedProjectSettings.setModules(externalModulePaths);
}
}
@@ -121,6 +121,14 @@ public enum GradleDependencyScope {
return null;
}
@Nullable
public static GradleDependencyScope fromIdeaMappingName(final String ideaMappingName) {
for (GradleDependencyScope scope : values()) {
if (scope.myIdeaMappingName.equals(ideaMappingName.toLowerCase())) return scope;
}
return null;
}
public String getIdeaMappingName() {
return myIdeaMappingName;
}
@@ -62,12 +62,14 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService {
boolean downloadSources = true;
final IdeaPlugin ideaPlugin = project.getPlugins().getPlugin(IdeaPlugin.class);
Map<String, Map<String, Collection<Configuration>>> userScopes = Collections.emptyMap();
if (ideaPlugin != null) {
IdeaModel ideaModel = ideaPlugin.getModel();
if (ideaModel != null && ideaModel.getModule() == null) {
if (ideaModel != null && ideaModel.getModule() != null) {
offline = ideaModel.getModule().isOffline();
downloadJavadoc = ideaModel.getModule().isDownloadJavadoc();
downloadSources = ideaModel.getModule().isDownloadSources();
userScopes = ideaModel.getModule().getScopes();
}
}
@@ -79,7 +81,7 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService {
dependenciesExtractor.extractProjectDependencies(plusConfigurations, new ArrayList<Configuration>());
for (IdeDependenciesExtractor.IdeProjectDependency ideProjectDependency : ideProjectDependencies) {
merge(scopesMap, ideProjectDependency);
merge(scopesMap, ideProjectDependency, userScopes);
}
if (!offline) {
@@ -87,14 +89,14 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService {
dependenciesExtractor.extractRepoFileDependencies(
project.getConfigurations(), plusConfigurations, new ArrayList<Configuration>(), downloadSources, downloadJavadoc);
for (IdeDependenciesExtractor.IdeRepoFileDependency repoFileDependency : ideRepoFileDependencies) {
merge(scopesMap, repoFileDependency);
merge(scopesMap, repoFileDependency, userScopes);
}
}
final List<IdeDependenciesExtractor.IdeLocalFileDependency> ideLocalFileDependencies =
dependenciesExtractor.extractLocalFileDependencies(plusConfigurations, new ArrayList<Configuration>());
for (IdeDependenciesExtractor.IdeLocalFileDependency fileDependency : ideLocalFileDependencies) {
merge(scopesMap, fileDependency);
merge(scopesMap, fileDependency, userScopes);
}
}
@@ -166,9 +168,11 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService {
return null;
}
private static void merge(Map<DependencyVersionId, Scopes> map, IdeDependenciesExtractor.IdeProjectDependency dependency) {
private static void merge(Map<DependencyVersionId, Scopes> map,
IdeDependenciesExtractor.IdeProjectDependency dependency,
Map<String, Map<String, Collection<Configuration>>> userScopes) {
final String configurationName = dependency.getDeclaredConfiguration().getName();
final GradleDependencyScope scope = GradleDependencyScope.fromName(configurationName);
final GradleDependencyScope scope = deduceScope(configurationName, userScopes);
if (scope == null) return;
final Project project = dependency.getProject();
@@ -190,9 +194,11 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService {
return String.valueOf(o == null ? "" : o);
}
private static void merge(Map<DependencyVersionId, Scopes> map, IdeDependenciesExtractor.IdeRepoFileDependency dependency) {
private static void merge(Map<DependencyVersionId, Scopes> map,
IdeDependenciesExtractor.IdeRepoFileDependency dependency,
Map<String, Map<String, Collection<Configuration>>> userScopes) {
final String configurationName = dependency.getDeclaredConfiguration().getName();
final GradleDependencyScope scope = GradleDependencyScope.fromName(configurationName);
final GradleDependencyScope scope = deduceScope(configurationName, userScopes);
if (scope == null) return;
final ModuleVersionIdentifier dependencyId;
@@ -218,16 +224,18 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService {
}
private static String parseClassifier(ModuleVersionIdentifier dependencyId, File dependencyFile) {
if(dependencyFile == null) return null;
if (dependencyFile == null) return null;
String dependencyFileName = dependencyFile.getName();
int i = dependencyFileName.indexOf(dependencyId.getName() + '-' + dependencyId.getVersion() + '-');
return i != -1 ? dependencyFileName.substring(i, dependencyFileName.length()) : null;
}
private static void merge(Map<DependencyVersionId, Scopes> map, IdeDependenciesExtractor.IdeLocalFileDependency dependency) {
private static void merge(Map<DependencyVersionId, Scopes> map,
IdeDependenciesExtractor.IdeLocalFileDependency dependency,
Map<String, Map<String, Collection<Configuration>>> userScopes) {
final String configurationName = dependency.getDeclaredConfiguration().getName();
final GradleDependencyScope scope = GradleDependencyScope.fromName(configurationName);
final GradleDependencyScope scope = deduceScope(configurationName, userScopes);
if (scope == null) return;
String path = dependency.getFile().getPath();
@@ -242,6 +250,33 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService {
}
}
/**
* Deduce configuration scope based on configuration name using gradle conventions.
* IDEA gradle plugin only 'plus' configuration used to support configuration based on a custom configuration (not conventional)
*
* @param configurationName gradle configuration name
* @param userScopes gradle IDEA plugin scopes map
* @return deduced scope
*/
private static GradleDependencyScope deduceScope(String configurationName,
Map<String, Map<String, Collection<Configuration>>> userScopes) {
GradleDependencyScope scope = GradleDependencyScope.fromName(configurationName);
if (scope == null) {
for (Map.Entry<String, Map<String, Collection<Configuration>>> entry : userScopes.entrySet()) {
Collection<Configuration> plusConfigurations = entry.getValue().get("plus");
if (plusConfigurations == null) continue;
for (Configuration plus : plusConfigurations) {
if (plus.getName().equals(configurationName)) {
return GradleDependencyScope.fromIdeaMappingName(entry.getKey());
}
}
}
}
return scope;
}
private static class MyModuleVersionIdentifier implements ModuleVersionIdentifier, Serializable {
private final String myName;
@@ -33,7 +33,9 @@ public class Scopes {
myForProductionRuntime = scope.isForProductionRuntime();
myForTestCompile = scope.isForTestCompile();
myForTestRuntime = scope.isForTestRuntime();
myIsProvided = scope == GradleDependencyScope.PROVIDED_COMPILE || scope == GradleDependencyScope.PROVIDED_RUNTIME;
myIsProvided = scope == GradleDependencyScope.PROVIDED_COMPILE ||
scope == GradleDependencyScope.PROVIDED_RUNTIME ||
scope == GradleDependencyScope.PROVIDED;
}
public GradleDependencyScope[] getScopes() {
@@ -74,6 +76,9 @@ public class Scopes {
myForProductionRuntime = myForProductionRuntime || scope.isForProductionRuntime();
myForTestCompile = myForTestCompile || scope.isForTestCompile();
myForTestRuntime = myForTestRuntime || scope.isForTestRuntime();
myIsProvided = myIsProvided || scope == GradleDependencyScope.PROVIDED_COMPILE || scope == GradleDependencyScope.PROVIDED_RUNTIME;
myIsProvided = myIsProvided ||
scope == GradleDependencyScope.PROVIDED_COMPILE ||
scope == GradleDependencyScope.PROVIDED_RUNTIME ||
scope == GradleDependencyScope.PROVIDED;
}
}
@@ -0,0 +1,38 @@
//noinspection GrPackage
allprojects {
apply plugin: 'java'
apply plugin: 'idea'
version = '1.0'
sourceCompatibility = 1.6
configurations {
provided
}
sourceSets {
main {
compileClasspath += configurations.provided
}
}
idea {
module {
scopes.PROVIDED.plus += configurations.provided
}
}
}
project(":service") {
dependencies {
compile (project(':api'))
}
}
project(":api") {
dependencies {
provided(project(':lib'))
}
}
@@ -0,0 +1,4 @@
//noinspection GrPackage
include "lib"
include "api"
include "service"
@@ -20,6 +20,8 @@ import com.intellij.util.containers.ContainerUtil;
import org.gradle.tooling.model.DomainObjectSet;
import org.gradle.tooling.model.idea.IdeaDependency;
import org.gradle.tooling.model.idea.IdeaModule;
import org.gradle.tooling.model.idea.IdeaModuleDependency;
import org.jetbrains.plugins.gradle.model.GradleDependencyScope;
import org.jetbrains.plugins.gradle.model.ProjectDependenciesModel;
import org.junit.Test;
@@ -53,6 +55,53 @@ public class ModelDependenciesBuilderImplTest extends AbstractModelBuilderTest {
assertEquals(1, dependencies.size());
}
@Test
public void testGradleIdeaPluginPlusScopesDependenciesModel() throws Exception {
ModelDependenciesBuilderImpl dependenciesBuilder = new ModelDependenciesBuilderImpl();
assertTrue(dependenciesBuilder.canBuild("org.jetbrains.plugins.gradle.model.ProjectDependenciesModel"));
DomainObjectSet<? extends IdeaModule> ideaModules = allModels.getIdeaProject().getModules();
// test api module dependencies
IdeaModule apiModule = ContainerUtil.find(ideaModules, new Condition<IdeaModule>() {
@Override
public boolean value(IdeaModule module) {
return module.getName().equals("api");
}
});
assertNotNull(apiModule);
DomainObjectSet<? extends IdeaDependency> dependencies = apiModule.getDependencies();
assertEquals(1, dependencies.size());
IdeaDependency libDependency = dependencies.getAt(0);
assertEquals(GradleDependencyScope.PROVIDED.name(), libDependency.getScope().getScope());
assertTrue(libDependency instanceof IdeaModuleDependency);
IdeaModuleDependency libModuleDependency = (IdeaModuleDependency)libDependency;
assertNotNull(libModuleDependency.getDependencyModule());
assertEquals("lib", libModuleDependency.getDependencyModule().getName());
// test service module dependencies
IdeaModule serviceModule = ContainerUtil.find(ideaModules, new Condition<IdeaModule>() {
@Override
public boolean value(IdeaModule module) {
return module.getName().equals("service");
}
});
assertNotNull(serviceModule);
DomainObjectSet<? extends IdeaDependency> serviceModuleDependencies = serviceModule.getDependencies();
assertEquals(1, serviceModuleDependencies.size());
IdeaDependency apiDependency = serviceModuleDependencies.getAt(0);
assertEquals(GradleDependencyScope.COMPILE.name(), apiDependency.getScope().getScope());
assertTrue(apiDependency instanceof IdeaModuleDependency);
IdeaModuleDependency apiModuleDependency = (IdeaModuleDependency)apiDependency;
assertNotNull(apiModuleDependency.getDependencyModule());
assertEquals("api", apiModuleDependency.getDependencyModule().getName());
}
@Override
protected Set<Class> getModels() {
return ContainerUtil.<Class>set(ProjectDependenciesModel.class);