Skip to content

fix(cli): honor a caller-forwarded --target_pattern_file - #1388

Merged
mcook42 merged 2 commits into
mainfrom
fix/target-pattern-file-conflict
Aug 14, 2026
Merged

fix(cli): honor a caller-forwarded --target_pattern_file#1388
mcook42 merged 2 commits into
mainfrom
fix/target-pattern-file-conflict

Conversation

@mcook42

@mcook42 mcook42 commented Aug 13, 2026

Copy link
Copy Markdown
Member

Split out of #1370 (fix 1 of 3). See that PR's description for full context on all three defects found in the same investigation.

A caller-forwarded --target_pattern_file conflicted with the default target pattern. run_bazel_task only suppressed its own --target-pattern-file setting, but Bazel's --bazel-flag=--target_pattern_file=<path> — what tools/bazel produces for every Bazel-native flag, and so what an IntelliJ BSP sync sends — was invisible to the runner. ctx.args.targets then fell back to its declared default (["..."]), which reaches Bazel as residue alongside the forwarded flag:

ERROR: Command-line target pattern and --target_pattern_file cannot both be specified

That pair has no last-wins rule in Bazel. It's a hard conflict, so the only decision run_bazel_task owns is whether to invent a pattern the user never typed. Every precedence question belongs to Bazel's own option parser. target_patterns() now asks the effective RunCommand (rc.flag_value("--target_pattern_file", ...)) whether a pattern file reached Bazel by any spelling, using the same last-wins / =-form / two-token matching as crates/bazelrc.

Test plan

  • New test cases — target_patterns in bazel_runner_test.axl: default forwarded when nothing supplies patterns; suppressed by a forwarded --bazel-flag; suppressed by aspect's own --target-pattern-file; explicit patterns always forwarded; the lookup is command-scoped. Verified locally: bazel run //crates/aspect-cli:aspect-cli -- dev test-bazel-runnerbazel_runner_test.axl: OK (10 sections).
  • New CI coverage — extends test-flags-task in both .buildkite/pipeline.yaml and .github/workflows/ci-workflows.yaml with one aspect build in the plugin's exact shape (--bazel-flag=--target_pattern_file=...), asserting the composed command line is accepted by Bazel.

Before / after (captured on main)

Check Before After
Plugin-shaped invocation cannot both be specified, exit 2 exit 0
Two-token --target_pattern_file <path> cannot both be specified exit 0
Pattern file from a .bazelrc line default pattern collided exit 0 — now suppresses the default too

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 46a452b5-91a0-4468-b131-e0c52960c3af

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@aspect-workflows

aspect-workflows Bot commented Aug 13, 2026

Copy link
Copy Markdown

✨ Aspect Workflows Tasks

📅 Thu Aug 13 22:32:37 UTC 2026

❌ 1 failed task

  • ❌ delivery-uncacheable [delivery] · ⏱ 17.1s · ✨ Aspect · 🐙 GitHub Actions
    💬 failed in deliver · Delivery failed (1 delivery fail)

⚠️ 3 flagged tasks

  • ⚠️ delivery-gha-debug [delivery] · ⏱ 51.3s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Delivery complete (1 delivered · 2 warn · 4 skipped)
  • ⚠️ delivery-gha [delivery] · ⏱ 53s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Delivery complete (1 delivered · 2 warn · 4 skipped)
  • ⚠️ delivery-uncacheable-warn [delivery] · ⏱ 13s · ✨ Aspect · 🐙 GitHub Actions
    💬 Delivery complete (1 warn)

✅ 29 successful tasks

  • ✅ axl-smoke-gha-bootstrap [build] · ⏱ 1m 22s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel build complete (1 built)
  • ✅ run-axl-smoke [run] · ⏱ 20.4s · 🐙 GitHub Actions · ☑️ Check
    💬 Ran //examples/deliverable:py_deliverable
  • ✅ run-axl-smoke-2 [run] · ⏱ 14.1s · 🐙 GitHub Actions · ☑️ Check
    💬 Ran //examples/deliverable:sh_deliverable
  • ✅ axl-tests-gha-bootstrap [build] · ⏱ 1m · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel build complete (1 built)
  • ✅ build-gha-debug [build] · ⏱ 6m 1s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel build complete (172 built)
  • ✅ build-gha [build] · ⏱ 7m 9s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel build complete (172 built)
  • ✅ build-gha-ephemeral [build] · ⏱ 1m 18s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel build complete (10 built)
  • ✅ buildifier-gha-debug [buildifier] · ⏱ 41.6s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ buildifier-gha [buildifier] · ⏱ 38.4s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ delivery-no-remote-exec [delivery] · ⏱ 6.5s · ✨ Aspect · 🐙 GitHub Actions
    💬 Delivery complete (no deliveries)
  • ✅ format-gha-debug [format] · ⏱ 1m 7s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ format-format-repeat-task [format] · ⏱ 1m 29s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ format-format-repeat-task-2 [format] · ⏱ 11.1s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ format-format-repeat-task-3 [format] · ⏱ 10s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ format-format-repeat-task-4 [format] · ⏱ 9.5s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ format-gha [format] · ⏱ 1m 23s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ gazelle-gha-debug [gazelle] · ⏱ 30.7s · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ gazelle-from-source-gha-debug [gazelle] · ⏱ 2m 34s · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ gazelle-from-source-gha [gazelle] · ⏱ 2m 3s · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ gazelle-gha [gazelle] · ⏱ 36.1s · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ init-shell [build] · ⏱ 33.4s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel build complete (10 built)
  • ✅ lint-gha-debug [lint] · ⏱ 1m 19s · 🐙 GitHub Actions · ☑️ Check
    💬 Lint complete (clean)
  • ✅ lint-gha [lint] · ⏱ 47s · 🐙 GitHub Actions · ☑️ Check
    💬 Lint complete (clean)
  • ✅ test-gha-debug [test] · ⏱ 11m 50s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (26/26 passed · 26 cached)
  • ✅ test-gha-ide-target-pattern-file [build] · ⏱ 20.5s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel build complete (1 built)
  • ✅ test-gha-coverage [test] · ⏱ 31.3s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (1/1 passed · 1 cached)
  • ✅ test-gha-target-pattern-file [test] · ⏱ 18.8s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (1/1 passed · 1 cached)
  • ✅ test-gha [test] · ⏱ 10m 2s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (26/26 passed · 26 cached)
  • ✅ test-gha-ephemeral [test] · ⏱ 1m 47s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (1/1 passed)

