Skip to content

Commit

Permalink
Local repo rules in Starlark
Browse files Browse the repository at this point in the history
Added `local_repository` and `new_local_repository` as Starlark repo rules under `@bazel_tools//tools/build_defs/repo:local.bzl`. They're drop-in replacements for their native counterparts.

Work towards #18285.

RELNOTES: The `local_repository` and `new_local_repository` repository rules are now available as Starlark rules under `@bazel_tools//tools/build_defs/repo:local.bzl`. They are drop-in replacements for their native counterparts, and can be used in module extensions.

Closes #21681.

PiperOrigin-RevId: 615926923
Change-Id: I0cc7355b011751da23f2a3aa189f120ef177e0fe
  • Loading branch information
Wyverald committed Apr 30, 2024
1 parent e09b536 commit e565fa5
Show file tree
Hide file tree
Showing 18 changed files with 375 additions and 111 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,18 @@ private RepositoryDirectoryValue.Builder fetchInternal(
new IOException(rule + " must create a directory"), Transience.TRANSIENT);
}

// Make sure the fetched repo has a boundary file.
if (!WorkspaceFileHelper.isValidRepoRoot(outputDirectory)) {
if (outputDirectory.isSymbolicLink()) {
// The created repo is actually just a symlink to somewhere else (think local_repository).
// In this case, we shouldn't try to create the repo boundary file ourselves, but report an
// error instead.
throw new RepositoryFunctionException(
new IOException(
"No MODULE.bazel, REPO.bazel, or WORKSPACE file found in " + outputDirectory),
Transience.TRANSIENT);
}
// Otherwise, we can just create an empty REPO.bazel file.
try {
FileSystemUtils.createEmptyFile(outputDirectory.getRelative(LabelConstants.REPO_FILE_NAME));
if (starlarkSemantics.getBool(BuildLanguageOptions.ENABLE_WORKSPACE)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public RepositoryDirectoryValue.Builder fetch(
Map<RepoRecordedInput, String> recordedInputValues,
SkyKey key)
throws InterruptedException, RepositoryFunctionException {
// DO NOT MODIFY THIS! It's being deprecated in favor of Starlark counterparts.
// See https://github.com/bazelbuild/bazel/issues/18285
String userDefinedPath = RepositoryFunction.getPathAttr(rule);
Path targetPath = directories.getWorkspace().getRelative(userDefinedPath);
RepositoryDirectoryValue.Builder result =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public class LocalRepositoryRule implements RuleDefinition {

@Override
public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) {
// DO NOT MODIFY THIS! It's being deprecated in favor of Starlark counterparts.
// See https://github.com/bazelbuild/bazel/issues/18285
return builder
/* <!-- #BLAZE_RULE(local_repository).ATTRIBUTE(path) -->
The path to the local repository's directory.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ public RepositoryDirectoryValue.Builder fetch(
Map<RepoRecordedInput, String> recordedInputValues,
SkyKey key)
throws InterruptedException, RepositoryFunctionException {
// DO NOT MODIFY THIS! It's being deprecated in favor of Starlark counterparts.
// See https://github.com/bazelbuild/bazel/issues/18285

NewRepositoryFileHandler fileHandler = new NewRepositoryFileHandler(directories.getWorkspace());
if (!fileHandler.prepareFile(rule, env)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public class NewLocalRepositoryRule implements RuleDefinition {

@Override
public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) {
// DO NOT MODIFY THIS! It's being deprecated in favor of Starlark counterparts.
// See https://github.com/bazelbuild/bazel/issues/18285
return builder
/* <!-- #BLAZE_RULE(new_local_repository).ATTRIBUTE(path) -->
A path on the local filesystem.
Expand Down
97 changes: 75 additions & 22 deletions src/test/py/bazel/bazel_external_repository_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,10 @@ def testNewLocalRepositoryNoticesFileChangeInRepoRoot(self):
"""Regression test for https://github.com/bazelbuild/bazel/issues/7063."""
rule_definition = [
'load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")',
(
'load("@bazel_tools//tools/build_defs/repo:local.bzl",'
' "new_local_repository")'
),
'new_local_repository(',
' name = "r",',
' path = "./repo",',
Expand Down Expand Up @@ -280,9 +284,16 @@ def testDeletedPackagesOnExternalRepo(self):
])
self.ScratchFile('other_repo/pkg/ignore/file')
work_dir = self.ScratchDir('my_repo')
self.ScratchFile('my_repo/WORKSPACE', [
"local_repository(name = 'other_repo', path='../other_repo')",
])
self.ScratchFile(
'my_repo/WORKSPACE',
[
(
'load("@bazel_tools//tools/build_defs/repo:local.bzl",'
' "local_repository")'
),
"local_repository(name = 'other_repo', path='../other_repo')",
],
)

exit_code, _, stderr = self.RunBazel(
args=['build', '@other_repo//pkg:file'],
Expand Down Expand Up @@ -317,9 +328,16 @@ def testBazelignoreFileOnExternalRepo(self):
])
self.ScratchFile('other_repo/pkg/ignore/file.txt')
work_dir = self.ScratchDir('my_repo')
self.ScratchFile('my_repo/WORKSPACE', [
'local_repository(name = "other_repo", path="../other_repo")',
])
self.ScratchFile(
'my_repo/WORKSPACE',
[
(
'load("@bazel_tools//tools/build_defs/repo:local.bzl",'
' "local_repository")'
),
'local_repository(name = "other_repo", path="../other_repo")',
],
)

exit_code, _, stderr = self.RunBazel(
args=['build', '@other_repo//pkg:file'],
Expand Down Expand Up @@ -368,9 +386,16 @@ def testUniverseScopeWithBazelIgnoreInExternalRepo(self):
])

work_dir = self.ScratchDir('my_repo')
self.ScratchFile('my_repo/WORKSPACE', [
'local_repository(name = "other_repo", path="../other_repo")',
])
self.ScratchFile(
'my_repo/WORKSPACE',
[
(
'load("@bazel_tools//tools/build_defs/repo:local.bzl",'
' "local_repository")'
),
'local_repository(name = "other_repo", path="../other_repo")',
],
)

_, stdout, _ = self.RunBazel(
args=[
Expand All @@ -395,9 +420,16 @@ def testBazelignoreFileFromMainRepoDoesNotAffectExternalRepos(self):
self.ScratchFile('other_repo/foo/bar/file.txt')

work_dir = self.ScratchDir('my_repo')
self.ScratchFile('my_repo/WORKSPACE', [
'local_repository(name = "other_repo", path="../other_repo")',
])
self.ScratchFile(
'my_repo/WORKSPACE',
[
(
'load("@bazel_tools//tools/build_defs/repo:local.bzl",'
' "local_repository")'
),
'local_repository(name = "other_repo", path="../other_repo")',
],
)
# This should not exclude @other_repo//foo/bar
self.ScratchFile('my_repo/.bazelignore', ['foo/bar'])

Expand All @@ -420,9 +452,16 @@ def testBazelignoreFileFromExternalRepoDoesNotAffectMainRepo(self):
')',
])
self.ScratchFile('my_repo/foo/bar/file.txt')
self.ScratchFile('my_repo/WORKSPACE', [
'local_repository(name = "other_repo", path="../other_repo")',
])
self.ScratchFile(
'my_repo/WORKSPACE',
[
(
'load("@bazel_tools//tools/build_defs/repo:local.bzl",'
' "local_repository")'
),
'local_repository(name = "other_repo", path="../other_repo")',
],
)

_, stdout, _ = self.RunBazel(args=['query', '//foo/bar/...'], cwd=work_dir)
self.assertIn('//foo/bar:file', ''.join(stdout))
Expand All @@ -438,9 +477,16 @@ def testMainBazelignoreContainingRepoName(self):
self.ScratchFile('other_repo/foo/bar/file.txt')

work_dir = self.ScratchDir('my_repo')
self.ScratchFile('my_repo/WORKSPACE', [
'local_repository(name = "other_repo", path="../other_repo")',
])
self.ScratchFile(
'my_repo/WORKSPACE',
[
(
'load("@bazel_tools//tools/build_defs/repo:local.bzl",'
' "local_repository")'
),
'local_repository(name = "other_repo", path="../other_repo")',
],
)
# This should not exclude @other_repo//foo/bar, because .bazelignore doesn't
# support having repository name in the path fragment.
self.ScratchFile('my_repo/.bazelignore', ['@other_repo//foo/bar'])
Expand Down Expand Up @@ -470,10 +516,17 @@ def testExternalBazelignoreContainingRepoName(self):
self.ScratchFile('third_repo/foo/bar/file.txt')

work_dir = self.ScratchDir('my_repo')
self.ScratchFile('my_repo/WORKSPACE', [
'local_repository(name = "other_repo", path="../other_repo")',
'local_repository(name = "third_repo", path="../third_repo")',
])
self.ScratchFile(
'my_repo/WORKSPACE',
[
(
'load("@bazel_tools//tools/build_defs/repo:local.bzl",'
' "local_repository")'
),
'local_repository(name = "other_repo", path="../other_repo")',
'local_repository(name = "third_repo", path="../third_repo")',
],
)

self.RunBazel(args=['build', '@other_repo//:file'], cwd=work_dir)

Expand Down
22 changes: 19 additions & 3 deletions src/test/py/bazel/bazel_workspace_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,15 @@ def testWorkspaceDotBazelFileWithExternalRepo(self):
# Test WORKSPACE.bazel takes priority over WORKSPACE
self.ScratchFile("B/WORKSPACE")
workspace_dot_bazel = self.ScratchFile(
"B/WORKSPACE.bazel", ["local_repository(name = 'A', path='../A')"])
"B/WORKSPACE.bazel",
[
(
'load("@bazel_tools//tools/build_defs/repo:local.bzl",'
' "local_repository")'
),
"local_repository(name = 'A', path='../A')",
],
)
self.ScratchFile("B/bin.py")
self.ScratchFile("B/BUILD", [
"py_binary(",
Expand All @@ -78,8 +86,16 @@ def testWorkspaceDotBazelFileWithExternalRepo(self):
self.assertIn("no such package '@@A//'", "".join(stderr))

# Test a WORKSPACE.bazel directory won't confuse Bazel
self.ScratchFile("B/WORKSPACE",
["local_repository(name = 'A', path='../A')"])
self.ScratchFile(
"B/WORKSPACE",
[
(
'load("@bazel_tools//tools/build_defs/repo:local.bzl",'
' "local_repository")'
),
"local_repository(name = 'A', path='../A')",
],
)
self.ScratchDir("B/WORKSPACE.bazel")
self.RunBazel(args=["build", ":bin"], cwd=work_dir)

Expand Down
17 changes: 16 additions & 1 deletion src/test/py/bazel/bzlmod/bazel_module_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,10 @@ def testWorkspaceEvaluatedBzlCanSeeRootModuleMappings(self):
self.ScratchFile(
'WORKSPACE.bzlmod',
[
(
'load("@bazel_tools//tools/build_defs/repo:local.bzl",'
' "local_repository")'
),
'local_repository(name="foo", path="foo", repo_mapping={',
' "@bar":"@baz",',
' "@my_aaa":"@aaa",',
Expand Down Expand Up @@ -497,6 +501,10 @@ def testNoModuleDotBazelAndFallbackToWorkspace(self):
self.ScratchFile(
'WORKSPACE',
[
(
'load("@bazel_tools//tools/build_defs/repo:local.bzl",'
' "local_repository")'
),
'local_repository(name="hello", path="hello")',
'load("@hello//:world.bzl", "message")',
'print(message)',
Expand Down Expand Up @@ -562,7 +570,14 @@ def testNativeModuleNameAndVersion(self):
],
)
self.ScratchFile(
'WORKSPACE.bzlmod', ['local_repository(name="quux",path="quux")']
'WORKSPACE.bzlmod',
[
(
'load("@bazel_tools//tools/build_defs/repo:local.bzl",'
' "local_repository")'
),
'local_repository(name="quux",path="quux")',
],
)
self.ScratchFile(
'BUILD',
Expand Down
4 changes: 3 additions & 1 deletion src/test/shell/bazel/check_external_files_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ setup_local() {
mkdir main
cd main
cat >> "$(create_workspace_with_default_repos WORKSPACE)" <<EOF
load("@bazel_tools//tools/build_defs/repo:local.bzl", "local_repository")
local_repository(
name="local_rep",
path="../local_rep",
Expand Down Expand Up @@ -205,7 +206,8 @@ test_no_fetch_then_fetch() {
--noexperimental_check_output_files \
--watchfs \
@remote//:g >& "$TEST_log" && fail "Expected build to fail" || true
expect_log "no such package '@@bazel_tools//tools/build_defs/repo'"
expect_log "no such package"
expect_log "fetching repositories is disabled"
bazel build \
--fetch \
--noexperimental_check_external_repository_files \
Expand Down
3 changes: 3 additions & 0 deletions src/test/shell/bazel/external_integration_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1113,6 +1113,7 @@ EOF

function test_use_bind_as_repository() {
cat >> $(create_workspace_with_default_repos WORKSPACE) <<'EOF'
load("@bazel_tools//tools/build_defs/repo:local.bzl", "local_repository")
local_repository(name = 'foobar', path = 'foo')
bind(name = 'foo', actual = '@foobar//:test')
EOF
Expand Down Expand Up @@ -1163,6 +1164,7 @@ function test_flip_flopping() {
cd -

cat > local_ws <<EOF
load("@bazel_tools//tools/build_defs/repo:local.bzl", "local_repository")
local_repository(
name = "repo",
path = "$REPO_PATH",
Expand Down Expand Up @@ -2840,6 +2842,7 @@ function test_external_java_target_depends_on_external_resources() {
mkdir -p $test_repo2

cat >> $(create_workspace_with_default_repos WORKSPACE) <<EOF
load("@bazel_tools//tools/build_defs/repo:local.bzl", "local_repository")
local_repository(name = 'repo1', path='$test_repo1')
local_repository(name = 'repo2', path='$test_repo2')
EOF
Expand Down
3 changes: 3 additions & 0 deletions src/test/shell/bazel/external_starlark_load_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ function run_external_starlark_load_test() {
external_repo=${new_workspace_dir}

cat > ${WORKSPACE_DIR}/WORKSPACE <<EOF
load("@bazel_tools//tools/build_defs/repo:local.bzl", "local_repository")
local_repository(name = "external_repo", path = "${external_repo}")
EOF

Expand Down Expand Up @@ -126,6 +127,7 @@ remote_rule = rule(
EOF

cat > WORKSPACE <<EOF
load("@bazel_tools//tools/build_defs/repo:local.bzl", "local_repository")
local_repository(
name = "r",
path = "$repo2",
Expand Down Expand Up @@ -158,6 +160,7 @@ function test_starlark_repository_nested_relative_label() {

# local
cat > WORKSPACE <<EOF
load("@bazel_tools//tools/build_defs/repo:local.bzl", "local_repository")
local_repository(
name = "r1",
path = "$repo1",
Expand Down
Loading

0 comments on commit e565fa5

Please sign in to comment.