Skip to content

Commit

Permalink
Implement REPO.bazel
Browse files Browse the repository at this point in the history
- REPO.bazel is a new file at the root of repos that can only contain a `repo()` call with a bunch of package default arguments (similar to `package()`)
- A new SkyFunction, RepoFileFunction, evaluates a REPO.bazel file and returns the `PackageArgs` object containing those arguments
- PackageFunction for packages in repo `@foo` now depends on RepoFileFunction for `@foo`

Fixes #18077

PiperOrigin-RevId: 551313372
Change-Id: If5769edec49fef148d17596f524ab7df935862b4
  • Loading branch information
Wyverald authored and copybara-github committed Jul 26, 2023
1 parent 1d24355 commit 3774f00
Show file tree
Hide file tree
Showing 17 changed files with 578 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.google.devtools.build.lib.collect.nestedset.Depset;
import com.google.devtools.build.lib.packages.BuildGlobals;
import com.google.devtools.build.lib.packages.Proto;
import com.google.devtools.build.lib.packages.RepoCallable;
import com.google.devtools.build.lib.packages.SelectorList;
import com.google.devtools.build.lib.packages.StarlarkGlobals;
import com.google.devtools.build.lib.packages.StarlarkNativeModule;
Expand Down Expand Up @@ -120,4 +121,11 @@ public ImmutableMap<String, Object> getSclToplevels() {
env.put("struct", StructProvider.STRUCT);
return env.buildOrThrow();
}

