aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/repository
diff options
context:
space:
mode:
authorGravatar Damien Martin-Guillerez <dmarting@google.com>2017-02-13 15:46:33 +0000
committerGravatar Dmitry Lomov <dslomov@google.com>2017-02-14 14:18:20 +0000
commit59f826495a4fd80ab6ec05ede08737bfb9a11bd2 (patch)
tree62276f8c1e082b5b999e01238b073424a65a42e4 /src/main/java/com/google/devtools/build/lib/rules/repository
parent3c0c2624e1b64cee51d00dfbe403689a4c2bbf46 (diff)
Add environ attribute to repository_rule
This environ attribute let the repository rule implementor describes on which environment variable change a repository should be refetched. RELNOTES[NEW]: environ parameter to the repository_rule function let defines a list of environment variables for which a change of value will trigger a repository refetching. Design doc: https://bazel.build/designs/2016/10/18/repository-invalidation.html [step 3 & 4] Fixes #1595. -- Change-Id: Ibc2f93e69cb08baf86107cc9a9428b7a0eba1bac Reviewed-on: https://cr.bazel.build/8139 PiperOrigin-RevId: 147345203 MOS_MIGRATED_REVID=147345203
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/repository')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
index 354d30f4c3..f0ad02a67c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
@@ -26,6 +26,7 @@ import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.Rule;
+import com.google.devtools.build.lib.skyframe.ActionEnvironmentFunction;
import com.google.devtools.build.lib.skyframe.FileSymlinkException;
import com.google.devtools.build.lib.skyframe.FileValue;
import com.google.devtools.build.lib.skyframe.InconsistentFilesystemException;
@@ -47,6 +48,7 @@ import com.google.devtools.build.skyframe.SkyKey;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Map;
+import java.util.Objects;
import javax.annotation.Nullable;
/**
@@ -164,6 +166,59 @@ public abstract class RepositoryFunction {
}
/**
+ * A method that can be called from a implementation of
+ * {@link #fetch(Rule, Path, BlazeDirectories, Environment, Map)} to declare a list of Skyframe
+ * dependencies on environment variable. It also add the information to the marker file. It
+ * returns the list of environment variable on which the function depends, or null if the skyframe
+ * function needs to be restarted.
+ */
+ protected Map<String, String> declareEnvironmentDependencies(Map<String, String> markerData,
+ Environment env, Iterable<String> keys) throws InterruptedException {
+ Map<String, String> environ = ActionEnvironmentFunction.getEnvironmentView(env, keys);
+
+ // Returns true if there is a null value and we need to wait for some dependencies.
+ if (environ == null) {
+ return null;
+ }
+ // Add the dependencies to the marker file
+ for (Map.Entry<String, String> value : environ.entrySet()) {
+ markerData.put("ENV:" + value.getKey(), value.getValue());
+ }
+ return environ;
+ }
+
+ /**
+ * Verify marker data previously saved by
+ * {@link #declareEnvironmentDependencies(Map, Environment, Iterable)}. This function is to be
+ * called from a {@link #verifyMarkerData(Rule, Map, Environment)} function to verify the values
+ * for environment variables.
+ */
+ protected boolean verifyEnvironMarkerData(Map<String, String> markerData, Environment env,
+ Iterable<String> keys) throws InterruptedException {
+ Map<String, String> environ = ActionEnvironmentFunction.getEnvironmentView(env, keys);
+ if (env.valuesMissing()) {
+ return false; // Returns false so caller knows to return immediately
+ }
+ // Verify that all environment variable in the marker file are also in keys
+ for (String key : markerData.keySet()) {
+ if (key.startsWith("ENV:") && !environ.containsKey(key.substring(4))) {
+ return false;
+ }
+ }
+ // Now verify the values of the marker data
+ for (Map.Entry<String, String> value : environ.entrySet()) {
+ if (!markerData.containsKey("ENV:" + value.getKey())) {
+ return false;
+ }
+ String markerValue = markerData.get("ENV:" + value.getKey());
+ if (!Objects.equals(markerValue, value.getValue())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
* Whether fetching is done using local operations only.
*
* <p>If this is false, Bazel may decide not to re-fetch the repository, for example when the