Skip to content

Commit 2659f49

Browse files
fmeumcopybara-github
authored andcommitted
Include actual MODULE.bazel location in stack traces
Instead of `<name>@<version>/MODULE.bazel`, the actual location of a MODULE.bazel file is now reported in stack traces, either as a file path or a URL. Closes #18572. PiperOrigin-RevId: 538597414 Change-Id: I038e070d9bd4397bba2ed491597cadd0b56d6481
1 parent 10fb5f6 commit 2659f49

File tree

10 files changed

+110
-47
lines changed

10 files changed

+110
-47
lines changed

src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ java_library(
1616
srcs = [
1717
"ArchiveRepoSpecBuilder.java",
1818
"AttributeValues.java",
19+
"ModuleFile.java",
1920
"ModuleKey.java",
2021
"RepoSpec.java",
2122
"Version.java",

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,12 @@ private Optional<byte[]> grabFile(String url, ExtendedEventHandler eventHandler)
8888
}
8989

9090
@Override
91-
public Optional<byte[]> getModuleFile(ModuleKey key, ExtendedEventHandler eventHandler)
91+
public Optional<ModuleFile> getModuleFile(ModuleKey key, ExtendedEventHandler eventHandler)
9292
throws IOException, InterruptedException {
93-
return grabFile(
93+
String url =
9494
constructUrl(
95-
getUrl(), "modules", key.getName(), key.getVersion().toString(), "MODULE.bazel"),
96-
eventHandler);
95+
getUrl(), "modules", key.getName(), key.getVersion().toString(), "MODULE.bazel");
96+
return grabFile(url, eventHandler).map(content -> ModuleFile.create(content, url));
9797
}
9898

9999
/** Represents fields available in {@code bazel_registry.json} for the registry. */
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2023 The Bazel Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
16+
package com.google.devtools.build.lib.bazel.bzlmod;
17+
18+
import com.google.auto.value.AutoValue;
19+
20+
/** A MODULE.bazel file's content and location. */
21+
@AutoValue
22+
public abstract class ModuleFile {
23+
/** The raw content of the module file. */
24+
@SuppressWarnings("mutable")
25+
public abstract byte[] getContent();
26+
27+
/** The user-facing location of the module file, e.g. a file system path or URL. */
28+
public abstract String getLocation();
29+
30+
public static ModuleFile create(byte[] content, String location) {
31+
return new AutoValue_ModuleFile(content, location);
32+
}
33+
}

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

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,11 @@ public SkyValue compute(SkyKey skyKey, Environment env)
110110
return null;
111111
}
112112
String moduleFileHash =
113-
new Fingerprint().addBytes(getModuleFileResult.moduleFileContents).hexDigestAndReset();
113+
new Fingerprint().addBytes(getModuleFileResult.moduleFile.getContent()).hexDigestAndReset();
114114

