From 878a3129fcfb3a73e64b90df7bd2629141d60266 Mon Sep 17 00:00:00 2001 From: Peter Ebden Date: Thu, 2 Nov 2023 15:18:18 +0000 Subject: [PATCH 01/10] Add targetset --- src/core/BUILD | 54 +++++-------------------------------- src/core/target_set.go | 53 ++++++++++++++++++++++++++++++++++++ src/core/target_set_test.go | 29 ++++++++++++++++++++ 3 files changed, 88 insertions(+), 48 deletions(-) create mode 100644 src/core/target_set.go create mode 100644 src/core/target_set_test.go diff --git a/src/core/BUILD b/src/core/BUILD index c9e9b6169c..c8645451c3 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -2,30 +2,10 @@ subinclude("//build_defs:benchmark") go_library( name = "core", - srcs = [ - "atomic_bool.go", - "atomic_float32.go", - "build_env.go", - "build_input.go", - "build_label.go", - "build_target.go", - "cache.go", - "command_replacements.go", - "config.go", - "config_flags.go", - "cycle_detector.go", - "graph.go", - "lock.go", - "package.go", - "previous_op.go", - "resources.go", - "stamp.go", - "state.go", - "subrepo.go", - "test_results.go", - "utils.go", - "version.go", - ], + srcs = glob( + ["*.go"], + exclude = ["*_test.go"], + ), pgo_file = "//:pgo", visibility = ["PUBLIC"], deps = [ @@ -52,29 +32,7 @@ go_library( go_test( name = "core_test", - srcs = [ - "build_env_test.go", - "build_input_test.go", - "build_label_fuzz_test.go", - "build_label_test.go", - "build_target_benchmark_test.go", - "build_target_test.go", - "command_replacements_test.go", - "config_test.go", - "cycle_detector_test.go", - "graph_benchmark_test.go", - "graph_test.go", - "label_parse_test.go", - "lock_test.go", - "package_test.go", - "previous_op_test.go", - "stamp_test.go", - "state_test.go", - "subrepo_test.go", - "test_results_test.go", - "utils_benchmark_test.go", - "utils_test.go", - ], + srcs = glob(["*_test.go"]), data = ["test_data"], filter_srcs = False, # As above deps = [ @@ -102,4 +60,4 @@ benchmark( name = "graph_benchmark", srcs = ["graph_benchmark_test.go"], deps = [":core"], -) +) \ No newline at end of file diff --git a/src/core/target_set.go b/src/core/target_set.go new file mode 100644 index 0000000000..cb8c38443b --- /dev/null +++ b/src/core/target_set.go @@ -0,0 +1,53 @@ +package core + +import ( + "sync" +) + +// A TargetSet contains a series of targets and supports efficiently checking for membership +// The zero value is not safe for use. +type TargetSet struct { + targets map[BuildLabel]struct{} + packages map[packageKey]struct{} + mutex sync.RWMutex +} + +// NewTargetSet returns a new TargetSet. +func NewTargetSet() *TargetSet { + return &TargetSet{ + targets: map[BuildLabel]struct{}{}, + packages: map[packageKey]struct{}{}, + } +} + +// Add adds a new target to this set. +func (ts *TargetSet) Add(label BuildLabel) { + ts.mutex.Lock() + defer ts.mutex.Unlock() + if label.IsAllSubpackages() { + panic("TargetSet doesn't support ... labels") + } else if label.IsAllTargets() { + ts.packages[label.packageKey()] = struct{}{} + } else { + ts.targets[label] = struct{}{} + } +} + +// Match checks if this label is covered by the set (either explicitly or via :all) +func (ts *TargetSet) Match(label BuildLabel) bool { + ts.mutex.RLock() + defer ts.mutex.RUnlock() + if _, present := ts.targets[label]; present { + return true + } + _, present := ts.packages[label.packageKey()] + return present +} + +// MatchExact checks if this label was explicitly added to the set (i.e. :all doesn't count) +func (ts *TargetSet) MatchExact(label BuildLabel) bool { + ts.mutex.RLock() + defer ts.mutex.RUnlock() + _, present := ts.targets[label] + return present +} diff --git a/src/core/target_set_test.go b/src/core/target_set_test.go new file mode 100644 index 0000000000..5bc1c7b0e2 --- /dev/null +++ b/src/core/target_set_test.go @@ -0,0 +1,29 @@ +package core + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestTargetSetMatch(t *testing.T) { + ts := NewTargetSet() + ts.Add(ParseBuildLabel("//src/core:core", "")) + ts.Add(ParseBuildLabel("//src/parse:all", "")) + assert.True(t, ts.Match(ParseBuildLabel("//src/core:core", ""))) + assert.False(t, ts.Match(ParseBuildLabel("//src/core:core_test", ""))) + assert.True(t, ts.Match(ParseBuildLabel("//src/parse:parse", ""))) + assert.True(t, ts.Match(ParseBuildLabel("//src/parse:parse_test", ""))) + assert.False(t, ts.Match(ParseBuildLabel("//src/build", ""))) +} + +func TestTargetSetMatchExact(t *testing.T) { + ts := NewTargetSet() + ts.Add(ParseBuildLabel("//src/core:core", "")) + ts.Add(ParseBuildLabel("//src/parse:all", "")) + assert.True(t, ts.MatchExact(ParseBuildLabel("//src/core:core", ""))) + assert.False(t, ts.MatchExact(ParseBuildLabel("//src/core:core_test", ""))) + assert.False(t, ts.MatchExact(ParseBuildLabel("//src/parse:parse", ""))) + assert.False(t, ts.MatchExact(ParseBuildLabel("//src/parse:parse_test", ""))) + assert.False(t, ts.MatchExact(ParseBuildLabel("//src/build", ""))) +} From 4a96e39264cce33c5cf5f8cf719d5faece7a9576 Mon Sep 17 00:00:00 2001 From: Peter Ebden Date: Thu, 2 Nov 2023 15:20:37 +0000 Subject: [PATCH 02/10] start using it --- src/core/state.go | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/core/state.go b/src/core/state.go index 65410ead66..c545bf009c 100644 --- a/src/core/state.go +++ b/src/core/state.go @@ -286,8 +286,7 @@ type stateProgress struct { // The set of known states allStates []*BuildState // Targets that we were originally requested to build - originalTargets []BuildLabel - originalTargetMutex sync.Mutex + originalTargets TargetSet // True if something about the build has failed. failed atomicBool // True if >= 1 target has failed to build @@ -423,14 +422,10 @@ func (state *BuildState) IsOriginalTarget(target *BuildTarget) bool { } func (state *BuildState) isOriginalTarget(target *BuildTarget, exact bool) bool { - state.progress.originalTargetMutex.Lock() - defer state.progress.originalTargetMutex.Unlock() - for _, original := range state.progress.originalTargets { - if original == target.Label || (!exact && original.IsAllTargets() && original.PackageName == target.Label.PackageName && state.ShouldInclude(target)) { - return true - } + if exact { + return state.progress.originalTargets.MatchExact(target.Label) } - return false + return state.progress.originalTargets.Match(target.Label) && state.ShouldInclude(target) } // IsOriginalTargetOrParent is like IsOriginalTarget but checks the target's parent too (if it has one) @@ -480,9 +475,7 @@ func (state *BuildState) AddOriginalTarget(label BuildLabel, addToList bool) { } } if addToList { - state.progress.originalTargetMutex.Lock() - state.progress.originalTargets = append(state.progress.originalTargets, label) - state.progress.originalTargetMutex.Unlock() + state.progress.originalTargets.Add(label) } state.addPendingParse(label, OriginalTarget, ParseModeNormal) } From 8bcf6f2ec843b45b1e5300c827e5ad1e5dad2acd Mon Sep 17 00:00:00 2001 From: Peter Ebden Date: Thu, 2 Nov 2023 15:34:12 +0000 Subject: [PATCH 03/10] Add AllTargets --- src/core/build_label.go | 36 ++++++++++++++++++++++++++++++++++-- src/core/state.go | 13 ++++--------- src/core/target_set.go | 16 ++++++++++++++++ src/core/target_set_test.go | 14 ++++++++++++++ 4 files changed, 68 insertions(+), 11 deletions(-) diff --git a/src/core/build_label.go b/src/core/build_label.go index c59c0eac9a..384a1f4843 100644 --- a/src/core/build_label.go +++ b/src/core/build_label.go @@ -284,10 +284,33 @@ func (label BuildLabel) Includes(that BuildLabel) bool { return false } +// Compare compares this build label to another one (suitable for using with slices.SortFunc) +func (label BuildLabel) Compare(other BuildLabel) int { + if label.Subrepo != other.Subrepo { + if label.Subrepo < other.Subrepo { + return -1 + } + return 1 + } else if label.PackageName != other.PackageName { + if label.PackageName < other.PackageName { + return -1 + } + return 1 + } else if label.Name != other.Name { + if label.Name < other.Name { + return -1 + } + return 1 + } + return 0 +} + // Less returns true if this build label would sort less than another one. func (label BuildLabel) Less(other BuildLabel) bool { - if label.PackageName == other.PackageName { - return label.Name < other.Name + if label.Subrepo != other.Subrepo { + return label.Subrepo < other.Subrepo + } else if label.PackageName != other.PackageName { + return label.PackageName < other.PackageName } return label.PackageName < other.PackageName } @@ -535,6 +558,15 @@ func (key packageKey) String() string { return key.Name } +// BuildLabel returns a build label representing this package key. +func (key packageKey) BuildLabel() BuildLabel { + return BuildLabel{ + Subrepo: key.Subrepo, + PackageName: key.Name, + Name: "all", + } +} + // LooksLikeABuildLabel returns true if the string appears to be a build label, false if not. // Useful for cases like rule sources where sources can be a filename or a label. func LooksLikeABuildLabel(str string) bool { diff --git a/src/core/state.go b/src/core/state.go index c545bf009c..8a78b62b4e 100644 --- a/src/core/state.go +++ b/src/core/state.go @@ -286,7 +286,7 @@ type stateProgress struct { // The set of known states allStates []*BuildState // Targets that we were originally requested to build - originalTargets TargetSet + originalTargets *TargetSet // True if something about the build has failed. failed atomicBool // True if >= 1 target has failed to build @@ -695,18 +695,12 @@ func (state *BuildState) NumDone() int { // ExpandOriginalLabels expands any pseudo-labels (ie. :all, ... has already been resolved to a bunch :all targets) // from the set of original labels. This will exclude non-test targets when we're building for test. func (state *BuildState) ExpandOriginalLabels() BuildLabels { - state.progress.originalTargetMutex.Lock() - targets := state.progress.originalTargets[:] - state.progress.originalTargetMutex.Unlock() - return state.ExpandLabels(targets) + return state.ExpandLabels(state.progress.originalTargets.AllTargets()) } // ExpandAllOriginalLabels is the same as ExpandOriginalLabels except it always includes non-test targets func (state *BuildState) ExpandAllOriginalLabels() BuildLabels { - state.progress.originalTargetMutex.Lock() - targets := state.progress.originalTargets[:] - state.progress.originalTargetMutex.Unlock() - return state.expandLabels(targets, false) + return state.expandLabels(state.progress.originalTargets.AllTargets(), false) } func AnnotateLabels(labels []BuildLabel) []AnnotatedOutputLabel { @@ -1387,6 +1381,7 @@ func NewBuildState(config *Configuration) *BuildState { packageWaits: cmap.New[packageKey, chan struct{}](cmap.DefaultShardCount, hashPackageKey), internalResults: make(chan *BuildResult, 1000), cycleDetector: cycleDetector{graph: graph}, + originalTargets: NewTargetSet(), }, initOnce: new(sync.Once), preloadDownloadOnce: new(sync.Once), diff --git a/src/core/target_set.go b/src/core/target_set.go index cb8c38443b..26dd135e3e 100644 --- a/src/core/target_set.go +++ b/src/core/target_set.go @@ -1,6 +1,7 @@ package core import ( + "slices" "sync" ) @@ -51,3 +52,18 @@ func (ts *TargetSet) MatchExact(label BuildLabel) bool { _, present := ts.targets[label] return present } + +// AllTargets returns a copy of the set of targets +func (ts *TargetSet) AllTargets() []BuildLabel { + ts.mutex.RLock() + defer ts.mutex.RUnlock() + ret := make([]BuildLabel, 0, len(ts.targets)+len(ts.packages)) + for target := range ts.targets { + ret = append(ret, target) + } + for pkg := range ts.packages { + ret = append(ret, pkg.BuildLabel()) + } + slices.SortFunc(ret, BuildLabel.Compare) + return ret +} diff --git a/src/core/target_set_test.go b/src/core/target_set_test.go index 5bc1c7b0e2..340b508b9b 100644 --- a/src/core/target_set_test.go +++ b/src/core/target_set_test.go @@ -27,3 +27,17 @@ func TestTargetSetMatchExact(t *testing.T) { assert.False(t, ts.MatchExact(ParseBuildLabel("//src/parse:parse_test", ""))) assert.False(t, ts.MatchExact(ParseBuildLabel("//src/build", ""))) } + +func TestAllTargets(t *testing.T) { + ts := NewTargetSet() + labels := []BuildLabel{ + ParseBuildLabel("//src/core:core", ""), + ParseBuildLabel("//src/core:core_test", ""), + ParseBuildLabel("//src/parse:all", ""), + ParseBuildLabel("//src/parse:parse_test", ""), + } + for _, label := range labels { + ts.Add(label) + } + assert.Equal(t, labels, ts.AllTargets()) +} From 0ee7324e51c7711e73c7fe4ae36dbc797adf5104 Mon Sep 17 00:00:00 2001 From: Peter Ebden Date: Thu, 2 Nov 2023 15:41:43 +0000 Subject: [PATCH 04/10] Update a couple of tests --- src/core/build_label.go | 2 +- src/core/state_test.go | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/core/build_label.go b/src/core/build_label.go index 384a1f4843..4826098c7f 100644 --- a/src/core/build_label.go +++ b/src/core/build_label.go @@ -312,7 +312,7 @@ func (label BuildLabel) Less(other BuildLabel) bool { } else if label.PackageName != other.PackageName { return label.PackageName < other.PackageName } - return label.PackageName < other.PackageName + return label.Name < other.Name } // Paths is an implementation of BuildInput interface; we use build labels directly as inputs. diff --git a/src/core/state_test.go b/src/core/state_test.go index 5ac86a07ae..c10d0b5686 100644 --- a/src/core/state_test.go +++ b/src/core/state_test.go @@ -59,7 +59,8 @@ func TestExpandVisibleOriginalTargets(t *testing.T) { func TestExpandOriginalSubLabels(t *testing.T) { state := NewDefaultBuildState() - state.AddOriginalTarget(BuildLabel{PackageName: "src/core", Name: "..."}, true) + state.AddOriginalTarget(BuildLabel{PackageName: "src/core", Name: "all"}, true) + state.AddOriginalTarget(BuildLabel{PackageName: "src/core/tests", Name: "all"}, true) state.Include = []string{"go"} state.Exclude = []string{"py"} addTarget(state, "//src/core:target1", "go") @@ -76,17 +77,18 @@ func TestExpandOriginalSubLabels(t *testing.T) { func TestExpandOriginalLabelsOrdering(t *testing.T) { state := NewDefaultBuildState() state.AddOriginalTarget(BuildLabel{PackageName: "src/parse", Name: "parse"}, true) - state.AddOriginalTarget(BuildLabel{PackageName: "src/core", Name: "..."}, true) + state.AddOriginalTarget(BuildLabel{PackageName: "src/core", Name: "all"}, true) + state.AddOriginalTarget(BuildLabel{PackageName: "src/core/tests", Name: "all"}, true) state.AddOriginalTarget(BuildLabel{PackageName: "src/build", Name: "build"}, true) addTarget(state, "//src/core:target1", "go") addTarget(state, "//src/core:target2", "py") addTarget(state, "//src/core/tests:target3", "go") expected := BuildLabels{ - {PackageName: "src/parse", Name: "parse"}, + {PackageName: "src/build", Name: "build"}, {PackageName: "src/core", Name: "target1"}, {PackageName: "src/core", Name: "target2"}, {PackageName: "src/core/tests", Name: "target3"}, - {PackageName: "src/build", Name: "build"}, + {PackageName: "src/parse", Name: "parse"}, } assert.Equal(t, expected, state.ExpandOriginalLabels()) } From 56ed27aebcec55ae437d5832c71c27001088ea78 Mon Sep 17 00:00:00 2001 From: Peter Ebden Date: Thu, 2 Nov 2023 15:53:20 +0000 Subject: [PATCH 05/10] Add tests --- src/core/build_label_test.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/core/build_label_test.go b/src/core/build_label_test.go index 8ee242f226..bd48a4f788 100644 --- a/src/core/build_label_test.go +++ b/src/core/build_label_test.go @@ -179,6 +179,38 @@ func TestSingleSlash(t *testing.T) { assert.Equal(t, BuildLabel{PackageName: "common/go/pool", Name: "pool"}, label) } +func TestLess(t *testing.T) { + foo := ParseBuildLabel("//third_party:foo", "") + bar := ParseBuildLabel("//third_party:bar", "") + assert.True(t, bar.Less(foo)) + assert.False(t, foo.Less(bar)) + assert.False(t, foo.Less(foo)) +} + +func TestLessSubrepo(t *testing.T) { + foo := ParseBuildLabel("//third_party:foo", "") + bar := ParseBuildLabel("///baz//third_party:bar", "") + assert.False(t, bar.Less(foo)) + assert.True(t, foo.Less(bar)) + assert.False(t, foo.Less(foo)) +} + +func TestCompare(t *testing.T) { + foo := ParseBuildLabel("//third_party:foo", "") + bar := ParseBuildLabel("//third_party:bar", "") + assert.Equal(t, -1, bar.Compare(foo)) + assert.Equal(t, 1, foo.Compare(bar)) + assert.Equal(t, 0, foo.Compare(foo)) +} + +func TestCompareSubrepo(t *testing.T) { + foo := ParseBuildLabel("//third_party:foo", "") + bar := ParseBuildLabel("///baz//third_party:bar", "") + assert.Equal(t, 1, bar.Compare(foo)) + assert.Equal(t, -1, foo.Compare(bar)) + assert.Equal(t, 0, foo.Compare(foo)) +} + func TestMain(m *testing.M) { // Used to support TestComplete, the function it's testing re-execs // itself thinking that it's actually plz. From 809836bfddd8c9d24d01cde826e19614ad6e3552 Mon Sep 17 00:00:00 2001 From: Peter Ebden Date: Thu, 2 Nov 2023 16:01:45 +0000 Subject: [PATCH 06/10] Preserve original ordering --- src/core/state_test.go | 4 ++-- src/core/target_set.go | 19 ++++++------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/core/state_test.go b/src/core/state_test.go index c10d0b5686..010988a24e 100644 --- a/src/core/state_test.go +++ b/src/core/state_test.go @@ -84,11 +84,11 @@ func TestExpandOriginalLabelsOrdering(t *testing.T) { addTarget(state, "//src/core:target2", "py") addTarget(state, "//src/core/tests:target3", "go") expected := BuildLabels{ - {PackageName: "src/build", Name: "build"}, + {PackageName: "src/parse", Name: "parse"}, {PackageName: "src/core", Name: "target1"}, {PackageName: "src/core", Name: "target2"}, {PackageName: "src/core/tests", Name: "target3"}, - {PackageName: "src/parse", Name: "parse"}, + {PackageName: "src/build", Name: "build"}, } assert.Equal(t, expected, state.ExpandOriginalLabels()) } diff --git a/src/core/target_set.go b/src/core/target_set.go index 26dd135e3e..de0a1f7c30 100644 --- a/src/core/target_set.go +++ b/src/core/target_set.go @@ -1,16 +1,16 @@ package core import ( - "slices" "sync" ) // A TargetSet contains a series of targets and supports efficiently checking for membership // The zero value is not safe for use. type TargetSet struct { - targets map[BuildLabel]struct{} - packages map[packageKey]struct{} - mutex sync.RWMutex + targets map[BuildLabel]struct{} + packages map[packageKey]struct{} + everything []BuildLabel + mutex sync.RWMutex } // NewTargetSet returns a new TargetSet. @@ -32,6 +32,7 @@ func (ts *TargetSet) Add(label BuildLabel) { } else { ts.targets[label] = struct{}{} } + ts.everything = append(ts.everything, label) } // Match checks if this label is covered by the set (either explicitly or via :all) @@ -57,13 +58,5 @@ func (ts *TargetSet) MatchExact(label BuildLabel) bool { func (ts *TargetSet) AllTargets() []BuildLabel { ts.mutex.RLock() defer ts.mutex.RUnlock() - ret := make([]BuildLabel, 0, len(ts.targets)+len(ts.packages)) - for target := range ts.targets { - ret = append(ret, target) - } - for pkg := range ts.packages { - ret = append(ret, pkg.BuildLabel()) - } - slices.SortFunc(ret, BuildLabel.Compare) - return ret + return ts.everything[:] } From 27fcfe9635296505a400eecd25f8263ec3c52369 Mon Sep 17 00:00:00 2001 From: Peter Ebden Date: Thu, 2 Nov 2023 16:04:36 +0000 Subject: [PATCH 07/10] Exclude gocritic for test files, my tests don't need any more criticism --- .golangci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.golangci.yml b/.golangci.yml index d168aaff55..d054da176b 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -23,6 +23,7 @@ issues: linters: - errcheck - dupl + - gocritic - path: src/core/config.go # The config struct is big & complex and there's usually only one. text: fieldalignment linters: From 5a544e4d3caeb3c4829e698c2f444641c9646deb Mon Sep 17 00:00:00 2001 From: Peter Ebden Date: Thu, 2 Nov 2023 16:22:31 +0000 Subject: [PATCH 08/10] Version bump --- ChangeLog | 1 + VERSION | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 39f6557f12..ac10566be3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,7 @@ Version 17.4.0 * Add all commit date formats to supported git_show() format verbs (#2930) * Fix reduce builtin (#2925) * Fix issue with completing idents in the language server (#2917) + * Improve performance when a large number of input targets are supplied (#2942) Version 17.3.1 -------------- diff --git a/VERSION b/VERSION index 4880bd2cdf..c2e4e0d9a9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -17.4.0-beta.3 +17.4.0-beta.4 From ce90345c1643d9db347b1386445c1ba7bc182d00 Mon Sep 17 00:00:00 2001 From: Peter Ebden Date: Thu, 2 Nov 2023 17:00:53 +0000 Subject: [PATCH 09/10] Fix IsOriginalTarget logic --- src/core/state.go | 3 ++- src/core/target_set.go | 7 ++++--- src/core/target_set_test.go | 20 +++++++++++++++----- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/core/state.go b/src/core/state.go index 8a78b62b4e..88de3cfd10 100644 --- a/src/core/state.go +++ b/src/core/state.go @@ -425,7 +425,8 @@ func (state *BuildState) isOriginalTarget(target *BuildTarget, exact bool) bool if exact { return state.progress.originalTargets.MatchExact(target.Label) } - return state.progress.originalTargets.Match(target.Label) && state.ShouldInclude(target) + matched, wasExact := state.progress.originalTargets.Match(target.Label) + return matched && (wasExact || state.ShouldInclude(target)) } // IsOriginalTargetOrParent is like IsOriginalTarget but checks the target's parent too (if it has one) diff --git a/src/core/target_set.go b/src/core/target_set.go index de0a1f7c30..7e4ae97abc 100644 --- a/src/core/target_set.go +++ b/src/core/target_set.go @@ -36,14 +36,15 @@ func (ts *TargetSet) Add(label BuildLabel) { } // Match checks if this label is covered by the set (either explicitly or via :all) -func (ts *TargetSet) Match(label BuildLabel) bool { +// The first return checks if it's matched, the second if the match was exact or not. +func (ts *TargetSet) Match(label BuildLabel) (bool, bool) { ts.mutex.RLock() defer ts.mutex.RUnlock() if _, present := ts.targets[label]; present { - return true + return true, true } _, present := ts.packages[label.packageKey()] - return present + return present, false } // MatchExact checks if this label was explicitly added to the set (i.e. :all doesn't count) diff --git a/src/core/target_set_test.go b/src/core/target_set_test.go index 340b508b9b..02e1af5be1 100644 --- a/src/core/target_set_test.go +++ b/src/core/target_set_test.go @@ -10,11 +10,21 @@ func TestTargetSetMatch(t *testing.T) { ts := NewTargetSet() ts.Add(ParseBuildLabel("//src/core:core", "")) ts.Add(ParseBuildLabel("//src/parse:all", "")) - assert.True(t, ts.Match(ParseBuildLabel("//src/core:core", ""))) - assert.False(t, ts.Match(ParseBuildLabel("//src/core:core_test", ""))) - assert.True(t, ts.Match(ParseBuildLabel("//src/parse:parse", ""))) - assert.True(t, ts.Match(ParseBuildLabel("//src/parse:parse_test", ""))) - assert.False(t, ts.Match(ParseBuildLabel("//src/build", ""))) + matched, exact := ts.Match(ParseBuildLabel("//src/core:core", "")) + assert.True(t, matched) + assert.True(t, exact) + matched, exact = ts.Match(ParseBuildLabel("//src/core:core_test", "")) + assert.False(t, matched) + assert.False(t, exact) + matched, exact = ts.Match(ParseBuildLabel("//src/parse:parse", "")) + assert.True(t, matched) + assert.False(t, exact) + matched, exact = ts.Match(ParseBuildLabel("//src/parse:parse_test", "")) + assert.True(t, matched) + assert.False(t, exact) + matched, exact = ts.Match(ParseBuildLabel("//src/build", "")) + assert.False(t, matched) + assert.False(t, exact) } func TestTargetSetMatchExact(t *testing.T) { From 2f195868f40d6c560e4f482f3de88ebc8f6cfdf5 Mon Sep 17 00:00:00 2001 From: Peter Ebden Date: Thu, 2 Nov 2023 17:06:21 +0000 Subject: [PATCH 10/10] goddamn tabses, we hates them --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ac10566be3..9ba31731e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,7 +11,7 @@ Version 17.4.0 * Add all commit date formats to supported git_show() format verbs (#2930) * Fix reduce builtin (#2925) * Fix issue with completing idents in the language server (#2917) - * Improve performance when a large number of input targets are supplied (#2942) + * Improve performance when a large number of input targets are supplied (#2942) Version 17.3.1 --------------