add Partition method to LabelListAttribute
It can be tedious to split a LabelListAttribute on all of the configuration axes, so LabelListAttribute.Partition can be used to do this based on a predicate function. Test: go test ./bazel Change-Id: I78ff8c24ce9c86bab5896290d8afe979d56545b6
This commit is contained in:
@@ -119,7 +119,7 @@ func (ll *LabelList) uniqueParentDirectories() []string {
|
||||
return dirs
|
||||
}
|
||||
|
||||
// Add inserts the label Label at the end of the LabelList.
|
||||
// Add inserts the label Label at the end of the LabelList.Includes.
|
||||
func (ll *LabelList) Add(label *Label) {
|
||||
if label == nil {
|
||||
return
|
||||
@@ -127,6 +127,14 @@ func (ll *LabelList) Add(label *Label) {
|
||||
ll.Includes = append(ll.Includes, *label)
|
||||
}
|
||||
|
||||
// AddExclude inserts the label Label at the end of the LabelList.Excludes.
|
||||
func (ll *LabelList) AddExclude(label *Label) {
|
||||
if label == nil {
|
||||
return
|
||||
}
|
||||
ll.Excludes = append(ll.Excludes, *label)
|
||||
}
|
||||
|
||||
// Append appends the fields of other labelList to the corresponding fields of ll.
|
||||
func (ll *LabelList) Append(other LabelList) {
|
||||
if len(ll.Includes) > 0 || len(other.Includes) > 0 {
|
||||
@@ -137,6 +145,30 @@ func (ll *LabelList) Append(other LabelList) {
|
||||
}
|
||||
}
|
||||
|
||||
// Partition splits a LabelList into two LabelLists depending on the return value
|
||||
// of the predicate.
|
||||
// This function preserves the Includes and Excludes, but it does not provide
|
||||
// that information to the partition function.
|
||||
func (ll *LabelList) Partition(predicate func(label Label) bool) (LabelList, LabelList) {
|
||||
predicated := LabelList{}
|
||||
unpredicated := LabelList{}
|
||||
for _, include := range ll.Includes {
|
||||
if predicate(include) {
|
||||
predicated.Add(&include)
|
||||
} else {
|
||||
unpredicated.Add(&include)
|
||||
}
|
||||
}
|
||||
for _, exclude := range ll.Excludes {
|
||||
if predicate(exclude) {
|
||||
predicated.AddExclude(&exclude)
|
||||
} else {
|
||||
unpredicated.AddExclude(&exclude)
|
||||
}
|
||||
}
|
||||
return predicated, unpredicated
|
||||
}
|
||||
|
||||
// UniqueSortedBazelLabels takes a []Label and deduplicates the labels, and returns
|
||||
// the slice in a sorted order.
|
||||
func UniqueSortedBazelLabels(originalLabels []Label) []Label {
|
||||
@@ -822,6 +854,29 @@ func (lla *LabelListAttribute) ResolveExcludes() {
|
||||
}
|
||||
}
|
||||
|
||||
// Partition splits a LabelListAttribute into two LabelListAttributes depending
|
||||
// on the return value of the predicate.
|
||||
// This function preserves the Includes and Excludes, but it does not provide
|
||||
// that information to the partition function.
|
||||
func (lla LabelListAttribute) Partition(predicate func(label Label) bool) (LabelListAttribute, LabelListAttribute) {
|
||||
predicated := LabelListAttribute{}
|
||||
unpredicated := LabelListAttribute{}
|
||||
|
||||
valuePartitionTrue, valuePartitionFalse := lla.Value.Partition(predicate)
|
||||
predicated.SetValue(valuePartitionTrue)
|
||||
unpredicated.SetValue(valuePartitionFalse)
|
||||
|
||||
for axis, selectValueLabelLists := range lla.ConfigurableValues {
|
||||
for config, labelList := range selectValueLabelLists {
|
||||
configPredicated, configUnpredicated := labelList.Partition(predicate)
|
||||
predicated.SetSelectValue(axis, config, configPredicated)
|
||||
unpredicated.SetSelectValue(axis, config, configUnpredicated)
|
||||
}
|
||||
}
|
||||
|
||||
return predicated, unpredicated
|
||||
}
|
||||
|
||||
// OtherModuleContext is a limited context that has methods with information about other modules.
|
||||
type OtherModuleContext interface {
|
||||
ModuleFromName(name string) (blueprint.Module, bool)
|
||||
|
@@ -310,6 +310,134 @@ func TestResolveExcludes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLabelListAttributePartition(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
input LabelListAttribute
|
||||
predicated LabelListAttribute
|
||||
unpredicated LabelListAttribute
|
||||
predicate func(label Label) bool
|
||||
}{
|
||||
{
|
||||
name: "move all to predicated partition",
|
||||
input: MakeLabelListAttribute(makeLabelList(
|
||||
[]string{"keep1", "throw1", "keep2", "throw2"},
|
||||
[]string{"keep1", "throw1", "keep2", "throw2"},
|
||||
)),
|
||||
predicated: MakeLabelListAttribute(makeLabelList(
|
||||
[]string{"keep1", "throw1", "keep2", "throw2"},
|
||||
[]string{"keep1", "throw1", "keep2", "throw2"},
|
||||
)),
|
||||
unpredicated: LabelListAttribute{},
|
||||
predicate: func(label Label) bool {
|
||||
return true
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "move all to unpredicated partition",
|
||||
input: MakeLabelListAttribute(makeLabelList(
|
||||
[]string{"keep1", "throw1", "keep2", "throw2"},
|
||||
[]string{"keep1", "throw1", "keep2", "throw2"},
|
||||
)),
|
||||
predicated: LabelListAttribute{},
|
||||
unpredicated: MakeLabelListAttribute(makeLabelList(
|
||||
[]string{"keep1", "throw1", "keep2", "throw2"},
|
||||
[]string{"keep1", "throw1", "keep2", "throw2"},
|
||||
)),
|
||||
predicate: func(label Label) bool {
|
||||
return false
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "partition includes and excludes",
|
||||
input: MakeLabelListAttribute(makeLabelList(
|
||||
[]string{"keep1", "throw1", "keep2", "throw2"},
|
||||
[]string{"keep1", "throw1", "keep2", "throw2"},
|
||||
)),
|
||||
predicated: MakeLabelListAttribute(makeLabelList(
|
||||
[]string{"keep1", "keep2"},
|
||||
[]string{"keep1", "keep2"},
|
||||
)),
|
||||
unpredicated: MakeLabelListAttribute(makeLabelList(
|
||||
[]string{"throw1", "throw2"},
|
||||
[]string{"throw1", "throw2"},
|
||||
)),
|
||||
predicate: func(label Label) bool {
|
||||
return strings.HasPrefix(label.Label, "keep")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "partition excludes only",
|
||||
input: MakeLabelListAttribute(makeLabelList(
|
||||
[]string{},
|
||||
[]string{"keep1", "throw1", "keep2", "throw2"},
|
||||
)),
|
||||
predicated: MakeLabelListAttribute(makeLabelList(
|
||||
[]string{},
|
||||
[]string{"keep1", "keep2"},
|
||||
)),
|
||||
unpredicated: MakeLabelListAttribute(makeLabelList(
|
||||
[]string{},
|
||||
[]string{"throw1", "throw2"},
|
||||
)),
|
||||
predicate: func(label Label) bool {
|
||||
return strings.HasPrefix(label.Label, "keep")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "partition includes only",
|
||||
input: MakeLabelListAttribute(makeLabelList(
|
||||
[]string{"keep1", "throw1", "keep2", "throw2"},
|
||||
[]string{},
|
||||
)),
|
||||
predicated: MakeLabelListAttribute(makeLabelList(
|
||||
[]string{"keep1", "keep2"},
|
||||
[]string{},
|
||||
)),
|
||||
unpredicated: MakeLabelListAttribute(makeLabelList(
|
||||
[]string{"throw1", "throw2"},
|
||||
[]string{},
|
||||
)),
|
||||
predicate: func(label Label) bool {
|
||||
return strings.HasPrefix(label.Label, "keep")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty partition",
|
||||
input: MakeLabelListAttribute(makeLabelList([]string{}, []string{})),
|
||||
predicated: LabelListAttribute{},
|
||||
unpredicated: LabelListAttribute{},
|
||||
predicate: func(label Label) bool {
|
||||
return true
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
predicated, unpredicated := tc.input.Partition(tc.predicate)
|
||||
if !predicated.Value.Equals(tc.predicated.Value) {
|
||||
t.Errorf("expected predicated labels to be %v; got %v", tc.predicated, predicated)
|
||||
}
|
||||
for axis, configs := range predicated.ConfigurableValues {
|
||||
tcConfigs, ok := tc.predicated.ConfigurableValues[axis]
|
||||
if !ok || !reflect.DeepEqual(configs, tcConfigs) {
|
||||
t.Errorf("expected predicated labels to be %v; got %v", tc.predicated, predicated)
|
||||
}
|
||||
}
|
||||
if !unpredicated.Value.Equals(tc.unpredicated.Value) {
|
||||
t.Errorf("expected unpredicated labels to be %v; got %v", tc.unpredicated, unpredicated)
|
||||
}
|
||||
for axis, configs := range unpredicated.ConfigurableValues {
|
||||
tcConfigs, ok := tc.unpredicated.ConfigurableValues[axis]
|
||||
if !ok || !reflect.DeepEqual(configs, tcConfigs) {
|
||||
t.Errorf("expected unpredicated labels to be %v; got %v", tc.unpredicated, unpredicated)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// labelAddSuffixForTypeMapper returns a LabelMapper that adds suffix to label name for modules of
|
||||
// typ
|
||||
func labelAddSuffixForTypeMapper(suffix, typ string) LabelMapper {
|
||||
|
Reference in New Issue
Block a user