Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[8.1.0] Add repository_ctx.original_name #25191

Merged
merged 1 commit into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.StructImpl;
import com.google.devtools.build.lib.packages.StructProvider;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
import com.google.devtools.build.lib.repository.RepositoryFetchProgress;
import com.google.devtools.build.lib.rules.repository.NeedsSkyframeRestartException;
Expand Down Expand Up @@ -143,11 +144,33 @@ public ImmutableMap<RepoRecordedInput.DirTree, String> getRecordedDirTreeInputs(
@StarlarkMethod(
name = "name",
structField = true,
doc = "The name of the external repository created by this rule.")
doc =
"The canonical name of the external repository created by this rule. This name is"
+ " guaranteed to be unique among all external repositories, but its exact format is"
+ " not specified. Use <a href='#original_name'><code>original_name</code></a>"
+ " instead to get the name that was originally specified as the <code>name</code>"
+ " when this repository rule was instantiated.")
public String getName() {
return rule.getName();
}

@StarlarkMethod(
name = "original_name",
structField = true,
doc =
"The name that was originally specified as the <code>name</code> attribute when this"
+ " repository rule was instantiated. This name is not necessarily unique among"
+ " external repositories. Use <a href='#name'><code>name</code></a> instead to get"
+ " the canonical name of the external repository.")
public String getOriginalName() {
String originalName = (String) rule.getAttr("$original_name", Type.STRING);
// The original name isn't set for WORKSPACE-defined repositories as well as repositories
// backing Bazel modules. In case of the former, the original name is the same as the name, in
// the latter the original name doesn't matter as the restricted set of rules that can back
// Bazel modules do not use the name.
return originalName != null ? originalName : rule.getName();
}

@StarlarkMethod(
name = "workspace_root",
structField = true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ public StarlarkCallable repositoryRule(
builder.setCallStack(
callstack.subList(0, callstack.size() - 1)); // pop 'repository_rule' itself

builder.addAttribute(attr("$original_name", STRING).defaultValue("").build());
builder.addAttribute(attr("$local", BOOLEAN).defaultValue(local).build());
builder.addAttribute(attr("$configure", BOOLEAN).defaultValue(configure).build());
if (thread.getSemantics().getBool(BuildLanguageOptions.EXPERIMENTAL_REPO_REMOTE_EXEC)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,12 @@ public SkyValue compute(SkyKey skyKey, Environment env)
Optional<RepoSpec> repoSpec = checkRepoFromNonRegistryOverrides(root, repositoryName);
if (repoSpec.isPresent()) {
return createRuleFromSpec(
repoSpec.get(), repositoryName, basicMainRepoMapping, starlarkSemantics, env);
repoSpec.get(),
repositoryName,
/* originalName= */ null,
basicMainRepoMapping,
starlarkSemantics,
env);
}

// BazelDepGraphValue is affected by repos found in Step 1, therefore it should NOT
Expand All @@ -116,7 +121,12 @@ public SkyValue compute(SkyKey skyKey, Environment env)
repoSpec = checkRepoFromBazelModules(bazelDepGraphValue, repositoryName);
if (repoSpec.isPresent()) {
return createRuleFromSpec(
repoSpec.get(), repositoryName, basicMainRepoMapping, starlarkSemantics, env);
repoSpec.get(),
repositoryName,
/* originalName= */ null,
basicMainRepoMapping,
starlarkSemantics,
env);
}

// Step 3: look for the repo from module extension evaluation results.
Expand All @@ -142,7 +152,7 @@ public SkyValue compute(SkyKey skyKey, Environment env)
}
RepoSpec extRepoSpec = extensionValue.generatedRepoSpecs().get(internalRepo);
return createRuleFromSpec(
extRepoSpec, repositoryName, basicMainRepoMapping, starlarkSemantics, env);
extRepoSpec, repositoryName, internalRepo, basicMainRepoMapping, starlarkSemantics, env);
}

