repository context: support status updates Add a function to the repository context to update the current status of the rule execution. As repository rules might take quite some time to set up an external repository, it is desirable for the user to know what the rule is currently doing, e.g., fetching, unpacking, patching. Fixes #1289. Fixes #6427. Change-Id: I1e812d43d7eba900f266abf70fe00bf1917f198f PiperOrigin-RevId: 220774485
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 72ccaf8..b4c581b 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
@@ -28,6 +28,7 @@ import com.google.devtools.build.lib.bazel.repository.downloader.HttpDownloader; import com.google.devtools.build.lib.bazel.repository.downloader.HttpUtils; import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.events.ExtendedEventHandler.FetchProgress; import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.Rule; @@ -145,6 +146,31 @@ } @Override + public void reportProgress(String status) { + final String message = status == null ? "" : status; + final String id = "@" + getName(); + + env.getListener() + .post( + new FetchProgress() { + @Override + public String getResourceIdentifier() { + return id; + } + + @Override + public String getProgress() { + return message; + } + + @Override + public boolean isFinished() { + return false; + } + }); + } + + @Override public void symlink(Object from, Object to, Location location) throws RepositoryFunctionException, EvalException, InterruptedException { SkylarkPath fromPath = getPath("symlink()", from);
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/repository/SkylarkRepositoryContextApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/repository/SkylarkRepositoryContextApi.java index fe34483..9ab414f 100644 --- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/repository/SkylarkRepositoryContextApi.java +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/repository/SkylarkRepositoryContextApi.java
@@ -78,6 +78,17 @@ public RepositoryPathApi<?> path(Object path) throws EvalException, InterruptedException; @SkylarkCallable( + name = "report_progress", + doc = "Update the progress status for the fetching of this repository", + parameters = { + @Param( + name = "status", + allowedTypes = {@ParamType(type = String.class)}, + doc = "string describing the current status of the fetch progress") + }) + public void reportProgress(String status); + + @SkylarkCallable( name = "symlink", doc = "Create a symlink on the filesystem.", useLocation = true,
diff --git a/src/test/shell/bazel/external_integration_test.sh b/src/test/shell/bazel/external_integration_test.sh index 3a54e71..7a48ae3d 100755 --- a/src/test/shell/bazel/external_integration_test.sh +++ b/src/test/shell/bazel/external_integration_test.sh
@@ -1680,4 +1680,42 @@ && fail "Expected failure due to unsupported symlink" || : } +function test_progress_reporting() { + WRKDIR=$(mktemp -d "${TEST_TMPDIR}/testXXXXXX") + cd "${WRKDIR}" + + cat > rule.bzl <<'EOF' +def _rule_impl(ctx): + ctx.report_progress("First action") + ctx.execute(["/bin/sh", "-c", "sleep 5"]) + ctx.report_progress("Second action") + ctx.execute(["/bin/sh", "-c", "sleep 5"]) + ctx.report_progress("Actual files") + ctx.file("data", "Hello world") + ctx.file("BUILD", "exports_files(['data'])") + +with_progress = repository_rule( + implementation = _rule_impl, + attrs = {}, +) +EOF + + cat > WORKSPACE <<'EOF' +load("//:rule.bzl", "with_progress") +with_progress(name="foo") +EOF + cat > BUILD <<'EOF' +genrule( + name = "local", + srcs = ["@foo//:data"], + outs = ["local.txt"], + cmd = "cp $< $@", +) +EOF + bazel build --curses=yes //:local > "${TEST_log}" 2>&1 \ + || fail "exepected succes" + expect_log "foo.*First action" + expect_log "foo.*Second action" +} + run_suite "external tests"