Skip to content

Commit 40ec2cd

Browse files
Wyveraldcopybara-github
authored andcommitted
Store information about each proxy in ModuleExtensionUsage
The current ModuleExtensionUsage class was designed in the days before we allowed multiple `use_extension` calls for the same extension in the same module. This PR brings the class up to speed to better reflect the actual API. This will also lay the groundwork for `bazel mod tidy` working with `include()`d segments. Work towards #22063 Closes #22307. PiperOrigin-RevId: 632377764 Change-Id: I282a68bc7962088ae4583418f73b2e60a0ec88f0
1 parent 9aeca24 commit 40ec2cd

18 files changed

+664
-526
lines changed

MODULE.bazel.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelDepGraphFunction.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,13 +237,13 @@ static BzlmodFlagsAndEnvVars getFlagsAndEnvVars(Environment env) throws Interrup
237237
Code.BAD_MODULE,
238238
e,
239239
"invalid label for module extension found at %s",
240-
usage.getLocation());
240+
usage.getProxies().getFirst().getLocation());
241241
}
242242
if (!moduleExtensionId.getBzlFileLabel().getRepository().isVisible()) {
243243
throw ExternalDepsException.withMessage(
244244
Code.BAD_MODULE,
245245
"invalid label for module extension found at %s: no repo visible as '@%s' here",
246-
usage.getLocation(),
246+
usage.getProxies().getFirst().getLocation(),
247247
moduleExtensionId.getBzlFileLabel().getRepository().getName());
248248
}
249249
extensionUsagesTableBuilder.put(moduleExtensionId, module.getKey(), usage);

