diff options
author | 2016-02-19 12:09:12 +0000 | |
---|---|---|
committer | 2016-02-19 14:55:30 +0000 | |
commit | d629bb285cafade33b40d9cde236ee87146a832e (patch) | |
tree | f4427be509152a7684a7fc39d52e88650960c0a4 /src/main/java/com | |
parent | c0a9fb61212bd18547802f03cb62d9d4184d776d (diff) |
Add repository_ctx.which(str): returns the path of a command
This methods mimick the behavior of the `which` utility.
Issue #893: Step 4 of http://goo.gl/OZV3o0. See http://goo.gl/fD4ZsY.
--
MOS_MIGRATED_REVID=115050970
Diffstat (limited to 'src/main/java/com')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java index cdd211812b..b57a838dd2 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java @@ -14,13 +14,17 @@ package com.google.devtools.build.lib.bazel.repository.skylark; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.packages.AggregatingAttributeMapper; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException; import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; import com.google.devtools.build.lib.syntax.ClassObject.SkylarkClassObject; +import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.Runtime; import com.google.devtools.build.lib.syntax.SkylarkType; import com.google.devtools.build.lib.syntax.Type; @@ -28,6 +32,7 @@ import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.skyframe.SkyFunctionException.Transience; +import java.io.File; import java.io.IOException; /** @@ -125,6 +130,52 @@ public class SkylarkRepositoryContext { } } + @SkylarkCallable( + name = "which", + doc = + "Returns the path of the corresponding program or None " + + "if there is no such program in the path" + ) + public Object which(String program) throws EvalException { + if (program.contains("/") || program.contains("\\")) { + throw new EvalException(Location.BUILTIN, + "Program argument of which() may not contains a / or a \\ ('" + program + "' given)"); + } + for (String p : pathEnv) { + PathFragment fragment = new PathFragment(p); + if (fragment.isAbsolute()) { + // We ignore relative path as they don't mean much here (relative to where? the workspace + // root?). + Path path = outputDirectory.getFileSystem().getPath(fragment).getChild(program); + try { + if (path.exists() && path.isExecutable()) { + return new SkylarkPath(path); + } + } catch (IOException e) { + // IOException when checking executable file means we cannot read the file data so + // we cannot executes it, swallow the exception. + } + } + } + return Runtime.NONE; + } + + // This is non final so that test can overwrite it. + private static ImmutableList<String> pathEnv = getPathEnvironment(); + + @VisibleForTesting + static void setPathEnvironment(String... pathEnv) { + SkylarkRepositoryContext.pathEnv = ImmutableList.<String>copyOf(pathEnv); + } + + private static ImmutableList<String> getPathEnvironment() { + String pathEnv = System.getenv("PATH"); + if (pathEnv == null) { + return ImmutableList.of(); + } + return ImmutableList.copyOf(pathEnv.split(File.pathSeparator)); + } + @Override public String toString() { return "repository_ctx[" + rule.getLabel() + "]"; |