🔁 Reproduce

❌ delivery (delivery-uncacheable · delivery-gha-debug · delivery-gha · delivery-uncacheable-warn)

# --mode=always --track-state=false for off-runner with no state backend.
aspect delivery \
  --commit-sha=a4ac3d9f00f6ec2695ea6821d57bf809cf803db5 \
  --mode=always \
  --track-state=false \
  --dry-run=true

Install aspect: aspect.build/docs/cli/install


⏱ Last updated Thu Aug 13 22:53:07 UTC 2026 · 📊 GitHub API quota 3,054/15,000 (20% used, resets in 22m)
🚀 Powered by Aspect CLI (v0.0.0-dev)  |  Aspect Build · X · LinkedIn · YouTube

@mcook42
mcook42 force-pushed the fix/target-pattern-file-conflict branch from 67d1f81 to 54be6a9 Compare August 13, 2026 16:03
flagged = final_status == "warning",
)

def target_patterns(explicit: bool, cli_targets: list[str], own_pattern_file: str, rc, command: str) -> list[str]:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can rc have a type? I have no idea what it is...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I traced it back to lifecycle.axl.setup_phase where it's defined as

RunCommand | None: the active run command with `bazel_trait` (also
registered via `ctx.bazel.use_rc`), else `None`. Does not return when a
health check fails (step 4).

There are a few other places where the rc value is passed around, so to type this for real I'd probably need to follow up with another PR to correctly type the rc value throughout the call chain

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you can do that in a followup if the context is in your (or claudes) brain atm?

`run_bazel_task` only suppressed its target-pattern default for aspect's own
`--target-pattern-file` arg. Bazel's spelling reaching aspect as
`--bazel-flag=--target_pattern_file=<path>` — what `tools/bazel` produces for
every Bazel-native flag, and so what an IntelliJ BSP sync sends — lands in
`ctx.args.bazel_flags` instead, invisible there. `ctx.args.targets` then fell
back to its declared default `["..."]`, which reaches Bazel as residue
alongside the forwarded flag:

    ERROR: Command-line target pattern and --target_pattern_file
           cannot both be specified

That pair has no last-wins rule in Bazel — it is a hard conflict. So the only
decision this runner owns is whether to invent a pattern the user never typed;
every precedence question belongs to Bazel's own option parser.

A `RunCommand` is the *effective* option set, not just the rc file — CLI flags
live in it as the `<command line>` source — so
`rc.flag_value("--target_pattern_file", ...)` answers for the forwarded
spelling with the same last-wins / `=`-form / two-token matching as
`crates/bazelrc`. Reaching it only needed the ordering fixed: aspect's own
`--target-pattern-file` moves from `base_flags` (an *input* to `parse_rc`) to
the per-invocation `flags`, freeing patterns to resolve after the rc parse.
That also keeps the flag out of the rc's `always` bucket, so it is no longer
expanded for every command.

Explicit patterns are always forwarded, so Bazel emits the error above itself
and the runner's second spelling of it is dropped. The existence check on
`--target-pattern-file` stays, since aspect resolves that path.

Supersedes the reverted `forwarded_flag_value` scan (c993267 / 2af86d1),
which reimplemented Bazel's option parsing in AXL.
The unit tests cover target_patterns in isolation, but nothing exercised
it end to end: that a caller-forwarded --target_pattern_file, in the shape
the IntelliJ Bazel plugin produces (Bazel's own flag spelling behind
--bazel-flag), is a command line Bazel actually accepts.

Extend the existing test-flags-task step in both pipelines with one
aspect build in that shape.

Split out of the combined IDE/BSP smoke-test commit in #1370 — the
--build_event_binary_file half goes with that fix's own PR.
@mcook42
mcook42 force-pushed the fix/target-pattern-file-conflict branch from 54be6a9 to a4ac3d9 Compare August 13, 2026 22:24
@mcook42
mcook42 marked this pull request as ready for review August 14, 2026 14:32
@mcook42
mcook42 merged commit dd4a1dc into main Aug 14, 2026
74 checks passed
@mcook42
mcook42 deleted the fix/target-pattern-file-conflict branch August 14, 2026 14:33

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a4ac3d9f00

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

own_pattern_file = getattr(ctx.args, "target_pattern_file", "") if hasattr(ctx.args, "target_pattern_file") else ""
if own_pattern_file:
if not ctx.std.fs.exists(own_pattern_file):
fail("--target-pattern-file: file not found: " + own_pattern_file)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate missing pattern files before setup

When a user passes aspect build/test --target-pattern-file with a nonexistent path, this fail() now runs after setup_phase() has already sent the initial running TaskUpdate, and it aborts before the normal _emit_terminal() path sends final=True. In CI with the GitHub/Buildkite lifecycle handlers that initial surface/check is left in the setup/running state (or later orphaned) instead of being marked as the task failure; keep this validation before setup_phase() or emit a terminal failed update before aborting.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mcook42 please read over this and debate if it's worth thinking about

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants