| // Copyright 2014 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.pkgcache; |
| |
| |
| import com.google.common.base.Splitter; |
| import com.google.common.base.Strings; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.devtools.build.lib.actions.LocalHostCapacity; |
| import com.google.devtools.build.lib.cmdline.LabelSyntaxException; |
| import com.google.devtools.build.lib.cmdline.PackageIdentifier; |
| import com.google.devtools.build.lib.packages.ConstantRuleVisibility; |
| import com.google.devtools.build.lib.packages.RuleVisibility; |
| import com.google.devtools.build.lib.util.ResourceConverter; |
| import com.google.devtools.common.options.Converter; |
| import com.google.devtools.common.options.Converters; |
| import com.google.devtools.common.options.Option; |
| import com.google.devtools.common.options.OptionDocumentationCategory; |
| import com.google.devtools.common.options.OptionEffectTag; |
| import com.google.devtools.common.options.OptionMetadataTag; |
| import com.google.devtools.common.options.OptionsBase; |
| import com.google.devtools.common.options.OptionsParsingException; |
| import java.util.List; |
| |
| /** Options for configuring Packages -- loading and default behaviors. */ |
| public class PackageOptions extends OptionsBase { |
| |
| /** Converter for the {@code --default_visibility} option. */ |
| public static class DefaultVisibilityConverter extends Converter.Contextless<RuleVisibility> { |
| @Override |
| public RuleVisibility convert(String input) throws OptionsParsingException { |
| if (input.equals("public")) { |
| return ConstantRuleVisibility.PUBLIC; |
| } else if (input.equals("private")) { |
| return ConstantRuleVisibility.PRIVATE; |
| } else { |
| throw new OptionsParsingException("Not a valid default visibility: '" + input |
| + "' (should be 'public' or 'private'"); |
| } |
| } |
| |
| @Override |
| public String getTypeDescription() { |
| return "default visibility"; |
| } |
| } |
| |
| /** Converter for globbing threads. */ |
| public static class ParallelismConverter extends ResourceConverter { |
| public ParallelismConverter() throws OptionsParsingException { |
| super( |
| /* autoSupplier= */ () -> |
| (int) Math.ceil(LocalHostCapacity.getLocalHostCapacity().getCpuUsage()), |
| /* minValue= */ 1, |
| /* maxValue= */ Integer.MAX_VALUE); |
| } |
| } |
| |
| @Option( |
| name = "package_path", |
| defaultValue = "%workspace%", |
| converter = Converters.ColonSeparatedOptionListConverter.class, |
| documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, |
| effectTags = {OptionEffectTag.UNKNOWN}, |
| help = |
| "A colon-separated list of where to look for packages. " |
| + "Elements beginning with '%workspace%' are relative to the enclosing " |
| + "workspace. If omitted or empty, the default is the output of " |
| + "'bazel info default-package-path'.") |
| public List<String> packagePath; |
| |
| @Option( |
| name = "show_loading_progress", |
| defaultValue = "true", |
| documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, |
| effectTags = {OptionEffectTag.UNKNOWN}, |
| help = "If enabled, causes Bazel to print \"Loading package:\" messages.") |
| public boolean showLoadingProgress; |
| |
| @Option( |
| name = "deleted_packages", |
| defaultValue = "", |
| converter = CommaSeparatedPackageNameListConverter.class, |
| documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, |
| effectTags = {OptionEffectTag.UNKNOWN}, |
| help = |
| "A comma-separated list of names of packages which the " |
| + "build system will consider non-existent, even if they are " |
| + "visible somewhere on the package path.\n" |
| + "Use this option when deleting a subpackage 'x/y' of an " |
| + "existing package 'x'. For example, after deleting x/y/BUILD " |
| + "in your client, the build system may complain if it " |
| + "encounters a label '//x:y/z' if that is still provided by another " |
| + "package_path entry. Specifying --deleted_packages x/y avoids this " |
| + "problem." |
| ) |
| public List<PackageIdentifier> deletedPackages; |
| |
| @Option( |
| name = "default_visibility", |
| defaultValue = "private", |
| converter = DefaultVisibilityConverter.class, |
| documentationCategory = OptionDocumentationCategory.UNDOCUMENTED, |
| effectTags = {OptionEffectTag.UNKNOWN}, |
| help = |
| "Default visibility for packages that don't set it explicitly ('public' or " + "'private')." |
| ) |
| public RuleVisibility defaultVisibility; |
| |
| @Option( |
| name = "incompatible_enforce_config_setting_visibility", |
| // TODO(b/179944632): set this and --incompatible_config_setting_private_default_visibility |
| // to true, then make these no-ops, then remove. |
| defaultValue = "true", |
| documentationCategory = OptionDocumentationCategory.STARLARK_SEMANTICS, |
| effectTags = {OptionEffectTag.LOADING_AND_ANALYSIS}, |
| metadataTags = {OptionMetadataTag.INCOMPATIBLE_CHANGE}, |
| help = |
| "If true, enforce config_setting visibility restrictions. If false, every " |
| + "config_setting is visible to every target. See " |
| + "https://github.com/bazelbuild/bazel/issues/12932.") |
| public boolean enforceConfigSettingVisibility; |
| |
| @Option( |
| name = "incompatible_config_setting_private_default_visibility", |
| defaultValue = "false", |
| documentationCategory = OptionDocumentationCategory.STARLARK_SEMANTICS, |
| effectTags = {OptionEffectTag.LOADING_AND_ANALYSIS}, |
| metadataTags = {OptionMetadataTag.INCOMPATIBLE_CHANGE}, |
| help = |
| "If incompatible_enforce_config_setting_visibility=false, this is a noop. Else, if this" |
| + " flag is false, any config_setting without an explicit visibility attribute is" |
| + " //visibility:public. If this flag is true, config_setting follows the same" |
| + " visibility logic as all other rules. See" |
| + " https://github.com/bazelbuild/bazel/issues/12933.") |
| public boolean configSettingPrivateDefaultVisibility; |
| |
| @Option( |
| name = "legacy_globbing_threads", |
| defaultValue = "100", |
| converter = ParallelismConverter.class, |
| documentationCategory = OptionDocumentationCategory.UNDOCUMENTED, |
| effectTags = {OptionEffectTag.UNKNOWN}, |
| help = |
| "Number of threads to use for glob evaluation. Takes " |
| + ResourceConverter.FLAG_SYNTAX |
| + ". \"auto\" means to use a reasonable value derived from the machine's hardware" |
| + " profile (e.g. the number of processors).") |
| public int globbingThreads; |
| |
| @Option( |
| name = "experimental_max_directories_to_eagerly_visit_in_globbing", |
| defaultValue = "-1", |
| documentationCategory = OptionDocumentationCategory.UNDOCUMENTED, |
| effectTags = {OptionEffectTag.UNKNOWN}, |
| help = |
| "If non-negative, the first time a glob is evaluated in a package, the subdirectories of " |
| + "the package will be traversed in order to warm filesystem caches and compensate for " |
| + "lack of parallelism in globbing. At most this many directories will be visited." |
| ) |
| public int maxDirectoriesToEagerlyVisitInGlobbing; |
| |
| @Option( |
| name = "fetch", |
| defaultValue = "true", |
| documentationCategory = OptionDocumentationCategory.UNDOCUMENTED, |
| effectTags = {OptionEffectTag.UNKNOWN}, |
| help = "Allows the command to fetch external dependencies" |
| ) |
| public boolean fetch; |
| |
| @Option( |
| name = "experimental_check_output_files", |
| defaultValue = "true", |
| documentationCategory = OptionDocumentationCategory.UNDOCUMENTED, |
| effectTags = {OptionEffectTag.UNKNOWN}, |
| help = |
| "Check for modifications made to the output files of a build. Consider setting " |
| + "this flag to false if you don't expect these files to change outside of bazel " |
| + "since it will speed up subsequent runs as they won't have to check a " |
| + "previous run's cache.") |
| public boolean checkOutputFiles; |
| |
| /** A converter from strings containing comma-separated names of packages to lists of strings. */ |
| public static class CommaSeparatedPackageNameListConverter |
| extends Converter.Contextless<List<PackageIdentifier>> { |
| |
| private static final Splitter COMMA_SPLITTER = Splitter.on(','); |
| |
| @Override |
| public List<PackageIdentifier> convert(String input) throws OptionsParsingException { |
| if (Strings.isNullOrEmpty(input)) { |
| return ImmutableList.of(); |
| } |
| ImmutableList.Builder<PackageIdentifier> list = ImmutableList.builder(); |
| for (String s : COMMA_SPLITTER.split(input)) { |
| try { |
| list.add(PackageIdentifier.parse(s)); |
| } catch (LabelSyntaxException e) { |
| throw new OptionsParsingException(e.getMessage()); |
| } |
| } |
| return list.build(); |
| } |
| |
| @Override |
| public String getTypeDescription() { |
| return "comma-separated list of package names"; |
| } |
| |
| } |
| |
| public ImmutableSet<PackageIdentifier> getDeletedPackages() { |
| if (deletedPackages == null) { |
| return ImmutableSet.of(); |
| } |
| return ImmutableSet.copyOf(deletedPackages); |
| } |
| } |