blob: cd8b5f26fe28ad31143f488abe5ce9cabab8c0e4 [file] [log] [blame]
// 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.packages;
import com.google.auto.value.AutoValue;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.devtools.build.lib.analysis.config.FeatureSet;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.CollectionUtils;
import com.google.devtools.build.lib.packages.License.DistributionType;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Starlark;
/**
* A group of {@link Package} argument values that may be provided by `package()` or `repo()` calls.
*/
@AutoValue
public abstract class PackageArgs {
public static final PackageArgs DEFAULT =
PackageArgs.builder()
.setDefaultVisibility(RuleVisibility.PRIVATE)
.setDefaultTestOnly(false)
.setFeatures(FeatureSet.EMPTY)
.setLicense(License.NO_LICENSE)
.setDistribs(License.DEFAULT_DISTRIB)
.setDefaultCompatibleWith(ImmutableSet.of())
.setDefaultRestrictedTo(ImmutableSet.of())
.setDefaultPackageMetadata(ImmutableList.of())
.build();
/** See {@link Package#getDefaultVisibility()}. */
@Nullable
abstract RuleVisibility defaultVisibility();
/** See {@link Package#getDefaultTestOnly()}. */
@Nullable
abstract Boolean defaultTestOnly();
/** See {@link Package#getDefaultDeprecation()}. */
@Nullable
abstract String defaultDeprecation();
/** See {@link Package#getFeatures()}. */
abstract FeatureSet features();
/** See {@link Package#getDefaultLicense()}. */
@Nullable
abstract License license();
/** See {@link Package#getDefaultDistribs()}. */
@Nullable
abstract ImmutableSet<DistributionType> distribs();
/** See {@link Package#getDefaultCompatibleWith()}. */
@Nullable
abstract ImmutableSet<Label> defaultCompatibleWith();
/** See {@link Package#getDefaultRestrictedTo()}. */
@Nullable
abstract ImmutableSet<Label> defaultRestrictedTo();
/** See {@link Package#getDefaultPackageMetadata()}. */
@Nullable
abstract ImmutableList<Label> defaultPackageMetadata();
public static Builder builder() {
return new AutoValue_PackageArgs.Builder().setFeatures(FeatureSet.EMPTY);
}
abstract Builder toBuilder();
/** Builder type for {@link PackageArgs}. */
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder setDefaultVisibility(RuleVisibility x);
public abstract Builder setDefaultTestOnly(Boolean x);
public abstract Builder setDefaultDeprecation(String x);
abstract FeatureSet features();
public abstract Builder setFeatures(FeatureSet x);
@CanIgnoreReturnValue
public final Builder mergeFeatures(FeatureSet x) {
return setFeatures(FeatureSet.merge(features(), x));
}
public abstract Builder setLicense(License x);
public abstract Builder setDistribs(Set<DistributionType> x);
/** Note that we don't check dupes in this method. Check beforehand! */
public abstract Builder setDefaultCompatibleWith(Iterable<Label> x);
/** Note that we don't check dupes in this method. Check beforehand! */
public abstract Builder setDefaultRestrictedTo(Iterable<Label> x);
@Nullable
abstract ImmutableList<Label> defaultPackageMetadata();
/** Note that we don't check dupes in this method. Check beforehand! */
public abstract Builder setDefaultPackageMetadata(List<Label> x);
public abstract PackageArgs build();
}
private static void throwIfHasDupes(List<Label> labels, String what) throws EvalException {
var dupes = ImmutableSortedSet.copyOf(CollectionUtils.duplicatedElementsOf(labels));
if (!dupes.isEmpty()) {
throw Starlark.errorf("duplicate label(s) in %s: %s", what, Joiner.on(", ").join(dupes));
}
}
/**
* Processes the given Starlark parameter to the {@code package()/repo()} call into a field on a
* {@link Builder} object.
*/
public static void processParam(
String name, Object rawValue, String what, LabelConverter labelConverter, Builder builder)
throws EvalException {
if (name.equals("default_visibility")) {
List<Label> value = BuildType.LABEL_LIST.convert(rawValue, what, labelConverter);
builder.setDefaultVisibility(RuleVisibility.parse(value));
} else if (name.equals("default_testonly")) {
Boolean value = Type.BOOLEAN.convert(rawValue, what, labelConverter);
builder.setDefaultTestOnly(value);
} else if (name.equals("default_deprecation")) {
String value = Type.STRING.convert(rawValue, what, labelConverter);
builder.setDefaultDeprecation(value);
} else if (name.equals("features")) {
List<String> value = Type.STRING_LIST.convert(rawValue, what, labelConverter);
builder.mergeFeatures(FeatureSet.parse(value));
} else if (name.equals("licenses")) {
License value = BuildType.LICENSE.convert(rawValue, what, labelConverter);
builder.setLicense(value);
} else if (name.equals("distribs")) {
Set<DistributionType> value = BuildType.DISTRIBUTIONS.convert(rawValue, what, labelConverter);
builder.setDistribs(value);
} else if (name.equals("default_compatible_with")) {
List<Label> value = BuildType.LABEL_LIST.convert(rawValue, what, labelConverter);
throwIfHasDupes(value, name);
builder.setDefaultCompatibleWith(value);
} else if (name.equals("default_restricted_to")) {
List<Label> value = BuildType.LABEL_LIST.convert(rawValue, what, labelConverter);
throwIfHasDupes(value, name);
builder.setDefaultRestrictedTo(value);
} else if (name.equals("default_applicable_licenses")
|| name.equals("default_package_metadata")) {
List<Label> value = BuildType.LABEL_LIST.convert(rawValue, what, labelConverter);
if (builder.defaultPackageMetadata() != null) {
throw Starlark.errorf(
"Can not set both default_package_metadata and default_applicable_licenses."
+ " Move all declarations to default_package_metadata.");
}
throwIfHasDupes(value, name);
builder.setDefaultPackageMetadata(value);
} else {
throw Starlark.errorf("unexpected keyword argument: %s", name);
}
}
/**
* Returns a new {@link PackageArgs} containing the result of merging {@code other} into {@code
* this}. {@code other}'s fields take precedence if specified.
*/
public PackageArgs mergeWith(PackageArgs other) {
Builder builder = toBuilder();
if (other.defaultVisibility() != null) {
builder.setDefaultVisibility(other.defaultVisibility());
}
if (other.defaultTestOnly() != null) {
builder.setDefaultTestOnly(other.defaultTestOnly());
}
if (other.defaultDeprecation() != null) {
builder.setDefaultDeprecation(other.defaultDeprecation());
}
if (!other.features().equals(FeatureSet.EMPTY)) {
builder.mergeFeatures(other.features());
}
if (other.license() != null) {
builder.setLicense(other.license());
}
if (other.distribs() != null) {
builder.setDistribs(other.distribs());
}
if (other.defaultCompatibleWith() != null) {
builder.setDefaultCompatibleWith(other.defaultCompatibleWith());
}
if (other.defaultRestrictedTo() != null) {
builder.setDefaultRestrictedTo(other.defaultRestrictedTo());
}
if (other.defaultPackageMetadata() != null) {
builder.setDefaultPackageMetadata(other.defaultPackageMetadata());
}
return builder.build();
}
}