diff options
Diffstat (limited to 'src/main/groovy/com/android/tools/internal/license/ReportTask.java')
-rw-r--r-- | src/main/groovy/com/android/tools/internal/license/ReportTask.java | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/src/main/groovy/com/android/tools/internal/license/ReportTask.java b/src/main/groovy/com/android/tools/internal/license/ReportTask.java new file mode 100644 index 0000000..8964c2f --- /dev/null +++ b/src/main/groovy/com/android/tools/internal/license/ReportTask.java @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.tools.internal.license; + +import com.android.tools.internal.artifacts.PomHandler; +import com.android.tools.internal.artifacts.PomHandler.License; +import com.google.common.base.Splitter; +import com.google.common.collect.Lists; +import org.gradle.api.DefaultTask; +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.artifacts.ModuleVersionIdentifier; +import org.gradle.api.artifacts.ResolvedArtifact; +import org.gradle.api.artifacts.component.ComponentIdentifier; +import org.gradle.api.artifacts.component.ProjectComponentIdentifier; +import org.gradle.api.artifacts.result.DependencyResult; +import org.gradle.api.artifacts.result.ResolvedComponentResult; +import org.gradle.api.artifacts.result.ResolvedDependencyResult; +import org.gradle.api.tasks.TaskAction; + +import java.io.File; +import java.io.IOException; +import java.util.*; + +/** + * Tasks outputting the license information for the external dependencies. + * + * It queries the 'runtime' configuration object, and fails if it doesn't find pom + * file associated with the dependencies. + * + * This will NOT work with local jars. + */ +public class ReportTask extends DefaultTask { + + @TaskAction + public void report() throws IOException { + Project project = getProject(); + + Configuration runtimeConfig = project.getConfigurations().getByName("runtime"); + + Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts = collectArtifacts(runtimeConfig); + + Set<? extends DependencyResult> dependencyResultSet = runtimeConfig + .getIncoming().getResolutionResult().getRoot().getDependencies(); + + Set<File> pomFiles = new HashSet<File>(); + + for (DependencyResult dependencyResult : dependencyResultSet) { + if (dependencyResult instanceof ResolvedDependencyResult) { + processConfig( + ((ResolvedDependencyResult) dependencyResult).getSelected(), + artifacts, + pomFiles); + } + } + + for (File pomFile : pomFiles) { + PomHandler pomHandler = new PomHandler(pomFile); + + ModuleVersionIdentifier artifactName = pomHandler.getArtifactName(); + System.out.println(artifactName); + + List<License> licenses = pomHandler.getLicenses(); + + + File parentPomFile = pomFile; + PomHandler parentPomHandler = pomHandler; + while (licenses.isEmpty()) { + // get the parent pom + parentPomFile = computeParentPomLocation(parentPomFile, parentPomHandler); + parentPomHandler = new PomHandler(parentPomFile); + licenses = parentPomHandler.getLicenses(); + } + + if (!licenses.isEmpty()) { + for (License license : licenses) { + System.out.println(" > " + license.getName()); + if (license.getUrl() != null) { + System.out.println(" " + license.getUrl()); + } + if (license.getComments() != null) { + System.out.println(" " + license.getComments()); + } + } + } else { + throw new RuntimeException("unable to find license info for " + artifactName); + } + } + } + + private static File computeParentPomLocation(File pomFile, PomHandler pomHandler) throws IOException { + // To find the location of the parentPom, we can rely on the following location pattern for pom files: + // groupIdSeg1/groupIdSeg2/.../name/version/name-version.pom + // So first we back track from the current pom to find the root of the repo + + // first remove the pom file, the version and the name: + File parentPomFile = pomFile.getParentFile().getParentFile().getParentFile(); + + // now get the number of groupId segment + Iterable<String> segments = Splitter.on('.').split(pomHandler.getArtifactName().getGroup()); + //noinspection unused + for (String segment : segments) { + parentPomFile = parentPomFile.getParentFile(); + } + + // now get the parent pom coordinate + ModuleVersionIdentifier parentPomCoord = pomHandler.getParentPom(); + + // add the segments + segments = Splitter.on('.').split(parentPomCoord.getGroup()); + for (String segment : segments) { + parentPomFile = new File(parentPomFile, segment); + } + + // add the name, version + String name = parentPomCoord.getName(); + parentPomFile = new File(parentPomFile, name); + String version = parentPomCoord.getVersion(); + parentPomFile = new File(parentPomFile, version); + + // add the pom filename + parentPomFile = new File(parentPomFile, name + "-" + version + ".pom"); + return parentPomFile; + } + + private static Map<ModuleVersionIdentifier, List<ResolvedArtifact>> collectArtifacts(Configuration configuration) { + Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts = new HashMap<ModuleVersionIdentifier, List<ResolvedArtifact>>(); + + Set<ResolvedArtifact> 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); + } + } + + return artifacts; + } + + private static void processConfig( + ResolvedComponentResult resolvedComponentResult, + Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts, + Set<File> pomFiles) { + + ModuleVersionIdentifier moduleVersion = resolvedComponentResult.getModuleVersion(); + + ComponentIdentifier id = resolvedComponentResult.getId(); + if (!(id instanceof ProjectComponentIdentifier)) { + + List<ResolvedArtifact> moduleArtifacts = artifacts.get(moduleVersion); + + if (moduleArtifacts != null) { + for (ResolvedArtifact artifact : moduleArtifacts) { + File artifactFile = artifact.getFile(); + String filename = artifactFile.getName().replaceAll(".jar$", ".pom").replaceAll(".aar$", ".pom"); + + // rename the file to get the pom. + File pomFile = new File(artifactFile.getParentFile(), filename); + + if (!pomFile.exists()) { + throw new RuntimeException("Missing Pom file for artifact: " + artifactFile); + } + + pomFiles.add(pomFile); + } + } + } + + // then recursively + Set<? extends DependencyResult> dependencies = resolvedComponentResult.getDependencies(); + for (DependencyResult dependencyResult : dependencies) { + if (dependencyResult instanceof ResolvedDependencyResult) { + processConfig( + ((ResolvedDependencyResult) dependencyResult).getSelected(), + artifacts, + pomFiles); + } + } + } +} |