private static Optional<RepoSpec> checkRepoFromNonRegistryOverrides(
Expand All @@ -168,6 +178,7 @@ private Optional<RepoSpec> checkRepoFromBazelModules(
private BzlmodRepoRuleValue createRuleFromSpec(
RepoSpec repoSpec,
RepositoryName repositoryName,
@Nullable String originalName,
RepositoryMapping basicMainRepoMapping,
StarlarkSemantics starlarkSemantics,
Environment env)
Expand All @@ -177,11 +188,13 @@ private BzlmodRepoRuleValue createRuleFromSpec(
return null;
}

var attributes =
var attributesBuilder =
ImmutableMap.<String, Object>builder()
.putAll(repoSpec.attributes().attributes())
.put("name", repositoryName.getName())
.buildOrThrow();
.put("name", repositoryName.getName());
if (originalName != null) {
attributesBuilder.put("$original_name", originalName);
}
try {
Rule rule =
BzlmodRepoRuleCreator.createRule(
Expand All @@ -194,7 +207,7 @@ private BzlmodRepoRuleValue createRuleFromSpec(
StarlarkThread.callStackEntry(
"BzlmodRepoRuleFunction.createRuleFromSpec", Location.BUILTIN)),
ruleClass,
attributes);
attributesBuilder.buildOrThrow());
return new BzlmodRepoRuleValue(rule.getPackage(), rule.getName());
} catch (InvalidRuleException e) {
throw new BzlmodRepoRuleFunctionException(e, Transience.PERSISTENT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,13 @@ public void setup() throws Exception {
" ctx.file('WORKSPACE')",
" ctx.file('BUILD')",
" ctx.file('data.bzl', 'data = '+json.encode(ctx.attr.data))",
" ctx.file(",
" 'names.bzl',",
" 'names='+json.encode({",
" 'name': ctx.name,",
" 'original_name': ctx.original_name,",
" })",
" )",
"data_repo = repository_rule(",
" implementation=_data_repo_impl,",
" attrs={'data':attr.string()})");
Expand Down Expand Up @@ -328,8 +335,12 @@ public void simpleExtension() throws Exception {
scratch.file(
workspaceRoot.getRelative("data.bzl").getPathString(),
"load('@foo//:data.bzl', foo_data='data')",
"load('@foo//:names.bzl', foo_names='names')",
"load('@bar//:data.bzl', bar_data='data')",
"data = 'foo:'+foo_data+' bar:'+bar_data");
"load('@bar//:names.bzl', bar_names='names')",
"data = 'foo:'+foo_data+' bar:'+bar_data",
"names = 'foo:'+foo_names['name']+' bar:'+bar_names['name']",
"original_names = 'foo:'+foo_names['original_name']+' bar:'+bar_names['original_name']");

SkyKey skyKey = BzlLoadValue.keyForBuild(Label.parseCanonical("//:data.bzl"));
EvaluationResult<BzlLoadValue> result =
Expand All @@ -338,6 +349,10 @@ public void simpleExtension() throws Exception {
throw result.getError().getException();
}
assertThat(result.get(skyKey).getModule().getGlobal("data")).isEqualTo("foo:fu bar:ba");
assertThat(result.get(skyKey).getModule().getGlobal("names"))
.isEqualTo("foo:+ext+foo bar:+ext+bar");
assertThat(result.get(skyKey).getModule().getGlobal("original_names"))
.isEqualTo("foo:foo bar:bar");
}

@Test
Expand Down Expand Up @@ -2896,30 +2911,45 @@ public void innate() throws Exception {
workspaceRoot.getRelative("MODULE.bazel").getPathString(),
"bazel_dep(name='foo',version='1.0')",
"data_repo = use_repo_rule('@foo//:repo.bzl', 'data_repo')",
"data_repo(name='data', data='get up at 6am.')");
"data_repo(name='data1', data='get up at 6am.')");
scratch.file(workspaceRoot.getRelative("BUILD").getPathString());
scratch.file(
workspaceRoot.getRelative("data.bzl").getPathString(),
"load('@data//:data.bzl', self_data='data')",
"load('@data1//:data.bzl', self_data='data')",
"load('@data1//:names.bzl', self_names='names')",
"load('@foo//:data.bzl', foo_data='data')",
"data=self_data+' '+foo_data");
"load('@foo//:names.bzl', foo_names='names')",
"data=self_data+' '+foo_data",
"names=self_names['name']+' '+foo_names['name']",
"original_names=self_names['original_name']+' '+foo_names['original_name']");

