Skip to content

Commit e12c44d

Browse files
fmeumcopybara-github
authored andcommitted
Track repo rule label attributes after the first non-existent one
Even with this commit, the fact that a particular label in a repository rule's label attributes does not resolve to a regular file is not tracked, which means that there is still a potential for incorrect incremental fetches. Work towards #13441 Closes #18352. PiperOrigin-RevId: 531150549 Change-Id: I086e4813ca88a3f49cde77d9be20adaaf954834b
1 parent 04805ca commit e12c44d

File tree

3 files changed

+64
-8
lines changed

3 files changed

+64
-8
lines changed

src/main/java/com/google/devtools/build/lib/bazel/repository/starlark/StarlarkRepositoryContext.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.google.devtools.build.lib.packages.StructProvider;
3232
import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
3333
import com.google.devtools.build.lib.repository.RepositoryFetchProgress;
34+
import com.google.devtools.build.lib.rules.repository.NeedsSkyframeRestartException;
3435
import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException;
3536
import com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper;
3637
import com.google.devtools.build.lib.runtime.ProcessWrapper;
@@ -516,26 +517,42 @@ public String toString() {
516517
*/
517518
// TODO(wyv): somehow migrate this to the base context too.
518519
public void enforceLabelAttributes() throws EvalException, InterruptedException {
520+
// TODO: If a labels fails to resolve to an existing regular file, we do not add a dependency on
521+
// that fact - if the file is created later or changes its type, it will not trigger a rerun of
522+
// the repository function.
519523
StructImpl attr = getAttr();
520524
for (String name : attr.getFieldNames()) {
521525
Object value = attr.getValue(name);
522526
if (value instanceof Label) {
523-
getPathFromLabel((Label) value);
527+
dependOnLabelIgnoringErrors((Label) value);
524528
}
525529
if (value instanceof Sequence) {
526530
for (Object entry : (Sequence) value) {
527531
if (entry instanceof Label) {
528-
getPathFromLabel((Label) entry);
532+
dependOnLabelIgnoringErrors((Label) entry);
529533
}
530534
}
531535
}
532536
if (value instanceof Dict) {
533537
for (Object entry : ((Dict) value).keySet()) {
534538
if (entry instanceof Label) {
535-
getPathFromLabel((Label) entry);
539+
dependOnLabelIgnoringErrors((Label) entry);
536540
}
537541
}
538542
}
539543
}
540544
}
545+
546+
private void dependOnLabelIgnoringErrors(Label label)
547+
throws InterruptedException, NeedsSkyframeRestartException {
548+
try {
549+
getPathFromLabel(label);
550+
} catch (NeedsSkyframeRestartException e) {
551+
throw e;
552+
} catch (EvalException e) {
553+
// EvalExceptions indicate labels not referring to existing files. This is fine,
554+
// as long as they are never resolved to files in the execution of the rule; we allow
555+
// non-strict rules.
556+
}
557+
}
541558
}

src/main/java/com/google/devtools/build/lib/bazel/repository/starlark/StarlarkRepositoryFunction.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,11 +198,6 @@ public RepositoryDirectoryValue.Builder fetch(
198198
} catch (NeedsSkyframeRestartException e) {
199199
// Missing values are expected; just restart before we actually start the rule
200200
return null;
201-
} catch (EvalException e) {
202-
// EvalExceptions indicate labels not referring to existing files. This is fine,
203-
// as long as they are never resolved to files in the execution of the rule; we allow
204-
// non-strict rules. So now we have to start evaluating the actual rule, even if that
205-
// means the rule might get restarted for legitimate reasons.
206201
}
207202

208203
// This rule is mainly executed for its side effect. Nevertheless, the return value is

src/test/shell/bazel/starlark_prefetching_test.sh

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,4 +227,48 @@ EOF
227227
bazel build @ext//:foo || fail "expected success"
228228
}
229229

230+
# Regression test for https://github.com/bazelbuild/bazel/issues/13441
231+
function test_files_tracked_with_non_existing_files() {
232+
cat > rules.bzl <<'EOF'
233+
def _repo_impl(ctx):
234+
ctx.symlink(ctx.path(Label("@//:WORKSPACE")).dirname, "link")
235+
print("b.txt: " + ctx.read("link/b.txt"))
236+
print("c.txt: " + ctx.read("link/c.txt"))
237+
238+
ctx.file("BUILD")
239+
ctx.file("WORKSPACE")
240+
241+
repo = repository_rule(
242+
_repo_impl,
243+
attrs = {"_files": attr.label_list(
244+
default = [
245+
Label("@//:a.txt"),
246+
Label("@//:b.txt"),
247+
Label("@//:c.txt"),
248+
],
249+
)},
250+
)
251+
EOF
252+
253+
cat > WORKSPACE <<'EOF'
254+
load(":rules.bzl", "repo")
255+
repo(name = "ext")
256+
EOF
257+
touch BUILD
258+
259+
# a.txt is intentionally not created
260+
echo "bbbb" > b.txt
261+
echo "cccc" > c.txt
262+
263+
# The missing file dependency is tolerated.
264+
bazel build @ext//:all &> "$TEST_log" || fail "Expected repository rule to build"
265+
expect_log "b.txt: bbbb"
266+
expect_log "c.txt: cccc"
267+
268+
echo "not_cccc" > c.txt
269+
bazel build @ext//:all &> "$TEST_log" || fail "Expected repository rule to build"
270+
expect_log "b.txt: bbbb"
271+
expect_log "c.txt: not_cccc"
272+
}
273+
230274
run_suite "Starlark repo prefetching tests"

0 commit comments

Comments
 (0)