diff options
author | Adam Michael <ajmichael@google.com> | 2016-12-19 23:02:39 +0000 |
---|---|---|
committer | Yue Gan <yueg@google.com> | 2016-12-20 06:13:17 +0000 |
commit | 8e1cd5d9ff931d07f2724e1f08e2cd8f9442fdf4 (patch) | |
tree | fde7873cbbafdebaa64112b037cde7c34a067322 /src/main/java/com/google | |
parent | c788603564be18b0b04128225980812f8ecd7a08 (diff) |
Make android_sdk_repository build_tools_version attribute optional.
If none is specified, the highest version installed in <sdk>/build-tools/ will
be used.
RELNOTES: android_sdk_repository build_tools_version is now optional. The
highest installed build-tools will be used if none is specified.
--
PiperOrigin-RevId: 142490569
MOS_MIGRATED_REVID=142490569
Diffstat (limited to 'src/main/java/com/google')
2 files changed, 81 insertions, 2 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java index d609c2276b..f031d69b53 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java @@ -24,12 +24,16 @@ import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue; import com.google.devtools.build.lib.rules.repository.RepositoryFunction; +import com.google.devtools.build.lib.skyframe.DirectoryListingValue; +import com.google.devtools.build.lib.skyframe.Dirents; import com.google.devtools.build.lib.skyframe.FileSymlinkException; import com.google.devtools.build.lib.skyframe.FileValue; import com.google.devtools.build.lib.skyframe.InconsistentFilesystemException; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.ResourceFileLoader; +import com.google.devtools.build.lib.vfs.Dirent; +import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.lib.vfs.RootedPath; @@ -46,6 +50,7 @@ import javax.annotation.Nullable; * Implementation of the {@code android_sdk_repository} rule. */ public class AndroidSdkRepositoryFunction extends RepositoryFunction { + private static final String BUILD_TOOLS_DIR_NAME = "build-tools"; private static final Revision MIN_BUILD_TOOLS_REVISION = new Revision(24, 0, 3); @Override @@ -67,8 +72,21 @@ public class AndroidSdkRepositoryFunction extends RepositoryFunction { } AttributeMap attributes = NonconfigurableAttributeMapper.of(rule); - String buildToolsDirectory = attributes.get("build_tools_version", Type.STRING); Integer apiLevel = attributes.get("api_level", Type.INTEGER); + String buildToolsDirectory; + if (attributes.isAttributeValueExplicitlySpecified("build_tools_version")) { + buildToolsDirectory = attributes.get("build_tools_version", Type.STRING); + } else { + // If the build_tools_version attribute is not explicitly set, we select the highest version + // installed in the SDK. + DirectoryListingValue directoryValue = + getBuildToolsDirectoryListing( + directories.getOutputBase().getFileSystem(), pathFragment, env); + if (directoryValue == null) { + return null; + } + buildToolsDirectory = getNewestBuildToolsDirectory(rule, directoryValue.getDirents()); + } // android_sdk_repository.build_tools_version is technically actually the name of the // directory in $sdk/build-tools. Most of the time this is just the actual build tools @@ -142,6 +160,64 @@ public class AndroidSdkRepositoryFunction extends RepositoryFunction { } } + /** + * Gets a DirectoryListingValue for the build-tools directory under the sdkRepoPathFragment + * or returns null. + */ + private static DirectoryListingValue getBuildToolsDirectoryListing( + FileSystem fs, PathFragment sdkRepoPathFragment, Environment env) + throws RepositoryFunctionException, InterruptedException { + try { + return (DirectoryListingValue) + env.getValueOrThrow( + DirectoryListingValue.key( + RootedPath.toRootedPath( + fs.getRootDirectory(), + fs.getPath(sdkRepoPathFragment).getChild(BUILD_TOOLS_DIR_NAME))), + InconsistentFilesystemException.class); + } catch (InconsistentFilesystemException e) { + throw new RepositoryFunctionException(new IOException(e), Transience.PERSISTENT); + } + } + + /** + * Gets the newest build tools directory according to {@link Revision}. + * + * @throws RepositoryFunctionException if none of the buildToolsDirectories are directories and + * have names that are parsable as build tools version. + */ + private static String getNewestBuildToolsDirectory(Rule rule, Dirents buildToolsDirectories) + throws RepositoryFunctionException { + String newestBuildToolsDirectory = null; + Revision newestBuildToolsRevision = null; + for (Dirent buildToolsDirectory : buildToolsDirectories) { + if (buildToolsDirectory.getType() != Dirent.Type.DIRECTORY) { + continue; + } + try { + Revision buildToolsRevision = Revision.parseRevision(buildToolsDirectory.getName()); + if (newestBuildToolsRevision == null + || buildToolsRevision.compareTo(newestBuildToolsRevision) > 0) { + newestBuildToolsDirectory = buildToolsDirectory.getName(); + newestBuildToolsRevision = buildToolsRevision; + } + } catch (NumberFormatException e) { + // Ignore unparsable build tools directories. + } + } + if (newestBuildToolsDirectory == null) { + throw new RepositoryFunctionException( + new EvalException( + rule.getLocation(), + String.format( + "Bazel requires Android build tools version %s or newer but none are installed. " + + "Please install a recent version through the Android SDK manager.", + MIN_BUILD_TOOLS_REVISION)), + Transience.PERSISTENT); + } + return newestBuildToolsDirectory; + } + private static Properties getBuildToolsSourceProperties( Path directory, String buildToolsDirectory, Environment env) throws RepositoryFunctionException, InterruptedException { diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryRule.java index 75968bcb84..d87f4602e9 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryRule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryRule.java @@ -63,7 +63,10 @@ public class AndroidSdkRepositoryRule implements RuleDefinition { // actually "x.y.z-rcN". E.g., for 24, the directory is "$sdk/build-tools/24.0.0-preview", // but the version is e.g. "24 rc3". The android_sdk rule that is generated from // android_sdk_repository would need the real version ("24 rc3"). - .add(attr("build_tools_version", STRING).mandatory().nonconfigurable("WORKSPACE rule")) + // + // If build_tools_version is not specified explicitly, the highest build tools version + // installed will be used. + .add(attr("build_tools_version", STRING).nonconfigurable("WORKSPACE rule")) .add(attr("api_level", INTEGER).mandatory().nonconfigurable("WORKSPACE rule")) .build(); } |