115115
ModuleFileGlobals moduleFileGlobals =
116116
execModuleFile(
117-
getModuleFileResult.moduleFileContents,
117+
getModuleFileResult.moduleFile,
118118
getModuleFileResult.registry,
119119
moduleKey,
120120
// Dev dependencies should always be ignored if the current module isn't the root module
@@ -151,8 +151,8 @@ private SkyValue computeForRootModule(StarlarkSemantics starlarkSemantics, Envir
151151
if (env.getValue(FileValue.key(moduleFilePath)) == null) {
152152
return null;
153153
}
154-
byte[] moduleFile = readFile(moduleFilePath.asPath());
155-
String moduleFileHash = new Fingerprint().addBytes(moduleFile).hexDigestAndReset();
154+
ModuleFile moduleFile = readModuleFile(moduleFilePath.asPath());
155+
String moduleFileHash = new Fingerprint().addBytes(moduleFile.getContent()).hexDigestAndReset();
156156
ModuleFileGlobals moduleFileGlobals =
157157
execModuleFile(
158158
moduleFile,
@@ -189,15 +189,15 @@ private SkyValue computeForRootModule(StarlarkSemantics starlarkSemantics, Envir
189189
}
190190

191191
private ModuleFileGlobals execModuleFile(
192-
byte[] moduleFile,
192+
ModuleFile moduleFile,
193193
@Nullable Registry registry,
194194
ModuleKey moduleKey,
195195
boolean ignoreDevDeps,
196196
StarlarkSemantics starlarkSemantics,
197197
Environment env)
198198
throws ModuleFileFunctionException, InterruptedException {
199199
StarlarkFile starlarkFile =
200-
StarlarkFile.parse(ParserInput.fromUTF8(moduleFile, moduleKey + "/MODULE.bazel"));
200+
StarlarkFile.parse(ParserInput.fromUTF8(moduleFile.getContent(), moduleFile.getLocation()));
201201
if (!starlarkFile.ok()) {
202202
Event.replayEventsOn(env.getListener(), starlarkFile.errors());
203203
throw errorf(Code.BAD_MODULE, "error parsing MODULE.bazel file for %s", moduleKey);
@@ -224,7 +224,7 @@ private ModuleFileGlobals execModuleFile(
224224
}
225225

226226
private static class GetModuleFileResult {
227-
byte[] moduleFileContents;
227+
ModuleFile moduleFile;
228228
// `registry` can be null if this module has a non-registry override.
229229
@Nullable Registry registry;
230230
}
@@ -249,7 +249,7 @@ private GetModuleFileResult getModuleFile(
249249
return null;
250250
}
251251
GetModuleFileResult result = new GetModuleFileResult();
252-
result.moduleFileContents = readFile(moduleFilePath.asPath());
252+
result.moduleFile = readModuleFile(moduleFilePath.asPath());
253253
return result;
254254
}
255255

@@ -285,11 +285,11 @@ private GetModuleFileResult getModuleFile(
285285
GetModuleFileResult result = new GetModuleFileResult();
286286
for (Registry registry : registryObjects) {
287287
try {
288-
Optional<byte[]> moduleFile = registry.getModuleFile(key, env.getListener());
289-
if (!moduleFile.isPresent()) {
288+
Optional<ModuleFile> moduleFile = registry.getModuleFile(key, env.getListener());
289+
if (moduleFile.isEmpty()) {
290290
continue;
291291
}
292-
result.moduleFileContents = moduleFile.get();
292+
result.moduleFile = moduleFile.get();
293293
result.registry = registry;
294294
return result;
295295
} catch (IOException e) {
@@ -301,9 +301,10 @@ private GetModuleFileResult getModuleFile(
301301
throw errorf(Code.MODULE_NOT_FOUND, "module not found in registries: %s", key);
302302
}
303303

304-
private static byte[] readFile(Path path) throws ModuleFileFunctionException {
304+
private static ModuleFile readModuleFile(Path path) throws ModuleFileFunctionException {
305305
try {
306-
return FileSystemUtils.readWithKnownFileSize(path, path.getFileSize());
306+
return ModuleFile.create(
307+
FileSystemUtils.readWithKnownFileSize(path, path.getFileSize()), path.getPathString());
307308
} catch (IOException e) {
308309
throw errorf(Code.MODULE_NOT_FOUND, "MODULE.bazel expected but not found at %s", path);
309310
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public interface Registry {
3131
* Retrieves the contents of the module file of the module identified by {@code key} from the
3232
* registry. Returns {@code Optional.empty()} when the module is not found in this registry.
3333
*/
34-
Optional<byte[]> getModuleFile(ModuleKey key, ExtendedEventHandler eventHandler)
34+
Optional<ModuleFile> getModuleFile(ModuleKey key, ExtendedEventHandler eventHandler)
3535
throws IOException, InterruptedException;
3636

3737
/**

src/test/java/com/google/devtools/build/lib/bazel/bzlmod/FakeRegistry.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,16 @@ public String getUrl() {
6363
}
6464

6565
@Override
66-
public Optional<byte[]> getModuleFile(ModuleKey key, ExtendedEventHandler eventHandler) {
67-
return Optional.ofNullable(modules.get(key)).map(value -> value.getBytes(UTF_8));
66+
public Optional<ModuleFile> getModuleFile(ModuleKey key, ExtendedEventHandler eventHandler) {
67+
return Optional.ofNullable(modules.get(key))
68+
.map(value -> value.getBytes(UTF_8))
69+
.map(
70+
content ->
71+
ModuleFile.create(
72+
content,
73+
String.format(
74+
"%s/modules/%s/%s/MODULE.bazel",
75+
url, key.getName(), key.getVersion().toString())));
6876
}
6977

7078
@Override

src/test/java/com/google/devtools/build/lib/bazel/bzlmod/IndexRegistryTest.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ public void testHttpUrl() throws Exception {
7272

7373
Registry registry = registryFactory.getRegistryWithUrl(server.getUrl() + "/myreg");
7474
assertThat(registry.getModuleFile(createModuleKey("foo", "1.0"), reporter))
75-
.hasValue("lol".getBytes(UTF_8));
75+
.hasValue(
76+
ModuleFile.create(
77+
"lol".getBytes(UTF_8), server.getUrl() + "/myreg/modules/foo/1.0/MODULE.bazel"));
7678
assertThat(registry.getModuleFile(createModuleKey("bar", "1.0"), reporter)).isEmpty();
7779
}
7880

@@ -94,7 +96,9 @@ public void testHttpUrlWithNetrcCreds() throws Exception {
9496

9597
downloadManager.setNetrcCreds(new NetrcCredentials(netrc));
9698
assertThat(registry.getModuleFile(createModuleKey("foo", "1.0"), reporter))
97-
.hasValue("lol".getBytes(UTF_8));
99+
.hasValue(
100+
ModuleFile.create(
101+
"lol".getBytes(UTF_8), server.getUrl() + "/myreg/modules/foo/1.0/MODULE.bazel"));
98102
assertThat(registry.getModuleFile(createModuleKey("bar", "1.0"), reporter)).isEmpty();
99103
}
100104

@@ -110,7 +114,7 @@ public void testFileUrl() throws Exception {
110114
registryFactory.getRegistryWithUrl(
111115
new File(tempFolder.getRoot(), "fakereg").toURI().toString());
112116
assertThat(registry.getModuleFile(createModuleKey("foo", "1.0"), reporter))
113-
.hasValue("lol".getBytes(UTF_8));
117+
.hasValue(ModuleFile.create("lol".getBytes(UTF_8), file.toURI().toString()));
114118
assertThat(registry.getModuleFile(createModuleKey("bar", "1.0"), reporter)).isEmpty();
115119
}
116120

src/test/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleExtensionResolutionTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,7 +1191,7 @@ public void importNonExistentRepo() throws Exception {
11911191
.contains(
11921192
"module extension \"ext\" from \"//:defs.bzl\" does not generate repository"
11931193
+ " \"missing_repo\", yet it is imported as \"my_repo\" in the usage at"
1194-
+ " <root>/MODULE.bazel:1:20");
1194+
+ " /ws/MODULE.bazel:1:20");
11951195
}
11961196

11971197
@Test
@@ -1658,7 +1658,7 @@ public void extensionMetadata() throws Exception {
16581658

16591659
assertEventCount(1, eventCollector);
16601660
assertContainsEvent(
1661-
"WARNING <root>/MODULE.bazel:3:20: The module extension ext defined in @ext//:defs.bzl"
1661+
"WARNING /ws/MODULE.bazel:3:20: The module extension ext defined in @ext//:defs.bzl"
16621662
+ " reported incorrect imports of repositories via use_repo():\n"
16631663
+ "\n"
16641664
+ "Imported, but not created by the extension (will cause the build to fail):\n"
@@ -1736,11 +1736,11 @@ public void extensionMetadata_all() throws Exception {
17361736
.isEqualTo(
17371737
"module extension \"ext\" from \"@ext~1.0//:defs.bzl\" does not generate repository "
17381738
+ "\"invalid_dep\", yet it is imported as \"invalid_dep\" in the usage at "
1739-
+ "<root>/MODULE.bazel:3:20");
1739+
+ "/ws/MODULE.bazel:3:20");
17401740

17411741
assertEventCount(1, eventCollector);
17421742
assertContainsEvent(
1743-
"WARNING <root>/MODULE.bazel:3:20: The module extension ext defined in @ext//:defs.bzl"
1743+
"WARNING /ws/MODULE.bazel:3:20: The module extension ext defined in @ext//:defs.bzl"
17441744
+ " reported incorrect imports of repositories via use_repo():\n"
17451745
+ "\n"
17461746
+ "Imported, but not created by the extension (will cause the build to fail):\n"
@@ -1815,11 +1815,11 @@ public void extensionMetadata_allDev() throws Exception {
18151815
.isEqualTo(
18161816
"module extension \"ext\" from \"@ext~1.0//:defs.bzl\" does not generate repository "
18171817
+ "\"invalid_dep\", yet it is imported as \"invalid_dep\" in the usage at "
1818-
+ "<root>/MODULE.bazel:3:20");
1818+
+ "/ws/MODULE.bazel:3:20");
18191819

18201820
assertEventCount(1, eventCollector);
18211821
assertContainsEvent(
1822-
"WARNING <root>/MODULE.bazel:3:20: The module extension ext defined in @ext//:defs.bzl"
1822+
"WARNING /ws/MODULE.bazel:3:20: The module extension ext defined in @ext//:defs.bzl"
18231823
+ " reported incorrect imports of repositories via use_repo():\n"
18241824
+ "\n"
18251825
+ "Imported, but not created by the extension (will cause the build to fail):\n"

0 commit comments

Comments
 (0)