xcodebuild-axi 0.1.9 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +152 -1
- package/README.md +25 -57
- package/dist/src/archive.d.ts +35 -6
- package/dist/src/archive.js +63 -21
- package/dist/src/archive.js.map +1 -1
- package/dist/src/commands/coverage.d.ts +13 -2
- package/dist/src/commands/coverage.js +314 -7
- package/dist/src/commands/coverage.js.map +1 -1
- package/dist/src/commands/export.d.ts +4 -4
- package/dist/src/commands/export.js +194 -11
- package/dist/src/commands/export.js.map +1 -1
- package/dist/src/commands/info.d.ts +2 -2
- package/dist/src/commands/info.js +56 -3
- package/dist/src/commands/info.js.map +1 -1
- package/dist/src/commands/result.d.ts +23 -3
- package/dist/src/commands/result.js +654 -7
- package/dist/src/commands/result.js.map +1 -1
- package/dist/src/surface.d.ts +7 -1
- package/dist/src/surface.js +41 -164
- package/dist/src/surface.js.map +1 -1
- package/dist/src/toon.d.ts +2 -0
- package/dist/src/toon.js +15 -0
- package/dist/src/toon.js.map +1 -1
- package/dist/src/xccov.d.ts +94 -0
- package/dist/src/xccov.js +178 -2
- package/dist/src/xccov.js.map +1 -1
- package/dist/src/xcodebuild.d.ts +18 -0
- package/dist/src/xcodebuild.js +38 -1
- package/dist/src/xcodebuild.js.map +1 -1
- package/dist/src/xcresult.d.ts +216 -0
- package/dist/src/xcresult.js +188 -4
- package/dist/src/xcresult.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,155 @@ Notable changes to `xcodebuild-axi`. Versions follow
|
|
|
4
4
|
[semver](https://semver.org/); the format follows
|
|
5
5
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
6
6
|
|
|
7
|
+
## [0.1.11] - 2026-09-21
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **`result --export <what>` gets files out of a bundle**: `attachments`,
|
|
12
|
+
`diagnostics`, `metrics`, or `evaluations`. A UI test's screenshots, the
|
|
13
|
+
diagnostics report `test --diagnostics` collects, and the CSVs behind a
|
|
14
|
+
performance measurement were all in the bundle and reachable only by shelling
|
|
15
|
+
out to `xcresulttool`.
|
|
16
|
+
|
|
17
|
+
It writes under `~/Library/Caches/xcodebuild-axi/exports/` by default, or
|
|
18
|
+
wherever `--to` says — never into the working tree, so asking what is in a CI
|
|
19
|
+
artifact cannot dirty the checkout it sits in. `--test`, `--filter '*.png'`
|
|
20
|
+
and `--failures` narrow what comes out, and each is **refused** where it does
|
|
21
|
+
not apply rather than ignored: a diagnostics report covers the whole run, so
|
|
22
|
+
`--test` beside it would answer a different question than the one asked.
|
|
23
|
+
|
|
24
|
+
The report is what landed and where, with each exported file tied back to the
|
|
25
|
+
test that produced it — a screenshot's filename is a UUID, and the manifest
|
|
26
|
+
is the only thing that makes it findable. `xcresulttool` narrates an
|
|
27
|
+
attachment export with one "Skipped export for <test>: no matching
|
|
28
|
+
attachments" per test, which is dropped.
|
|
29
|
+
|
|
30
|
+
- **`result --against <baseline.xcresult>`** answers the question CI actually
|
|
31
|
+
asks — not "did this run fail" but "did it fail in a way the last one did
|
|
32
|
+
not". It reports the counts on both sides and their direction
|
|
33
|
+
(`failures: 0 → 1 (+1 -0)`), then the tests that newly fail, the ones that
|
|
34
|
+
now pass, the ones added and removed, and any new warning. A failure the
|
|
35
|
+
baseline did not have is listed first, because it is the only part of a
|
|
36
|
+
comparison that stops a merge.
|
|
37
|
+
|
|
38
|
+
Two bundles with nothing in common — a build against a test run — get an
|
|
39
|
+
explicit answer saying so. `xcresulttool` prints a bare `null` there, which
|
|
40
|
+
is otherwise indistinguishable from a clean comparison.
|
|
41
|
+
|
|
42
|
+
- **`result <a> <b> [...] --merge`** combines the bundles of a sharded test run
|
|
43
|
+
into one, which is the only way that run gets a single verdict. The merged
|
|
44
|
+
bundle is read back and reported from, rather than described from its
|
|
45
|
+
inputs. It lands under `~/Library/Caches` unless `--to` says otherwise, and a
|
|
46
|
+
`--to` that already exists is refused rather than written over — the bundle
|
|
47
|
+
under our own cache directory is ours to clear, one the caller named is not.
|
|
48
|
+
|
|
49
|
+
With these two, **`xcresulttool` coverage is 81% of its leaves** and every
|
|
50
|
+
remaining one is deprecated by Xcode or superseded here.
|
|
51
|
+
|
|
52
|
+
- **`coverage` sees everything `xccov` sees.** Five leaves, and the command's
|
|
53
|
+
path argument now also takes an `.xccovreport` or an `.xccovarchive`:
|
|
54
|
+
|
|
55
|
+
- `--functions <file>` is per-function coverage, which is where an uncovered
|
|
56
|
+
branch finally gets a name. A file at 60% says a test is missing; it does
|
|
57
|
+
not say which one.
|
|
58
|
+
- `--lines <file>` is how many times each line ran, read out of the archive
|
|
59
|
+
rather than the report. Consecutive lines that never ran collapse into one
|
|
60
|
+
range — a 400-line file was 400 rows to find the eight that matter.
|
|
61
|
+
- `--against <path>` answers "did coverage drop" from two bundles this tool
|
|
62
|
+
wrote, reporting which way it moved overall and then per file, worst
|
|
63
|
+
first.
|
|
64
|
+
- `--merge` combines the coverage of a sharded run. `xccov merge` takes
|
|
65
|
+
report/archive **pairs** rather than result bundles, so each bundle is
|
|
66
|
+
unpacked with `xcresulttool export coverage` first — that two-step is the
|
|
67
|
+
reason merging coverage across shards is something people give up on.
|
|
68
|
+
|
|
69
|
+
With them, **`xccov` coverage is 100%** and companion coverage overall is
|
|
70
|
+
43.7%.
|
|
71
|
+
|
|
72
|
+
### Fixed
|
|
73
|
+
|
|
74
|
+
- `xccov`'s refusals are no longer wrapped in NSError. A bad path came back as
|
|
75
|
+
`Error: Error Domain=XCCovErrorDomain Code=0 "Failed to load result bundle"
|
|
76
|
+
UserInfo={NSLocalizedDescription=Failed to load result bundle,
|
|
77
|
+
NSUnderlyingError=0x… {…}}` — 400 characters around a five-word answer that
|
|
78
|
+
was already in there.
|
|
79
|
+
|
|
80
|
+
## [0.1.10] - 2026-09-21
|
|
81
|
+
|
|
82
|
+
### Added
|
|
83
|
+
|
|
84
|
+
- **`result` reads the rest of what is in an `.xcresult`.** Seven modes, each
|
|
85
|
+
its own question, none of which had an answer short of shelling out to
|
|
86
|
+
`xcresulttool` and parsing JSON:
|
|
87
|
+
|
|
88
|
+
- `--tests` lists every test the run recorded, failures first, with the
|
|
89
|
+
identifier `--only` and `--activities --test` take.
|
|
90
|
+
- `--activities --test <id>` prints the step-by-step trail of one test,
|
|
91
|
+
indented by depth — what a UI test actually did before it failed.
|
|
92
|
+
- `--insights` reports Xcode's own diagnosis of the run.
|
|
93
|
+
- `--metrics` reports the performance measurements an `XCTMetric` test took,
|
|
94
|
+
which `test --perf-diagnostics` collects and nothing could read back.
|
|
95
|
+
- `--log [build|action|console]` reports the stored log as the timed tree it
|
|
96
|
+
is: the slowest sections of a build, ranked, without rebuilding it.
|
|
97
|
+
- `--available` says what the bundle holds — test results, coverage,
|
|
98
|
+
diagnostics, which logs — so a read that would fail can be skipped rather
|
|
99
|
+
than attempted.
|
|
100
|
+
- `--metadata` reports the bundle's own format version, storage backend and
|
|
101
|
+
compression.
|
|
102
|
+
|
|
103
|
+
That takes `xcresulttool` coverage from 19% to 52.4% of its leaves, and the
|
|
104
|
+
companion tools as a whole from 18.3% to 28.2%.
|
|
105
|
+
|
|
106
|
+
- **The export options plist is fully covered.** `export` gained a flag for
|
|
107
|
+
each of the twelve keys that had none, so nothing about a distribution
|
|
108
|
+
requires authoring XML any more:
|
|
109
|
+
|
|
110
|
+
`--profile <id>=<name>`, `--certificate`, `--installer-certificate`,
|
|
111
|
+
`--distribution-bundle-id`, `--keep-swift-symbols`, `--internal-only`,
|
|
112
|
+
`--app-store-info`, `--icloud-env`, `--thinning`, `--manifest <key>=<url>`,
|
|
113
|
+
`--odr-base-url`, `--no-embed-odr`.
|
|
114
|
+
|
|
115
|
+
The ones that change whether a release works at all: `--profile` and
|
|
116
|
+
`--certificate` are manual signing, which until now could be _asked for_
|
|
117
|
+
with `--signing-style manual` and not completed — so the flag existed and
|
|
118
|
+
the export it produced could not be signed as intended. `--internal-only`
|
|
119
|
+
marks a TestFlight build as not for external distribution, which is what a
|
|
120
|
+
PR build wants. `--manifest` is over-the-web distribution, and it is refused
|
|
121
|
+
unless all three of its URLs are present, because a partial manifest exports
|
|
122
|
+
without an error and produces a link that cannot install.
|
|
123
|
+
|
|
124
|
+
Two spellings are handled rather than passed on: Xcode writes its named
|
|
125
|
+
thinning options with angle brackets (`<none>`), and the Xcode 26 method
|
|
126
|
+
names (`app-store`, `ad-hoc`, `development`) still work and are reported as
|
|
127
|
+
the current name they mean.
|
|
128
|
+
|
|
129
|
+
- `info --sdk <name>` reports one SDK in full — path, platform path, platform,
|
|
130
|
+
and both versions. That was `xcodebuild -version -sdk <name> <infoitem>`,
|
|
131
|
+
which answers one field per invocation and only if you already know the
|
|
132
|
+
field names. A build script that needs the SDK path, or an agent asked which
|
|
133
|
+
build of the SDK it compiled against, had to shell out for it.
|
|
134
|
+
|
|
135
|
+
With it, **every leaf of xcodebuild's own surface that this tool wraps is
|
|
136
|
+
covered**: 160 of 161, and the one left is `installsrc`, which is declined
|
|
137
|
+
on purpose and says so.
|
|
138
|
+
|
|
139
|
+
### Changed
|
|
140
|
+
|
|
141
|
+
- The flags that shape the generated options plist are now **refused**
|
|
142
|
+
alongside `--options` rather than silently ignored. `--upload` already was;
|
|
143
|
+
`--team`, `--signing-style` and the ten new ones were not, so a release could
|
|
144
|
+
pass `--team` beside a hand-written plist and get a build signed by whatever
|
|
145
|
+
the plist said.
|
|
146
|
+
|
|
147
|
+
### Fixed
|
|
148
|
+
|
|
149
|
+
- `xcresulttool`'s own explanation of a failed read is now the error message.
|
|
150
|
+
It writes `Error: …` on stderr and exits non-zero; the reason was thrown away
|
|
151
|
+
and replaced with a guess ("the bundle may be from an incompatible Xcode
|
|
152
|
+
version"), so `--log console` on a bundle with no console log was reported as
|
|
153
|
+
a version problem rather than as the absent log it is. The guess is only
|
|
154
|
+
offered now when `xcresulttool` gave no reason of its own.
|
|
155
|
+
|
|
7
156
|
## [0.1.9] - 2026-09-21
|
|
8
157
|
|
|
9
158
|
### Added
|
|
@@ -294,7 +443,9 @@ First release.
|
|
|
294
443
|
- 100% of the 117 options `xcodebuild -help` lists are covered, declared in
|
|
295
444
|
`src/surface.ts` and checked against the installed Xcode in CI.
|
|
296
445
|
|
|
297
|
-
[unreleased]: https://github.com/alexrrouse/xcodebuild-axi/compare/v0.1.
|
|
446
|
+
[unreleased]: https://github.com/alexrrouse/xcodebuild-axi/compare/v0.1.11...HEAD
|
|
447
|
+
[0.1.11]: https://github.com/alexrrouse/xcodebuild-axi/compare/v0.1.10...v0.1.11
|
|
448
|
+
[0.1.10]: https://github.com/alexrrouse/xcodebuild-axi/compare/v0.1.9...v0.1.10
|
|
298
449
|
[0.1.9]: https://github.com/alexrrouse/xcodebuild-axi/compare/v0.1.8...v0.1.9
|
|
299
450
|
[0.1.8]: https://github.com/alexrrouse/xcodebuild-axi/compare/v0.1.7...v0.1.8
|
|
300
451
|
[0.1.7]: https://github.com/alexrrouse/xcodebuild-axi/compare/v0.1.6...v0.1.7
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<a href="https://www.npmjs.com/package/xcodebuild-axi"><img alt="npm" src="https://img.shields.io/npm/v/xcodebuild-axi?style=flat-square" /></a>
|
|
5
5
|
<a href="https://axi.md/"><img alt="AXI" src="https://img.shields.io/badge/AXI-compliant-blue?style=flat-square" /></a>
|
|
6
6
|
<img alt="Platform" src="https://img.shields.io/badge/platform-macOS-lightgrey?style=flat-square" />
|
|
7
|
-
<!-- coverage-badge:start --><img alt="xcodebuild coverage" src="https://img.shields.io/badge/xcodebuild_coverage-
|
|
7
|
+
<!-- coverage-badge:start --><img alt="xcodebuild coverage" src="https://img.shields.io/badge/xcodebuild_coverage-99.4%25-brightgreen?style=flat-square" /><!-- coverage-badge:end -->
|
|
8
8
|
<img alt="License" src="https://img.shields.io/badge/license-MIT-green?style=flat-square" />
|
|
9
9
|
</p>
|
|
10
10
|
|
|
@@ -171,7 +171,7 @@ Every command takes `--help`.
|
|
|
171
171
|
|
|
172
172
|
<!-- coverage:start -->
|
|
173
173
|
|
|
174
|
-
**Coverage:
|
|
174
|
+
**Coverage: 99.4% of the 161 leaves `xcodebuild` documents** — every option, build action, export options key, `-create-xcframework` argument, and the second forms that only a usage line mentions.
|
|
175
175
|
|
|
176
176
|
A leaf is one switch you could type. Counting options alone says 100% (117/117), which was true and hid every gap below: an option is one thing, and `-exportOptionsPlist` alone opens eighteen more.
|
|
177
177
|
|
|
@@ -179,10 +179,10 @@ A leaf is one switch you could type. Counting options alone says 100% (117/117),
|
|
|
179
179
|
| ------------------------------------------------------ | ------- | --------------- |
|
|
180
180
|
| `xcodebuild -help` options | 117 | 117 (100%) |
|
|
181
181
|
| build actions | 10 | 9 (90%) |
|
|
182
|
-
| second forms (`-version <infoitem>`, `-license check`) | 8 |
|
|
183
|
-
| `-exportOptionsPlist` keys | 18 |
|
|
182
|
+
| second forms (`-version <infoitem>`, `-license check`) | 8 | 8 (100%) |
|
|
183
|
+
| `-exportOptionsPlist` keys | 18 | 18 (100%) |
|
|
184
184
|
| `-create-xcframework` options | 8 | 8 (100%) |
|
|
185
|
-
| **total** | **161** | **
|
|
185
|
+
| **total** | **161** | **160 (99.4%)** |
|
|
186
186
|
|
|
187
187
|
**Reach: 100%** of the 328 command-and-option pairs. The same options, counted once per command xcodebuild accepts them on — because `-target` exposed on `build` and missing from `settings` is not covered for anyone asking `settings`. 0 pairs are open.
|
|
188
188
|
|
|
@@ -204,65 +204,33 @@ The one action left out is `installsrc` — it copies sources into `SRCROOT` as
|
|
|
204
204
|
|
|
205
205
|
### Companion tools
|
|
206
206
|
|
|
207
|
-
`xcresulttool`, `xccov` and `simctl` are not xcodebuild, so they are not in the number above — but this tool wraps all three, and an agent that has to shell out to one directly has dropped back down. **
|
|
207
|
+
`xcresulttool`, `xccov` and `simctl` are not xcodebuild, so they are not in the number above — but this tool wraps all three, and an agent that has to shell out to one directly has dropped back down. **43.7% of 71 leaves**, counted the same way:
|
|
208
208
|
|
|
209
209
|
| Tool | Leaves | Covered |
|
|
210
210
|
| -------------- | ------ | --------- |
|
|
211
|
-
| `xcresulttool` | 21 |
|
|
212
|
-
| `xccov` | 9 |
|
|
211
|
+
| `xcresulttool` | 21 | 17 (81%) |
|
|
212
|
+
| `xccov` | 9 | 9 (100%) |
|
|
213
213
|
| `simctl` | 41 | 5 (12.2%) |
|
|
214
214
|
|
|
215
215
|
### Still open
|
|
216
216
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
| Leaf
|
|
220
|
-
|
|
|
221
|
-
|
|
|
222
|
-
|
|
|
223
|
-
| `
|
|
224
|
-
| `
|
|
225
|
-
| `
|
|
226
|
-
| `
|
|
227
|
-
| `
|
|
228
|
-
| `
|
|
229
|
-
| `
|
|
230
|
-
| `
|
|
231
|
-
| `
|
|
232
|
-
| `
|
|
233
|
-
| `
|
|
234
|
-
| `onDemandResourcesAssetPacksBaseURL` (export options) | `export` | on-demand resource asset packs cannot be pointed at a host |
|
|
235
|
-
| `xcresulttool get test-results tests` | `result` | the full test tree of a finished run cannot be listed |
|
|
236
|
-
| `xcresulttool get test-results activities` | `result` | the step-by-step activity trail of a failing test cannot be read |
|
|
237
|
-
| `xcresulttool get test-results insights` | `result` | Xcode's own diagnosis of a run is left on the floor |
|
|
238
|
-
| `xcresulttool get test-results metrics` | `result` | `test --perf-diagnostics` collects performance metrics nothing can read back |
|
|
239
|
-
| `xcresulttool get log` | `result` | the build log inside the bundle is reachable only as the raw transcript file |
|
|
240
|
-
| `xcresulttool get content-availability` | `result` | whether a bundle even has coverage or test results is found out by failing to read it |
|
|
241
|
-
| `xcresulttool export diagnostics` | `result` | `test --diagnostics` collects a diagnostics report that cannot be extracted |
|
|
242
|
-
| `xcresulttool export attachments` | `result` | UI test screenshots and attachments cannot be got out of the bundle |
|
|
243
|
-
| `xcresulttool export metrics` | `result` | performance measurements cannot be exported as CSV |
|
|
244
|
-
| `xcresulttool export evaluations` | `result` | evaluation attachments cannot be exported |
|
|
245
|
-
| `xcresulttool compare` | `result` | two runs cannot be diffed, which is the question CI asks most |
|
|
246
|
-
| `xcresulttool merge` | `result` | the bundles of a sharded test run cannot be combined |
|
|
247
|
-
| `xcresulttool metadata` | `result` | a bundle's own metadata cannot be read |
|
|
248
|
-
| `xccov view --report --functions-for-file` | `coverage` | coverage stops at the file, so the uncovered function has no name |
|
|
249
|
-
| `xccov view --archive` | `coverage` | a standalone .xccovarchive cannot be read, only a result bundle |
|
|
250
|
-
| `xccov view --file` | `coverage` | the per-line coverage of one file cannot be printed |
|
|
251
|
-
| `xccov diff` | `coverage` | 'did coverage drop' cannot be answered from two bundles this tool wrote |
|
|
252
|
-
| `xccov merge` | `coverage` | the coverage of a sharded run cannot be combined |
|
|
253
|
-
| `simctl install` | `sim` | a built .app cannot be put on the simulator it was built for |
|
|
254
|
-
| `simctl launch` | `sim` | the app a build just produced cannot be run |
|
|
255
|
-
| `simctl terminate` | `?` | a running app cannot be stopped |
|
|
256
|
-
| `simctl uninstall` | `?` | an installed app cannot be removed |
|
|
257
|
-
| `simctl listapps` | `sim` | what is installed on a simulator cannot be listed |
|
|
258
|
-
| `simctl create` | `?` | a missing device cannot be created |
|
|
259
|
-
| `simctl delete` | `sim` | stale devices cannot be reclaimed, and they cost gigabytes |
|
|
260
|
-
| `simctl io` | `sim` | a screenshot of a failing UI cannot be taken |
|
|
261
|
-
| `simctl openurl` | `sim` | a deep link cannot be opened, which is how deep links are tested |
|
|
262
|
-
| `simctl privacy` | `sim` | a permission prompt cannot be granted ahead of a UI test |
|
|
263
|
-
| `simctl push` | `sim` | a push notification cannot be simulated |
|
|
264
|
-
| `simctl status_bar` | `sim` | the status bar cannot be pinned, which screenshot tests need |
|
|
265
|
-
| `simctl ui` | `sim` | dark mode and content size cannot be set for a test run |
|
|
217
|
+
13 leaves are known gaps rather than decisions — each one a reason someone would still reach for the raw tool:
|
|
218
|
+
|
|
219
|
+
| Leaf | Unreachable from | What that costs |
|
|
220
|
+
| ------------------- | ---------------- | ---------------------------------------------------------------- |
|
|
221
|
+
| `simctl install` | `sim` | a built .app cannot be put on the simulator it was built for |
|
|
222
|
+
| `simctl launch` | `sim` | the app a build just produced cannot be run |
|
|
223
|
+
| `simctl terminate` | `?` | a running app cannot be stopped |
|
|
224
|
+
| `simctl uninstall` | `?` | an installed app cannot be removed |
|
|
225
|
+
| `simctl listapps` | `sim` | what is installed on a simulator cannot be listed |
|
|
226
|
+
| `simctl create` | `?` | a missing device cannot be created |
|
|
227
|
+
| `simctl delete` | `sim` | stale devices cannot be reclaimed, and they cost gigabytes |
|
|
228
|
+
| `simctl io` | `sim` | a screenshot of a failing UI cannot be taken |
|
|
229
|
+
| `simctl openurl` | `sim` | a deep link cannot be opened, which is how deep links are tested |
|
|
230
|
+
| `simctl privacy` | `sim` | a permission prompt cannot be granted ahead of a UI test |
|
|
231
|
+
| `simctl push` | `sim` | a push notification cannot be simulated |
|
|
232
|
+
| `simctl status_bar` | `sim` | the status bar cannot be pinned, which screenshot tests need |
|
|
233
|
+
| `simctl ui` | `sim` | dark mode and content size cannot be set for a test run |
|
|
266
234
|
|
|
267
235
|
The denominator is read from `xcodebuild -help` rather than hand-maintained, and this table is written against **Xcode 27.0** — the option list moves between releases. `npm run coverage:check` fails on that Xcode if an option here is unclassified or has been dropped, and reports the difference without failing on any other.
|
|
268
236
|
|
package/dist/src/archive.d.ts
CHANGED
|
@@ -19,17 +19,46 @@ export declare function readArchiveInfo(archivePath: string): Promise<ArchiveInf
|
|
|
19
19
|
/** The `method` values Xcode 27 accepts in an export options plist. */
|
|
20
20
|
export declare const EXPORT_METHODS: readonly ["app-store-connect", "release-testing", "enterprise", "debugging", "developer-id", "mac-application", "validation"];
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* The names Xcode 26 and earlier used, which every existing pipeline and every
|
|
23
|
+
* answer written before Xcode 27 still says. xcodebuild itself still accepts
|
|
24
|
+
* them, so refusing them here would be this tool being stricter than the thing
|
|
25
|
+
* it wraps.
|
|
26
|
+
*/
|
|
27
|
+
export declare const EXPORT_METHOD_ALIASES: Record<string, string>;
|
|
28
|
+
/**
|
|
29
|
+
* Every key `-exportOptionsPlist` accepts, and what it is for.
|
|
23
30
|
*
|
|
24
|
-
*
|
|
25
|
-
* of
|
|
26
|
-
*
|
|
31
|
+
* The plist is the whole configuration surface of `-exportArchive`. A key with
|
|
32
|
+
* no flag in front of it is a key that sends the agent back to authoring XML,
|
|
33
|
+
* which is the side quest this file exists to remove.
|
|
27
34
|
*/
|
|
28
|
-
export
|
|
35
|
+
export interface ExportOptions {
|
|
29
36
|
method: string;
|
|
30
37
|
destination?: string;
|
|
31
38
|
teamID?: string;
|
|
32
39
|
signingStyle?: string;
|
|
40
|
+
signingCertificate?: string;
|
|
41
|
+
installerSigningCertificate?: string;
|
|
42
|
+
/** Bundle identifier -> profile name or UUID, for manual signing. */
|
|
43
|
+
provisioningProfiles?: Record<string, string>;
|
|
44
|
+
distributionBundleIdentifier?: string;
|
|
33
45
|
uploadSymbols?: boolean;
|
|
46
|
+
stripSwiftSymbols?: boolean;
|
|
34
47
|
manageAppVersionAndBuildNumber?: boolean;
|
|
35
|
-
|
|
48
|
+
testFlightInternalTestingOnly?: boolean;
|
|
49
|
+
generateAppStoreInformation?: boolean;
|
|
50
|
+
iCloudContainerEnvironment?: string;
|
|
51
|
+
thinning?: string;
|
|
52
|
+
/** appURL, displayImageURL and fullSizeImageURL, for web distribution. */
|
|
53
|
+
manifest?: Record<string, string>;
|
|
54
|
+
embedOnDemandResourcesAssetPacksInBundle?: boolean;
|
|
55
|
+
onDemandResourcesAssetPacksBaseURL?: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build an export options plist.
|
|
59
|
+
*
|
|
60
|
+
* `-exportArchive` requires one, and authoring XML by hand is exactly the kind
|
|
61
|
+
* of unguessable side quest an agent fails at. Given a method (and whatever
|
|
62
|
+
* else was asked for), the plist is derivable, so derive it.
|
|
63
|
+
*/
|
|
64
|
+
export declare function exportOptionsPlist(options: ExportOptions): string;
|
package/dist/src/archive.js
CHANGED
|
@@ -46,31 +46,52 @@ export const EXPORT_METHODS = [
|
|
|
46
46
|
"validation",
|
|
47
47
|
];
|
|
48
48
|
/**
|
|
49
|
-
*
|
|
49
|
+
* The names Xcode 26 and earlier used, which every existing pipeline and every
|
|
50
|
+
* answer written before Xcode 27 still says. xcodebuild itself still accepts
|
|
51
|
+
* them, so refusing them here would be this tool being stricter than the thing
|
|
52
|
+
* it wraps.
|
|
53
|
+
*/
|
|
54
|
+
export const EXPORT_METHOD_ALIASES = {
|
|
55
|
+
"app-store": "app-store-connect",
|
|
56
|
+
"ad-hoc": "release-testing",
|
|
57
|
+
development: "debugging",
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* The order keys are written in. Xcode does not care, but a generated file a
|
|
61
|
+
* human may end up reading should group signing with signing.
|
|
62
|
+
*/
|
|
63
|
+
const EXPORT_OPTION_ORDER = [
|
|
64
|
+
"method",
|
|
65
|
+
"destination",
|
|
66
|
+
"teamID",
|
|
67
|
+
"signingStyle",
|
|
68
|
+
"signingCertificate",
|
|
69
|
+
"installerSigningCertificate",
|
|
70
|
+
"provisioningProfiles",
|
|
71
|
+
"distributionBundleIdentifier",
|
|
72
|
+
"uploadSymbols",
|
|
73
|
+
"stripSwiftSymbols",
|
|
74
|
+
"manageAppVersionAndBuildNumber",
|
|
75
|
+
"testFlightInternalTestingOnly",
|
|
76
|
+
"generateAppStoreInformation",
|
|
77
|
+
"iCloudContainerEnvironment",
|
|
78
|
+
"thinning",
|
|
79
|
+
"manifest",
|
|
80
|
+
"embedOnDemandResourcesAssetPacksInBundle",
|
|
81
|
+
"onDemandResourcesAssetPacksBaseURL",
|
|
82
|
+
];
|
|
83
|
+
/**
|
|
84
|
+
* Build an export options plist.
|
|
50
85
|
*
|
|
51
86
|
* `-exportArchive` requires one, and authoring XML by hand is exactly the kind
|
|
52
|
-
* of unguessable side quest an agent fails at. Given a method (and
|
|
53
|
-
*
|
|
87
|
+
* of unguessable side quest an agent fails at. Given a method (and whatever
|
|
88
|
+
* else was asked for), the plist is derivable, so derive it.
|
|
54
89
|
*/
|
|
55
90
|
export function exportOptionsPlist(options) {
|
|
56
|
-
const entries =
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
entries.push(` <key>destination</key>\n <string>${options.destination}</string>`);
|
|
61
|
-
}
|
|
62
|
-
if (options.teamID) {
|
|
63
|
-
entries.push(` <key>teamID</key>\n <string>${options.teamID}</string>`);
|
|
64
|
-
}
|
|
65
|
-
if (options.signingStyle) {
|
|
66
|
-
entries.push(` <key>signingStyle</key>\n <string>${options.signingStyle}</string>`);
|
|
67
|
-
}
|
|
68
|
-
if (options.uploadSymbols !== undefined) {
|
|
69
|
-
entries.push(` <key>uploadSymbols</key>\n <${options.uploadSymbols}/>`);
|
|
70
|
-
}
|
|
71
|
-
if (options.manageAppVersionAndBuildNumber !== undefined) {
|
|
72
|
-
entries.push(` <key>manageAppVersionAndBuildNumber</key>\n <${options.manageAppVersionAndBuildNumber}/>`);
|
|
73
|
-
}
|
|
91
|
+
const entries = EXPORT_OPTION_ORDER.flatMap((key) => {
|
|
92
|
+
const value = options[key];
|
|
93
|
+
return value === undefined ? [] : [` <key>${key}</key>\n${render(value)}`];
|
|
94
|
+
});
|
|
74
95
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
75
96
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
76
97
|
<plist version="1.0">
|
|
@@ -80,4 +101,25 @@ ${entries.join("\n")}
|
|
|
80
101
|
</plist>
|
|
81
102
|
`;
|
|
82
103
|
}
|
|
104
|
+
function render(value) {
|
|
105
|
+
if (typeof value === "boolean")
|
|
106
|
+
return ` <${value}/>`;
|
|
107
|
+
if (typeof value === "string")
|
|
108
|
+
return ` <string>${escapeXml(value)}</string>`;
|
|
109
|
+
const inner = Object.entries(value)
|
|
110
|
+
.map(([key, entry]) => ` <key>${escapeXml(key)}</key>\n <string>${escapeXml(entry)}</string>`)
|
|
111
|
+
.join("\n");
|
|
112
|
+
return ` <dict>\n${inner}\n </dict>`;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* A manifest URL with a query string carries `&`, and an unescaped one makes
|
|
116
|
+
* the plist unparseable -- which xcodebuild reports as a failed export rather
|
|
117
|
+
* than as a bad file.
|
|
118
|
+
*/
|
|
119
|
+
function escapeXml(value) {
|
|
120
|
+
return value
|
|
121
|
+
.replace(/&/g, "&")
|
|
122
|
+
.replace(/</g, "<")
|
|
123
|
+
.replace(/>/g, ">");
|
|
124
|
+
}
|
|
83
125
|
//# sourceMappingURL=archive.js.map
|
package/dist/src/archive.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/archive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AA+BjC,MAAM,UAAU,eAAe,CAC7B,WAAmB;IAEnB,OAAO,IAAI,OAAO,CAAC,CAAC,cAAc,EAAE,EAAE;QACpC,QAAQ,CACN,QAAQ,EACR,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,EAChE,EAAE,QAAQ,EAAE,OAAO,EAAE,EACrB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YAChB,IAAI,KAAK,EAAE,CAAC;gBACV,cAAc,CAAC,SAAS,CAAC,CAAC;gBAC1B,OAAO;YACT,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAoB,CAAC;gBACrD,MAAM,GAAG,GAAG,MAAM,CAAC,qBAAqB,IAAI,EAAE,CAAC;gBAC/C,cAAc,CAAC;oBACb,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC3D,GAAG,CAAC,MAAM,CAAC,YAAY,KAAK,SAAS;wBACnC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,YAAY,EAAE;wBACpC,CAAC,CAAC,EAAE,CAAC;oBACP,GAAG,CAAC,GAAG,CAAC,kBAAkB,KAAK,SAAS;wBACtC,CAAC,CAAC,EAAE,gBAAgB,EAAE,GAAG,CAAC,kBAAkB,EAAE;wBAC9C,CAAC,CAAC,EAAE,CAAC;oBACP,GAAG,CAAC,GAAG,CAAC,0BAA0B,KAAK,SAAS;wBAC9C,CAAC,CAAC,EAAE,gBAAgB,EAAE,GAAG,CAAC,0BAA0B,EAAE;wBACtD,CAAC,CAAC,EAAE,CAAC;oBACP,GAAG,CAAC,GAAG,CAAC,eAAe,KAAK,SAAS;wBACnC,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,eAAe,EAAE;wBACtC,CAAC,CAAC,EAAE,CAAC;oBACP,GAAG,CAAC,GAAG,CAAC,eAAe,KAAK,SAAS;wBACnC,CAAC,CAAC,EAAE,eAAe,EAAE,GAAG,CAAC,eAAe,EAAE;wBAC1C,CAAC,CAAC,EAAE,CAAC;iBACR,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,cAAc,CAAC,SAAS,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,uEAAuE;AACvE,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,mBAAmB;IACnB,iBAAiB;IACjB,YAAY;IACZ,WAAW;IACX,cAAc;IACd,iBAAiB;IACjB,YAAY;CACJ,CAAC;AAEX;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/archive.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const
|
|
1
|
+
import { type CoverageLine } from "../xccov.js";
|
|
2
|
+
export declare const COVERAGE_HELP = "usage: xcodebuild-axi coverage <path> [flags]\nReads code coverage out of a result bundle \u2014 one percentage per target, not the\nthousands of per-file lines xccov prints by default. The path can also be an\n.xccovreport or .xccovarchive.\nflags[9]:\n --files list per-file coverage as well as per-target\n --target <name> only this target\n --below <percent> only files under this coverage, e.g. --below 50\n --functions <file> per-function coverage for one file, so an uncovered\n branch has a name\n --lines <file> how many times each line of one file ran\n --against <path> compare coverage with an earlier run: what moved, and\n which files went with it\n --merge combine the coverage of two or more runs into one report\n --to <path> where --merge writes (default: under ~/Library/Caches)\n --max <n> rows to list before summarizing the rest (default: 25)\nnote:\n Coverage has to have been collected. Run the tests with\n `xcodebuild-axi test --coverage` if the bundle has none.\n\n --lines reads the archive rather than the report: the report knows what\n percentage of a file ran, the archive knows how many times each line did.\nexamples:\n xcodebuild-axi coverage ~/Library/Caches/xcodebuild-axi/MyApps-1a2b3c4d/MyApp-test.xcresult\n xcodebuild-axi coverage build/MyApp.xcresult --files --below 50\n xcodebuild-axi coverage build/MyApp.xcresult --functions Checkout.swift\n xcodebuild-axi coverage build/MyApp.xcresult --against build/baseline.xcresult\n";
|
|
3
|
+
export declare const COVERAGE_FLAGS: readonly ["--files", "--target", "--below", "--functions", "--lines", "--against", "--merge", "--to", "--max"];
|
|
3
4
|
export declare function coverageCommand(args: string[]): Promise<string>;
|
|
5
|
+
/** Consecutive lines that never ran, as ranges rather than one row each. */
|
|
6
|
+
export declare function uncoveredRanges(lines: CoverageLine[]): Array<Record<string, unknown>>;
|
|
7
|
+
/**
|
|
8
|
+
* Which way coverage moved, in words.
|
|
9
|
+
*
|
|
10
|
+
* Words rather than a signed percentage because TOON quotes any scalar that
|
|
11
|
+
* starts with `-`, and `"-2.1%"` costs more in quotes than `down 2.1%` costs
|
|
12
|
+
* in letters.
|
|
13
|
+
*/
|
|
14
|
+
export declare function movement(delta: number): string;
|