From 23518b8df6bee3ca35202d942bfbd041ba7ca8f8 Mon Sep 17 00:00:00 2001 From: salma-samy Date: Tue, 11 Apr 2023 04:32:44 -0700 Subject: [PATCH] Add repospec to the module - With this we can get the repospec directly from the module not the registry (no need for internet access) - Since Repospec & Tag classes have an "attributes" field that can hold starlark values, an adapter was needed to serialize/deserialize starlark values PiperOrigin-RevId: 523364539 Change-Id: Ifcdf0c6b4b6fbbcdae9c14a4b0cd7f53ae91c161 --- .../lib/bazel/BazelRepositoryModule.java | 10 +- .../bazel/bzlmod/ArchiveRepoSpecBuilder.java | 2 +- .../lib/bazel/bzlmod/AttributeValues.java | 58 +++++++ .../bazel/bzlmod/AttributeValuesAdapter.java | 156 ++++++++++++++++++ .../devtools/build/lib/bazel/bzlmod/BUILD | 3 + .../bazel/bzlmod/BazelDepGraphFunction.java | 6 +- .../bazel/bzlmod/BazelLockFileFunction.java | 13 +- .../lib/bazel/bzlmod/BazelLockFileValue.java | 1 + .../bzlmod/BazelModuleResolutionFunction.java | 50 +++++- .../build/lib/bazel/bzlmod/GitOverride.java | 2 +- .../lib/bazel/bzlmod/GsonTypeAdapterUtil.java | 38 +---- .../build/lib/bazel/bzlmod/IndexRegistry.java | 5 +- .../lib/bazel/bzlmod/LocalPathOverride.java | 3 +- .../build/lib/bazel/bzlmod/Module.java | 13 +- .../lib/bazel/bzlmod/ModuleFileGlobals.java | 2 +- .../lib/bazel/bzlmod/ModuleFileValue.java | 4 +- .../build/lib/bazel/bzlmod/RepoSpec.java | 16 +- .../devtools/build/lib/bazel/bzlmod/Tag.java | 5 +- .../lib/bazel/bzlmod/TypeCheckedTag.java | 2 +- .../lib/skyframe/BzlmodRepoRuleFunction.java | 90 +++------- .../build/lib/analysis/util/AnalysisMock.java | 4 +- .../bzlmod/AttributeValuesAdapterTest.java | 71 ++++++++ .../devtools/build/lib/bazel/bzlmod/BUILD | 1 + .../bzlmod/BazelDepGraphFunctionTest.java | 8 +- .../bzlmod/BazelLockFileFunctionTest.java | 10 +- .../BazelModuleResolutionFunctionTest.java | 8 +- .../bzlmod/BzlmodRepoRuleFunctionTest.java | 59 ++++++- .../lib/bazel/bzlmod/BzlmodTestUtil.java | 2 +- .../build/lib/bazel/bzlmod/FakeRegistry.java | 5 +- .../lib/bazel/bzlmod/IndexRegistryTest.java | 4 +- .../bzlmod/ModuleExtensionResolutionTest.java | 8 +- .../bazel/bzlmod/ModuleFileFunctionTest.java | 77 +++++---- .../build/lib/bazel/bzlmod/RepoSpecTest.java | 13 +- .../repository/RepositoryDelegatorTest.java | 4 +- 34 files changed, 530 insertions(+), 223 deletions(-) create mode 100644 src/main/java/com/google/devtools/build/lib/bazel/bzlmod/AttributeValues.java create mode 100644 src/main/java/com/google/devtools/build/lib/bazel/bzlmod/AttributeValuesAdapter.java create mode 100644 src/test/java/com/google/devtools/build/lib/bazel/bzlmod/AttributeValuesAdapterTest.java diff --git a/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java b/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java index 9e16cbf75f3385..e20e15d35819c1 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java @@ -25,6 +25,7 @@ import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue; +import com.google.devtools.build.lib.bazel.bzlmod.AttributeValues; import com.google.devtools.build.lib.bazel.bzlmod.BazelDepGraphFunction; import com.google.devtools.build.lib.bazel.bzlmod.BazelLockFileFunction; import com.google.devtools.build.lib.bazel.bzlmod.BazelModuleInspectorFunction; @@ -233,7 +234,8 @@ public void workspaceInit( public RepoSpec getRepoSpec(RepositoryName repoName) { return RepoSpec.builder() .setRuleClassName("local_config_platform") - .setAttributes(ImmutableMap.of("name", repoName.getName())) + .setAttributes( + AttributeValues.create(ImmutableMap.of("name", repoName.getName()))) .build(); } @@ -251,11 +253,9 @@ public ResolutionReason getResolutionReason() { SkyFunctions.MODULE_FILE, new ModuleFileFunction(registryFactory, directories.getWorkspace(), builtinModules)) .addSkyFunction( - SkyFunctions.BAZEL_DEP_GRAPH, - new BazelDepGraphFunction(directories.getWorkspace(), registryFactory)) + SkyFunctions.BAZEL_DEP_GRAPH, new BazelDepGraphFunction(directories.getWorkspace())) .addSkyFunction( - SkyFunctions.BAZEL_LOCK_FILE, - new BazelLockFileFunction(directories.getWorkspace(), registryFactory)) + SkyFunctions.BAZEL_LOCK_FILE, new BazelLockFileFunction(directories.getWorkspace())) .addSkyFunction(SkyFunctions.BAZEL_MODULE_INSPECTION, new BazelModuleInspectorFunction()) .addSkyFunction(SkyFunctions.BAZEL_MODULE_RESOLUTION, new BazelModuleResolutionFunction()) .addSkyFunction(SkyFunctions.SINGLE_EXTENSION_EVAL, singleExtensionEvalFunction) diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ArchiveRepoSpecBuilder.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ArchiveRepoSpecBuilder.java index 122cc45d2f0f0a..cce77aa47fd3f5 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ArchiveRepoSpecBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ArchiveRepoSpecBuilder.java @@ -98,7 +98,7 @@ public RepoSpec build() { return RepoSpec.builder() .setBzlFile("@bazel_tools//tools/build_defs/repo:http.bzl") .setRuleClassName("http_archive") - .setAttributes(attrBuilder.buildOrThrow()) + .setAttributes(AttributeValues.create(attrBuilder.buildOrThrow())) .build(); } } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/AttributeValues.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/AttributeValues.java new file mode 100644 index 00000000000000..d73e4ac443bff9 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/AttributeValues.java @@ -0,0 +1,58 @@ +// 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.bazel.bzlmod; + +import com.google.auto.value.AutoValue; +import com.google.common.collect.Maps; +import com.ryanharter.auto.value.gson.GenerateTypeAdapter; +import java.util.List; +import java.util.Map; +import net.starlark.java.eval.Dict; +import net.starlark.java.eval.Starlark; + +/** Wraps a dictionary of attribute names and values. Always uses a dict to represent them */ +@AutoValue +@GenerateTypeAdapter +public abstract class AttributeValues { + + public static AttributeValues create(Dict attribs) { + return new AutoValue_AttributeValues(attribs); + } + + public static AttributeValues create(Map attribs) { + return new AutoValue_AttributeValues( + Dict.immutableCopyOf(Maps.transformValues(attribs, AttributeValues::valueToStarlark))); + } + + public abstract Dict attributes(); + + // TODO(salmasamy) this is a copy of Attribute::valueToStarlark, Maybe think of a better place? + private static Object valueToStarlark(Object x) { + // Is x a non-empty string_list_dict? + if (x instanceof Map) { + Map map = (Map) x; + if (!map.isEmpty() && map.values().iterator().next() instanceof List) { + Dict.Builder dict = Dict.builder(); + for (Map.Entry e : map.entrySet()) { + dict.put(e.getKey(), Starlark.fromJava(e.getValue(), null)); + } + return dict.buildImmutable(); + } + } + // For all other attribute values, shallow conversion is safe. + return Starlark.fromJava(x, null); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/AttributeValuesAdapter.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/AttributeValuesAdapter.java new file mode 100644 index 00000000000000..c178ed60717e01 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/AttributeValuesAdapter.java @@ -0,0 +1,156 @@ +// 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.bazel.bzlmod; + +import com.google.devtools.build.lib.cmdline.Label; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonNull; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonPrimitive; +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import net.starlark.java.eval.Dict; +import net.starlark.java.eval.EvalException; +import net.starlark.java.eval.Mutability; +import net.starlark.java.eval.Starlark; +import net.starlark.java.eval.StarlarkInt; +import net.starlark.java.eval.StarlarkList; + +/** Helps serialize/deserialize {@link AttributeValues}, which contains Starlark values. */ +public class AttributeValuesAdapter extends TypeAdapter { + + @Override + public void write(JsonWriter out, AttributeValues attributeValues) throws IOException { + JsonObject jsonObject = new JsonObject(); + for (Map.Entry entry : attributeValues.attributes().entrySet()) { + jsonObject.add(entry.getKey(), serializeObject(entry.getValue())); + } + out.jsonValue(jsonObject.toString()); + } + + @Override + public AttributeValues read(JsonReader in) throws IOException { + JsonObject jsonObject = JsonParser.parseReader(in).getAsJsonObject(); + Dict.Builder dict = Dict.builder(); + for (Map.Entry entry : jsonObject.entrySet()) { + dict.put(entry.getKey(), deserializeObject(entry.getValue())); + } + return AttributeValues.create(dict.buildImmutable()); + } + + /** + * Starlark Object Types Bool Integer String Label List (Int, label, string) Dict (String,list) & + * (Label, String) + */ + private JsonElement serializeObject(Object obj) { + if (obj.equals(Starlark.NONE)) { + return JsonNull.INSTANCE; + } else if (obj instanceof Boolean) { + return new JsonPrimitive((Boolean) obj); + } else if (obj instanceof StarlarkInt) { + try { + return new JsonPrimitive(((StarlarkInt) obj).toInt("serialization into the lockfile")); + } catch (EvalException e) { + throw new IllegalArgumentException("Unable to parse StarlarkInt to Integer: " + e); + } + } else if (obj instanceof String || obj instanceof Label) { + return new JsonPrimitive(serializeObjToString(obj)); + } else if (obj instanceof Dict) { + JsonObject jsonObject = new JsonObject(); + for (Map.Entry entry : ((Dict) obj).entrySet()) { + jsonObject.add(serializeObjToString(entry.getKey()), serializeObject(entry.getValue())); + } + return jsonObject; + } else if (obj instanceof StarlarkList) { + JsonArray jsonArray = new JsonArray(); + for (Object item : (StarlarkList) obj) { + jsonArray.add(serializeObject(item)); + } + return jsonArray; + } else { + throw new IllegalArgumentException("Unsupported type: " + obj.getClass()); + } + } + + private Object deserializeObject(JsonElement json) { + if (json == null || json.isJsonNull()) { + return Starlark.NONE; + } else if (json.isJsonPrimitive()) { + JsonPrimitive jsonPrimitive = json.getAsJsonPrimitive(); + if (jsonPrimitive.isBoolean()) { + return jsonPrimitive.getAsBoolean(); + } else if (jsonPrimitive.isNumber()) { + return StarlarkInt.of(jsonPrimitive.getAsInt()); + } else if (jsonPrimitive.isString()) { + return deserializeStringToObject(jsonPrimitive.getAsString()); + } else { + throw new IllegalArgumentException("Unsupported JSON primitive: " + jsonPrimitive); + } + } else if (json.isJsonObject()) { + JsonObject jsonObject = json.getAsJsonObject(); + Dict.Builder dict = Dict.builder(); + for (Map.Entry entry : jsonObject.entrySet()) { + dict.put(deserializeStringToObject(entry.getKey()), deserializeObject(entry.getValue())); + } + return dict.buildImmutable(); + } else if (json.isJsonArray()) { + JsonArray jsonArray = json.getAsJsonArray(); + List list = new ArrayList<>(); + for (JsonElement item : jsonArray) { + list.add(deserializeObject(item)); + } + return StarlarkList.copyOf(Mutability.IMMUTABLE, list); + } else { + throw new IllegalArgumentException("Unsupported JSON element: " + json); + } + } + + /** + * Serializes an object (Label or String) to String A label is converted to a String as it is. A + * String is being modified with a delimiter to be easily differentiated from the label when + * deserializing. + * + * @param obj String or Label + * @return serialized object + */ + private String serializeObjToString(Object obj) { + if (obj instanceof Label) { + return ((Label) obj).getUnambiguousCanonicalForm(); + } + return "--" + obj; + } + + /** + * Deserializes a string to either a label or a String depending on the prefix. A string will have + * a delimiter at the start, else it is converted to a label. + * + * @param value String to be deserialized + * @return Object of type String of Label + */ + private Object deserializeStringToObject(String value) { + if (value.startsWith("--")) { + return value.substring(2); + } + return Label.parseCanonicalUnchecked(value); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD index be8f1938dd6884..218bfdf05f9202 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD @@ -15,6 +15,7 @@ java_library( name = "common", srcs = [ "ArchiveRepoSpecBuilder.java", + "AttributeValues.java", "ModuleKey.java", "RepoSpec.java", "Version.java", @@ -51,6 +52,7 @@ java_library( "TagClass.java", ], deps = [ + ":common", "//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/lib/starlarkbuildapi/repository", @@ -129,6 +131,7 @@ java_library( java_library( name = "resolution_impl", srcs = [ + "AttributeValuesAdapter.java", "BazelDepGraphFunction.java", "BazelLockFileFunction.java", "BazelModuleResolutionFunction.java", diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelDepGraphFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelDepGraphFunction.java index c33ce992c9c299..c8d616d0b70f6c 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelDepGraphFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelDepGraphFunction.java @@ -54,11 +54,9 @@ public class BazelDepGraphFunction implements SkyFunction { private final Path rootDirectory; - private final RegistryFactory registryFactory; - public BazelDepGraphFunction(Path rootDirectory, RegistryFactory registryFactory) { + public BazelDepGraphFunction(Path rootDirectory) { this.rootDirectory = rootDirectory; - this.registryFactory = registryFactory; } @Override @@ -105,7 +103,7 @@ public SkyValue compute(SkyKey skyKey, Environment env) depGraph = selectionResult.getResolvedDepGraph(); if (starlarkSemantics.getBool(BuildLanguageOptions.ENABLE_LOCKFILE)) { BazelLockFileFunction.updateLockedModule( - root.getModuleFileHash(), depGraph, rootDirectory, registryFactory, flags); + root.getModuleFileHash(), depGraph, rootDirectory, flags); } } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileFunction.java index 99d0c049dd7de0..5709ad4925d3fd 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileFunction.java @@ -15,6 +15,7 @@ package com.google.devtools.build.lib.bazel.bzlmod; +import static com.google.devtools.build.lib.bazel.bzlmod.GsonTypeAdapterUtil.LOCKFILE_GSON; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.collect.ImmutableList; @@ -32,7 +33,6 @@ import com.google.devtools.build.skyframe.SkyFunctionException.Transience; import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyValue; -import com.google.gson.Gson; import com.google.gson.JsonIOException; import java.io.FileNotFoundException; import java.io.IOException; @@ -42,7 +42,6 @@ public class BazelLockFileFunction implements SkyFunction { private final Path rootDirectory; - private final RegistryFactory registryFactory; private static final BzlmodFlagsAndEnvVars EMPTY_FLAGS = BzlmodFlagsAndEnvVars.create( @@ -52,9 +51,8 @@ public class BazelLockFileFunction implements SkyFunction { BazelLockFileValue.create( BazelLockFileValue.LOCK_FILE_VERSION, "", EMPTY_FLAGS, ImmutableMap.of()); - public BazelLockFileFunction(Path rootDirectory, RegistryFactory registryFactory) { + public BazelLockFileFunction(Path rootDirectory) { this.rootDirectory = rootDirectory; - this.registryFactory = registryFactory; } @Override @@ -70,10 +68,9 @@ public SkyValue compute(SkyKey skyKey, Environment env) } BazelLockFileValue bazelLockFileValue; - Gson gson = GsonTypeAdapterUtil.getLockfileGsonWithTypeAdapters(registryFactory); try { String json = FileSystemUtils.readContent(lockfilePath.asPath(), UTF_8); - bazelLockFileValue = gson.fromJson(json, BazelLockFileValue.class); + bazelLockFileValue = LOCKFILE_GSON.fromJson(json, BazelLockFileValue.class); } catch (FileNotFoundException e) { bazelLockFileValue = EMPTY_LOCKFILE; } catch (IOException ex) { @@ -92,7 +89,6 @@ public static void updateLockedModule( String hashedModule, ImmutableMap resolvedDepGraph, Path rootDirectory, - RegistryFactory registryFactory, BzlmodFlagsAndEnvVars flags) throws BazelModuleResolutionFunctionException { RootedPath lockfilePath = @@ -101,9 +97,8 @@ public static void updateLockedModule( BazelLockFileValue value = BazelLockFileValue.create( BazelLockFileValue.LOCK_FILE_VERSION, hashedModule, flags, resolvedDepGraph); - Gson gson = GsonTypeAdapterUtil.getLockfileGsonWithTypeAdapters(registryFactory); try { - FileSystemUtils.writeContent(lockfilePath.asPath(), UTF_8, gson.toJson(value)); + FileSystemUtils.writeContent(lockfilePath.asPath(), UTF_8, LOCKFILE_GSON.toJson(value)); } catch (IOException e) { throw new BazelModuleResolutionFunctionException( ExternalDepsException.withCauseAndMessage( diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileValue.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileValue.java index 0ff4315b7d2e6c..15a81bb2b49a78 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileValue.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileValue.java @@ -55,4 +55,5 @@ public static BazelLockFileValue create( /** The post-selection dep graph retrieved from the lock file. */ public abstract ImmutableMap getModuleDepGraph(); + } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelModuleResolutionFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelModuleResolutionFunction.java index f7bb9253476dd6..3c9f1c825e6c97 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelModuleResolutionFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelModuleResolutionFunction.java @@ -109,7 +109,35 @@ public SkyValue compute(SkyKey skyKey, Environment env) Objects.requireNonNull(ALLOWED_YANKED_VERSIONS.get(env))), env.getListener()); - return selectionResultValue; + // Add repo spec to each module and remove registry + try { + ImmutableMap.Builder mapBuilder = ImmutableMap.builder(); + for (Map.Entry entry : resolvedDepGraph.entrySet()) { + Module module = entry.getValue(); + // Only change modules with registry (not overridden) + if (module.getRegistry() != null) { + RepoSpec moduleRepoSpec = + module + .getRegistry() + .getRepoSpec(module.getKey(), module.getCanonicalRepoName(), env.getListener()); + ModuleOverride override = root.getOverrides().get(entry.getKey().getName()); + moduleRepoSpec = maybeAppendAdditionalPatches(moduleRepoSpec, override); + module = module.toBuilder().setRepoSpec(moduleRepoSpec).setRegistry(null).build(); + } + mapBuilder.put(entry.getKey(), module); + } + resolvedDepGraph = mapBuilder.buildOrThrow(); + } catch (IOException e) { + throw new BazelModuleResolutionFunctionException( + ExternalDepsException.withMessage( + Code.ERROR_ACCESSING_REGISTRY, + "Unable to get module repo spec from registry: %s", + e.getMessage()), + Transience.PERSISTENT); + } + + return BazelModuleResolutionValue.create( + resolvedDepGraph, selectionResultValue.getUnprunedDepGraph()); } private static void verifyRootModuleDirectDepsAreAccurate( @@ -321,6 +349,26 @@ private void verifyYankedVersions( } } + private RepoSpec maybeAppendAdditionalPatches(RepoSpec repoSpec, ModuleOverride override) { + if (!(override instanceof SingleVersionOverride)) { + return repoSpec; + } + SingleVersionOverride singleVersion = (SingleVersionOverride) override; + if (singleVersion.getPatches().isEmpty()) { + return repoSpec; + } + ImmutableMap.Builder attrBuilder = ImmutableMap.builder(); + attrBuilder.putAll(repoSpec.attributes().attributes()); + attrBuilder.put("patches", singleVersion.getPatches()); + attrBuilder.put("patch_cmds", singleVersion.getPatchCmds()); + attrBuilder.put("patch_args", ImmutableList.of("-p" + singleVersion.getPatchStrip())); + return RepoSpec.builder() + .setBzlFile(repoSpec.bzlFile()) + .setRuleClassName(repoSpec.ruleClassName()) + .setAttributes(AttributeValues.create(attrBuilder.buildOrThrow())) + .build(); + } + static class BazelModuleResolutionFunctionException extends SkyFunctionException { BazelModuleResolutionFunctionException(ExternalDepsException e, Transience transience) { super(e, transience); diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/GitOverride.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/GitOverride.java index 6270a43fea7658..4b264cf098be32 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/GitOverride.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/GitOverride.java @@ -62,7 +62,7 @@ public RepoSpec getRepoSpec(RepositoryName repoName) { return RepoSpec.builder() .setBzlFile("@bazel_tools//tools/build_defs/repo:git.bzl") .setRuleClassName("git_repository") - .setAttributes(attrBuilder.buildOrThrow()) + .setAttributes(AttributeValues.create(attrBuilder.buildOrThrow())) .build(); } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/GsonTypeAdapterUtil.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/GsonTypeAdapterUtil.java index 048c39cf883734..6110dc77f1a549 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/GsonTypeAdapterUtil.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/GsonTypeAdapterUtil.java @@ -20,7 +20,6 @@ import static com.google.devtools.build.lib.bazel.bzlmod.DelegateTypeAdapterFactory.IMMUTABLE_MAP; import com.google.common.base.Splitter; -import com.google.common.base.VerifyException; import com.google.devtools.build.lib.bazel.bzlmod.Version.ParseException; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -30,7 +29,6 @@ import com.google.gson.stream.JsonWriter; import com.ryanharter.auto.value.gson.GenerateTypeAdapter; import java.io.IOException; -import java.net.URISyntaxException; import java.util.List; /** @@ -89,25 +87,7 @@ public ModuleKey read(JsonReader jsonReader) throws IOException { } }; - public static TypeAdapter registryTypeAdapter(RegistryFactory registryFactory) { - return new TypeAdapter<>() { - @Override - public void write(JsonWriter jsonWriter, Registry registry) throws IOException { - jsonWriter.value(registry.getUrl()); - } - - @Override - public Registry read(JsonReader jsonReader) throws IOException { - try { - return registryFactory.getRegistryWithUrl(jsonReader.nextString()); - } catch (URISyntaxException e) { - throw new VerifyException("Lockfile registry URL is not valid", e); - } - } - }; - } - - private static final GsonBuilder adapterGson = + public static final Gson LOCKFILE_GSON = new GsonBuilder() .setPrettyPrinting() .disableHtmlEscaping() @@ -117,19 +97,9 @@ public Registry read(JsonReader jsonReader) throws IOException { .registerTypeAdapterFactory(IMMUTABLE_LIST) .registerTypeAdapterFactory(IMMUTABLE_BIMAP) .registerTypeAdapter(Version.class, VERSION_TYPE_ADAPTER) - .registerTypeAdapter(ModuleKey.class, MODULE_KEY_TYPE_ADAPTER); - - /** - * Gets a gson with registered adapters needed to read the lockfile. - * - * @param registryFactory Registry factory to use in the registry adapter - * @return gson with type adapters - */ - public static Gson getLockfileGsonWithTypeAdapters(RegistryFactory registryFactory) { - return adapterGson - .registerTypeAdapter(Registry.class, registryTypeAdapter(registryFactory)) - .create(); - } + .registerTypeAdapter(ModuleKey.class, MODULE_KEY_TYPE_ADAPTER) + .registerTypeAdapter(AttributeValues.class, new AttributeValuesAdapter()) + .create(); private GsonTypeAdapterUtil() {} } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/IndexRegistry.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/IndexRegistry.java index 3b5164f167680d..6cb6fc0b453c48 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/IndexRegistry.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/IndexRegistry.java @@ -186,8 +186,9 @@ private RepoSpec createLocalPathRepoSpec( return RepoSpec.builder() .setRuleClassName("local_repository") .setAttributes( - ImmutableMap.of( - "name", repoName.getName(), "path", PathFragment.create(path).toString())) + AttributeValues.create( + ImmutableMap.of( + "name", repoName.getName(), "path", PathFragment.create(path).toString()))) .build(); } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/LocalPathOverride.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/LocalPathOverride.java index 28e4cc4e476b55..33f5f64caf33d0 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/LocalPathOverride.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/LocalPathOverride.java @@ -35,7 +35,8 @@ public static LocalPathOverride create(String path) { public RepoSpec getRepoSpec(RepositoryName repoName) { return RepoSpec.builder() .setRuleClassName("local_repository") - .setAttributes(ImmutableMap.of("name", repoName.getName(), "path", getPath())) + .setAttributes( + AttributeValues.create(ImmutableMap.of("name", repoName.getName(), "path", getPath()))) .build(); } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/Module.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/Module.java index 66125402de6506..86fae25df40b45 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/Module.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/Module.java @@ -138,13 +138,22 @@ public final RepositoryMapping getRepoMappingWithBazelDepsOnly() { return RepositoryMapping.create(mapping.buildOrThrow(), getCanonicalRepoName()); } + // TODO(salmasamy) create two modules (One with registry, one with repospec and only necessary + // things for lockfile) /** * The registry where this module came from. Must be null iff the module has a {@link - * NonRegistryOverride}. + * NonRegistryOverride}. Set to null after running selection and verifying yanked versions. */ @Nullable public abstract Registry getRegistry(); + /** + * The repo spec for this module (information about the attributes of its repository rule) Filled + * after running selection to avoid extra calls to the registry. + */ + @Nullable + public abstract RepoSpec getRepoSpec(); + /** The module extensions used in this module. */ public abstract ImmutableList getExtensionUsages(); @@ -240,6 +249,8 @@ public Builder addOriginalDep(String depRepoName, ModuleKey depKey) { public abstract Builder setRegistry(Registry value); + public abstract Builder setRepoSpec(RepoSpec value); + public abstract Builder setExtensionUsages(ImmutableList value); abstract ImmutableList.Builder extensionUsagesBuilder(); diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileGlobals.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileGlobals.java index eb135d4eff3dd6..aac2c75776f03c 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileGlobals.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileGlobals.java @@ -500,7 +500,7 @@ public void call(Dict kwargs, StarlarkThread thread) { tags.add( Tag.builder() .setTagName(tagName) - .setAttributeValues(kwargs) + .setAttributeValues(AttributeValues.create(kwargs)) .setDevDependency(devDependency) .setLocation(thread.getCallerLocation()) .build()); diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileValue.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileValue.java index 38bc90e77266a1..99e71fd5006447 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileValue.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileValue.java @@ -72,11 +72,11 @@ public abstract static class RootModuleFileValue extends ModuleFileValue { public static RootModuleFileValue create( Module module, - String moduleHash, + String moduleFileHash, ImmutableMap overrides, ImmutableMap nonRegistryOverrideCanonicalRepoNameLookup) { return new AutoValue_ModuleFileValue_RootModuleFileValue( - module, moduleHash, overrides, nonRegistryOverrideCanonicalRepoNameLookup); + module, moduleFileHash, overrides, nonRegistryOverrideCanonicalRepoNameLookup); } } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/RepoSpec.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/RepoSpec.java index 1aee3ae959a28b..f5f2e6f851c8b7 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/RepoSpec.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/RepoSpec.java @@ -15,9 +15,8 @@ package com.google.devtools.build.lib.bazel.bzlmod; import com.google.auto.value.AutoValue; -import com.google.common.collect.ImmutableMap; import com.ryanharter.auto.value.gson.GenerateTypeAdapter; -import java.util.Optional; +import javax.annotation.Nullable; /** * A class holding information about the attributes of a repository rule and where the rule class is @@ -30,11 +29,12 @@ public abstract class RepoSpec { /** * The label string for the bzl file this repository rule is defined in, empty for native rule. */ - public abstract Optional bzlFile(); + @Nullable + public abstract String bzlFile(); public abstract String ruleClassName(); - public abstract ImmutableMap attributes(); + public abstract AttributeValues attributes(); public static Builder builder() { return new AutoValue_RepoSpec.Builder(); @@ -45,17 +45,15 @@ public static Builder builder() { public abstract static class Builder { public abstract Builder setBzlFile(String bzlFile); - public abstract Builder setBzlFile(Optional bzlFile); - public abstract Builder setRuleClassName(String name); - public abstract Builder setAttributes(ImmutableMap attributes); + public abstract Builder setAttributes(AttributeValues attributes); public abstract RepoSpec build(); } public boolean isNativeRepoRule() { - return !bzlFile().isPresent(); + return bzlFile() == null; } /** @@ -63,6 +61,6 @@ public boolean isNativeRepoRule() { * repo rule: //:repo.bzl%my_repo */ public String getRuleClass() { - return bzlFile().map(f -> f + "%").orElse("") + ruleClassName(); + return (bzlFile() == null ? "" : bzlFile() + "%") + ruleClassName(); } } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/Tag.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/Tag.java index c23454ed7f245a..4ee4d6db356c92 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/Tag.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/Tag.java @@ -17,7 +17,6 @@ import com.google.auto.value.AutoValue; import com.ryanharter.auto.value.gson.GenerateTypeAdapter; -import net.starlark.java.eval.Dict; import net.starlark.java.syntax.Location; /** @@ -33,7 +32,7 @@ public abstract class Tag { public abstract String getTagName(); /** All keyword arguments supplied to the tag instance. */ - public abstract Dict getAttributeValues(); + public abstract AttributeValues getAttributeValues(); /** Whether this tag was created using a proxy created with dev_dependency = True. */ public abstract boolean isDevDependency(); @@ -51,7 +50,7 @@ public abstract static class Builder { public abstract Builder setTagName(String value); - public abstract Builder setAttributeValues(Dict value); + public abstract Builder setAttributeValues(AttributeValues value); public abstract Builder setDevDependency(boolean value); diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/TypeCheckedTag.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/TypeCheckedTag.java index adbb8075000f02..55595a67ef58f0 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/TypeCheckedTag.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/TypeCheckedTag.java @@ -46,7 +46,7 @@ private TypeCheckedTag(TagClass tagClass, Object[] attrValues, boolean devDepend public static TypeCheckedTag create(TagClass tagClass, Tag tag, LabelConverter labelConverter) throws ExternalDepsException { Object[] attrValues = new Object[tagClass.getAttributes().size()]; - for (Map.Entry attrValue : tag.getAttributeValues().entrySet()) { + for (Map.Entry attrValue : tag.getAttributeValues().attributes().entrySet()) { Integer attrIndex = tagClass.getAttributeIndices().get(attrValue.getKey()); if (attrIndex == null) { throw ExternalDepsException.withMessage( diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BzlmodRepoRuleFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/BzlmodRepoRuleFunction.java index fe4977fe1e001b..e4942e3efadb7d 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/BzlmodRepoRuleFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/BzlmodRepoRuleFunction.java @@ -27,17 +27,13 @@ import com.google.devtools.build.lib.bazel.bzlmod.ModuleFileValue; import com.google.devtools.build.lib.bazel.bzlmod.ModuleFileValue.RootModuleFileValue; import com.google.devtools.build.lib.bazel.bzlmod.ModuleKey; -import com.google.devtools.build.lib.bazel.bzlmod.ModuleOverride; import com.google.devtools.build.lib.bazel.bzlmod.NonRegistryOverride; -import com.google.devtools.build.lib.bazel.bzlmod.Registry; import com.google.devtools.build.lib.bazel.bzlmod.RepoSpec; import com.google.devtools.build.lib.bazel.bzlmod.SingleExtensionEvalValue; -import com.google.devtools.build.lib.bazel.bzlmod.SingleVersionOverride; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.PackageIdentifier; import com.google.devtools.build.lib.cmdline.RepositoryMapping; import com.google.devtools.build.lib.cmdline.RepositoryName; -import com.google.devtools.build.lib.events.ExtendedEventHandler; import com.google.devtools.build.lib.packages.NoSuchPackageException; import com.google.devtools.build.lib.packages.Package; import com.google.devtools.build.lib.packages.Rule; @@ -52,7 +48,6 @@ import com.google.devtools.build.skyframe.SkyFunctionException.Transience; import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyValue; -import java.io.IOException; import java.util.Map.Entry; import java.util.Optional; import javax.annotation.Nullable; @@ -104,38 +99,28 @@ public SkyValue compute(SkyKey skyKey, Environment env) } RepositoryName repositoryName = ((BzlmodRepoRuleValue.Key) skyKey).argument(); - BazelDepGraphValue bazelDepGraphValue; - // Try to find a module from this repository name. If not found, try to find - // an extension. If none found, it is an invalid name (return not found) - - // Look for the repo from Bazel module generated repos. - try { - // Step 1: Look for repositories defined by non-registry overrides. - Optional repoSpec = checkRepoFromNonRegistryOverrides(root, repositoryName); - if (repoSpec.isPresent()) { - return createRuleFromSpec(repoSpec.get(), starlarkSemantics, env); - } + // Step 1: Look for repositories defined by non-registry overrides. + Optional repoSpec = checkRepoFromNonRegistryOverrides(root, repositoryName); + if (repoSpec.isPresent()) { + return createRuleFromSpec(repoSpec.get(), starlarkSemantics, env); + } - // BazelDepGraphValue is affected by repos found in Step 1, therefore it should NOT - // be requested in Step 1 to avoid cycle dependency. - bazelDepGraphValue = (BazelDepGraphValue) env.getValue(BazelDepGraphValue.KEY); - if (env.valuesMissing()) { - return null; - } + // BazelDepGraphValue is affected by repos found in Step 1, therefore it should NOT + // be requested in Step 1 to avoid cycle dependency. + BazelDepGraphValue bazelDepGraphValue = + (BazelDepGraphValue) env.getValue(BazelDepGraphValue.KEY); + if (env.valuesMissing()) { + return null; + } - // Step 2: Look for repositories derived from Bazel Modules. - repoSpec = - checkRepoFromBazelModules( - bazelDepGraphValue, root.getOverrides(), env.getListener(), repositoryName); - if (repoSpec.isPresent()) { - return createRuleFromSpec(repoSpec.get(), starlarkSemantics, env); - } - } catch (IOException e) { - throw new BzlmodRepoRuleFunctionException(e, Transience.PERSISTENT); + // Step 2: Look for repositories derived from Bazel Modules. + repoSpec = checkRepoFromBazelModules(bazelDepGraphValue, repositoryName); + if (repoSpec.isPresent()) { + return createRuleFromSpec(repoSpec.get(), starlarkSemantics, env); } - // Otherwise, look for the repo from module extension evaluation results. + // Step 3: look for the repo from module extension evaluation results. Optional extensionId = bazelDepGraphValue.getExtensionUniqueNames().entrySet().stream() .filter(e -> repositoryName.getName().startsWith(e.getValue() + "~")) @@ -173,41 +158,14 @@ private static Optional checkRepoFromNonRegistryOverrides( } private Optional checkRepoFromBazelModules( - BazelDepGraphValue bazelDepGraphValue, - ImmutableMap overrides, - ExtendedEventHandler eventListener, - RepositoryName repositoryName) - throws InterruptedException, IOException { + BazelDepGraphValue bazelDepGraphValue, RepositoryName repositoryName) { ModuleKey moduleKey = bazelDepGraphValue.getCanonicalRepoNameLookup().get(repositoryName); if (moduleKey == null) { return Optional.empty(); } com.google.devtools.build.lib.bazel.bzlmod.Module module = bazelDepGraphValue.getDepGraph().get(moduleKey); - Registry registry = checkNotNull(module.getRegistry()); - RepoSpec repoSpec = registry.getRepoSpec(moduleKey, repositoryName, eventListener); - repoSpec = maybeAppendAdditionalPatches(repoSpec, overrides.get(moduleKey.getName())); - return Optional.of(repoSpec); - } - - private RepoSpec maybeAppendAdditionalPatches(RepoSpec repoSpec, ModuleOverride override) { - if (!(override instanceof SingleVersionOverride)) { - return repoSpec; - } - SingleVersionOverride singleVersion = (SingleVersionOverride) override; - if (singleVersion.getPatches().isEmpty()) { - return repoSpec; - } - ImmutableMap.Builder attrBuilder = ImmutableMap.builder(); - attrBuilder.putAll(repoSpec.attributes()); - attrBuilder.put("patches", singleVersion.getPatches()); - attrBuilder.put("patch_cmds", singleVersion.getPatchCmds()); - attrBuilder.put("patch_args", ImmutableList.of("-p" + singleVersion.getPatchStrip())); - return RepoSpec.builder() - .setBzlFile(repoSpec.bzlFile()) - .setRuleClassName(repoSpec.ruleClassName()) - .setAttributes(attrBuilder.buildOrThrow()) - .build(); + return Optional.of(checkNotNull(module.getRepoSpec())); } @Nullable @@ -225,7 +183,7 @@ private BzlmodRepoRuleValue createRuleFromSpec( ruleClass = ruleClassProvider.getRuleClassMap().get(repoSpec.ruleClassName()); } else { ImmutableMap loadedModules = - loadBzlModules(env, repoSpec.bzlFile().get(), starlarkSemantics); + loadBzlModules(env, repoSpec.bzlFile(), starlarkSemantics); if (env.valuesMissing()) { return null; } @@ -242,7 +200,7 @@ private BzlmodRepoRuleValue createRuleFromSpec( env.getListener(), "BzlmodRepoRuleFunction.createRule", ruleClass, - repoSpec.attributes()); + repoSpec.attributes().attributes()); return new BzlmodRepoRuleValue(rule.getPackage(), rule.getName()); } catch (InvalidRuleException e) { throw new BzlmodRepoRuleFunctionException(e, Transience.PERSISTENT); @@ -301,7 +259,7 @@ private ImmutableMap loadBzlModules( private RuleClass getStarlarkRuleClass( RepoSpec repoSpec, ImmutableMap loadedModules) throws BzlmodRepoRuleFunctionException { - Object object = loadedModules.get(repoSpec.bzlFile().get()).getGlobal(repoSpec.ruleClassName()); + Object object = loadedModules.get(repoSpec.bzlFile()).getGlobal(repoSpec.ruleClassName()); if (object instanceof RuleFunction) { return ((RuleFunction) object).getRuleClass(); } else { @@ -321,10 +279,6 @@ private static final class BzlmodRepoRuleFunctionException extends SkyFunctionEx super(e, transience); } - BzlmodRepoRuleFunctionException(IOException e, Transience transience) { - super(e, transience); - } - BzlmodRepoRuleFunctionException(EvalException e, Transience transience) { super(e, transience); } diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java index 162c01a546a171..a511ce2d7d0c8e 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java @@ -143,9 +143,9 @@ public ImmutableMap getSkyFunctions(BlazeDirectori directories.getWorkspace(), getBuiltinModules(directories)), SkyFunctions.BAZEL_DEP_GRAPH, - new BazelDepGraphFunction(directories.getWorkspace(), FakeRegistry.DEFAULT_FACTORY), + new BazelDepGraphFunction(directories.getWorkspace()), SkyFunctions.BAZEL_LOCK_FILE, - new BazelLockFileFunction(directories.getWorkspace(), FakeRegistry.DEFAULT_FACTORY), + new BazelLockFileFunction(directories.getWorkspace()), SkyFunctions.BAZEL_MODULE_RESOLUTION, new BazelModuleResolutionFunction(), SkyFunctions.CLIENT_ENVIRONMENT_VARIABLE, diff --git a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/AttributeValuesAdapterTest.java b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/AttributeValuesAdapterTest.java new file mode 100644 index 00000000000000..8ae80136ea764f --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/AttributeValuesAdapterTest.java @@ -0,0 +1,71 @@ +// 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.bazel.bzlmod; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.testutil.FoundationTestCase; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.Map; +import net.starlark.java.eval.Dict; +import net.starlark.java.eval.Mutability; +import net.starlark.java.eval.StarlarkInt; +import net.starlark.java.eval.StarlarkList; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class AttributeValuesAdapterTest extends FoundationTestCase { + + @Test + public void testAttributeValuesAdapter() throws IOException { + Dict.Builder dict = new Dict.Builder<>(); + Label l1 = Label.parseCanonicalUnchecked("@//foo:bar"); + Label l2 = Label.parseCanonicalUnchecked("@//foo:tar"); + dict.put("Integer", StarlarkInt.of(56)); + dict.put("Boolean", false); + dict.put("String", "Hello"); + dict.put("Label", l1); + dict.put( + "ListOfInts", StarlarkList.of(Mutability.IMMUTABLE, StarlarkInt.of(1), StarlarkInt.of(2))); + dict.put("ListOfLabels", StarlarkList.of(Mutability.IMMUTABLE, l1, l2)); + dict.put("ListOfStrings", StarlarkList.of(Mutability.IMMUTABLE, "Hello", "There!")); + Dict.Builder dictLabelString = new Dict.Builder<>(); + dictLabelString.put(l1, "Label#1"); + dictLabelString.put(l2, "Label#2"); + dict.put("DictOfLabel-String", dictLabelString.buildImmutable()); + + Dict builtDict = dict.buildImmutable(); + AttributeValuesAdapter attrAdapter = new AttributeValuesAdapter(); + String jsonString; + try (StringWriter stringWriter = new StringWriter()) { + attrAdapter.write(new JsonWriter(stringWriter), AttributeValues.create(builtDict)); + jsonString = stringWriter.toString(); + } + AttributeValues attributeValues; + try (StringReader stringReader = new StringReader(jsonString)) { + attributeValues = attrAdapter.read(new JsonReader(stringReader)); + } + + assertThat((Map) attributeValues.attributes()).containsExactlyEntriesIn(builtDict); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD index e1133d8e555cd6..79b8d5d4caaee2 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD +++ b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD @@ -79,6 +79,7 @@ java_library( "//src/test/java/com/google/devtools/build/lib/testutil", "//third_party:auto_value", "//third_party:caffeine", + "//third_party:gson", "//third_party:guava", "//third_party:jsr305", "//third_party:junit4", diff --git a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BazelDepGraphFunctionTest.java b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BazelDepGraphFunctionTest.java index 9cef1c466e8f6c..34cf49d627a05e 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BazelDepGraphFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BazelDepGraphFunctionTest.java @@ -122,12 +122,8 @@ public void setup() throws Exception { SkyFunctions.MODULE_FILE, new ModuleFileFunction(registryFactory, rootDirectory, ImmutableMap.of())) .put(SkyFunctions.PRECOMPUTED, new PrecomputedFunction()) - .put( - SkyFunctions.BAZEL_LOCK_FILE, - new BazelLockFileFunction(rootDirectory, registryFactory)) - .put( - SkyFunctions.BAZEL_DEP_GRAPH, - new BazelDepGraphFunction(rootDirectory, registryFactory)) + .put(SkyFunctions.BAZEL_LOCK_FILE, new BazelLockFileFunction(rootDirectory)) + .put(SkyFunctions.BAZEL_DEP_GRAPH, new BazelDepGraphFunction(rootDirectory)) .put(SkyFunctions.BAZEL_MODULE_RESOLUTION, resolutionFunctionMock) .put( SkyFunctions.CLIENT_ENVIRONMENT_VARIABLE, diff --git a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileFunctionTest.java b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileFunctionTest.java index d01a0a8057c4c3..3ca3eead809589 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileFunctionTest.java @@ -115,9 +115,7 @@ public void setup() throws Exception { .put( SkyFunctions.MODULE_FILE, new ModuleFileFunction(registryFactory, rootDirectory, ImmutableMap.of())) - .put( - SkyFunctions.BAZEL_LOCK_FILE, - new BazelLockFileFunction(rootDirectory, registryFactory)) + .put(SkyFunctions.BAZEL_LOCK_FILE, new BazelLockFileFunction(rootDirectory)) .put( SkyFunctions.CLIENT_ENVIRONMENT_VARIABLE, new ClientEnvironmentFunction( @@ -136,11 +134,7 @@ public SkyValue compute(SkyKey skyKey, Environment env) return null; } BazelLockFileFunction.updateLockedModule( - key.moduleHash(), - key.depGraph(), - rootDirectory, - registryFactory, - flags); + key.moduleHash(), key.depGraph(), rootDirectory, flags); return new SkyValue() {}; } }) diff --git a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BazelModuleResolutionFunctionTest.java b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BazelModuleResolutionFunctionTest.java index 8cf78d71f3e517..8796ab95306c99 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BazelModuleResolutionFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BazelModuleResolutionFunctionTest.java @@ -111,12 +111,8 @@ public void setup() throws Exception { SkyFunctions.MODULE_FILE, new ModuleFileFunction(registryFactory, rootDirectory, ImmutableMap.of())) .put(SkyFunctions.PRECOMPUTED, new PrecomputedFunction()) - .put( - SkyFunctions.BAZEL_DEP_GRAPH, - new BazelDepGraphFunction(rootDirectory, registryFactory)) - .put( - SkyFunctions.BAZEL_LOCK_FILE, - new BazelLockFileFunction(rootDirectory, registryFactory)) + .put(SkyFunctions.BAZEL_DEP_GRAPH, new BazelDepGraphFunction(rootDirectory)) + .put(SkyFunctions.BAZEL_LOCK_FILE, new BazelLockFileFunction(rootDirectory)) .put(SkyFunctions.BAZEL_MODULE_RESOLUTION, new BazelModuleResolutionFunction()) .put( SkyFunctions.CLIENT_ENVIRONMENT_VARIABLE, diff --git a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BzlmodRepoRuleFunctionTest.java b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BzlmodRepoRuleFunctionTest.java index f59d874fd0e3ef..44356022499fa3 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BzlmodRepoRuleFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BzlmodRepoRuleFunctionTest.java @@ -34,6 +34,7 @@ import com.google.devtools.build.lib.cmdline.RepositoryName; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.Type; +import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; import com.google.devtools.build.lib.skyframe.BazelSkyframeExecutorConstants; import com.google.devtools.build.lib.skyframe.BzlmodRepoRuleFunction; @@ -123,12 +124,8 @@ public void setup() throws Exception { .put( BzlmodRepoRuleValue.BZLMOD_REPO_RULE, new BzlmodRepoRuleFunction(ruleClassProvider, directories)) - .put( - SkyFunctions.BAZEL_DEP_GRAPH, - new BazelDepGraphFunction(rootDirectory, registryFactory)) - .put( - SkyFunctions.BAZEL_LOCK_FILE, - new BazelLockFileFunction(rootDirectory, registryFactory)) + .put(SkyFunctions.BAZEL_DEP_GRAPH, new BazelDepGraphFunction(rootDirectory)) + .put(SkyFunctions.BAZEL_LOCK_FILE, new BazelLockFileFunction(rootDirectory)) .put(SkyFunctions.BAZEL_MODULE_RESOLUTION, new BazelModuleResolutionFunction()) .put( SkyFunctions.MODULE_FILE, @@ -140,6 +137,7 @@ public void setup() throws Exception { differencer); PrecomputedValue.STARLARK_SEMANTICS.set(differencer, StarlarkSemantics.DEFAULT); + ModuleFileFunction.REGISTRIES.set(differencer, ImmutableList.of()); ModuleFileFunction.IGNORE_DEV_DEPS.set(differencer, false); ModuleFileFunction.MODULE_OVERRIDES.set(differencer, ImmutableMap.of()); BazelModuleResolutionFunction.ALLOWED_YANKED_VERSIONS.set(differencer, ImmutableList.of()); @@ -179,6 +177,55 @@ public void testRepoSpec_bazelModule() throws Exception { assertThat(repoRule.getAttr("path", Type.STRING)).isEqualTo("/usr/local/modules/ccc~2.0"); } + @Test + public void testRepoSpec_lockfile() throws Exception { + scratch.file( + workspaceRoot.getRelative("MODULE.bazel").getPathString(), + "bazel_dep(name='bbb',version='2.0')"); + + FakeRegistry registry = + registryFactory + .newFakeRegistry("/usr/local/modules") + .addModule(createModuleKey("bbb", "2.0"), "module(name='bbb', version='2.0')"); + ModuleFileFunction.REGISTRIES.set(differencer, ImmutableList.of(registry.getUrl())); + + PrecomputedValue.STARLARK_SEMANTICS.set( + differencer, + StarlarkSemantics.builder().setBool(BuildLanguageOptions.ENABLE_LOCKFILE, true).build()); + + RepositoryName repo = RepositoryName.create("bbb~2.0"); + EvaluationResult result = + evaluator.evaluate(ImmutableList.of(BzlmodRepoRuleValue.key(repo)), evaluationContext); + if (result.hasError()) { + fail(result.getError().toString()); + } + BzlmodRepoRuleValue bzlmodRepoRuleValue = result.get(BzlmodRepoRuleValue.key(repo)); + Rule repoRule = bzlmodRepoRuleValue.getRule(); + assertThat(repoRule.getName()).isEqualTo("bbb~2.0"); + + /* Rerun the setup to: + 1.Reset evaluator to remove the sky values cache. + 2.Reset registry factory to be empty (now "bbb" doesn't exist at all) + without the lockfile "bbb" should not be found and this should fail + */ + setup(); + PrecomputedValue.STARLARK_SEMANTICS.set( + differencer, + StarlarkSemantics.builder().setBool(BuildLanguageOptions.ENABLE_LOCKFILE, true).build()); + + registry = registryFactory.newFakeRegistry("/usr/local/modules"); + ModuleFileFunction.REGISTRIES.set(differencer, ImmutableList.of(registry.getUrl())); + + // Calling again should read from lockfile and still find ccc + result = evaluator.evaluate(ImmutableList.of(BzlmodRepoRuleValue.key(repo)), evaluationContext); + if (result.hasError()) { + fail(result.getError().toString()); + } + bzlmodRepoRuleValue = result.get(BzlmodRepoRuleValue.key(repo)); + repoRule = bzlmodRepoRuleValue.getRule(); + assertThat(repoRule.getName()).isEqualTo("bbb~2.0"); + } + @Test public void testRepoSpec_nonRegistryOverride() throws Exception { scratch.file( diff --git a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BzlmodTestUtil.java b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BzlmodTestUtil.java index 2af63ead6d9d35..484e40e0dce23e 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BzlmodTestUtil.java +++ b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BzlmodTestUtil.java @@ -305,7 +305,7 @@ public Tag build() { return Tag.builder() .setTagName(tagName) .setLocation(Location.BUILTIN) - .setAttributeValues(attrValuesBuilder.buildImmutable()) + .setAttributeValues(AttributeValues.create(attrValuesBuilder.buildImmutable())) .setDevDependency(devDependency) .build(); } diff --git a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/FakeRegistry.java b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/FakeRegistry.java index e731065e4b4304..593a3c5484da7a 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/FakeRegistry.java +++ b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/FakeRegistry.java @@ -73,8 +73,9 @@ public RepoSpec getRepoSpec( return RepoSpec.builder() .setRuleClassName("local_repository") .setAttributes( - ImmutableMap.of( - "name", repoName.getName(), "path", rootPath + "/" + repoName.getName())) + AttributeValues.create( + ImmutableMap.of( + "name", repoName.getName(), "path", rootPath + "/" + repoName.getName()))) .build(); } diff --git a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/IndexRegistryTest.java b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/IndexRegistryTest.java index f927043bed1429..ecc02549969121 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/IndexRegistryTest.java +++ b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/IndexRegistryTest.java @@ -201,7 +201,9 @@ public void testGetLocalPathRepoSpec() throws Exception { .isEqualTo( RepoSpec.builder() .setRuleClassName("local_repository") - .setAttributes(ImmutableMap.of("name", "foorepo", "path", "/hello/bar/project_x")) + .setAttributes( + AttributeValues.create( + ImmutableMap.of("name", "foorepo", "path", "/hello/bar/project_x"))) .build()); } diff --git a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleExtensionResolutionTest.java b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleExtensionResolutionTest.java index 35e06507ea1705..c0ccd70173aba6 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleExtensionResolutionTest.java +++ b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleExtensionResolutionTest.java @@ -247,12 +247,8 @@ public void setup() throws Exception { .put( BzlmodRepoRuleValue.BZLMOD_REPO_RULE, new BzlmodRepoRuleFunction(ruleClassProvider, directories)) - .put( - SkyFunctions.BAZEL_LOCK_FILE, - new BazelLockFileFunction(rootDirectory, registryFactory)) - .put( - SkyFunctions.BAZEL_DEP_GRAPH, - new BazelDepGraphFunction(rootDirectory, registryFactory)) + .put(SkyFunctions.BAZEL_LOCK_FILE, new BazelLockFileFunction(rootDirectory)) + .put(SkyFunctions.BAZEL_DEP_GRAPH, new BazelDepGraphFunction(rootDirectory)) .put(SkyFunctions.BAZEL_MODULE_RESOLUTION, new BazelModuleResolutionFunction()) .put(SkyFunctions.SINGLE_EXTENSION_USAGES, new SingleExtensionUsagesFunction()) .put(SkyFunctions.SINGLE_EXTENSION_EVAL, singleExtensionEvalFunction) diff --git a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunctionTest.java b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunctionTest.java index 1b8e52ac9cc8fe..3c3d956ff2eabb 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunctionTest.java @@ -481,9 +481,10 @@ public void testModuleExtensions_good() throws Exception { Tag.builder() .setTagName("tag") .setAttributeValues( - Dict.builder() - .put("key", "val") - .buildImmutable()) + AttributeValues.create( + Dict.builder() + .put("key", "val") + .buildImmutable())) .setDevDependency(false) .setLocation( Location.fromFileLineColumn("mymod@1.0/MODULE.bazel", 4, 11)) @@ -499,9 +500,10 @@ public void testModuleExtensions_good() throws Exception { Tag.builder() .setTagName("tag1") .setAttributeValues( - Dict.builder() - .put("key1", "val1") - .buildImmutable()) + AttributeValues.create( + Dict.builder() + .put("key1", "val1") + .buildImmutable())) .setDevDependency(false) .setLocation( Location.fromFileLineColumn("mymod@1.0/MODULE.bazel", 7, 12)) @@ -510,9 +512,10 @@ public void testModuleExtensions_good() throws Exception { Tag.builder() .setTagName("tag2") .setAttributeValues( - Dict.builder() - .put("key2", "val2") - .buildImmutable()) + AttributeValues.create( + Dict.builder() + .put("key2", "val2") + .buildImmutable())) .setDevDependency(false) .setLocation( Location.fromFileLineColumn("mymod@1.0/MODULE.bazel", 8, 12)) @@ -529,9 +532,10 @@ public void testModuleExtensions_good() throws Exception { Tag.builder() .setTagName("dep") .setAttributeValues( - Dict.builder() - .put("coord", "junit") - .buildImmutable()) + AttributeValues.create( + Dict.builder() + .put("coord", "junit") + .buildImmutable())) .setDevDependency(false) .setLocation( Location.fromFileLineColumn("mymod@1.0/MODULE.bazel", 12, 10)) @@ -540,9 +544,10 @@ public void testModuleExtensions_good() throws Exception { Tag.builder() .setTagName("dep") .setAttributeValues( - Dict.builder() - .put("coord", "guava") - .buildImmutable()) + AttributeValues.create( + Dict.builder() + .put("coord", "guava") + .buildImmutable())) .setDevDependency(false) .setLocation( Location.fromFileLineColumn("mymod@1.0/MODULE.bazel", 14, 10)) @@ -593,9 +598,10 @@ public void testModuleExtensions_duplicateProxy_asRoot() throws Exception { Tag.builder() .setTagName("tag") .setAttributeValues( - Dict.builder() - .put("name", "tag1") - .buildImmutable()) + AttributeValues.create( + Dict.builder() + .put("name", "tag1") + .buildImmutable())) .setDevDependency(true) .setLocation( Location.fromFileLineColumn("/MODULE.bazel", 2, 11)) @@ -604,9 +610,10 @@ public void testModuleExtensions_duplicateProxy_asRoot() throws Exception { Tag.builder() .setTagName("tag") .setAttributeValues( - Dict.builder() - .put("name", "tag2") - .buildImmutable()) + AttributeValues.create( + Dict.builder() + .put("name", "tag2") + .buildImmutable())) .setDevDependency(false) .setLocation( Location.fromFileLineColumn("/MODULE.bazel", 5, 11)) @@ -615,9 +622,10 @@ public void testModuleExtensions_duplicateProxy_asRoot() throws Exception { Tag.builder() .setTagName("tag") .setAttributeValues( - Dict.builder() - .put("name", "tag3") - .buildImmutable()) + AttributeValues.create( + Dict.builder() + .put("name", "tag3") + .buildImmutable())) .setDevDependency(true) .setLocation( Location.fromFileLineColumn("/MODULE.bazel", 8, 11)) @@ -626,9 +634,10 @@ public void testModuleExtensions_duplicateProxy_asRoot() throws Exception { Tag.builder() .setTagName("tag") .setAttributeValues( - Dict.builder() - .put("name", "tag4") - .buildImmutable()) + AttributeValues.create( + Dict.builder() + .put("name", "tag4") + .buildImmutable())) .setDevDependency(false) .setLocation( Location.fromFileLineColumn("/MODULE.bazel", 11, 11)) @@ -680,9 +689,10 @@ public void testModuleExtensions_duplicateProxy_asDep() throws Exception { Tag.builder() .setTagName("tag") .setAttributeValues( - Dict.builder() - .put("name", "tag2") - .buildImmutable()) + AttributeValues.create( + Dict.builder() + .put("name", "tag2") + .buildImmutable())) .setDevDependency(false) .setLocation( Location.fromFileLineColumn("mymod@1.0/MODULE.bazel", 6, 11)) @@ -691,9 +701,10 @@ public void testModuleExtensions_duplicateProxy_asDep() throws Exception { Tag.builder() .setTagName("tag") .setAttributeValues( - Dict.builder() - .put("name", "tag4") - .buildImmutable()) + AttributeValues.create( + Dict.builder() + .put("name", "tag4") + .buildImmutable())) .setDevDependency(false) .setLocation( Location.fromFileLineColumn("mymod@1.0/MODULE.bazel", 12, 11)) diff --git a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/RepoSpecTest.java b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/RepoSpecTest.java index 754f65d29c1c8a..e7a84d633a3b02 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/RepoSpecTest.java +++ b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/RepoSpecTest.java @@ -15,9 +15,9 @@ package com.google.devtools.build.lib.bazel.bzlmod; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; import com.google.common.collect.ImmutableMap; +import java.util.Map; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -31,12 +31,12 @@ public void nativeRepoSpecTest() { RepoSpec repoSpec = RepoSpec.builder() .setRuleClassName("local_repository") - .setAttributes(ImmutableMap.of("path", "/foo/bar")) + .setAttributes(AttributeValues.create(ImmutableMap.of("path", "/foo/bar"))) .build(); assertThat(repoSpec.isNativeRepoRule()).isTrue(); assertThat(repoSpec.ruleClassName()).isEqualTo("local_repository"); assertThat(repoSpec.getRuleClass()).isEqualTo("local_repository"); - assertThat(repoSpec.attributes()).containsExactly("path", "/foo/bar"); + assertThat((Map) repoSpec.attributes().attributes()).containsExactly("path", "/foo/bar"); } @Test @@ -45,12 +45,13 @@ public void starlarkRepoSpecTest() { RepoSpec.builder() .setBzlFile("//pkg:repo.bzl") .setRuleClassName("my_repo") - .setAttributes(ImmutableMap.of("attr1", "foo", "attr2", "bar")) + .setAttributes(AttributeValues.create(ImmutableMap.of("attr1", "foo", "attr2", "bar"))) .build(); assertThat(repoSpec.isNativeRepoRule()).isFalse(); - assertThat(repoSpec.bzlFile()).hasValue("//pkg:repo.bzl"); + assertThat(repoSpec.bzlFile()).isEqualTo("//pkg:repo.bzl"); assertThat(repoSpec.ruleClassName()).isEqualTo("my_repo"); assertThat(repoSpec.getRuleClass()).isEqualTo("//pkg:repo.bzl%my_repo"); - assertThat(repoSpec.attributes()).containsExactly("attr1", "foo", "attr2", "bar"); + assertThat((Map) repoSpec.attributes().attributes()) + .containsExactly("attr1", "foo", "attr2", "bar"); } } diff --git a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java index 32e0f628188c1b..8d14668241df38 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java @@ -225,9 +225,7 @@ public void setupDelegator() throws Exception { .put( SkyFunctions.MODULE_FILE, new ModuleFileFunction(registryFactory, rootPath, ImmutableMap.of())) - .put( - SkyFunctions.BAZEL_DEP_GRAPH, - new BazelDepGraphFunction(rootDirectory, registryFactory)) + .put(SkyFunctions.BAZEL_DEP_GRAPH, new BazelDepGraphFunction(rootDirectory)) .put(SkyFunctions.BAZEL_MODULE_RESOLUTION, new BazelModuleResolutionFunction()) .put( BzlmodRepoRuleValue.BZLMOD_REPO_RULE,