aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com
diff options
context:
space:
mode:
authorGravatar Damien Martin-Guillerez <dmarting@google.com>2016-02-19 12:09:12 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2016-02-19 14:55:30 +0000
commitd629bb285cafade33b40d9cde236ee87146a832e (patch)
treef4427be509152a7684a7fc39d52e88650960c0a4 /src/main/java/com
parentc0a9fb61212bd18547802f03cb62d9d4184d776d (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.java51
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() + "]";