Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/generate_release_rcs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ name: Generate releaseble artifacts
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [ main ]
branches: [main]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ jobs:
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # ratchet:gradle/actions/wrapper-validation@v6.1.0
- name: Lint GitHub Actions
uses: abcxyz/actions/.github/actions/lint-github-actions@e32ec3bd6af6d87d79fe7c441f435eb7ad11d527 # ratchet:abcxyz/actions/.github/actions/lint-github-actions@main
uses: abcxyz/actions/.github/actions/lint-github-actions@3894a8d6a18b9aa159fe9092501d523d97f07110 # ratchet:abcxyz/actions/.github/actions/lint-github-actions@main
- name: Ratchet Check
uses: sethvargo/ratchet@8b4ca256dbed184350608a3023620f267f0a5253 # ratchet:sethvargo/ratchet@main
uses: sethvargo/ratchet@27f7515b4648e179168f8f8ae2257636fdb03c48 # ratchet:sethvargo/ratchet@main
with:
files: .github/workflows/*.yml

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2018 Google LLC
* Copyright 2018-2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -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,6 +50,10 @@ class ArtifactInfo {
return version
}

String getHash() {
return hash
}

@Override
boolean equals(Object obj) {
if (obj instanceof ArtifactInfo) {
Expand All @@ -53,7 +66,10 @@ class ArtifactInfo {

@Override
int hashCode() {
return group.hashCode() ^ name.hashCode() ^ version.hashCode()
int result = group.hashCode()
result = 31 * result + name.hashCode()
result = 31 * result + version.hashCode()
return result
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2018 Google LLC
* Copyright 2018-2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,16 +18,18 @@ package com.google.android.gms.oss.licenses.plugin

import com.android.tools.build.libraries.metadata.AppDependencies
import groovy.json.JsonBuilder
import groovy.json.JsonGenerator
import groovy.transform.PackageScope
import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Optional
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.slf4j.LoggerFactory

import java.util.stream.Collectors
Expand All @@ -39,12 +41,24 @@ 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, pre-computed hashes
* of SNAPSHOT artifacts are provided via {@link #getSnapshotHashes()}. These are
* tracked as {@code @Input} so Gradle detects when a re-published SNAPSHOT has
* different content, triggering re-execution and propagating the change to
* {@link LicensesTask}.
*/
@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.
@PackageScope
static final ArtifactInfo ABSENT_ARTIFACT =
new ArtifactInfo("absent", "absent", "absent")

@OutputFile
abstract RegularFileProperty getDependenciesJson()

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

/**
* Pre-computed SHA-256 hashes for SNAPSHOT artifacts, keyed by GAV coordinate.
* Computed lazily in {@link OssLicensesPlugin} from the resolved artifact files.
*
* This is an {@code @Input} so Gradle tracks the hash values for up-to-date checks.
* When a SNAPSHOT is re-published with different content, its hash changes, which
* causes this task to re-execute and produce an updated JSON report — in turn
* triggering {@link LicensesTask} to re-run.
*/
@Input
@Optional
abstract MapProperty<String, String> getSnapshotHashes()

@TaskAction
void action() {
def artifactInfoSet = loadArtifactInfo()
Expand All @@ -67,6 +94,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 +105,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 +120,11 @@ abstract class DependencyTask extends DefaultTask {
} as AppDependencies
}

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

return appDependencies.libraryList.stream()
.filter { it.libraryOneofCase == MAVEN_LIBRARY }
.sorted { o1, o2 ->
Expand All @@ -105,11 +137,13 @@ 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 gav = "$group:$name:$version".toString()
String hash = hashes.get(gav)

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

Expand Down

This file was deleted.

Loading
Loading