aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com
diff options
context:
space:
mode:
authorGravatar Adam Michael <ajmichael@google.com>2016-12-19 23:02:39 +0000
committerGravatar Yue Gan <yueg@google.com>2016-12-20 06:13:17 +0000
commit8e1cd5d9ff931d07f2724e1f08e2cd8f9442fdf4 (patch)
treefde7873cbbafdebaa64112b037cde7c34a067322 /src/main/java/com
parentc788603564be18b0b04128225980812f8ecd7a08 (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')
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java78
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryRule.java5
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();
}