use of org.gradle.api.artifacts.ModuleVersionIdentifier in project atlas by alibaba.
the class TDependencyManager method gatherDependencies.
@NonNull
private DependencyContainer gatherDependencies(@NonNull Configuration configuration, @NonNull final VariantDependencies variantDeps, @NonNull Multimap<AndroidLibrary, Configuration> reverseLibMap, @NonNull Set<String> currentUnresolvedDependencies, @Nullable String testedProjectPath, @NonNull Set<String> artifactSet, @NonNull ScopeType scopeType) {
// collect the artifacts first.
Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts = Maps.newHashMap();
configuration = collectArtifacts(configuration, artifacts);
// keep a map of modules already processed so that we don't go through sections of the
// graph that have been seen elsewhere.
Map<ModuleVersionIdentifier, List<LibraryDependency>> foundLibraries = Maps.newHashMap();
Map<ModuleVersionIdentifier, List<JarDependency>> foundJars = Maps.newHashMap();
// get the graph for the Android and Jar dependencies. This does not include
// local jars.
List<LibraryDependency> libraryDependencies = Lists.newArrayList();
List<JarDependency> jarDependencies = Lists.newArrayList();
Set<? extends DependencyResult> dependencyResultSet = configuration.getIncoming().getResolutionResult().getRoot().getDependencies();
for (DependencyResult dependencyResult : dependencyResultSet) {
if (dependencyResult instanceof ResolvedDependencyResult) {
addDependency(((ResolvedDependencyResult) dependencyResult).getSelected(), variantDeps, configuration, libraryDependencies, jarDependencies, foundLibraries, foundJars, artifacts, reverseLibMap, currentUnresolvedDependencies, testedProjectPath, Collections.emptyList(), artifactSet, scopeType, false, /*forceProvided*/
0);
} else if (dependencyResult instanceof UnresolvedDependencyResult) {
ComponentSelector attempted = ((UnresolvedDependencyResult) dependencyResult).getAttempted();
if (attempted != null) {
currentUnresolvedDependencies.add(attempted.toString());
}
}
}
// also need to process local jar files, as they are not processed by the
// resolvedConfiguration result. This only includes the local jar files for this project.
List<JarDependency> localJars = Lists.newArrayList();
for (Dependency dependency : configuration.getAllDependencies()) {
if (dependency instanceof SelfResolvingDependency && !(dependency instanceof ProjectDependency)) {
Set<File> files = ((SelfResolvingDependency) dependency).resolve();
for (File localJarFile : files) {
if (DEBUG_DEPENDENCY) {
System.out.println("LOCAL " + configuration.getName() + ": " + localJarFile.getName());
}
// only accept local jar, no other types.
if (!localJarFile.getName().toLowerCase(Locale.getDefault()).endsWith(DOT_JAR)) {
variantDeps.getChecker().handleIssue(localJarFile.getAbsolutePath(), SyncIssue.TYPE_NON_JAR_LOCAL_DEP, SyncIssue.SEVERITY_ERROR, String.format("Project %s: Only Jar-type local dependencies are supported. Cannot handle: %s", project.getName(), localJarFile.getAbsolutePath()));
} else {
JarDependency localJar;
switch(scopeType) {
case PACKAGE:
localJar = new JarDependency(localJarFile);
artifactSet.add(computeVersionLessCoordinateKey(localJar.getResolvedCoordinates()));
break;
case COMPILE:
MavenCoordinates coord = JarDependency.getCoordForLocalJar(localJarFile);
boolean provided = !artifactSet.contains(computeVersionLessCoordinateKey(coord));
localJar = new JarDependency(localJarFile, ImmutableList.of(), coord, null, provided);
break;
case COMPILE_ONLY:
// if we only have the compile scope, ignore computation of the
// provided bits.
localJar = new JarDependency(localJarFile);
break;
default:
throw new RuntimeException("unsupported ProvidedComputationAction");
}
localJars.add(localJar);
}
}
}
}
return new DependencyContainerImpl(libraryDependencies, jarDependencies, localJars);
}
use of org.gradle.api.artifacts.ModuleVersionIdentifier in project atlas by alibaba.
the class TDependencyManager method resolveDependencyForApplicationConfig.
private void resolveDependencyForApplicationConfig(@NonNull final VariantDependencies variantDeps, @Nullable VariantDependencies testedVariantDeps, @Nullable String testedProjectPath, @NonNull Multimap<AndroidLibrary, Configuration> reverseLibMap) {
boolean needPackageScope = true;
if (AndroidGradleOptions.buildModelOnly(project)) {
// if we're only syncing (building the model), then we only need the package
// scope if we will actually pass it to the IDE.
Integer modelLevelInt = AndroidGradleOptions.buildModelOnlyVersion(project);
int modelLevel = AndroidProject.MODEL_LEVEL_0_ORIGNAL;
if (modelLevelInt != null) {
modelLevel = modelLevelInt;
}
needPackageScope = modelLevel >= AndroidProject.MODEL_LEVEL_2_DEP_GRAPH;
}
Configuration compileClasspath = variantDeps.getCompileConfiguration();
Configuration packageClasspath = variantDeps.getPackageConfiguration();
if (DEBUG_DEPENDENCY) {
System.out.println(">>>>>>>>>>");
System.out.println(project.getName() + ":" + compileClasspath.getName() + "/" + packageClasspath.getName());
}
Set<String> resolvedModules = Sets.newHashSet();
Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts = Maps.newHashMap();
collectArtifacts(compileClasspath, artifacts);
collectArtifacts(packageClasspath, artifacts);
// 不使用官方的扁平化的依赖处理,改用自己处理树状的依赖关系;对于application的依赖,我们只取compile的依赖
ResolvedDependencyContainer compileResolvedDependencyContainer = new ResolvedDependencyContainer(project);
Set<ModuleVersionIdentifier> directDependencies = new HashSet<ModuleVersionIdentifier>();
Set<? extends DependencyResult> projectDependencies = compileClasspath.getIncoming().getResolutionResult().getRoot().getDependencies();
for (DependencyResult dependencyResult : projectDependencies) {
if (dependencyResult instanceof ResolvedDependencyResult) {
ModuleVersionIdentifier moduleVersion = ((ResolvedDependencyResult) dependencyResult).getSelected().getModuleVersion();
CircleDependencyCheck circleDependencyCheck = new CircleDependencyCheck(moduleVersion);
if (!directDependencies.contains(moduleVersion)) {
directDependencies.add(moduleVersion);
resolveDependency(compileResolvedDependencyContainer, null, ((ResolvedDependencyResult) dependencyResult).getSelected(), artifacts, variantDeps, 0, circleDependencyCheck, circleDependencyCheck.getRootDependencyNode(), resolvedModules);
}
}
}
AndroidDependencyTree androidDependencyTree = compileResolvedDependencyContainer.reslovedDependencies().toAndroidDependency();
AtlasBuildContext.androidDependencyTrees.put(variantDeps.getName(), androidDependencyTree);
//output tree file only once
if (project.getLogger().isInfoEnabled()) {
project.getLogger().info("[dependencyTree" + variantDeps.getName() + "]" + JSON.toJSONString(androidDependencyTree.getDependencyJson(), true));
}
// 设置reverseMap
for (AndroidLibrary libInfo : androidDependencyTree.getAarBundles()) {
reverseLibMap.put(libInfo, variantDeps.getCompileConfiguration());
}
Set<String> currentUnresolvedDependencies = Sets.newHashSet();
// records the artifact we find during package, to detect provided only dependencies.
Set<String> artifactSet = Sets.newHashSet();
// start with package dependencies, record the artifacts
DependencyContainer packagedDependencies;
if (needPackageScope) {
packagedDependencies = gatherDependencies(packageClasspath, variantDeps, reverseLibMap, currentUnresolvedDependencies, testedProjectPath, artifactSet, ScopeType.PACKAGE);
} else {
packagedDependencies = DependencyContainerImpl.getEmpty();
}
// then the compile dependencies, comparing against the record package dependencies
// to set the provided flag.
// if we have not compute the package scope, we disable the computation of
// provided bits. This disables the checks on impossible provided libs (provided aar in
// apk project).
ScopeType scopeType = needPackageScope ? ScopeType.COMPILE : ScopeType.COMPILE_ONLY;
DependencyContainer compileDependencies = gatherDependencies(compileClasspath, variantDeps, reverseLibMap, currentUnresolvedDependencies, testedProjectPath, artifactSet, scopeType);
if (extraModelInfo.getMode() != STANDARD && compileClasspath.getResolvedConfiguration().hasError()) {
for (String dependency : currentUnresolvedDependencies) {
extraModelInfo.handleSyncError(dependency, SyncIssue.TYPE_UNRESOLVED_DEPENDENCY, String.format("Unable to resolve dependency '%s'", dependency));
}
}
// validate the dependencies.
if (needPackageScope) {
variantDeps.getChecker().validate(compileDependencies, packagedDependencies, testedVariantDeps);
}
if (DEBUG_DEPENDENCY) {
System.out.println("*** COMPILE DEPS ***");
for (AndroidLibrary lib : compileDependencies.getAndroidDependencies()) {
System.out.println("LIB: " + lib);
}
for (JavaLibrary jar : compileDependencies.getJarDependencies()) {
System.out.println("JAR: " + jar);
}
for (JavaLibrary jar : compileDependencies.getLocalDependencies()) {
System.out.println("LOCAL-JAR: " + jar);
}
System.out.println("*** PACKAGE DEPS ***");
for (AndroidLibrary lib : packagedDependencies.getAndroidDependencies()) {
System.out.println("LIB: " + lib);
}
for (JavaLibrary jar : packagedDependencies.getJarDependencies()) {
System.out.println("JAR: " + jar);
}
for (JavaLibrary jar : packagedDependencies.getLocalDependencies()) {
System.out.println("LOCAL-JAR: " + jar);
}
System.out.println("***");
}
variantDeps.setDependencies(compileDependencies, packagedDependencies);
configureBuild(variantDeps);
if (DEBUG_DEPENDENCY) {
System.out.println(project.getName() + ":" + compileClasspath.getName() + "/" + packageClasspath.getName());
System.out.println("<<<<<<<<<<");
}
}
use of org.gradle.api.artifacts.ModuleVersionIdentifier in project atlas by alibaba.
the class TDependencyManager method addDependency.
private void addDependency(@NonNull ResolvedComponentResult resolvedComponentResult, @NonNull VariantDependencies configDependencies, @NonNull Configuration configuration, @NonNull Collection<LibraryDependency> outLibraries, @NonNull List<JarDependency> outJars, @NonNull Map<ModuleVersionIdentifier, List<LibraryDependency>> alreadyFoundLibraries, @NonNull Map<ModuleVersionIdentifier, List<JarDependency>> alreadyFoundJars, @NonNull Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts, @NonNull Multimap<AndroidLibrary, Configuration> reverseLibMap, @NonNull Set<String> currentUnresolvedDependencies, @Nullable String testedProjectPath, @NonNull List<String> projectChain, @NonNull Set<String> artifactSet, @NonNull ScopeType scopeType, boolean forceProvided, int indent) {
ModuleVersionIdentifier moduleVersion = resolvedComponentResult.getModuleVersion();
if (configDependencies.getChecker().checkForExclusion(moduleVersion)) {
return;
}
if (moduleVersion.getName().equals("support-annotations") && moduleVersion.getGroup().equals("com.android.support")) {
configDependencies.setAnnotationsPresent(true);
}
List<LibraryDependency> libsForThisModule = alreadyFoundLibraries.get(moduleVersion);
List<JarDependency> jarsForThisModule = alreadyFoundJars.get(moduleVersion);
if (libsForThisModule != null) {
if (DEBUG_DEPENDENCY) {
printIndent(indent, "FOUND LIB: " + moduleVersion.getName());
}
outLibraries.addAll(libsForThisModule);
for (AndroidLibrary lib : libsForThisModule) {
reverseLibMap.put(lib, configuration);
}
} else if (jarsForThisModule != null) {
if (DEBUG_DEPENDENCY) {
printIndent(indent, "FOUND JAR: " + moduleVersion.getName());
}
outJars.addAll(jarsForThisModule);
} else {
if (DEBUG_DEPENDENCY) {
printIndent(indent, "NOT FOUND: " + moduleVersion.getName());
}
// new module! Might be a jar or a library
// get the associated gradlepath
ComponentIdentifier id = resolvedComponentResult.getId();
String gradlePath = (id instanceof ProjectComponentIdentifier) ? ((ProjectComponentIdentifier) id).getProjectPath() : null;
// check if this is a tested app project (via a separate test module).
// In which case, all the dependencies must become provided.
boolean childForceProvided = forceProvided;
if (scopeType == ScopeType.COMPILE && testedProjectPath != null && testedProjectPath.equals(gradlePath)) {
childForceProvided = true;
}
// get the nested components first.
List<LibraryDependency> nestedLibraries = Lists.newArrayList();
List<JarDependency> nestedJars = Lists.newArrayList();
Set<? extends DependencyResult> dependencies = resolvedComponentResult.getDependencies();
for (DependencyResult dependencyResult : dependencies) {
if (dependencyResult instanceof ResolvedDependencyResult) {
ResolvedComponentResult selected = ((ResolvedDependencyResult) dependencyResult).getSelected();
List<String> newProjectChain = projectChain;
ComponentIdentifier identifier = selected.getId();
if (identifier instanceof ProjectComponentIdentifier) {
String projectPath = ((ProjectComponentIdentifier) identifier).getProjectPath();
int index = projectChain.indexOf(projectPath);
if (index != -1) {
projectChain.add(projectPath);
String path = Joiner.on(" -> ").join(projectChain.subList(index, projectChain.size()));
throw new CircularReferenceException("Circular reference between projects: " + path);
}
newProjectChain = Lists.newArrayList();
newProjectChain.addAll(projectChain);
newProjectChain.add(projectPath);
}
addDependency(selected, configDependencies, configuration, nestedLibraries, nestedJars, alreadyFoundLibraries, alreadyFoundJars, artifacts, reverseLibMap, currentUnresolvedDependencies, testedProjectPath, newProjectChain, artifactSet, scopeType, childForceProvided, indent + 1);
} else if (dependencyResult instanceof UnresolvedDependencyResult) {
ComponentSelector attempted = ((UnresolvedDependencyResult) dependencyResult).getAttempted();
if (attempted != null) {
currentUnresolvedDependencies.add(attempted.toString());
}
}
}
if (DEBUG_DEPENDENCY) {
printIndent(indent, "BACK2: " + moduleVersion.getName());
printIndent(indent, "NESTED LIBS: " + nestedLibraries.size());
printIndent(indent, "NESTED JARS: " + nestedJars.size());
}
// now loop on all the artifact for this modules.
List<ResolvedArtifact> moduleArtifacts = artifacts.get(moduleVersion);
if (moduleArtifacts != null) {
for (ResolvedArtifact artifact : moduleArtifacts) {
MavenCoordinates mavenCoordinates = createMavenCoordinates(artifact);
boolean provided = forceProvided;
String coordKey = computeVersionLessCoordinateKey(mavenCoordinates);
if (scopeType == ScopeType.PACKAGE) {
artifactSet.add(coordKey);
} else if (scopeType == ScopeType.COMPILE) {
provided |= !artifactSet.contains(coordKey);
}
if (EXT_LIB_ARCHIVE.equals(artifact.getExtension())) {
if (DEBUG_DEPENDENCY) {
printIndent(indent, "TYPE: AAR");
}
if (libsForThisModule == null) {
libsForThisModule = Lists.newArrayList();
alreadyFoundLibraries.put(moduleVersion, libsForThisModule);
}
String path = computeArtifactPath(moduleVersion, artifact);
String name = computeArtifactName(moduleVersion, artifact);
if (DEBUG_DEPENDENCY) {
printIndent(indent, "NAME: " + name);
printIndent(indent, "PATH: " + path);
}
File explodedDir = project.file(project.getBuildDir() + "/" + FD_INTERMEDIATES + "/exploded-aar/" + path);
@SuppressWarnings("unchecked") LibraryDependency LibraryDependency = new LibraryDependency(artifact.getFile(), explodedDir, nestedLibraries, nestedJars, name, artifact.getClassifier(), gradlePath, null, /*requestedCoordinates*/
mavenCoordinates, provided);
libsForThisModule.add(LibraryDependency);
outLibraries.add(LibraryDependency);
reverseLibMap.put(LibraryDependency, configuration);
} else if (EXT_JAR.equals(artifact.getExtension())) {
if (DEBUG_DEPENDENCY) {
printIndent(indent, "TYPE: JAR");
}
nestedLibraries.clear();
// check this jar does not have a dependency on an library, as this would not work.
if (!nestedLibraries.isEmpty()) {
// can detect this an accept it.
if (testedProjectPath != null && testedProjectPath.equals(gradlePath)) {
// if this is a package scope, then skip the dependencies.
if (scopeType == ScopeType.PACKAGE) {
recursiveLibSkip(nestedLibraries);
} else {
// if it's compile scope, make it optional.
provided = true;
}
outLibraries.addAll(nestedLibraries);
} else {
configDependencies.getChecker().handleIssue(createMavenCoordinates(artifact).toString(), SyncIssue.TYPE_JAR_DEPEND_ON_AAR, SyncIssue.SEVERITY_ERROR, String.format("Module '%s' depends on one or more Android Libraries but is a jar", moduleVersion));
}
}
if (jarsForThisModule == null) {
jarsForThisModule = Lists.newArrayList();
alreadyFoundJars.put(moduleVersion, jarsForThisModule);
}
JarDependency jarDependency = new JarDependency(artifact.getFile(), nestedJars, mavenCoordinates, gradlePath, provided);
// app module then skip it.
if (scopeType == ScopeType.PACKAGE && testedProjectPath != null && testedProjectPath.equals(gradlePath)) {
jarDependency.skip();
//noinspection unchecked
recursiveJavaSkip((List<JarDependency>) jarDependency.getDependencies());
}
if (DEBUG_DEPENDENCY) {
printIndent(indent, "JAR-INFO: " + jarDependency.toString());
}
jarsForThisModule.add(jarDependency);
outJars.add(jarDependency);
} else if (EXT_ANDROID_PACKAGE.equals(artifact.getExtension())) {
String name = computeArtifactName(moduleVersion, artifact);
configDependencies.getChecker().handleIssue(name, SyncIssue.TYPE_DEPENDENCY_IS_APK, SyncIssue.SEVERITY_ERROR, String.format("Dependency %s on project %s resolves to an APK archive " + "which is not supported as a compilation dependency. File: %s", name, project.getName(), artifact.getFile()));
} else if ("apklib".equals(artifact.getExtension())) {
String name = computeArtifactName(moduleVersion, artifact);
configDependencies.getChecker().handleIssue(name, SyncIssue.TYPE_DEPENDENCY_IS_APKLIB, SyncIssue.SEVERITY_ERROR, String.format("Packaging for dependency %s is 'apklib' and is not supported. " + "Only 'aar' libraries are supported.", name));
} else if ("awb".equals(artifact.getExtension())) {
break;
} else if ("solib".equals(artifact.getExtension())) {
break;
} else {
String name = computeArtifactName(moduleVersion, artifact);
logger.warning(String.format("Unrecognized dependency: '%s' (type: '%s', extension: '%s')", name, artifact.getType(), artifact.getExtension()));
}
}
}
if (DEBUG_DEPENDENCY) {
printIndent(indent, "DONE: " + moduleVersion.getName());
}
}
}
use of org.gradle.api.artifacts.ModuleVersionIdentifier in project atlas by alibaba.
the class DependencyManager method collectArtifacts.
private void collectArtifacts(Configuration configuration, Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts) {
Set<ResolvedArtifact> allArtifacts;
if (!extraModelInfo.getMode().equals(STANDARD)) {
allArtifacts = configuration.getResolvedConfiguration().getLenientConfiguration().getArtifacts(Specs.satisfyAll());
} else {
allArtifacts = configuration.getResolvedConfiguration().getResolvedArtifacts();
}
for (ResolvedArtifact artifact : allArtifacts) {
ModuleVersionIdentifier id = artifact.getModuleVersion().getId();
List<ResolvedArtifact> moduleArtifacts = artifacts.get(id);
if (moduleArtifacts == null) {
moduleArtifacts = Lists.newArrayList();
artifacts.put(id, moduleArtifacts);
}
if (!moduleArtifacts.contains(artifact)) {
moduleArtifacts.add(artifact);
}
}
}
use of org.gradle.api.artifacts.ModuleVersionIdentifier in project atlas by alibaba.
the class DependencyManager method parseDependencyTree.
protected AndroidDependencyTree parseDependencyTree(@NonNull VariantDependencies variantDeps) {
Configuration compileClasspath = variantDeps.getCompileConfiguration();
Configuration packageClasspath = variantDeps.getPackageConfiguration();
// TODO - shouldn't need to do this - fix this in Gradle
ensureConfigured(compileClasspath);
ensureConfigured(packageClasspath);
Set<String> currentUnresolvedDependencies = Sets.newHashSet();
// TODO - defer downloading until required -- This is hard to do as we need the info to build the variant
// config.
Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts = Maps.newHashMap();
collectArtifacts(compileClasspath, artifacts);
collectArtifacts(packageClasspath, artifacts);
// 不使用官方的扁平化的依赖处理,改用自己处理树状的依赖关系;对于application的依赖,我们只取compile的依赖
ResolvedDependencyContainer compileResolvedDependencyContainer = new ResolvedDependencyContainer();
Set<ModuleVersionIdentifier> directDependencies = new HashSet<ModuleVersionIdentifier>();
Set<? extends DependencyResult> projectDependencies = compileClasspath.getIncoming().getResolutionResult().getRoot().getDependencies();
for (DependencyResult dependencyResult : projectDependencies) {
if (dependencyResult instanceof ResolvedDependencyResult) {
ModuleVersionIdentifier moduleVersion = ((ResolvedDependencyResult) dependencyResult).getSelected().getModuleVersion();
CircleDependencyCheck circleDependencyCheck = new CircleDependencyCheck(moduleVersion);
if (!((HashSet<ModuleVersionIdentifier>) directDependencies).contains(moduleVersion)) {
((HashSet<ModuleVersionIdentifier>) directDependencies).add(moduleVersion);
resolveDependency(compileResolvedDependencyContainer, null, ((ResolvedDependencyResult) dependencyResult).getSelected(), artifacts, variantDeps, 0, circleDependencyCheck, circleDependencyCheck.getRootDependencyNode());
}
} else if (dependencyResult instanceof UnresolvedDependencyResult) {
ComponentSelector attempted = ((UnresolvedDependencyResult) dependencyResult).getAttempted();
if (attempted != null) {
((HashSet<String>) currentUnresolvedDependencies).add(attempted.toString());
}
}
}
AndroidDependencyTree androidDependencyTree = compileResolvedDependencyContainer.reslovedDependencies().toAndroidDependency();
return androidDependencyTree;
}
Aggregations