diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java index e96a42bc8ce9b4..df527b31de764f 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java @@ -182,6 +182,13 @@ public Builder addWorkspaceFilePrefix(String contents) { return this; } + @CanIgnoreReturnValue + @VisibleForTesting + public Builder clearWorkspaceFilePrefixForTesting() { + defaultWorkspaceFilePrefix.delete(0, defaultWorkspaceFilePrefix.length()); + return this; + } + @CanIgnoreReturnValue public Builder addWorkspaceFileSuffix(String contents) { defaultWorkspaceFileSuffix.append(contents); 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 27c5589a3e8ecc..4757485418ab5e 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 @@ -161,6 +161,7 @@ public class BazelRepositoryModule extends BlazeModule { private Optional vendorDirectory; private List allowedYankedVersions = ImmutableList.of(); + private boolean disableNativeRepoRules; private SingleExtensionEvalFunction singleExtensionEvalFunction; private final ExecutorService repoFetchingWorkerThreadPool = Executors.newFixedThreadPool( @@ -351,6 +352,7 @@ public void beforeCommand(CommandEnvironment env) throws AbruptExitException { if (repoOptions.repositoryDownloaderRetries >= 0) { downloadManager.setRetries(repoOptions.repositoryDownloaderRetries); } + disableNativeRepoRules = repoOptions.disableNativeRepoRules; repositoryCache.setHardlink(repoOptions.useHardlinks); if (repoOptions.experimentalScaleTimeouts > 0.0) { @@ -602,7 +604,9 @@ public ImmutableList getPrecomputedValues() { PrecomputedValue.injected(RepositoryDelegatorFunction.IS_VENDOR_COMMAND, false), PrecomputedValue.injected(RepositoryDelegatorFunction.VENDOR_DIRECTORY, vendorDirectory), PrecomputedValue.injected( - YankedVersionsUtil.ALLOWED_YANKED_VERSIONS, allowedYankedVersions)); + YankedVersionsUtil.ALLOWED_YANKED_VERSIONS, allowedYankedVersions), + PrecomputedValue.injected( + RepositoryDelegatorFunction.DISABLE_NATIVE_REPO_RULES, disableNativeRepoRules)); } @Override diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/LocalConfigPlatformFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/LocalConfigPlatformFunction.java index e251db006ecc2c..e9ae1ed20bfab7 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/LocalConfigPlatformFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/LocalConfigPlatformFunction.java @@ -56,6 +56,7 @@ public RepositoryDirectoryValue.Builder fetch( Map recordedInputValues, SkyKey key) throws RepositoryFunctionException, InterruptedException { + ensureNativeRepoRuleEnabled(rule, env, "the platform defined at @platforms//host"); StarlarkSemantics starlarkSemantics = PrecomputedValue.STARLARK_SEMANTICS.get(env); if (starlarkSemantics == null) { return null; diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java index a223f80f479ac4..7bc16929c1e7f8 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java @@ -97,6 +97,18 @@ public class RepositoryOptions extends OptionsBase { + " still run an arbitrary executable that accesses the Internet.") public boolean disableDownload; + @Option( + name = "incompatible_disable_native_repo_rules", + defaultValue = "false", + documentationCategory = OptionDocumentationCategory.BAZEL_CLIENT_OPTIONS, + effectTags = {OptionEffectTag.BAZEL_INTERNAL_CONFIGURATION}, + help = + "If false, native repo rules can be used in WORKSPACE; otherwise, Starlark repo rules " + + "must be used instead. Native repo rules include local_repository, " + + "new_local_repository, local_config_platform, android_sdk_repository, and " + + "android_ndk_repository.") + public boolean disableNativeRepoRules; + @Option( name = "experimental_repository_downloader_retries", defaultValue = "0", diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/local_config_platform.WORKSPACE b/src/main/java/com/google/devtools/build/lib/bazel/repository/local_config_platform.WORKSPACE index 8f293a91529254..de285fbd34ef2e 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/local_config_platform.WORKSPACE +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/local_config_platform.WORKSPACE @@ -1,3 +1,4 @@ +load("@bazel_tools//tools/build_defs/repo:local.bzl", "local_repository") load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") maybe( diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java index 8526baeb6bbea9..4475ccf27f2bad 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java @@ -272,6 +272,7 @@ public RepositoryDirectoryValue.Builder fetch( Map recordedInputValues, SkyKey key) throws InterruptedException, RepositoryFunctionException { + ensureNativeRepoRuleEnabled(rule, env, "https://github.com/bazelbuild/rules_android_ndk"); Map environ = declareEnvironmentDependencies(recordedInputValues, env, PATH_ENV_VAR_AS_SET); if (environ == null) { diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java index 09d9654b79660e..b75e9963aea127 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java @@ -201,6 +201,7 @@ public RepositoryDirectoryValue.Builder fetch( Map recordedInputValues, SkyKey key) throws RepositoryFunctionException, InterruptedException { + ensureNativeRepoRuleEnabled(rule, env, "https://github.com/bazelbuild/rules_android"); Map environ = declareEnvironmentDependencies(recordedInputValues, env, PATH_ENV_VAR_AS_SET); if (environ == null) { diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/rules_java_builtin.WORKSPACE b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/rules_java_builtin.WORKSPACE index 5b7589ae6c6eea..e2a1b2e0ecd254 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/rules_java_builtin.WORKSPACE +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/rules_java_builtin.WORKSPACE @@ -1,4 +1,5 @@ -local_repository( +load("@bazel_tools//tools/build_defs/repo:local.bzl", rules_java_builtin_local_repository = "local_repository") +rules_java_builtin_local_repository( name = "rules_java_builtin", path = __embedded_dir__ + "/rules_java", repo_mapping = {"@rules_java" : "@rules_java_builtin"} diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java index 931500575ddde9..047c42a9a7cd77 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java @@ -46,6 +46,8 @@ public RepositoryDirectoryValue.Builder fetch( Map recordedInputValues, SkyKey key) throws InterruptedException, RepositoryFunctionException { + ensureNativeRepoRuleEnabled( + rule, env, "load(\"@bazel_tools//tools/build_defs/repo:local.bzl\", \"local_repository\")"); // DO NOT MODIFY THIS! It's being deprecated in favor of Starlark counterparts. // See https://github.com/bazelbuild/bazel/issues/18285 String userDefinedPath = RepositoryFunction.getPathAttr(rule); diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java index 009bcd6f40b259..4907e2ea3fb3dd 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java @@ -62,6 +62,10 @@ public RepositoryDirectoryValue.Builder fetch( Map recordedInputValues, SkyKey key) throws InterruptedException, RepositoryFunctionException { + ensureNativeRepoRuleEnabled( + rule, + env, + "load(\"@bazel_tools//tools/build_defs/repo:local.bzl\", \"new_local_repository\")"); // DO NOT MODIFY THIS! It's being deprecated in favor of Starlark counterparts. // See https://github.com/bazelbuild/bazel/issues/18285 diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java index 4d8c46f8d5faa9..0deb637e45f0c0 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java @@ -90,6 +90,9 @@ public final class RepositoryDelegatorFunction implements SkyFunction { public static final Precomputed> VENDOR_DIRECTORY = new Precomputed<>("vendor_directory"); + public static final Precomputed DISABLE_NATIVE_REPO_RULES = + new Precomputed<>("disable_native_repo_rules"); + // The marker file version is inject in the rule key digest so the rule key is always different // when we decide to update the format. private static final int MARKER_FILE_VERSION = 7; diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java index 591211ce441f77..d40f336c9f1c82 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java @@ -187,6 +187,27 @@ public abstract RepositoryDirectoryValue.Builder fetch( SkyKey key) throws InterruptedException, RepositoryFunctionException; + protected static void ensureNativeRepoRuleEnabled(Rule rule, Environment env, String replacement) + throws RepositoryFunctionException, InterruptedException { + if (!isWorkspaceRepo(rule)) { + // If this native repo rule is used in a Bzlmod context, always allow it. This is because + // we're still using the native `local_repository` for `local_path_override`, and it's + // nontrivial to migrate that one to the Starlark version. + return; + } + if (!RepositoryDelegatorFunction.DISABLE_NATIVE_REPO_RULES.get(env)) { + return; + } + throw new RepositoryFunctionException( + Starlark.errorf( + "Native repo rule %s is disabled since the flag " + + "--incompatible_disable_native_repo_rules is set. Native repo rules are " + + "deprecated; please migrate to their Starlark counterparts. For %s, please use " + + "%s.", + rule.getRuleClass(), rule.getRuleClass(), replacement), + Transience.PERSISTENT); + } + /** * Verify the data provided by the marker file to check if a refetch is needed. Returns true if * the data is up to date and no refetch is needed and false if the data is obsolete and a refetch diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/packages/BazelPackageLoader.java b/src/main/java/com/google/devtools/build/lib/skyframe/packages/BazelPackageLoader.java index 18941473c15d75..ed1ccb52f70453 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/packages/BazelPackageLoader.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/packages/BazelPackageLoader.java @@ -24,6 +24,9 @@ import com.google.devtools.build.lib.bazel.bzlmod.ModuleFileFunction; import com.google.devtools.build.lib.bazel.bzlmod.RegistryFactory; import com.google.devtools.build.lib.bazel.bzlmod.RegistryFactoryImpl; +import com.google.devtools.build.lib.bazel.bzlmod.RegistryFunction; +import com.google.devtools.build.lib.bazel.bzlmod.RepoSpecFunction; +import com.google.devtools.build.lib.bazel.bzlmod.YankedVersionsFunction; import com.google.devtools.build.lib.bazel.bzlmod.YankedVersionsUtil; import com.google.devtools.build.lib.bazel.repository.RepositoryOptions; import com.google.devtools.build.lib.bazel.repository.cache.RepositoryCache; @@ -51,6 +54,7 @@ import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyFunctionName; import com.google.errorprone.annotations.CanIgnoreReturnValue; +import java.util.Map; import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; @@ -112,8 +116,10 @@ private Builder(Root workspaceDir, Path installBase, Path outputBase, AtomicBool RepositoryDelegatorFunction.FORCE_FETCH_CONFIGURE, RepositoryDelegatorFunction.FORCE_FETCH_DISABLED), PrecomputedValue.injected(RepositoryDelegatorFunction.VENDOR_DIRECTORY, Optional.empty()), - PrecomputedValue.injected(ModuleFileFunction.REGISTRIES, ImmutableList.of()), + PrecomputedValue.injected( + ModuleFileFunction.REGISTRIES, BazelRepositoryModule.DEFAULT_REGISTRIES), PrecomputedValue.injected(ModuleFileFunction.IGNORE_DEV_DEPS, false), + PrecomputedValue.injected(RepositoryDelegatorFunction.DISABLE_NATIVE_REPO_RULES, false), PrecomputedValue.injected( BazelModuleResolutionFunction.CHECK_DIRECT_DEPENDENCIES, RepositoryOptions.CheckDirectDepsMode.OFF), @@ -136,7 +142,8 @@ public BazelPackageLoader buildImpl() { new RegistryFactoryImpl( directories.getWorkspace(), downloadManager, Suppliers.ofInstance(ImmutableMap.of())); - // Allow tests to override SkyFunctions.MODULE_FILE to use fake registry + // Allow tests to override the following functions to use fake registry or custom built-in + // modules if (!this.extraSkyFunctions.containsKey(SkyFunctions.MODULE_FILE)) { addExtraSkyFunctions( ImmutableMap.of( @@ -144,7 +151,16 @@ public BazelPackageLoader buildImpl() { new ModuleFileFunction( ruleClassProvider.getBazelStarlarkEnvironment(), directories.getWorkspace(), - ImmutableMap.of()))); + ModuleFileFunction.getBuiltinModules(directories.getEmbeddedBinariesRoot()) + .entrySet() + .stream() + .filter(e -> e.getKey().equals("bazel_tools")) + .collect( + ImmutableMap.toImmutableMap(Map.Entry::getKey, Map.Entry::getValue))))); + } + if (!this.extraSkyFunctions.containsKey(SkyFunctions.REGISTRY)) { + addExtraSkyFunctions( + ImmutableMap.of(SkyFunctions.REGISTRY, new RegistryFunction(registryFactory))); } addExtraSkyFunctions( @@ -171,6 +187,8 @@ public BazelPackageLoader buildImpl() { EXTERNAL_PACKAGE_HELPER)) .put(SkyFunctions.BAZEL_DEP_GRAPH, new BazelDepGraphFunction()) .put(SkyFunctions.BAZEL_MODULE_RESOLUTION, new BazelModuleResolutionFunction()) + .put(SkyFunctions.REPO_SPEC, new RepoSpecFunction()) + .put(SkyFunctions.YANKED_VERSIONS, new YankedVersionsFunction()) .buildOrThrow()); return new BazelPackageLoader(this); diff --git a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java index a2e5923e91ed72..0e8d42c4fa459e 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java @@ -828,6 +828,15 @@ def http_file(**kwargs): def http_jar(**kwargs): pass """); + config.create( + "embedded_tools/tools/build_defs/repo/local.bzl", + """ + def local_repository(**kwargs): + pass + + def new_local_repository(**kwargs): + pass + """); config.create("embedded_tools/tools/jdk/jdk_build_file.bzl", "JDK_BUILD_TEMPLATE = ''"); config.create( "embedded_tools/tools/jdk/local_java_repository.bzl", 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 e163c74356ecab..6a0e4ce2631436 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 @@ -205,6 +205,7 @@ public ImmutableList getPrecomputedValues() { RepositoryDelegatorFunction.FORCE_FETCH, RepositoryDelegatorFunction.FORCE_FETCH_DISABLED), PrecomputedValue.injected(RepositoryDelegatorFunction.VENDOR_DIRECTORY, Optional.empty()), + PrecomputedValue.injected(RepositoryDelegatorFunction.DISABLE_NATIVE_REPO_RULES, false), PrecomputedValue.injected(ModuleFileFunction.REGISTRIES, ImmutableList.of()), PrecomputedValue.injected(ModuleFileFunction.IGNORE_DEV_DEPS, false), PrecomputedValue.injected(ModuleFileFunction.MODULE_OVERRIDES, ImmutableMap.of()), diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java index 7c5f089181dbf0..a14e5792238c35 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java @@ -240,6 +240,8 @@ protected void useRuleClassProvider(ConfiguredRuleClassProvider ruleClassProvide PrecomputedValue.injected( ModuleFileFunction.REGISTRIES, ImmutableList.of(registry.getUrl())), PrecomputedValue.injected(ModuleFileFunction.IGNORE_DEV_DEPS, false), + PrecomputedValue.injected( + RepositoryDelegatorFunction.DISABLE_NATIVE_REPO_RULES, false), PrecomputedValue.injected( ModuleFileFunction.MODULE_OVERRIDES, ImmutableMap.of()), PrecomputedValue.injected( @@ -292,6 +294,8 @@ private void reinitializeSkyframeExecutor() { PrecomputedValue.injected( ModuleFileFunction.REGISTRIES, ImmutableList.of(registry.getUrl())), PrecomputedValue.injected(ModuleFileFunction.IGNORE_DEV_DEPS, false), + PrecomputedValue.injected( + RepositoryDelegatorFunction.DISABLE_NATIVE_REPO_RULES, false), PrecomputedValue.injected( BazelModuleResolutionFunction.CHECK_DIRECT_DEPENDENCIES, CheckDirectDepsMode.WARNING), 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 39156c5bf0e0de..3e5d44dbcf4648 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 @@ -171,6 +171,7 @@ public void setup() throws Exception { ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder(); TestRuleClassProvider.addStandardRules(builder); builder + .clearWorkspaceFilePrefixForTesting() .clearWorkspaceFileSuffixForTesting() .addStarlarkBootstrap(new RepositoryBootstrap(new StarlarkRepositoryModule())); ConfiguredRuleClassProvider ruleClassProvider = builder.build(); diff --git a/src/test/java/com/google/devtools/build/lib/blackbox/tests/workspace/WorkspaceBlackBoxTest.java b/src/test/java/com/google/devtools/build/lib/blackbox/tests/workspace/WorkspaceBlackBoxTest.java index 32e48e146a34d5..928ff62451a820 100644 --- a/src/test/java/com/google/devtools/build/lib/blackbox/tests/workspace/WorkspaceBlackBoxTest.java +++ b/src/test/java/com/google/devtools/build/lib/blackbox/tests/workspace/WorkspaceBlackBoxTest.java @@ -265,7 +265,6 @@ public void testBadRepoName() throws Exception { context().write(WORKSPACE, "local_repository(name = '@a', path = 'abc')"); context().write("BUILD"); ProcessResult result = context().bazel().shouldFail().build("//..."); - assertThat(result.errString()) - .contains("Error in local_repository: invalid repository name '@a'"); + assertThat(result.errString()).contains("invalid repository name '@a'"); } } diff --git a/src/test/java/com/google/devtools/build/lib/packages/BUILD b/src/test/java/com/google/devtools/build/lib/packages/BUILD index d86eba46c07ba5..a28e89c0ae868e 100644 --- a/src/test/java/com/google/devtools/build/lib/packages/BUILD +++ b/src/test/java/com/google/devtools/build/lib/packages/BUILD @@ -157,6 +157,7 @@ java_library( "//src/main/java/com/google/devtools/build/lib/analysis:analysis_cluster", "//src/main/java/com/google/devtools/build/lib/analysis:blaze_directories", "//src/main/java/com/google/devtools/build/lib/analysis:server_directories", + "//src/main/java/com/google/devtools/build/lib/bazel/bzlmod:resolution_impl", "//src/main/java/com/google/devtools/build/lib/bazel/rules/python", "//src/main/java/com/google/devtools/build/lib/clock", "//src/main/java/com/google/devtools/build/lib/cmdline", @@ -168,6 +169,7 @@ java_library( "//src/main/java/com/google/devtools/build/lib/rules/proto", "//src/main/java/com/google/devtools/build/lib/rules/python", "//src/main/java/com/google/devtools/build/lib/skyframe:precomputed_value", + "//src/main/java/com/google/devtools/build/lib/skyframe:sky_functions", "//src/main/java/com/google/devtools/build/lib/skyframe:skyframe_cluster", "//src/main/java/com/google/devtools/build/lib/skyframe/packages:PackageFactoryBuilderWithSkyframeForTesting", "//src/main/java/com/google/devtools/build/lib/util", @@ -177,6 +179,7 @@ java_library( "//src/main/java/com/google/devtools/build/lib/vfs", "//src/main/java/com/google/devtools/build/lib/vfs:pathfragment", "//src/main/java/com/google/devtools/common/options", + "//src/test/java/com/google/devtools/build/lib/bazel/bzlmod:util", "//src/test/java/com/google/devtools/build/lib/rules/python:PythonTestUtils", "//src/test/java/com/google/devtools/build/lib/testutil", "//src/test/java/com/google/devtools/build/lib/testutil:SkyframeExecutorTestHelper", diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java b/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java index 691a9714972f80..54d6516f0694e2 100644 --- a/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java @@ -22,6 +22,7 @@ import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.analysis.ServerDirectories; +import com.google.devtools.build.lib.bazel.bzlmod.ModuleFileFunction; import com.google.devtools.build.lib.clock.BlazeClock; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.LabelSyntaxException; @@ -40,6 +41,7 @@ import com.google.devtools.build.lib.runtime.QuiescingExecutorsImpl; import com.google.devtools.build.lib.skyframe.BazelSkyframeExecutorConstants; import com.google.devtools.build.lib.skyframe.PrecomputedValue; +import com.google.devtools.build.lib.skyframe.SkyFunctions; import com.google.devtools.build.lib.skyframe.SkyframeExecutor; import com.google.devtools.build.lib.testutil.FoundationTestCase; import com.google.devtools.build.lib.testutil.SkyframeExecutorTestHelper; @@ -60,8 +62,8 @@ import org.junit.Before; /** - * This is a specialization of {@link FoundationTestCase} that's useful for - * implementing tests of the "packages" library. + * This is a specialization of {@link FoundationTestCase} that's useful for implementing tests of + * the "packages" library. */ public abstract class PackageLoadingTestCase extends FoundationTestCase { @@ -104,6 +106,13 @@ public final void initializeSkyframeExecutor() throws Exception { packageFactory = loadingMock .getPackageFactoryBuilderForTesting(directories) + .setExtraSkyFunctions( + ImmutableMap.of( + SkyFunctions.MODULE_FILE, + new ModuleFileFunction( + ruleClassProvider.getBazelStarlarkEnvironment(), + directories.getWorkspace(), + ImmutableMap.of()))) .setPackageValidator( (pkg, handler) -> { // Delegate to late-bound this.validator. @@ -212,8 +221,10 @@ protected void setBuildLanguageOptions(String... options) throws Exception { } protected Target getTarget(String label) - throws NoSuchPackageException, NoSuchTargetException, - LabelSyntaxException, InterruptedException { + throws NoSuchPackageException, + NoSuchTargetException, + LabelSyntaxException, + InterruptedException { return getTarget(Label.parseCanonical(label)); } @@ -258,8 +269,9 @@ protected static String genRule(String rule, String name, String... body) { } /** - * A utility function which generates the "deps" clause for a build file - * rule from a list of targets. + * A utility function which generates the "deps" clause for a build file rule from a list of + * targets. + * * @param depTargets the list of targets. * @return a string containing the deps clause */ diff --git a/src/test/java/com/google/devtools/build/lib/pkgcache/BUILD b/src/test/java/com/google/devtools/build/lib/pkgcache/BUILD index 486cb6eff657c5..63d62a3ce7098d 100644 --- a/src/test/java/com/google/devtools/build/lib/pkgcache/BUILD +++ b/src/test/java/com/google/devtools/build/lib/pkgcache/BUILD @@ -104,6 +104,8 @@ java_library( "//src/main/java/com/google/devtools/build/lib/analysis:analysis_cluster", "//src/main/java/com/google/devtools/build/lib/analysis:blaze_directories", "//src/main/java/com/google/devtools/build/lib/analysis:server_directories", + "//src/main/java/com/google/devtools/build/lib/bazel/bzlmod:resolution_impl", + "//src/test/java/com/google/devtools/build/lib/bazel/bzlmod:util", "//src/main/java/com/google/devtools/build/lib/clock", "//src/main/java/com/google/devtools/build/lib/cmdline", "//src/main/java/com/google/devtools/build/lib/events", @@ -113,6 +115,7 @@ java_library( "//src/main/java/com/google/devtools/build/lib/rules:repository/repository_function", "//src/main/java/com/google/devtools/build/lib/skyframe:diff_awareness", "//src/main/java/com/google/devtools/build/lib/skyframe:precomputed_value", + "//src/main/java/com/google/devtools/build/lib/skyframe:sky_functions", "//src/main/java/com/google/devtools/build/lib/skyframe:skyframe_cluster", "//src/main/java/com/google/devtools/build/lib/util:abrupt_exit_exception", "//src/main/java/com/google/devtools/build/lib/util/io", diff --git a/src/test/java/com/google/devtools/build/lib/pkgcache/IncrementalLoadingTest.java b/src/test/java/com/google/devtools/build/lib/pkgcache/IncrementalLoadingTest.java index 6b45e7efcd0ee1..c308409950599e 100644 --- a/src/test/java/com/google/devtools/build/lib/pkgcache/IncrementalLoadingTest.java +++ b/src/test/java/com/google/devtools/build/lib/pkgcache/IncrementalLoadingTest.java @@ -26,6 +26,8 @@ import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; import com.google.devtools.build.lib.analysis.ServerDirectories; +import com.google.devtools.build.lib.bazel.bzlmod.FakeRegistry; +import com.google.devtools.build.lib.bazel.bzlmod.ModuleFileFunction; import com.google.devtools.build.lib.clock.BlazeClock; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.events.Reporter; @@ -45,6 +47,7 @@ import com.google.devtools.build.lib.skyframe.DiffAwareness; import com.google.devtools.build.lib.skyframe.PrecomputedValue; import com.google.devtools.build.lib.skyframe.SequencedSkyframeExecutor; +import com.google.devtools.build.lib.skyframe.SkyFunctions; import com.google.devtools.build.lib.skyframe.SkyframeExecutor; import com.google.devtools.build.lib.testutil.ManualClock; import com.google.devtools.build.lib.testutil.SkyframeExecutorTestHelper; @@ -452,7 +455,15 @@ public DiffAwareness maybeCreate(Root pathEntry, ImmutableSet ignoredPaths loadingMock.getProductName()); ConfiguredRuleClassProvider ruleClassProvider = loadingMock.createRuleClassProvider(); PackageFactory pkgFactory = - loadingMock.getPackageFactoryBuilderForTesting(directories).build(ruleClassProvider, fs); + loadingMock.getPackageFactoryBuilderForTesting(directories) + .setExtraSkyFunctions( + ImmutableMap.of( + SkyFunctions.MODULE_FILE, + new ModuleFileFunction( + ruleClassProvider.getBazelStarlarkEnvironment(), + directories.getWorkspace(), + ImmutableMap.of()))) + .build(ruleClassProvider, fs); skyframeExecutor = BazelSkyframeExecutorConstants.newBazelSkyframeExecutorBuilder() .setPkgFactory(pkgFactory) diff --git a/src/test/java/com/google/devtools/build/lib/query2/testutil/SkyframeQueryHelper.java b/src/test/java/com/google/devtools/build/lib/query2/testutil/SkyframeQueryHelper.java index 3086004e745ece..af85d6ab0ef39f 100644 --- a/src/test/java/com/google/devtools/build/lib/query2/testutil/SkyframeQueryHelper.java +++ b/src/test/java/com/google/devtools/build/lib/query2/testutil/SkyframeQueryHelper.java @@ -419,6 +419,7 @@ protected SkyframeExecutor createSkyframeExecutor(ConfiguredRuleClassProvider ru PrecomputedValue.injected( ModuleFileFunction.REGISTRIES, ImmutableList.of(registry.getUrl())), PrecomputedValue.injected(ModuleFileFunction.IGNORE_DEV_DEPS, false), + PrecomputedValue.injected(RepositoryDelegatorFunction.DISABLE_NATIVE_REPO_RULES, false), PrecomputedValue.injected( BazelModuleResolutionFunction.CHECK_DIRECT_DEPENDENCIES, CheckDirectDepsMode.WARNING), 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 abf5c618b75a5d..943afea62d580d 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 @@ -158,6 +158,7 @@ public void setupDelegator() throws Exception { ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder(); TestRuleClassProvider.addStandardRules(builder); builder + .clearWorkspaceFilePrefixForTesting() .clearWorkspaceFileSuffixForTesting() .addStarlarkBootstrap(new RepositoryBootstrap(new StarlarkRepositoryModule())); ConfiguredRuleClassProvider ruleClassProvider = builder.build(); diff --git a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java index 84bb5478ce15ee..6a2536dc6284bf 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java @@ -47,59 +47,6 @@ @RunWith(JUnit4.class) public class RepositoryFunctionTest extends BuildViewTestCase { - /** - * Exposes RepositoryFunction's protected methods to this class. - */ - @VisibleForTesting - static class TestingRepositoryFunction extends RepositoryFunction { - @Nullable - @Override - public RepositoryDirectoryValue.Builder fetch( - Rule rule, - Path outputDirectory, - BlazeDirectories directories, - SkyFunction.Environment env, - Map recordedInputValues, - SkyKey key) - throws InterruptedException { - return null; - } - - @Override - protected boolean isLocal(Rule rule) { - return false; - } - - @Override - public Class getRuleDefinition() { - return null; - } - } - - @Test - public void testGetTargetPathRelative() throws Exception { - Rule rule = scratchRule("external", "z", "local_repository(", - " name = 'z',", - " path = 'a/b/c',", - ")"); - assertThat( - TestingRepositoryFunction.getTargetPath( - TestingRepositoryFunction.getPathAttr(rule), rootDirectory)) - .isEqualTo(rootDirectory.getRelative("a/b/c").asFragment()); - } - - @Test - public void testGetTargetPathAbsolute() throws Exception { - Rule rule = scratchRule("external", "w", "local_repository(", - " name = 'w',", - " path = '/a/b/c',", - ")"); - assertThat( - TestingRepositoryFunction.getTargetPath( - TestingRepositoryFunction.getPathAttr(rule), rootDirectory)) - .isEqualTo(PathFragment.create("/a/b/c")); - } - private static void assertMarkerFileEscaping(String testCase) { String escaped = RepositoryDelegatorFunction.escape(testCase); assertThat(RepositoryDelegatorFunction.unescape(escaped)).isEqualTo(testCase); diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/AbstractCollectPackagesUnderDirectoryTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/AbstractCollectPackagesUnderDirectoryTest.java index 6184d87980eda3..fda32805a973ee 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/AbstractCollectPackagesUnderDirectoryTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/AbstractCollectPackagesUnderDirectoryTest.java @@ -34,6 +34,7 @@ import com.google.devtools.build.lib.pkgcache.PathPackageLocator; import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunction; import com.google.devtools.build.lib.runtime.QuiescingExecutorsImpl; +import com.google.devtools.build.lib.skyframe.packages.PackageFactoryBuilderWithSkyframeForTesting; import com.google.devtools.build.lib.testing.common.FakeOptions; import com.google.devtools.build.lib.testutil.MoreAsserts; import com.google.devtools.build.lib.testutil.Scratch; @@ -288,17 +289,18 @@ private void initEvaluator() throws AbruptExitException, InterruptedException, I SkyframeExecutor skyframeExecutor = makeSkyframeExecutorFactory() .create( - TestPackageFactoryBuilderFactory.getInstance() - .builder(directories) + ((PackageFactoryBuilderWithSkyframeForTesting) + TestPackageFactoryBuilderFactory.getInstance().builder(directories)) + .setExtraSkyFunctions(getExtraSkyFunctions()) .build(ruleClassProvider, fileSystem), fileSystem, directories, new ActionKeyContext(), - /*workspaceStatusActionFactory=*/ null, - /*diffAwarenessFactories=*/ ImmutableList.of(), + /* workspaceStatusActionFactory= */ null, + /* diffAwarenessFactories= */ ImmutableList.of(), getExtraSkyFunctions(), SyscallCache.NO_CACHE, - /*repositoryHelpersHolder=*/ null, + /* repositoryHelpersHolder= */ null, SkyframeExecutor.SkyKeyStateReceiver.NULL_INSTANCE, BugReporter.defaultInstance()); skyframeExecutor.injectExtraPrecomputedValues( diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/BUILD b/src/test/java/com/google/devtools/build/lib/skyframe/BUILD index ce8364eb7960dd..cb69c0329f5851 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/BUILD +++ b/src/test/java/com/google/devtools/build/lib/skyframe/BUILD @@ -277,6 +277,7 @@ java_test( "//src/main/java/com/google/devtools/build/lib/skyframe:workspace_info", "//src/main/java/com/google/devtools/build/lib/skyframe:workspace_name_value", "//src/main/java/com/google/devtools/build/lib/skyframe/config", + "//src/main/java/com/google/devtools/build/lib/skyframe/packages:PackageFactoryBuilderWithSkyframeForTesting", "//src/main/java/com/google/devtools/build/lib/skyframe/rewinding", "//src/main/java/com/google/devtools/build/lib/skyframe/serialization", "//src/main/java/com/google/devtools/build/lib/skyframe/serialization:visible-for-serialization", diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/CollectPackagesUnderDirectoryTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/CollectPackagesUnderDirectoryTest.java index 0bc6a4df807db7..33edb4b0df4c15 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/CollectPackagesUnderDirectoryTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/CollectPackagesUnderDirectoryTest.java @@ -14,6 +14,8 @@ package com.google.devtools.build.lib.skyframe; import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.bazel.bzlmod.FakeRegistry; +import com.google.devtools.build.lib.bazel.bzlmod.ModuleFileFunction; import com.google.devtools.build.lib.packages.BuildFileName; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyFunctionName; @@ -37,7 +39,12 @@ protected List getBuildFileNamesByPriority() { @Override protected ImmutableMap getExtraSkyFunctions() { - return ImmutableMap.of(); + return ImmutableMap.of( + SkyFunctions.MODULE_FILE, + new ModuleFileFunction( + ruleClassProvider.getBazelStarlarkEnvironment(), + directories.getWorkspace(), + ImmutableMap.of())); } @Override diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java index c3eeb8c8bc4cef..47787ecac0c3c0 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java @@ -179,6 +179,7 @@ public SkyValue compute(SkyKey skyKey, Environment env) { RepositoryDelegatorFunction.REPOSITORY_OVERRIDES.set(differencer, ImmutableMap.of()); RepositoryDelegatorFunction.FORCE_FETCH.set( differencer, RepositoryDelegatorFunction.FORCE_FETCH_DISABLED); + RepositoryDelegatorFunction.DISABLE_NATIVE_REPO_RULES.set(differencer, false); RepositoryDelegatorFunction.VENDOR_DIRECTORY.set(differencer, Optional.empty()); RepositoryDelegatorFunction.RESOLVED_FILE_INSTEAD_OF_WORKSPACE.set( diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java index efc619ec1fa6ed..9410a3a6023774 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java @@ -192,6 +192,7 @@ public SkyValue compute(SkyKey skyKey, Environment env) { RepositoryDelegatorFunction.REPOSITORY_OVERRIDES.set(differencer, ImmutableMap.of()); RepositoryDelegatorFunction.FORCE_FETCH.set( differencer, RepositoryDelegatorFunction.FORCE_FETCH_DISABLED); + RepositoryDelegatorFunction.DISABLE_NATIVE_REPO_RULES.set(differencer, false); RepositoryDelegatorFunction.VENDOR_DIRECTORY.set(differencer, Optional.empty()); RepositoryDelegatorFunction.RESOLVED_FILE_INSTEAD_OF_WORKSPACE.set( diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/packages/BazelPackageLoaderTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/packages/BazelPackageLoaderTest.java index df680fbd1a7bf3..b160c1d588df18 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/packages/BazelPackageLoaderTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/packages/BazelPackageLoaderTest.java @@ -77,6 +77,8 @@ private static void mockEmbeddedTools(Path embeddedBinaries) throws IOException tools.getRelative("tools/cpp").createDirectoryAndParents(); tools.getRelative("tools/osx").createDirectoryAndParents(); FileSystemUtils.writeIsoLatin1(tools.getRelative("WORKSPACE"), ""); + FileSystemUtils.writeIsoLatin1(tools.getRelative("MODULE.bazel"), + "module(name='bazel_tools')"); FileSystemUtils.writeIsoLatin1(tools.getRelative("tools/cpp/BUILD"), ""); FileSystemUtils.writeIsoLatin1( tools.getRelative("tools/cpp/cc_configure.bzl"), @@ -103,6 +105,13 @@ private static void mockEmbeddedTools(Path embeddedBinaries) throws IOException "", "def http_jar(**kwargs):", " pass"); + FileSystemUtils.writeIsoLatin1( + tools.getRelative("tools/build_defs/repo/local.bzl"), + "def local_repository(**kwargs):", + " pass", + "", + "def new_local_repository(**kwargs):", + " pass"); FileSystemUtils.writeIsoLatin1( tools.getRelative("tools/build_defs/repo/utils.bzl"), "def maybe(repo_rule, name, **kwargs):", diff --git a/src/test/java/com/google/devtools/build/lib/testutil/TestRuleClassProvider.java b/src/test/java/com/google/devtools/build/lib/testutil/TestRuleClassProvider.java index 82500423693561..2dff998c2eb332 100644 --- a/src/test/java/com/google/devtools/build/lib/testutil/TestRuleClassProvider.java +++ b/src/test/java/com/google/devtools/build/lib/testutil/TestRuleClassProvider.java @@ -82,7 +82,7 @@ private static ConfiguredRuleClassProvider createRuleClassProvider(boolean clear builder.addRuleDefinition(new TestingDummyRule()); builder.addRuleDefinition(new MockToolchainRule()); if (clearSuffix) { - builder.clearWorkspaceFileSuffixForTesting(); + builder.clearWorkspaceFileSuffixForTesting().clearWorkspaceFilePrefixForTesting(); } return builder.build(); } diff --git a/src/test/py/bazel/bzlmod/bazel_module_test.py b/src/test/py/bazel/bzlmod/bazel_module_test.py index 24ee20186f80aa..ce5eb93f6ecf08 100644 --- a/src/test/py/bazel/bzlmod/bazel_module_test.py +++ b/src/test/py/bazel/bzlmod/bazel_module_test.py @@ -20,6 +20,7 @@ import subprocess import tempfile from absl.testing import absltest + from src.test.py.bazel import test_base from src.test.py.bazel.bzlmod.test_utils import BazelRegistry from src.test.py.bazel.bzlmod.test_utils import scratchFile @@ -48,6 +49,7 @@ def setUp(self): # In ipv6 only network, this has to be enabled. # 'startup --host_jvm_args=-Djava.net.preferIPv6Addresses=true', 'build --noenable_workspace', + 'build --incompatible_disable_native_repo_rules', 'build --registry=' + self.main_registry.getURL(), # We need to have BCR here to make sure built-in modules like # bazel_tools can work. @@ -869,6 +871,28 @@ def testHttpJar(self): self.RunBazel(['build', '@my_jar//jar']) + def testNoEnableNativeRepoRules(self): + self.ScratchFile('MODULE.bazel') + self.ScratchFile('WORKSPACE.bzlmod', + ['local_repository(name="foo",path="foo")']) + self.ScratchFile('BUILD', ['filegroup(name="bar")']) + self.ScratchFile('foo/REPO.bazel') + self.ScratchFile('foo/BUILD', ['filegroup(name="foo")']) + + self.RunBazel( + ['build', '--enable_workspace', + '--noincompatible_disable_native_repo_rules', '@foo']) + _, _, stderr = self.RunBazel( + ['build', '--enable_workspace', + '--incompatible_disable_native_repo_rules', '@foo'], + allow_failure=True) + self.assertIn('Native repo rule local_repository is disabled', + '\n'.join(stderr)) + # a build that doesn't use the defined @foo should be ok. + self.RunBazel( + ['build', '--enable_workspace', + '--incompatible_disable_native_repo_rules', ':bar']) + if __name__ == '__main__': absltest.main() diff --git a/src/test/shell/bazel/BUILD b/src/test/shell/bazel/BUILD index ce24e5e875f7f0..eb05d50cca6b47 100644 --- a/src/test/shell/bazel/BUILD +++ b/src/test/shell/bazel/BUILD @@ -681,7 +681,10 @@ sh_test( ":test-deps", "//src/main/java/com/google/devtools/build/lib/skyframe/packages/testing:BazelPackageLoaderTester", ], - tags = ["no_windows"], + tags = [ + "no_windows", + "requires-network", + ], ) sh_test( diff --git a/src/test/shell/integration/discard_graph_edges_test.sh b/src/test/shell/integration/discard_graph_edges_test.sh index 46aaf23de42b8b..35868fa8dfd473 100755 --- a/src/test/shell/integration/discard_graph_edges_test.sh +++ b/src/test/shell/integration/discard_graph_edges_test.sh @@ -271,7 +271,7 @@ function test_packages_cleared() { package_count="$(extract_histogram_count "$histo_file" \ 'devtools\.build\.lib\..*\.Package$')" # A few packages aren't cleared. - [[ "$package_count" -le 25 ]] \ + [[ "$package_count" -le 26 ]] \ || fail "package count $package_count too high" glob_count="$(extract_histogram_count "$histo_file" "GlobValueWithImmutableSet$")" [[ "$glob_count" -le 1 ]] \