src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelDepGraphValue.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,16 @@ public static BazelDepGraphValue createEmptyDepGraph() {
118118
*/
119119
public final RepositoryMapping getFullRepoMapping(ModuleKey key) {
120120
ImmutableMap.Builder<String, RepositoryName> mapping = ImmutableMap.builder();
121-
for (Map.Entry<ModuleExtensionId, ModuleExtensionUsage> e :
121+
for (Map.Entry<ModuleExtensionId, ModuleExtensionUsage> extIdAndUsage :
122122
getExtensionUsagesTable().column(key).entrySet()) {
123-
ModuleExtensionId extensionId = e.getKey();
124-
ModuleExtensionUsage usage = e.getValue();
125-
for (Map.Entry<String, String> entry : usage.getImports().entrySet()) {
126-
String canonicalRepoName =
127-
getExtensionUniqueNames().get(extensionId) + "~" + entry.getValue();
128-
mapping.put(entry.getKey(), RepositoryName.createUnvalidated(canonicalRepoName));
123+
ModuleExtensionId extensionId = extIdAndUsage.getKey();
124+
ModuleExtensionUsage usage = extIdAndUsage.getValue();
125+
String repoNamePrefix = getExtensionUniqueNames().get(extensionId) + "~";
126+
for (ModuleExtensionUsage.Proxy proxy : usage.getProxies()) {
127+
for (Map.Entry<String, String> entry : proxy.getImports().entrySet()) {
128+
String canonicalRepoName = repoNamePrefix + entry.getValue();
129+
mapping.put(entry.getKey(), RepositoryName.createUnvalidated(canonicalRepoName));
130+
}
129131
}
130132
}
131133
return getDepGraph()

src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileValue.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
@GenerateTypeAdapter
4040
public abstract class BazelLockFileValue implements SkyValue, Postable {
4141

42-
public static final int LOCK_FILE_VERSION = 8;
42+
public static final int LOCK_FILE_VERSION = 9;
4343

4444
@SerializationConstant public static final SkyKey KEY = () -> SkyFunctions.BAZEL_LOCK_FILE;
4545

src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleExtensionMetadata.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
import net.starlark.java.eval.Starlark;
4242
import net.starlark.java.eval.StarlarkList;
4343
import net.starlark.java.eval.StarlarkValue;
44-
import net.starlark.java.syntax.Location;
4544

4645
/** The Starlark object passed to the implementation function of module extension metadata. */
4746
@StarlarkBuiltin(
@@ -219,15 +218,19 @@ private static Optional<RootModuleFileFixup> generateFixup(
219218
Set<String> expectedImports,
220219
Set<String> expectedDevImports,
221220
EventHandler eventHandler) {
222-
var actualDevImports = ImmutableSet.copyOf(rootUsage.getDevImports());
221+
var actualDevImports =
222+
rootUsage.getProxies().stream()
223+
.filter(p -> p.isDevDependency())
224+
.flatMap(p -> p.getImports().values().stream())
225+
.collect(toImmutableSet());
223226
var actualImports =
224-
rootUsage.getImports().values().stream()
225-
.filter(repo -> !actualDevImports.contains(repo))
227+
rootUsage.getProxies().stream()
228+
.filter(p -> !p.isDevDependency())
229+
.flatMap(p -> p.getImports().values().stream())
226230
.collect(toImmutableSet());
227231

228232
String extensionBzlFile = rootUsage.getExtensionBzlFile();
229233
String extensionName = rootUsage.getExtensionName();
230-
Location location = rootUsage.getLocation();
231234

232235
var importsToAdd = ImmutableSortedSet.copyOf(Sets.difference(expectedImports, actualImports));
233236
var importsToRemove =
@@ -341,7 +344,7 @@ private static Optional<RootModuleFileFixup> generateFixup(
341344
.flatMap(Optional::stream)
342345
.collect(toImmutableList());
343346

344-
eventHandler.handle(Event.warn(location, message));
347+
eventHandler.handle(Event.warn(rootUsage.getProxies().getFirst().getLocation(), message));
345348
return Optional.of(new RootModuleFileFixup(buildozerCommands, rootUsage));
346349
}
347350

src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleExtensionUsage.java

Lines changed: 77 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,17 @@
1717
import static com.google.common.collect.ImmutableList.toImmutableList;
1818

1919
import com.google.auto.value.AutoValue;
20-
import com.google.common.collect.ImmutableBiMap;
2120
import com.google.common.collect.ImmutableList;
22-
import com.google.common.collect.ImmutableSet;
21+
import com.google.common.collect.ImmutableMap;
2322
import com.google.errorprone.annotations.CanIgnoreReturnValue;
2423
import com.ryanharter.auto.value.gson.GenerateTypeAdapter;
2524
import java.util.Optional;
2625
import net.starlark.java.syntax.Location;
2726

2827
/**
29-
* Represents one usage of a module extension in one MODULE.bazel file. This class records all the
30-
* information pertinent to the proxy object returned from the {@code use_extension} call.
28+
* Represents the usage of a module extension in one module. This class records all the information
29+
* pertinent to all the proxy objects returned from any {@code use_extension} calls in this module
30+
* that refer to the same extension (or isolate, when applicable).
3131
*
3232
* <p>When adding new fields, make sure to update {@link #trimForEvaluation()} as well.
3333
*/
@@ -49,40 +49,80 @@ public abstract class ModuleExtensionUsage {
4949
/** The module that contains this particular extension usage. */
5050
public abstract ModuleKey getUsingModule();
5151

52-
/**
53-
* The location where this proxy object was created (by the {@code use_extension} call). Note that
54-
* if there were multiple {@code use_extension} calls on same extension, then this only stores the
55-
* location of the first one.
56-
*/
57-
public abstract Location getLocation();
52+
/** Represents one "proxy object" returned from one {@code use_extension} call. */
53+
@AutoValue
54+
@GenerateTypeAdapter
55+
public abstract static class Proxy {
56+
/** The location of the {@code use_extension} call. */
57+
public abstract Location getLocation();
58+
59+
/**
60+
* The name of the proxy object; as in, the name that the return value of {@code use_extension}
61+
* is bound to. Is the empty string if the return value is not bound to any name (e.g. {@code
62+
* use_repo(use_extension(...))}).
63+
*/
64+
public abstract String getProxyName();
65+
66+
/** Whether {@code dev_dependency} is set to true. */
67+
public abstract boolean isDevDependency();
68+
69+
/**
70+
* All the repos imported, through this proxy, from this module extension into the scope of the
71+
* current module. The key is the local repo name (in the scope of the current module), and the
72+
* value is the name exported by the module extension.
73+
*/
74+
public abstract ImmutableMap<String, String> getImports();
75+
76+
public static Builder builder() {
77+
return new AutoValue_ModuleExtensionUsage_Proxy.Builder().setProxyName("");
78+
}
5879

59-
/**
60-
* All the repos imported from this module extension into the scope of the current module. The key
61-
* is the local repo name (in the scope of the current module), and the value is the name exported
62-
* by the module extension.
63-
*/
64-
public abstract ImmutableBiMap<String, String> getImports();
80+
/** Builder for {@link ModuleExtensionUsage.Proxy}. */
81+
@AutoValue.Builder
82+
public abstract static class Builder {
83+
public abstract Builder setLocation(Location value);
6584

66-
/**
67-
* The repo names as exported by the module extension that were imported using a proxy marked as a
68-
* dev dependency.
69-
*/
70-
public abstract ImmutableSet<String> getDevImports();
85+
public abstract String getProxyName();
86+
87+
public abstract Builder setProxyName(String value);
88+
89+
public abstract boolean isDevDependency();
90+
91+
public abstract Builder setDevDependency(boolean value);
92+
93+
abstract ImmutableMap.Builder<String, String> importsBuilder();
94+
95+
@CanIgnoreReturnValue
96+
public final Builder addImport(String key, String value) {
97+
importsBuilder().put(key, value);
98+
return this;
99+
}
100+
101+
public abstract Builder setImports(ImmutableMap<String, String> value);
102+
103+
public abstract Proxy build();
104+
}
105+
}
106+
107+
/** The list of proxy objects that constitute */
108+
public abstract ImmutableList<Proxy> getProxies();
71109

72110
/** All the tags specified by this module for this extension. */
73111
public abstract ImmutableList<Tag> getTags();
74112

75113
/**
76-
* Whether any <code>use_extension</code> calls for this usage had <code>dev_dependency = True
77-
* </code> set.*
114+
* Whether any {@code use_extension} calls for this usage had {@code dev_dependency = True} set.
78115
*/
79-
public abstract boolean getHasDevUseExtension();
116+
public final boolean getHasDevUseExtension() {
117+
return getProxies().stream().anyMatch(p -> p.isDevDependency());
118+
}
80119

81120
/**
82-
* Whether any <code>use_extension</code> calls for this usage had <code>dev_dependency = False
83-
* </code> set.*
121+
* Whether any {@code use_extension} calls for this usage had {@code dev_dependency = False} set.
84122
*/
85-
public abstract boolean getHasNonDevUseExtension();
123+
public final boolean getHasNonDevUseExtension() {
124+
return getProxies().stream().anyMatch(p -> !p.isDevDependency());
125+
}
86126

87127
public abstract Builder toBuilder();
88128

@@ -100,13 +140,12 @@ ModuleExtensionUsage trimForEvaluation() {
100140
// preserves correctness in case new fields are added without updating this code.
101141
return toBuilder()
102142
.setTags(getTags().stream().map(Tag::trimForEvaluation).collect(toImmutableList()))
143+
// Clear out all proxies as information contained therein isn't useful for evaluation.
103144
// Locations are only used for error reporting and thus don't influence whether the
104145
// evaluation of the extension is successful and what its result is in case of success.
105-
.setLocation(Location.BUILTIN)
106146
// Extension implementation functions do not see the imports, they are only validated
107147
// against the set of generated repos in a validation step that comes afterward.
108-
.setImports(ImmutableBiMap.of())
109-
.setDevImports(ImmutableSet.of())
148+
.setProxies(ImmutableList.of())
110149
.build();
111150
}
112151

@@ -122,26 +161,26 @@ public abstract static class Builder {
122161

123162
public abstract Builder setUsingModule(ModuleKey value);
124163

125-
public abstract Builder setLocation(Location value);
164+
public abstract Builder setProxies(ImmutableList<Proxy> value);
126165

127-
public abstract Builder setImports(ImmutableBiMap<String, String> value);
166+
abstract ImmutableList.Builder<Proxy> proxiesBuilder();
128167

129-
public abstract Builder setDevImports(ImmutableSet<String> value);
168+
@CanIgnoreReturnValue
169+
public Builder addProxy(Proxy value) {
170+
proxiesBuilder().add(value);
171+
return this;
172+
}
130173

131174
public abstract Builder setTags(ImmutableList<Tag> value);
132175

133176
abstract ImmutableList.Builder<Tag> tagsBuilder();
134177

135178
@CanIgnoreReturnValue
136-
public ModuleExtensionUsage.Builder addTag(Tag value) {
179+
public Builder addTag(Tag value) {
137180
tagsBuilder().add(value);
138181
return this;
139182
}
140183

141-
public abstract Builder setHasDevUseExtension(boolean hasDevUseExtension);
142-
143-
public abstract Builder setHasNonDevUseExtension(boolean hasNonDevUseExtension);
144-
145184
public abstract ModuleExtensionUsage build();
146185
}
147186
}

src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunction.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,13 +445,14 @@ public static RootModuleFileValue evaluateRootModuleFile(
445445
throw errorf(Code.BAD_MODULE, "error executing MODULE.bazel file for the root module");
446446
}
447447
for (ModuleExtensionUsage usage : module.getExtensionUsages()) {
448-
if (usage.getIsolationKey().isPresent() && usage.getImports().isEmpty()) {
448+
ModuleExtensionUsage.Proxy firstProxy = usage.getProxies().getFirst();
449+
if (usage.getIsolationKey().isPresent() && firstProxy.getImports().isEmpty()) {
449450
throw errorf(
450451
Code.BAD_MODULE,
451452
"the isolated usage at %s of extension %s defined in %s has no effect as no "
452453
+ "repositories are imported from it. Either import one or more repositories "
453454
+ "generated by the extension with use_repo or remove the usage.",
454-
usage.getLocation(),
455+
firstProxy.getLocation(),
455456
usage.getExtensionName(),
456457
usage.getExtensionBzlFile());
457458
}

0 commit comments

Comments
 (0)