Skip to content
Draft
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

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,22 @@ class ArtifactInfo {
private String group
private String name
private String version
private String hash

ArtifactInfo(String group,
String name,
String version) {
this(group, name, version, null)
}

ArtifactInfo(String group,
String name,
String version,
String hash) {
this.group = group
this.name = name
this.version = version
this.hash = hash
}

String getGroup() {
Expand All @@ -41,23 +50,37 @@ class ArtifactInfo {
return version
}

String getHash() {
return hash
}

@Override
boolean equals(Object obj) {
if (obj instanceof ArtifactInfo) {
return (group == obj.group
&& name == obj.name
&& version == obj.version)
&& version == obj.version
&& hash == obj.hash)
}
return false
}

@Override
int hashCode() {
return group.hashCode() ^ name.hashCode() ^ version.hashCode()
int result = group.hashCode()
result = 31 * result + name.hashCode()
result = 31 * result + version.hashCode()
result = 31 * result + (hash != null ? hash.hashCode() : 0)
return result
}

@Override
String toString() {
return "$group:$name:$version"
}

String toDebugString() {
String base = toString()
return hash != null ? "$base@$hash" : base
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@ import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.api.provider.MapProperty
import org.gradle.api.tasks.Internal
import org.slf4j.LoggerFactory

import java.security.MessageDigest
import java.util.stream.Collectors

import static com.android.tools.build.libraries.metadata.Library.LibraryOneofCase.MAVEN_LIBRARY
Expand All @@ -39,12 +42,22 @@ import static com.android.tools.build.libraries.metadata.Library.LibraryOneofCas
* Plugin into a JSON format that will be consumed by the {@link LicensesTask}.
*
* If the protobuf is not present (e.g. debug variants) it writes a single
* dependency on the {@link DependencyUtil#ABSENT_ARTIFACT}.
* dependency on the {@link #ABSENT_ARTIFACT}.
*
* To support active development with SNAPSHOT dependencies, this task calculates
* a hash of each snapshot artifact. If the snapshot is re-published with changes,
* the generated JSON report will change, which in turn triggers a re-run of
* the {@link LicensesTask} to update the final license output.
*/
@CacheableTask
abstract class DependencyTask extends DefaultTask {
private static final logger = LoggerFactory.getLogger(DependencyTask.class)

// Sentinel written to the JSON when AGP does not provide a dependency report (e.g. debug
// variants). LicensesTask detects this and renders a placeholder message instead of licenses.
protected static final ArtifactInfo ABSENT_ARTIFACT =
new ArtifactInfo("absent", "absent", "absent")

@OutputFile
abstract RegularFileProperty getDependenciesJson()

Expand All @@ -53,6 +66,17 @@ abstract class DependencyTask extends DefaultTask {
@Optional
abstract RegularFileProperty getLibraryDependenciesReport()

/**
* Map of GAV coordinates (group:name:version) to physical JAR/AAR files.
* Used to calculate hashes for SNAPSHOT versions to ensure correctness.
*
* Why @Internal? Same reason as in LicensesTask: the dependenciesJson report (which IS an @InputFile)
* is the stable proxy for this information. This task only reads these files to append a hash
* to that report if the version is a snapshot.
*/
@Internal
abstract MapProperty<String, File> getLibraryFilesByGav()

@TaskAction
void action() {
def artifactInfoSet = loadArtifactInfo()
Expand All @@ -67,6 +91,9 @@ abstract class DependencyTask extends DefaultTask {
group info.group
name info.name
version info.version
if (info.hash != null) {
hash info.hash
}
}
it.write(json.toPrettyString())
}
Expand All @@ -75,7 +102,7 @@ abstract class DependencyTask extends DefaultTask {
private Set<ArtifactInfo> loadArtifactInfo() {
if (!libraryDependenciesReport.isPresent()) {
logger.info("$name not provided with AppDependencies proto file.")
return [DependencyUtil.ABSENT_ARTIFACT]
return [ABSENT_ARTIFACT]
}

AppDependencies appDependencies = loadDependenciesFile()
Expand All @@ -90,9 +117,11 @@ abstract class DependencyTask extends DefaultTask {
} as AppDependencies
}

private static Set<ArtifactInfo> convertDependenciesToArtifactInfo(
private Set<ArtifactInfo> convertDependenciesToArtifactInfo(
AppDependencies appDependencies
) {
Map<String, File> fileMap = libraryFilesByGav.getOrElse([:])

return appDependencies.libraryList.stream()
.filter { it.libraryOneofCase == MAVEN_LIBRARY }
.sorted { o1, o2 ->
Expand All @@ -105,15 +134,31 @@ abstract class DependencyTask extends DefaultTask {
}
}
.map { library ->
return new ArtifactInfo(
library.mavenLibrary.groupId,
library.mavenLibrary.artifactId,
library.mavenLibrary.version
)
String group = library.mavenLibrary.groupId
String name = library.mavenLibrary.artifactId
String version = library.mavenLibrary.version
String hash = null

if (version.endsWith("-SNAPSHOT")) {
File file = fileMap.get("$group:$name:$version".toString())
if (file != null && file.exists()) {
hash = calculateHash(file)
}
}

return new ArtifactInfo(group, name, version, hash)
}.collect(Collectors.toCollection(LinkedHashSet::new))
}

private static void initOutput(File outputDir) {
protected String calculateHash(File file) {
MessageDigest digest = MessageDigest.getInstance("SHA-256")
file.eachByte(4096) { buffer, length ->
digest.update(buffer, 0, length)
}
return digest.digest().encodeHex().toString()
}

protected void initOutput(File outputDir) {
if (!outputDir.exists()) {
outputDir.mkdirs()
}
Expand Down

This file was deleted.

Loading
Loading