diff options
author | Damien Martin-Guillerez <dmarting@google.com> | 2017-02-13 15:46:33 +0000 |
---|---|---|
committer | Dmitry Lomov <dslomov@google.com> | 2017-02-14 14:18:20 +0000 |
commit | 59f826495a4fd80ab6ec05ede08737bfb9a11bd2 (patch) | |
tree | 62276f8c1e082b5b999e01238b073424a65a42e4 /src/main/java/com/google/devtools/build/lib/rules/repository | |
parent | 3c0c2624e1b64cee51d00dfbe403689a4c2bbf46 (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.java | 55 |
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 |