Skip to content

feat(cli): accept globs in --swift-test-xunit-paths - #1201

Merged
trunk-io[bot] merged 3 commits into
mainfrom
swift-test-xunit-globs
Sep 16, 2026
Merged

trunk-io[bot] merged 3 commits into
mainfrom
swift-test-xunit-globs

Conversation

@dfrankland

Copy link
Copy Markdown
Member

--swift-test-xunit-paths took literal filenames. handle_swift_test_xunit passed each comma-split value straight to File::open, so a pattern failed with failed to open ./junit*.xml: No such file or directory, and a repository with several test targets had to spell out every file swift test --xunit-output wrote. --junit-paths has always globbed, so one spelling of a path meant different things depending on which argument carried it.

What changed

Expansion now goes through the junit path's own, which brings its dedupe with it: matches are keyed by canonical path, so a file two patterns both match — or one reached through a symlink as well as directly — is parsed once rather than uploading every test it holds twice.

collect_files_per_glob only ever read junit_path off each wrapper it was given, so it now takes &[String] directly and expand_globs exposes the flattened result. That keeps one implementation rather than a second that drifts from it.

Two consequences worth a look in review

  • Relative values now resolve against the repo root, not the working directory, because that is what scan_from_glob does for junit globs. Only differs when the uploader runs outside the repo it is uploading for.
  • A value naming a file that is not there no longer fails on open. It matches nothing, exactly as a junit glob does, and the existing "No tests found in the provided swift test xunit paths" check decides whether that is an error. I first had literal (non-pattern) values keep the old hard error, on the grounds that the two filenames here are easy to misspell; that was scope I invented, and it's out.

Neither is a break for anyone on a release: the argument only exists in 0.15.5-beta.1/beta.2.

Testing

cargo test -p bundle passes (16 + 3). cargo test -p trunk-analytics-cli --test upload is 58 passed, 3 failed — the three swift_test_xunit tests, which need sourcekit-lsp for the declaration lookup and have no toolchain on my machine. All three fail at the same assertion, and upload_bundle_using_swift_test_xunit fails identically on unmodified origin/main, so it is the environment rather than this change. CI is the real check for those three, since it puts the Swift toolchain on PATH and sets REQUIRE_LANGUAGE_SERVER.

What that does verify locally: the cases.len() == 3 assertion runs before the declaration one in each, and passes in all three — including the new overlapping-glob-plus-symlink case, which is the dedupe.

New coverage:

  • bundle: four unit tests on expand_globs — two globs matching one file, a symlink to an already-matched file, repo-root-relative resolution, and a glob matching nothing. These need no Swift toolchain, so the expansion half is provable anywhere.
  • cli: swift_test_xunit_paths_are_globs, and a_swift_test_xunit_file_reached_twice_is_uploaded_once, which points a symlink at one fixture file and passes xunit*.xml,xunit.xml so three routes reach two files.

Fixture setup and bundle-reading in the existing test moved into helpers the new tests share.

Follow-ups, not in this PR

Both are accurate until this merges and should follow it.

🤖 Generated with Claude Code

The argument took literal filenames, so a repository with more than one test
target had to spell out every file `swift test --xunit-output` wrote, and a
pattern reached `File::open` verbatim and failed. `--junit-paths` has always
globbed, so the same spelling meant different things depending on which
argument carried it.

Expansion now goes through the junit path's own, which also brings its
dedupe: matches are keyed by canonical path, so a file two patterns both
match -- or one reached through a symlink as well as directly -- is parsed
once instead of uploading every test it holds twice.

`collect_files_per_glob` took junit wrappers to read one field off each, so
it now takes the globs themselves and `expand_globs` exposes the flattened
result. One implementation, rather than a second one that drifts.

Two consequences worth knowing. A relative value now resolves against the
repo root rather than the working directory, which is what `--junit-paths`
has always done and only differs when the uploader runs outside the repo. And
a value naming a file that is not there no longer fails on open -- it matches
nothing, exactly as a junit glob does, leaving the existing empty-results
check to decide whether that is an error.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@trunk-io

trunk-io Bot commented Sep 14, 2026

Copy link
Copy Markdown

😎 Merged successfully - details.

They only exercise `FileSetBuilder::expand_globs`, which is public, so
nothing about them needs to sit inside the module. As an integration test
they exercise the crate the way its callers do and cannot quietly come to
depend on a private detail.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@trunk-staging-io

trunk-staging-io Bot commented Sep 14, 2026

Copy link
Copy Markdown

Static BadgeStatic BadgeStatic Badge

Failed Test Failure Summary Logs
pending_quarantine_test should be quarantined when run with variant A test marked as pending was expected to fail but unexpectedly passed. Logs ↗︎
variant_quarantine_test should be quarantined when run with variant A test expected the sum of 2 + 2 to be 5, but it was actually 4, indicating a failing assertion. Logs ↗︎

View Full Report ↗︎Docs

Say what the code does and drop the rest: which argument historically
expanded differently, why a test needs no toolchain, what an uploaded
duplicate would look like downstream.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@trunk-io

trunk-io Bot commented Sep 14, 2026

Copy link
Copy Markdown

Static BadgeStatic BadgeStatic Badge

Failed Test Failure Summary Logs
pending_quarantine_test should be quarantined when run with variant A test marked as pending was expected to fail but unexpectedly passed. Logs ↗︎
variant_quarantine_test should be quarantined when run with variant A test expected the sum of 2 + 2 to be 5, but it was actually 4, indicating a failing assertion. Logs ↗︎

View Full Report ↗︎Docs

@codecov-commenter

codecov-commenter commented Sep 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.30769% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.93%. Comparing base (3da768f) to head (a41d520).

Files with missing lines Patch % Lines
cli/src/context.rs 71.42% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1201      +/-   ##
==========================================
+ Coverage   83.70%   83.93%   +0.22%     
==========================================
  Files          74       74              
  Lines       17652    17667      +15     
==========================================
+ Hits        14776    14828      +52     
+ Misses       2876     2839      -37     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

dfrankland added a commit to trunk-io/docs2 that referenced this pull request Sep 15, 2026
trunk-io/analytics-cli#1201 gives the argument the expansion `--junit-paths`
has always had, so "files, not globs" stops being true in the release these
pages already require.

One pattern reaches both files a run writes, which is a better example than
naming them, so the Swift Testing and GitHub Actions snippets now glob. Note
what the dedupe does while here: overlapping patterns cannot upload a test
twice, which is the question a glob raises and a file list does not.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@trunk-io
trunk-io Bot merged commit 266f305 into main Sep 16, 2026
35 checks passed
dfrankland added a commit to trunk-io/docs2 that referenced this pull request Sep 16, 2026
trunk-io/analytics-cli#1201 gives the argument the expansion `--junit-paths`
has always had, so "files, not globs" stops being true in the release these
pages already require.

One pattern reaches both files a run writes, which is a better example than
naming them, so the Swift Testing and GitHub Actions snippets now glob. Note
what the dedupe does while here: overlapping patterns cannot upload a test
twice, which is the question a glob raises and a file list does not.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants