diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 7289b78d40..b7c1de2ec5 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -18,4 +18,4 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@v8 with: - version: v2.13 + version: v2.14 diff --git a/VERSION b/VERSION index a9374e34bd..e71c09b90e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -17.34.0-beta.3 +17.34.0-beta.4 diff --git a/src/plz/plz.go b/src/plz/plz.go index 22cc3d72e5..081f5d55a9 100644 --- a/src/plz/plz.go +++ b/src/plz/plz.go @@ -401,7 +401,19 @@ func (r *runner) recursiveParseTarget(ctx context.Context, label, dependent core g, gctx := r.group(ctx) for dep := range target.DeclaredDependencies() { g.Go(func() error { - return r.RecursiveParse(gctx, dep, target.Label) + if dep.IsAllTargets() { + return r.RecursiveParse(gctx, dep, target.Label) + } + // Resolve require/provide first, so we only descend into whatever is actually provided to this + // target (otherwise e.g. a proto_library would drag in the dependencies of every language it supports). + for t, err := range r.resolveTarget(gctx, dep, target) { + if err != nil { + return err + } else if err := r.RecursiveParse(gctx, t.Label, target.Label); err != nil { + return err + } + } + return nil }) } return g.Wait() @@ -418,6 +430,11 @@ func (r *runner) recursiveParsePackage(ctx context.Context, label, dependent cor } g, gctx := r.group(ctx) for _, target := range pkg.AllTargets() { + // Only descend into targets the user asked for; e.g. with --include we shouldn't parse the + // dependencies of everything else in the package (which can be arbitrarily expensive). + if dependent == core.OriginalTarget && !r.state.ShouldInclude(target) { + continue + } g.Go(func() error { // N.B. No need to deduplicate these; recursiveParse does that for the whole walk. return r.recursiveParseTarget(gctx, target.Label, label) @@ -779,9 +796,16 @@ func (r *runner) limiter(remote bool) limiter { func (r *runner) QueueOriginalTaskSet(ctx context.Context, targets []core.BuildLabel, needTest, needBuild bool) { for _, target := range ReadStdinLabels(targets) { - r.tasks.Go(func() error { - return r.queueOriginalTask(ctx, target, needTest, needBuild) - }) + // Queue these synchronously where we can so the original targets are registered in the order given; + // various commands print results in that order. Subrepo labels with ... have to build the subrepo + // before they can be expanded though, so they go async. + if target.IsAllSubpackages() && target.Subrepo != "" { + r.tasks.Go(func() error { + return r.queueOriginalTask(ctx, target, needTest, needBuild) + }) + } else if err := r.queueOriginalTask(ctx, target, needTest, needBuild); err != nil { + r.tasks.Go(func() error { return err }) + } } } diff --git a/test/include/BUILD b/test/include/BUILD index fbc8d8e4c6..4a89138cc4 100644 --- a/test/include/BUILD +++ b/test/include/BUILD @@ -20,3 +20,23 @@ please_repo_e2e_test( plz_command = "numtargets=$(plz query alltargets //:all --exclude 'ba*' | wc -l) && if [[ $numtargets -ne 1 ]]; then echo \"Expected 1 target. Got $numtargets\" && exit 1; fi", repo = "test_repo", ) + +# Test that --include stops us parsing the dependencies of targets that aren't included. +please_repo_e2e_test( + name = "include_skips_parsing_deps_test", + expected_output = { + "out.txt": "//unparsed_deps:wanted", + }, + plz_command = "plz query alltargets //unparsed_deps:all --include wanted > out.txt", + repo = "test_repo", +) + +# Test that targets given on the command line are reported in the order given. +please_repo_e2e_test( + name = "original_target_order_test", + expected_output = { + "out.txt": "//:target2\n//unparsed_deps:wanted\n//:target1", + }, + plz_command = "plz query filter //:target2 //unparsed_deps:wanted //:target1 > out.txt", + repo = "test_repo", +) diff --git a/test/include/test_repo/unparsed_deps/BUILD_FILE b/test/include/test_repo/unparsed_deps/BUILD_FILE new file mode 100644 index 0000000000..436bb34668 --- /dev/null +++ b/test/include/test_repo/unparsed_deps/BUILD_FILE @@ -0,0 +1,14 @@ +genrule( + name = "wanted", + outs = ["wanted.txt"], + cmd = "touch $OUT", + labels = ["wanted"], +) + +# This depends on a package that doesn't exist; it's fine as long as nothing tries to parse its dependencies. +genrule( + name = "unwanted", + outs = ["unwanted.txt"], + cmd = "touch $OUT", + deps = ["//does_not_exist:target"], +)