registry.addModule(
createModuleKey("foo", "1.0"),
"module(name='foo',version='1.0')",
"data_repo = use_repo_rule('//:repo.bzl', 'data_repo')",
"data_repo(name='data', data='go to bed at 11pm.')");
"data_repo(name='data2', data='go to bed at 11pm.')");
scratch.file(modulesRoot.getRelative("foo+1.0/WORKSPACE").getPathString());
scratch.file(modulesRoot.getRelative("foo+1.0/BUILD").getPathString());
scratch.file(
modulesRoot.getRelative("foo+1.0/data.bzl").getPathString(),
"load('@data//:data.bzl',repo_data='data')",
"load('@data2//:data.bzl',repo_data='data')",
"data=repo_data");
scratch.file(
modulesRoot.getRelative("foo+1.0/names.bzl").getPathString(),
"load('@data2//:names.bzl',repo_names='names')",
"names=repo_names");
scratch.file(
modulesRoot.getRelative("foo+1.0/repo.bzl").getPathString(),
"def _data_repo_impl(ctx):",
" ctx.file('BUILD.bazel')",
" ctx.file('data.bzl', 'data='+json.encode(ctx.attr.data))",
" ctx.file(",
" 'names.bzl',",
" 'names='+json.encode({",
" 'name': ctx.name,",
" 'original_name': ctx.original_name,",
" })",
" )",
"data_repo = repository_rule(",
" implementation=_data_repo_impl, attrs={'data':attr.string()})");

Expand All @@ -2931,6 +2961,9 @@ public void innate() throws Exception {
}
assertThat(result.get(skyKey).getModule().getGlobal("data"))
.isEqualTo("get up at 6am. go to bed at 11pm.");
assertThat(result.get(skyKey).getModule().getGlobal("names"))
.isEqualTo("+_repo_rules+data1 foo++_repo_rules+data2");
assertThat(result.get(skyKey).getModule().getGlobal("original_names")).isEqualTo("data1 data2");
}

@Test
Expand Down
22 changes: 12 additions & 10 deletions src/test/py/bazel/bzlmod/mod_command_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,13 +467,13 @@ def testShowModuleAndExtensionReposFromBaseModule(self):
self.assertRegex(stdout.pop(4), r'^ integrity = ".*",$')
self.assertRegex(stdout.pop(19), r'^ path = ".*",$')
# lines after 'Rule data_repo defined at (most recent call last):'
stdout.pop(32)
stdout.pop(42)
self.assertRegex(stdout.pop(47), r'^ urls = \[".*"\],$')
self.assertRegex(stdout.pop(47), r'^ integrity = ".*",$')
stdout.pop(33)
stdout.pop(44)
self.assertRegex(stdout.pop(49), r'^ urls = \[".*"\],$')
self.assertRegex(stdout.pop(49), r'^ integrity = ".*",$')
# lines after '# Rule http_archive defined at (most recent call last):'
stdout.pop(13)
stdout.pop(55)
stdout.pop(57)
self.assertListEqual(
stdout,
[
Expand Down Expand Up @@ -507,30 +507,32 @@ def testShowModuleAndExtensionReposFromBaseModule(self):
'# <builtin>',
'data_repo(',
' name = "ext++ext+repo3",',
' _original_name = "repo3",',
' data = "requested repo",',
')',
'# Rule ext++ext+repo3 instantiated at (most recent call last):',
'# <builtin> in <toplevel>',
'# Rule data_repo defined at (most recent call last):',
# pop(32)
# pop(33)
'',
'## @my_repo4:',
'# <builtin>',
'data_repo(',
' name = "ext++ext+repo4",',
' _original_name = "repo4",',
' data = "requested repo",',
')',
'# Rule ext++ext+repo4 instantiated at (most recent call last):',
'# <builtin> in <toplevel>',
'# Rule data_repo defined at (most recent call last):',
# pop(42)
# pop(44)
'',
'## bar@2.0:',
'# <builtin>',
'http_archive(',
' name = "bar+",',
# pop(47) -- urls=[...]
# pop(47) -- integrity=...
# pop(49) -- urls=[...]
# pop(49) -- integrity=...
' strip_prefix = "",',
' remote_file_urls = {},',
' remote_file_integrity = {},',
Expand All @@ -540,7 +542,7 @@ def testShowModuleAndExtensionReposFromBaseModule(self):
'# Rule bar+ instantiated at (most recent call last):',
'# <builtin> in <toplevel>',
'# Rule http_archive defined at (most recent call last):',
# pop(55)
# pop(57)
'',
],
'wrong output in the show query for module and extension-generated'
Expand Down
Loading