fix(cli): accept --swift-test-xunit-paths as the only report source - #1198
Merged
Conversation
`--swift-test-xunit-paths` is absent from every `required_unless_present_any`
list, so the usage its own help text documents
trunk upload --swift-test-xunit-paths out-swift-testing.xml,out.xml
fails at argument parsing:
error: the following required arguments were not provided:
--junit-paths <JUNIT_PATHS>
--bazel-bep-path <BAZEL_BEP_PATH>
--test-reports <TEST_REPORTS>
It is a real report source -- `coalesce_junit_path_wrappers` handles it on its
own branch and produces junit path wrappers from it -- so it belongs in those
lists alongside the other three.
The workaround it forces is worse than the error. Callers have to supply a
junit glob they do not want, and the obvious value, the report they are already
uploading, silently doubles every test: the two lists are appended rather than
reconciled, so each test arrives once with the file a language server resolved
and once with none. Measured on a 3-case suite uploaded both ways, the bundle
holds 6 cases, and because `file` feeds `gen_info_id` those are two distinct
tests rather than one test twice.
`upload_bundle_using_swift_test_xunit` could not catch either problem. It
inherits `CommandBuilder`'s default `--junit-paths ./*`, which both hid the
missing requirement and matched the two xunit files it writes into the repo
root -- so the test has been exercising the double-upload path all along. Its
assertions keyed a HashMap by test name, and a duplicate carries the same name,
so the second copy overwrote the first and nothing looked wrong.
So the test now passes no paths argument at all, via a new `PathsState::NoPaths`
that is distinct from a `None` paths_state, and asserts the exact case count.
That makes it a real test of standalone usage, and gives the duplication
somewhere to show up if it comes back.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
😎 Merged successfully - details. |
`PathsState` is the report-source selector, and this change's whole claim is that --swift-test-xunit-paths is a fourth source alongside junit, BEP, and xcresult. A `NoPaths` variant said the opposite: that the source was something smuggled past the selector through extra_args, with a second flag to suppress the default. Nothing else wanted "no source at all", so the variant existed only to work around its own framing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
It contrasted PathsState against extra_args, which the code no longer does, so it documented the shape of an earlier edit rather than the test. The assertion keeps its own comment, which says why the count is exact and what six would mean -- neither readable off the code. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
dfrankland
requested review from
TylerJang27,
acatxnamedvirtue and
max-trunk
September 10, 2026 19:40
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1198 +/- ##
==========================================
+ Coverage 83.63% 83.85% +0.22%
==========================================
Files 74 74
Lines 17573 17573
==========================================
+ Hits 14697 14736 +39
+ Misses 2876 2837 -39 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
`Limits::default()` sizes one resolution on a machine doing nothing else. A test binary starts a `sourcekit-lsp` per test, all at once, under coverage instrumentation and alongside the rest of the workspace's suite -- and a server that has not answered `initialize` inside `request_timeout` is abandoned rather than waited on, so every test in that process resolves to nothing. That is what the x86_64 musl runner hit: three of these failed at exactly 30.016s, the default timeout, while the four that ran once the machine quietened took 10s each. The same tests take 0.4s on aarch64 once warm. Only the clock moves; every value the tests assert on is still resolved the way the defaults resolve it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
TylerJang27
approved these changes
Sep 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
--swift-test-xunit-pathsis absent from everyrequired_unless_present_anylist, so the usage its own help text documents does not parse:It is a real report source —
coalesce_junit_path_wrappershandles it on its own branch and produces junit path wrappers from it — so it belongs in those lists alongside the other three. Adding it there is the whole fix.Why the workaround is worse than the error
Callers have to supply a junit glob they do not want. The obvious value, the report they are already uploading, silently doubles every test: the two lists are appended rather than reconciled, so each test arrives once carrying the file a language server resolved and once carrying none.
Measured against
0.15.5-beta.1on a 3-case suite, from a checkout with no Swift toolchain so nothing resolved:--junit-paths '<report glob>'--swift-test-xunit-paths <report>+ a glob matching nothingfilefeedsgen_info_id, so on a real checkout those six are two distinct tests rather than one test twice. Every consumer hitting this requirement has to pick between a glob they invented and a doubled upload.The test could not have caught either problem
upload_bundle_using_swift_test_xunitinheritsCommandBuilder's default--junit-paths ./*. That hid the missing requirement, and it also matches the two xunit files the test writes into the repo root — so the test has been exercising the double-upload path since it landed. Its assertions keyed aHashMapby test name, and a duplicate carries the same name, so the second copy overwrote the first and nothing looked wrong.It now passes the reports through a new
PathsState::SwiftTestXunitPathsvariant and asserts the exact case count.PathsStateis the report-source selector, so putting the flag there is the harness stating the same thing this change does — a fourth source alongside junit, BEP, and xcresult — rather than smuggling it past the selector throughextra_args. Selecting it also suppresses the default glob, which is what makes this a genuine test of standalone usage, and the count gives the duplication somewhere to surface if it returns.Not fixed here
If a caller passes an explicit
--junit-pathsglob that happens to match a file also named in--swift-test-xunit-paths, the double upload still happens. That is a live footgun for a monorepo using a broad glob like**/*.xmlnext to a Swift suite.Fixing it properly means excluding the swift-handled files from the expanded junit set, which has to happen inside
FileSetBuilder— the swift path uploads a rewritten temp copy, so the duplicate pair have different paths and a canonical-path dedup would not see them. That is a threaded exclusion parameter throughbuild_file_sets, and a separate concern from this argument-parsing fix. Happy to follow up if you want it.Verification
cargo checkand the test suite have not been run locally — this environment has neither the pinnednightly-2026-06-11toolchain nor the system OpenSSLopenssl-sysneeds, and I would rather say so than imply a green run. The change is four clap attribute lists, one enum variant with its match arm, and test assertions. CI is the gate; please don't merge on my word that it compiles.The parsing behaviour above was verified by running the released
0.15.5-beta.1binary directly.🤖 Generated with Claude Code