@Override
public ImmutableMap<String, Object> getRepoToplevels() {
ImmutableMap.Builder<String, Object> env = ImmutableMap.builder();
Starlark.addMethods(env, RepoCallable.INSTANCE);
return env.buildOrThrow();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class LabelConstants {
public static final PathFragment WORKSPACE_DOT_BAZEL_FILE_NAME =
PathFragment.create("WORKSPACE.bazel");
public static final PathFragment MODULE_DOT_BAZEL_FILE_NAME = PathFragment.create("MODULE.bazel");
public static final PathFragment REPO_FILE_NAME = PathFragment.create("REPO.bazel");

public static final PathFragment MODULE_LOCKFILE_NAME = PathFragment.create("MODULE.bazel.lock");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
*/
@AutoValue
public abstract class PackageArgs {
public static final PackageArgs EMPTY = PackageArgs.builder().build();

public static final PackageArgs DEFAULT =
PackageArgs.builder()
.setDefaultVisibility(RuleVisibility.PRIVATE)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright 2023 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.devtools.build.lib.packages;

import java.util.Map;
import net.starlark.java.annot.Param;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkThread;

/** Definition of the {@code repo()} function used in REPO.bazel files. */
public final class RepoCallable {
private RepoCallable() {}

public static final RepoCallable INSTANCE = new RepoCallable();

@StarlarkMethod(
name = "repo",
documented = false, // documented separately
extraKeywords = @Param(name = "kwargs"),
useStarlarkThread = true)
public Object repoCallable(Map<String, Object> kwargs, StarlarkThread thread)
throws EvalException {
RepoThreadContext context = RepoThreadContext.fromOrFail(thread, "repo()");
if (context.isRepoFunctionCalled()) {
throw Starlark.errorf("'repo' can only be called once in the REPO.bazel file");
}
context.setRepoFunctionCalled();

if (kwargs.isEmpty()) {
throw Starlark.errorf("at least one argument must be given to the 'repo' function");
}

PackageArgs.Builder pkgArgsBuilder = PackageArgs.builder();
for (Map.Entry<String, Object> kwarg : kwargs.entrySet()) {
PackageArgs.processParam(
kwarg.getKey(),
kwarg.getValue(),
"repo() argument '" + kwarg.getKey() + "'",
context.getLabelConverter(),
pkgArgsBuilder);
}
context.setPackageArgs(pkgArgsBuilder.build());
return Starlark.NONE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright 2023 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.devtools.build.lib.packages;

import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkThread;

/** Context object for a Starlark thread evaluating the REPO.bazel file. */
public class RepoThreadContext {
private final LabelConverter labelConverter;
private PackageArgs packageArgs = PackageArgs.EMPTY;
private boolean repoFunctionCalled = false;

public static RepoThreadContext fromOrFail(StarlarkThread thread, String what)
throws EvalException {
RepoThreadContext context = thread.getThreadLocal(RepoThreadContext.class);
if (context == null) {
throw Starlark.errorf("%s can only be called from REPO.bazel", what);
}
return context;
}

public void storeInThread(StarlarkThread thread) {
thread.setThreadLocal(RepoThreadContext.class, this);
}

public RepoThreadContext(LabelConverter labelConverter) {
this.labelConverter = labelConverter;
}

public LabelConverter getLabelConverter() {
return labelConverter;
}

public boolean isRepoFunctionCalled() {
return repoFunctionCalled;
}

public void setRepoFunctionCalled() {
repoFunctionCalled = true;
}

public void setPackageArgs(PackageArgs packageArgs) {
this.packageArgs = packageArgs;
}

public PackageArgs getPackageArgs() {
return packageArgs;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,7 @@ public interface StarlarkGlobals {

/** Returns the top-levels for .scl files. */
ImmutableMap<String, Object> getSclToplevels();

/** Returns the top-levels for REPO.bazel files. */
ImmutableMap<String, Object> getRepoToplevels();
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
import net.starlark.java.syntax.Location;

/** The Starlark native module. */
// TODO(cparsons): Move the definition of native.package() to this class.
public class StarlarkNativeModule implements StarlarkNativeModuleApi {
private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();

Expand Down
36 changes: 36 additions & 0 deletions src/main/java/com/google/devtools/build/lib/skyframe/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ java_library(
":recursive_package_provider_backed_target_pattern_resolver",
":recursive_pkg_function",
":recursive_pkg_value",
":repo_file_function",
":repo_file_value",
":repository_mapping_function",
":repository_mapping_value",
":rule_configured_target_value",
Expand Down Expand Up @@ -2194,6 +2196,40 @@ java_library(
],
)

java_library(
name = "repo_file_function",
srcs = ["RepoFileFunction.java"],
deps = [
":precomputed_value",
":repo_file_value",
":repository_mapping_value",
"//src/main/java/com/google/devtools/build/lib/actions:file_metadata",
"//src/main/java/com/google/devtools/build/lib/cmdline",
"//src/main/java/com/google/devtools/build/lib/events",
"//src/main/java/com/google/devtools/build/lib/packages",
"//src/main/java/com/google/devtools/build/lib/rules:repository/repository_directory_value",
"//src/main/java/com/google/devtools/build/lib/vfs",
"//src/main/java/com/google/devtools/build/lib/vfs:pathfragment",
"//src/main/java/com/google/devtools/build/skyframe",
"//src/main/java/com/google/devtools/build/skyframe:skyframe-objects",
"//src/main/java/net/starlark/java/eval",
"//src/main/java/net/starlark/java/syntax",
"//third_party:jsr305",
],
)

java_library(
name = "repo_file_value",
srcs = ["RepoFileValue.java"],
deps = [
":sky_functions",
"//src/main/java/com/google/devtools/build/lib/cmdline",
"//src/main/java/com/google/devtools/build/lib/packages",
"//src/main/java/com/google/devtools/build/skyframe:skyframe-objects",
"//third_party:auto_value",
],
)

java_library(
name = "repository_mapping_function",
srcs = ["RepositoryMappingFunction.java"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import com.google.devtools.build.lib.server.FailureDetails.PackageLoading.Code;
import com.google.devtools.build.lib.skyframe.BzlLoadFunction.BzlLoadFailedException;
import com.google.devtools.build.lib.skyframe.GlobValue.InvalidGlobPatternException;
import com.google.devtools.build.lib.skyframe.RepoFileFunction.BadRepoFileException;
import com.google.devtools.build.lib.skyframe.StarlarkBuiltinsFunction.BuiltinsFailedException;
import com.google.devtools.build.lib.util.DetailedExitCode;
import com.google.devtools.build.lib.util.Pair;
Expand Down Expand Up @@ -1240,6 +1241,24 @@ private LoadedPackage loadPackage(
IgnoredPackagePrefixesValue repositoryIgnoredPackagePrefixes =
(IgnoredPackagePrefixesValue)
env.getValue(IgnoredPackagePrefixesValue.key(packageId.getRepository()));
RepoFileValue repoFileValue;
try {
repoFileValue =
(RepoFileValue)
env.getValueOrThrow(
RepoFileValue.key(packageId.getRepository()),
IOException.class,
BadRepoFileException.class);
} catch (IOException | BadRepoFileException e) {
throw PackageFunctionException.builder()
.setType(PackageFunctionException.Type.BUILD_FILE_CONTAINS_ERRORS)
.setPackageIdentifier(packageId)
.setTransience(Transience.PERSISTENT)
.setException(e)
.setMessage("bad REPO.bazel file")
.setPackageLoadingCode(PackageLoading.Code.BAD_REPO_FILE)
.build();
}
if (env.valuesMissing()) {
return null;
}
Expand Down Expand Up @@ -1375,8 +1394,9 @@ private LoadedPackage loadPackage(
.setFilename(buildFileRootedPath)
.setConfigSettingVisibilityPolicy(configSettingVisibilityPolicy);

pkgBuilder.mergePackageArgsFrom(
PackageArgs.builder().setDefaultVisibility(defaultVisibility));
pkgBuilder
.mergePackageArgsFrom(PackageArgs.builder().setDefaultVisibility(defaultVisibility))
.mergePackageArgsFrom(repoFileValue.packageArgs());

Set<SkyKey> globDepKeys = ImmutableSet.of();

Expand Down
Loading

0 comments on commit 3774f00

Please sign in to comment.