Skip to content

Commit

Permalink
Add workspace_root to repository_ctx (bazelbuild#15441)
Browse files Browse the repository at this point in the history
There are a number of use-cases for this, and I've seen it come up in
`bazel-discuss` and similar. It is possible to abuse this information,
but this information is currently available by looking up something like:

```python
repository_ctx.path(Label("@//:WORKSPACE")).dirname
```

But this is unreliable as `WORKSPACE.bazel` was added as an alternative
to `WORKSPACE`, and trying to look up a label which doesn't exist is a
fatal error.

We're currently using this to work around the fact that labels can't
exist if the file they point at doesn't already exist.
In repository rules we want users to be able to set an attribute to
point at a lockfile, which may not yet exist, and which our rule may
create as a side-effect of running. The nicest way we've worked out how
to do this is to use a `attr.string`, and use `repository_ctx.execute`
to test for the existence of a file, but that relies on being able to
find the path to the root repository.

It may be interesting to try to introduce some kind of fallible
label/path lookup, but that feels like a much bigger change for the
future.

Closes bazelbuild#13417.

PiperOrigin-RevId: 442839850

Co-authored-by: Daniel Wagner-Hall <dwagnerhall@apple.com>
  • Loading branch information
ckolli5 and illicitonion authored May 10, 2022
1 parent b877092 commit 8d510ec
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ public class StarlarkRepositoryContext extends StarlarkBaseExternalContext {

private final Rule rule;
private final PathPackageLocator packageLocator;
private final Path workspaceRoot;
private final StructImpl attrObject;
private final ImmutableSet<PathFragment> ignoredPatterns;

Expand All @@ -119,7 +120,9 @@ public class StarlarkRepositoryContext extends StarlarkBaseExternalContext {
double timeoutScaling,
@Nullable ProcessWrapper processWrapper,
StarlarkSemantics starlarkSemantics,
@Nullable RepositoryRemoteExecutor remoteExecutor)
@Nullable RepositoryRemoteExecutor remoteExecutor,
SyscallCache syscallCache,
Path workspaceRoot)
throws EvalException {
super(
outputDirectory,
Expand All @@ -133,6 +136,8 @@ public class StarlarkRepositoryContext extends StarlarkBaseExternalContext {
this.rule = rule;
this.packageLocator = packageLocator;
this.ignoredPatterns = ignoredPatterns;
this.syscallCache = syscallCache;
this.workspaceRoot = workspaceRoot;
WorkspaceAttributeMapper attrs = WorkspaceAttributeMapper.of(rule);
ImmutableMap.Builder<String, Object> attrBuilder = new ImmutableMap.Builder<>();
for (String name : attrs.getAttributeNames()) {
Expand All @@ -158,6 +163,14 @@ public String getName() {
return rule.getName();
}

@StarlarkMethod(
name = "workspace_root",
structField = true,
doc = "The path to the root workspace of the bazel invocation.")
public StarlarkPath getWorkspaceRoot() {
return new StarlarkPath(workspaceRoot);
}

@StarlarkMethod(
name = "attr",
structField = true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,9 @@ public RepositoryDirectoryValue.Builder fetch(
timeoutScaling,
processWrapper,
starlarkSemantics,
repositoryRemoteExecutor);
repositoryRemoteExecutor,
syscallCache,
directories.getWorkspace());

if (starlarkRepositoryContext.isRemotable()) {
// If a rule is declared remotable then invalidate it if remote execution gets
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,9 @@ protected void setUpContextForRule(
1.0,
/*processWrapper=*/ null,
starlarkSemantics,
repoRemoteExecutor);
repoRemoteExecutor,
SyscallCache.NO_CACHE,
root.asPath());
}

protected void setUpContextForRule(String name) throws Exception {
Expand Down Expand Up @@ -473,4 +475,10 @@ public void testDirectoryListing() throws Exception {
assertThat(context.path("/my/folder").readdir()).containsExactly(
context.path("/my/folder/a"), context.path("/my/folder/b"), context.path("/my/folder/c"));
}

@Test
public void testWorkspaceRoot() throws Exception {
setUpContextForRule("test");
assertThat(context.getWorkspaceRoot().getPath()).isEqualTo(root.asPath());
}
}

0 comments on commit 8d510ec

Please sign in to comment.