Updating how we roll android_deps
Bug: 668211
Change-Id: I77bdd5ac4caeb3b9ffb175aa3e2f29eb908803e4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1557858
Commit-Queue: Sam Maier <smaier@chromium.org>
Reviewed-by: Peter Wen <wnwen@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#657245}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: e367a3f08518be6516802bdef0306c46649c9378
diff --git a/roll/android_deps/build.gradle b/roll/android_deps/build.gradle
index 141aa0d..c3dc08e 100644
--- a/roll/android_deps/build.gradle
+++ b/roll/android_deps/build.gradle
@@ -91,6 +91,9 @@
task setUpRepository(type: BuildConfigGenerator) {
// Paths are relative to the chromium source root.
repositoryPath 'third_party/android_deps'
+ depsPath 'DEPS'
+ chromiumSourceRoot '../../../..'
+ cipdBucket 'chromium'
}
task wrapper(type: Wrapper) {
diff --git a/roll/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy b/roll/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
index fd5593b..21a6ae2 100644
--- a/roll/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
+++ b/roll/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
@@ -51,9 +51,41 @@
*/
String repositoryPath
+ /**
+ * Relative path to the DEPS file where the cipd packages are specified.
+ */
+ String depsPath
+
+ /**
+ * Relative path to the Chromium source root from the build.gradle file.
+ */
+ String chromiumSourceRoot
+
+ /**
+ * Name of the cipd root package.
+ */
+ String cipdBucket
+
+ /**
+ * Prefix of path to strip before uploading to CIPD.
+ */
+ String stripFromCipdPath
+
+ /**
+ * Skips license file import.
+ */
+ boolean skipLicenses
+
+ /**
+ * Only pull play services targets into BUILD.gn file.
+ * If the play services target depends on a non-play services target, it will use the target in
+ * //third_party/android_deps/BUILD.gn.
+ */
+ boolean onlyPlayServices
+
@TaskAction
void main() {
- def graph = new ChromiumDepGraph(project: project)
+ def graph = new ChromiumDepGraph(project: project, skipLicenses: skipLicenses)
def normalisedRepoPath = normalisePath(repositoryPath)
def rootDirPath = normalisePath(".")
@@ -63,7 +95,7 @@
// 2. Import artifacts into the local repository
def dependencyDirectories = []
graph.dependencies.values().each { dependency ->
- if (dependency.exclude || EXISTING_LIBS.get(dependency.id) != null) {
+ if (excludeDependency(dependency, onlyPlayServices)) {
return
}
logger.debug "Processing ${dependency.name}: \n${jsonDump(dependency)}"
@@ -83,25 +115,31 @@
}
new File("${absoluteDepDir}/README.chromium").write(makeReadme(dependency))
- new File("${absoluteDepDir}/cipd.yaml").write(makeCipdYaml(dependency, repositoryPath))
+ new File("${absoluteDepDir}/cipd.yaml").write(makeCipdYaml(dependency, cipdBucket,
+ stripFromCipdPath,
+ repositoryPath))
new File("${absoluteDepDir}/OWNERS").write(makeOwners())
- if (!dependency.licensePath?.trim()?.isEmpty()) {
- new File("${absoluteDepDir}/LICENSE").write(
- new File("${normalisedRepoPath}/${dependency.licensePath}").text)
- } else if (!dependency.licenseUrl?.trim()?.isEmpty()) {
- downloadFile(dependency.licenseUrl, new File("${absoluteDepDir}/LICENSE"))
+ if (!skipLicenses) {
+ if (!dependency.licensePath?.trim()?.isEmpty()) {
+ new File("${absoluteDepDir}/LICENSE").write(
+ new File("${normalisedRepoPath}/${dependency.licensePath}").text)
+ } else if (!dependency.licenseUrl?.trim()?.isEmpty()) {
+ downloadFile(dependency.licenseUrl, new File("${absoluteDepDir}/LICENSE"))
+ }
}
}
// 3. Generate the root level build files
- updateBuildTargetDeclaration(graph, "${normalisedRepoPath}/BUILD.gn")
- updateDepsDeclaration(graph, repositoryPath, "${rootDirPath}/DEPS")
+ updateBuildTargetDeclaration(graph, "${normalisedRepoPath}/BUILD.gn", onlyPlayServices)
+ updateDepsDeclaration(graph, cipdBucket, stripFromCipdPath, repositoryPath,
+ "${rootDirPath}/${depsPath}", onlyPlayServices)
dependencyDirectories.sort { path1, path2 -> return path1.compareTo(path2) }
updateReadmeReferenceFile(dependencyDirectories,
"${normalisedRepoPath}/additional_readme_paths.json")
}
- private static void updateBuildTargetDeclaration(ChromiumDepGraph depGraph, String path) {
+ private static void updateBuildTargetDeclaration(ChromiumDepGraph depGraph, String path,
+ boolean onlyPlayServices) {
File buildFile = new File(path)
def sb = new StringBuilder()
@@ -115,39 +153,43 @@
}
depGraph.dependencies.values().sort(dependencyComparator).each { dependency ->
- if (dependency.exclude || EXISTING_LIBS.get(dependency.id) != null) {
+ if (excludeDependency(dependency, onlyPlayServices)) {
return
}
def depsStr = ""
if (!dependency.children.isEmpty()) {
dependency.children.each { childDep ->
- def dep = depGraph.dependencies[childDep];
+ def dep = depGraph.dependencies[childDep]
if (dep.exclude) {
return
}
// Special case: If a child dependency is an existing lib, rather than skipping
// it, replace the child dependency with the existing lib.
def existingLib = EXISTING_LIBS.get(dep.id)
+ def targetName = translateTargetName(dep.id) + "_java"
if (existingLib != null) {
- depsStr += "\"${existingLib}\","
+ depsStr += "\"${existingLib}\","
+ } else if (onlyPlayServices && !isPlayServicesTarget(dep.id)) {
+ depsStr += "\"//third_party/android_deps:${targetName}\","
} else {
- depsStr += "\":${dep.id}_java\","
+ depsStr += "\":${targetName}\","
}
}
}
def libPath = "${DOWNLOAD_DIRECTORY_NAME}/${dependency.id}"
+ def targetName = translateTargetName(dependency.id) + "_java"
sb.append(BUILD_GN_GEN_REMINDER)
if (dependency.extension == 'jar') {
sb.append("""\
- java_prebuilt("${dependency.id}_java") {
+ java_prebuilt("${targetName}") {
jar_path = "${libPath}/${dependency.fileName}"
output_name = "${dependency.id}"
""".stripIndent())
if (dependency.supportsAndroid) sb.append(" supports_android = true\n")
} else if (dependency.extension == 'aar') {
sb.append("""\
- android_aar_prebuilt("${dependency.id}_java") {
+ android_aar_prebuilt("${targetName}") {
aar_path = "${libPath}/${dependency.fileName}"
info_path = "${libPath}/${dependency.id}.info"
""".stripIndent())
@@ -173,15 +215,28 @@
"${BUILD_GN_TOKEN_START}\n${sb.toString()}\n${BUILD_GN_TOKEN_END}"))
}
+ public static String translateTargetName(String targetName) {
+ if (isPlayServicesTarget(targetName)) {
+ return targetName.replaceFirst("com_", "").replaceFirst("android_gms_", "")
+ }
+ return targetName
+ }
+
+ public static boolean isPlayServicesTarget(String dependencyId) {
+ // Firebase has historically been treated as a part of play services, so it counts here for
+ // backwards compatibility.
+ return Pattern.matches(".*google.*(play_services|firebase).*", dependencyId)
+ }
+
private static void addSpecialTreatment(StringBuilder sb, String dependencyId) {
- if (Pattern.matches(".*google.*play_services.*", dependencyId)) {
- if (Pattern.matches(".*cast_framework.*", dependencyId)) {
+ if (isPlayServicesTarget(dependencyId)) {
+ if (Pattern.matches(".*cast_framework.*", dependencyId)) {
sb.append(' # Removing all resources from cast framework as they are unused bloat.\n')
sb.append(' strip_resources = true\n')
- } else {
+ } else {
sb.append(' # Removing drawables from GMS .aars as they are unused bloat.\n')
sb.append(' strip_drawables = true\n')
- }
+ }
}
switch(dependencyId) {
case 'com_android_support_support_compat':
@@ -224,8 +279,9 @@
}
}
- private static void updateDepsDeclaration(ChromiumDepGraph depGraph, String repoPath,
- String depsFilePath) {
+ private static void updateDepsDeclaration(ChromiumDepGraph depGraph, String cipdBucket,
+ String stripFromCipdPath, String repoPath,
+ String depsFilePath, boolean onlyPlayServices) {
File depsFile = new File(depsFilePath)
def sb = new StringBuilder()
// Note: The string we're inserting is nested 1 level, hence the 2 leading spaces. Same
@@ -238,16 +294,24 @@
}
depGraph.dependencies.values().sort(dependencyComparator).each { dependency ->
- if (dependency.exclude || EXISTING_LIBS.get(dependency.id) != null) {
+ if (excludeDependency(dependency, onlyPlayServices)) {
return
}
def depPath = "${DOWNLOAD_DIRECTORY_NAME}/${dependency.id}"
+ def cipdPath = "${cipdBucket}/"
+ if (stripFromCipdPath) {
+ assert repoPath.startsWith(stripFromCipdPath)
+ cipdPath += repoPath.substring(stripFromCipdPath.length() + 1)
+ } else {
+ cipdPath += repoPath
+ }
+ cipdPath += "/${depPath}"
sb.append("""\
|
| 'src/${repoPath}/${depPath}': {
| 'packages': [
| {
- | 'package': 'chromium/${repoPath}/${depPath}',
+ | 'package': '${cipdPath}',
| 'version': 'version:${dependency.version}-${CIPD_SUFFIX}',
| },
| ],
@@ -267,9 +331,14 @@
refFile.write(JsonOutput.prettyPrint(JsonOutput.toJson(directories)) + "\n")
}
+ public static boolean excludeDependency(ChromiumDepGraph.DependencyDescription dependency,
+ boolean onlyPlayServices) {
+ return dependency.exclude || EXISTING_LIBS.get(dependency.id) != null ||
+ (onlyPlayServices && !isPlayServicesTarget(dependency.id))
+ }
+
private String normalisePath(String pathRelativeToChromiumRoot) {
- def pathToChromiumRoot = "../../../.." // Relative to build.gradle, the project root.
- return project.file("${pathToChromiumRoot}/${pathRelativeToChromiumRoot}").absolutePath
+ return project.file("${chromiumSourceRoot}/${pathRelativeToChromiumRoot}").absolutePath
}
static String makeOwners() {
@@ -308,8 +377,20 @@
""".stripIndent()
}
- static String makeCipdYaml(ChromiumDepGraph.DependencyDescription dependency, String repoPath) {
+ static String makeCipdYaml(ChromiumDepGraph.DependencyDescription dependency, String cipdBucket,
+ String stripFromCipdPath, String repoPath) {
+ if (!stripFromCipdPath) {
+ stripFromCipdPath = ''
+ }
def cipdVersion = "${dependency.version}-${CIPD_SUFFIX}"
+ def cipdPath = "${cipdBucket}/"
+ if (stripFromCipdPath) {
+ assert repoPath.startsWith(stripFromCipdPath)
+ cipdPath += repoPath.substring(stripFromCipdPath.length() + 1)
+ } else {
+ cipdPath += repoPath
+ }
+ cipdPath += "/${DOWNLOAD_DIRECTORY_NAME}/${dependency.id}"
// NOTE: the fetch_all.py script relies on the format of this file!
// See fetch_all.py:GetCipdPackageInfo().
@@ -320,7 +401,7 @@
# To create CIPD package run the following command.
# cipd create --pkg-def cipd.yaml -tag version:${cipdVersion}
- package: chromium/${repoPath}/${DOWNLOAD_DIRECTORY_NAME}/${dependency.id}
+ package: ${cipdPath}
description: "${dependency.displayName}"
data:
- file: ${dependency.fileName}
diff --git a/roll/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy b/roll/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy
index af3f7be..f639b45 100644
--- a/roll/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy
+++ b/roll/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy
@@ -58,6 +58,7 @@
]
Project project
+ boolean skipLicenses
void collectDependencies() {
def compileConfig = project.configurations.getByName('compile').resolvedConfiguration
@@ -84,7 +85,8 @@
}
compileConfig.resolvedArtifacts.each { artifact ->
- def dep = dependencies.get(makeModuleId(artifact))
+ def id = makeModuleId(artifact)
+ def dep = dependencies.get(id)
assert dep != null : "No dependency collected for artifact ${artifact.name}"
dep.supportsAndroid = true
dep.testOnly = false
@@ -149,9 +151,11 @@
List<String> childModules) {
def pom = getPomFromArtifact(artifact.id.componentIdentifier).file
def pomContent = new XmlSlurper(false, false).parse(pom)
- String licenseName
- String licenseUrl
- (licenseName, licenseUrl) = resolveLicenseInformation(id, pomContent)
+ String licenseName = ''
+ String licenseUrl = ''
+ if (!skipLicenses) {
+ (licenseName, licenseUrl) = resolveLicenseInformation(id, pomContent)
+ }
// Get rid of irrelevant indent that might be present in the XML file.
def description = pomContent.description?.text()?.trim()?.replaceAll(/\s+/, " ")
@@ -208,6 +212,15 @@
}
}
+ if (skipLicenses) {
+ dep.licenseName = ''
+ dep.licensePath = ''
+ dep.licenseUrl = ''
+ if (dep.id?.endsWith('license')) {
+ dep.exclude = true
+ }
+ }
+
return dep
}
diff --git a/roll/android_deps/fetch_all.py b/roll/android_deps/fetch_all.py
index cea4b71..e537896 100755
--- a/roll/android_deps/fetch_all.py
+++ b/roll/android_deps/fetch_all.py
@@ -61,9 +61,6 @@
# Location of the android_deps libs directory from a root checkout.
_ANDROID_DEPS_LIBS_SUBDIR = _ANDROID_DEPS_SUBDIR + '/libs'
-# Location of the build.gradle file used to configure our dependencies.
-_BUILD_GRADLE_PATH = 'tools/android/roll/android_deps/build.gradle'
-
# Location of the buildSrc directory used implement our gradle task.
_GRADLE_BUILDSRC_PATH = 'tools/android/roll/android_deps/buildSrc'
@@ -74,14 +71,6 @@
_ANDROID_DEPS_ADDITIONAL_README_PATHS,
]
-# The list of files and dirs that are copied to the build directory by this
-# script. Should not include _UPDATED_GIT_FILES.
-_COPIED_PATHS = [
- _ANDROID_DEPS_LICENSE_SUBDIR,
- _BUILD_GRADLE_PATH,
- _GRADLE_BUILDSRC_PATH,
-]
-
# If this file exists in an aar file then it is appended to LICENSE
_THIRD_PARTY_LICENSE_FILENAME = 'third_party_licenses.txt'
@@ -274,7 +263,7 @@
return (package_name, package_tag)
-def ParseDeps(root_dir):
+def ParseDeps(root_dir, libs_dir):
"""Parse an android_deps/libs and retrieve package information.
Args:
@@ -286,8 +275,7 @@
and |package_name| and |package_tag| are the extracted from it.
"""
result = {}
- libs_dir = os.path.abspath(os.path.join(
- root_dir, _ANDROID_DEPS_LIBS_SUBDIR))
+ libs_dir = os.path.abspath(os.path.join(root_dir, libs_dir))
for cipd_file in FindInDirectory(libs_dir, 'cipd.yaml'):
pkg_name, pkg_tag = GetCipdPackageInfo(cipd_file)
cipd_path = os.path.dirname(cipd_file)
@@ -335,6 +323,16 @@
help='Path to Chromium source tree (auto-detect by default).')
parser.add_argument('--gradle-wrapper',
help='Path to custom gradle wrapper (auto-detect by default).')
+ parser.add_argument(
+ '--build-gradle',
+ help='Path to build.gradle relative to src/.',
+ default='tools/android/roll/android_deps/build.gradle')
+ parser.add_argument(
+ '--git-dir', help='Path to git subdir from chromium-dir.', default='.')
+ parser.add_argument(
+ '--ignore-licenses',
+ help='Ignores licenses for these deps.',
+ action='store_true')
parser.add_argument('--update-all', action='store_true',
help='Update current checkout in case of build.gradle changes.'
'This will also print a list of commands to upload new and updated '
@@ -346,21 +344,37 @@
'\'debug\')')
args = parser.parse_args()
- logging.basicConfig(format='%(message)s')
- logger = logging.getLogger()
- if args.log_level:
- logger.setLevel(args.log_level.upper())
-
# Determine Chromium source tree.
chromium_src = args.chromium_dir
if not chromium_src:
# Assume this script is stored under tools/android/roll/android_deps/
chromium_src = _CHROMIUM_SRC
+ chromium_src = os.path.abspath(chromium_src)
+
+ abs_git_dir = os.path.normpath(os.path.join(chromium_src, args.git_dir))
+
if not os.path.isdir(chromium_src):
raise Exception('Not a directory: ' + chromium_src)
+ if not os.path.isdir(abs_git_dir):
+ raise Exception('Not a directory: ' + abs_git_dir)
- chromium_src = os.path.abspath(chromium_src)
+ # The list of files and dirs that are copied to the build directory by this
+ # script. Should not include _UPDATED_GIT_FILES.
+ copied_paths = {
+ args.build_gradle:
+ args.build_gradle,
+ _GRADLE_BUILDSRC_PATH:
+ os.path.join(os.path.dirname(args.build_gradle), "buildSrc"),
+ }
+
+ if not args.ignore_licenses:
+ copied_paths[_ANDROID_DEPS_LICENSE_SUBDIR] = _ANDROID_DEPS_LICENSE_SUBDIR
+
+ logging.basicConfig(format='%(message)s')
+ logger = logging.getLogger()
+ if args.log_level:
+ logger.setLevel(args.log_level.upper())
# Handle --reset-workspace here.
if args.reset_workspace:
@@ -370,7 +384,7 @@
RunCommand(['rm', '-rf', cipd_dir])
print '# Saving build.gradle content'
- build_gradle_path = os.path.join(chromium_src, _BUILD_GRADLE_PATH)
+ build_gradle_path = os.path.join(chromium_src, args.build_gradle)
build_gradle = ReadFile(build_gradle_path)
print '# Resetting and re-syncing workspace. (may take a while).'
@@ -381,10 +395,12 @@
return
missing_files = []
- for src_path in _UPDATED_GIT_FILES + _COPIED_PATHS:
+ for src_path in copied_paths.keys():
if not os.path.exists(os.path.join(chromium_src, src_path)):
missing_files.append(src_path)
-
+ for src_path in _UPDATED_GIT_FILES:
+ if not os.path.exists(os.path.join(abs_git_dir, src_path)):
+ missing_files.append(src_path)
if missing_files:
raise Exception('Missing files from %s: %s' % (chromium_src, missing_files))
@@ -401,12 +417,12 @@
print '# Setup build directory.'
logging.debug('Using build directory: ' + build_dir)
for git_file in _UPDATED_GIT_FILES:
- git_data = ReadGitHeadFile(chromium_src, git_file)
- WriteFile(os.path.join(build_dir, git_file), git_data)
+ git_data = ReadGitHeadFile(abs_git_dir, git_file)
+ WriteFile(os.path.join(build_dir, args.git_dir, git_file), git_data)
- for path in _COPIED_PATHS:
- CopyFileOrDirectory(os.path.join(chromium_src, path),
- os.path.join(build_dir, path))
+ for path, dest in copied_paths.iteritems():
+ CopyFileOrDirectory(
+ os.path.join(chromium_src, path), os.path.join(build_dir, dest))
print '# Use Gradle to download packages and edit/create relevant files.'
# This gradle command generates the new DEPS and BUILD.gn files, it can also
@@ -414,16 +430,20 @@
# for such cases.
gradle_cmd = [
gradle_wrapper_path,
- '-b', os.path.join(build_dir, _BUILD_GRADLE_PATH),
+ '-b',
+ os.path.join(build_dir, args.build_gradle),
'setupRepository',
'--stacktrace',
]
RunCommand(gradle_cmd)
- libs_dir = os.path.join(build_dir, _ANDROID_DEPS_LIBS_SUBDIR)
+ libs_dir = os.path.join(build_dir, args.git_dir, _ANDROID_DEPS_LIBS_SUBDIR)
print '# Reformat %s.' % _ANDROID_DEPS_BUILD_GN
- gn_args = ['gn', 'format', os.path.join(build_dir, _ANDROID_DEPS_BUILD_GN)]
+ gn_args = [
+ 'gn', 'format',
+ os.path.join(build_dir, args.git_dir, _ANDROID_DEPS_BUILD_GN)
+ ]
RunCommand(gn_args)
print '# Generate Android .aar info and third-party license files.'
@@ -435,17 +455,19 @@
if not os.path.exists(aar_info_path):
logging.info('- %s' % aar_info_name)
RunCommand([aar_py, 'list', aar_file, '--output', aar_info_path])
- with zipfile.ZipFile(aar_file) as z:
- if _THIRD_PARTY_LICENSE_FILENAME in z.namelist():
- license_path = os.path.join(aar_dirname, 'LICENSE')
- # Make sure to append as we don't want to lose the existing license.
- with open(license_path, 'a') as f:
- f.write(z.read(_THIRD_PARTY_LICENSE_FILENAME))
+ if not args.ignore_licenses:
+ with zipfile.ZipFile(aar_file) as z:
+ if _THIRD_PARTY_LICENSE_FILENAME in z.namelist():
+ license_path = os.path.join(aar_dirname, 'LICENSE')
+ # Make sure to append as we don't want to lose the existing license.
+ with open(license_path, 'a') as f:
+ f.write(z.read(_THIRD_PARTY_LICENSE_FILENAME))
print '# Compare CIPD packages.'
- existing_packages = ParseDeps(chromium_src)
- build_packages = ParseDeps(build_dir)
+ existing_packages = ParseDeps(abs_git_dir, _ANDROID_DEPS_LIBS_SUBDIR)
+ build_packages = ParseDeps(
+ build_dir, os.path.join(args.git_dir, _ANDROID_DEPS_LIBS_SUBDIR))
deleted_packages = []
updated_packages = []
@@ -496,12 +518,13 @@
# Copy updated DEPS and BUILD.gn to build directory.
update_cmds = []
for updated_file in _UPDATED_GIT_FILES:
- CopyFileOrDirectory(os.path.join(build_dir, updated_file),
- os.path.join(chromium_src, updated_file))
+ CopyFileOrDirectory(
+ os.path.join(build_dir, args.git_dir, updated_file),
+ os.path.join(abs_git_dir, updated_file))
# Delete obsolete or updated package directories.
for pkg in deleted_packages + updated_packages:
- pkg_path = os.path.join(chromium_src, existing_packages[pkg].path)
+ pkg_path = os.path.join(abs_git_dir, existing_packages[pkg].path)
DeleteDirectory(pkg_path)
# Copy new and updated packages from build directory.