xcodebuild-axi 0.1.0
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 +35 -0
- package/LICENSE +21 -0
- package/README.md +304 -0
- package/dist/bin/xcodebuild-axi.d.ts +2 -0
- package/dist/bin/xcodebuild-axi.js +8 -0
- package/dist/bin/xcodebuild-axi.js.map +1 -0
- package/dist/src/action.d.ts +68 -0
- package/dist/src/action.js +373 -0
- package/dist/src/action.js.map +1 -0
- package/dist/src/archive.d.ts +33 -0
- package/dist/src/archive.js +77 -0
- package/dist/src/archive.js.map +1 -0
- package/dist/src/args.d.ts +23 -0
- package/dist/src/args.js +123 -0
- package/dist/src/args.js.map +1 -0
- package/dist/src/auth.d.ts +11 -0
- package/dist/src/auth.js +51 -0
- package/dist/src/auth.js.map +1 -0
- package/dist/src/cli.d.ts +20 -0
- package/dist/src/cli.js +132 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/commands/analyze.d.ts +2 -0
- package/dist/src/commands/analyze.js +32 -0
- package/dist/src/commands/analyze.js.map +1 -0
- package/dist/src/commands/archive.d.ts +2 -0
- package/dist/src/commands/archive.js +63 -0
- package/dist/src/commands/archive.js.map +1 -0
- package/dist/src/commands/build.d.ts +2 -0
- package/dist/src/commands/build.js +60 -0
- package/dist/src/commands/build.js.map +1 -0
- package/dist/src/commands/clean.d.ts +2 -0
- package/dist/src/commands/clean.js +39 -0
- package/dist/src/commands/clean.js.map +1 -0
- package/dist/src/commands/coverage.d.ts +2 -0
- package/dist/src/commands/coverage.js +111 -0
- package/dist/src/commands/coverage.js.map +1 -0
- package/dist/src/commands/destinations.d.ts +2 -0
- package/dist/src/commands/destinations.js +56 -0
- package/dist/src/commands/destinations.js.map +1 -0
- package/dist/src/commands/export.d.ts +2 -0
- package/dist/src/commands/export.js +170 -0
- package/dist/src/commands/export.js.map +1 -0
- package/dist/src/commands/find.d.ts +2 -0
- package/dist/src/commands/find.js +70 -0
- package/dist/src/commands/find.js.map +1 -0
- package/dist/src/commands/home.d.ts +9 -0
- package/dist/src/commands/home.js +97 -0
- package/dist/src/commands/home.js.map +1 -0
- package/dist/src/commands/info.d.ts +2 -0
- package/dist/src/commands/info.js +95 -0
- package/dist/src/commands/info.js.map +1 -0
- package/dist/src/commands/localize.d.ts +2 -0
- package/dist/src/commands/localize.js +121 -0
- package/dist/src/commands/localize.js.map +1 -0
- package/dist/src/commands/migrate.d.ts +8 -0
- package/dist/src/commands/migrate.js +177 -0
- package/dist/src/commands/migrate.js.map +1 -0
- package/dist/src/commands/packages.d.ts +2 -0
- package/dist/src/commands/packages.js +108 -0
- package/dist/src/commands/packages.js.map +1 -0
- package/dist/src/commands/platforms.d.ts +2 -0
- package/dist/src/commands/platforms.js +379 -0
- package/dist/src/commands/platforms.js.map +1 -0
- package/dist/src/commands/result.d.ts +2 -0
- package/dist/src/commands/result.js +100 -0
- package/dist/src/commands/result.js.map +1 -0
- package/dist/src/commands/schemes.d.ts +2 -0
- package/dist/src/commands/schemes.js +39 -0
- package/dist/src/commands/schemes.js.map +1 -0
- package/dist/src/commands/settings.d.ts +2 -0
- package/dist/src/commands/settings.js +191 -0
- package/dist/src/commands/settings.js.map +1 -0
- package/dist/src/commands/setup.d.ts +2 -0
- package/dist/src/commands/setup.js +84 -0
- package/dist/src/commands/setup.js.map +1 -0
- package/dist/src/commands/sim.d.ts +2 -0
- package/dist/src/commands/sim.js +187 -0
- package/dist/src/commands/sim.js.map +1 -0
- package/dist/src/commands/test.d.ts +2 -0
- package/dist/src/commands/test.js +317 -0
- package/dist/src/commands/test.js.map +1 -0
- package/dist/src/commands/testplans.d.ts +8 -0
- package/dist/src/commands/testplans.js +75 -0
- package/dist/src/commands/testplans.js.map +1 -0
- package/dist/src/commands/tests.d.ts +13 -0
- package/dist/src/commands/tests.js +154 -0
- package/dist/src/commands/tests.js.map +1 -0
- package/dist/src/commands/xcframework.d.ts +2 -0
- package/dist/src/commands/xcframework.js +77 -0
- package/dist/src/commands/xcframework.js.map +1 -0
- package/dist/src/context.d.ts +23 -0
- package/dist/src/context.js +72 -0
- package/dist/src/context.js.map +1 -0
- package/dist/src/destination.d.ts +50 -0
- package/dist/src/destination.js +174 -0
- package/dist/src/destination.js.map +1 -0
- package/dist/src/errors.d.ts +6 -0
- package/dist/src/errors.js +55 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/packages.d.ts +31 -0
- package/dist/src/packages.js +117 -0
- package/dist/src/packages.js.map +1 -0
- package/dist/src/report.d.ts +20 -0
- package/dist/src/report.js +39 -0
- package/dist/src/report.js.map +1 -0
- package/dist/src/scheme.d.ts +22 -0
- package/dist/src/scheme.js +66 -0
- package/dist/src/scheme.js.map +1 -0
- package/dist/src/simctl.d.ts +33 -0
- package/dist/src/simctl.js +85 -0
- package/dist/src/simctl.js.map +1 -0
- package/dist/src/surface.d.ts +55 -0
- package/dist/src/surface.js +350 -0
- package/dist/src/surface.js.map +1 -0
- package/dist/src/toon.d.ts +34 -0
- package/dist/src/toon.js +79 -0
- package/dist/src/toon.js.map +1 -0
- package/dist/src/version.d.ts +1 -0
- package/dist/src/version.js +24 -0
- package/dist/src/version.js.map +1 -0
- package/dist/src/xccov.d.ts +25 -0
- package/dist/src/xccov.js +78 -0
- package/dist/src/xccov.js.map +1 -0
- package/dist/src/xcodebuild.d.ts +65 -0
- package/dist/src/xcodebuild.js +163 -0
- package/dist/src/xcodebuild.js.map +1 -0
- package/dist/src/xcresult.d.ts +96 -0
- package/dist/src/xcresult.js +156 -0
- package/dist/src/xcresult.js.map +1 -0
- package/package.json +75 -0
- package/skills/xcodebuild-axi/SKILL.md +64 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { AxiError } from "../errors.js";
|
|
2
|
+
import { requireProject } from "../context.js";
|
|
3
|
+
import { requireScheme } from "../scheme.js";
|
|
4
|
+
import { runMetadata } from "../xcodebuild.js";
|
|
5
|
+
import { renderFields, renderHelp, renderList, renderOutput } from "../toon.js";
|
|
6
|
+
import { getFlag, getListFlag, hasFlag, rejectUnknownFlags } from "../args.js";
|
|
7
|
+
export const SETTINGS_HELP = `usage: xcodebuild-axi settings [flags]
|
|
8
|
+
Reads resolved build settings. Asking for the keys you want turns a 40 KB dump
|
|
9
|
+
into a few lines.
|
|
10
|
+
flags[7]:
|
|
11
|
+
--scheme <name> scheme to resolve against (required only when the project has more than one)
|
|
12
|
+
--key <NAME> setting to read; repeatable or comma-separated
|
|
13
|
+
--configuration <name> build configuration to resolve against
|
|
14
|
+
--all dump every setting (large — hundreds of keys)
|
|
15
|
+
--for-index the per-source-file settings an indexer sees
|
|
16
|
+
--file <path> with --for-index: the one source file to report on
|
|
17
|
+
--full with --for-index --file: list the long argument arrays
|
|
18
|
+
note:
|
|
19
|
+
--for-index answers a different question from the rest of this command: it
|
|
20
|
+
reports the compiler invocation the indexer builds per source file. The raw
|
|
21
|
+
payload measured 216 KB on a 12-scheme workspace, so without --file it
|
|
22
|
+
reports only which targets have index settings and how many files each has.
|
|
23
|
+
examples:
|
|
24
|
+
xcodebuild-axi settings --key PRODUCT_BUNDLE_IDENTIFIER,MARKETING_VERSION
|
|
25
|
+
xcodebuild-axi settings --scheme MyApp --key SWIFT_VERSION
|
|
26
|
+
xcodebuild-axi settings --scheme MyApp --for-index --file MyApp/AppFeature.swift
|
|
27
|
+
`;
|
|
28
|
+
const FLAGS = [
|
|
29
|
+
"--scheme",
|
|
30
|
+
"--key",
|
|
31
|
+
"--configuration",
|
|
32
|
+
"--all",
|
|
33
|
+
"--for-index",
|
|
34
|
+
"--file",
|
|
35
|
+
"--full",
|
|
36
|
+
];
|
|
37
|
+
const VALUE_FLAGS = ["--scheme", "--key", "--configuration", "--file"];
|
|
38
|
+
export async function settingsCommand(args) {
|
|
39
|
+
rejectUnknownFlags(args, "settings", FLAGS, VALUE_FLAGS);
|
|
40
|
+
const keys = getListFlag(args, "--key");
|
|
41
|
+
const all = hasFlag(args, "--all");
|
|
42
|
+
const forIndex = hasFlag(args, "--for-index");
|
|
43
|
+
if (keys.length === 0 && !all && !forIndex) {
|
|
44
|
+
throw new AxiError("settings needs --key or --all", "VALIDATION_ERROR", [
|
|
45
|
+
"xcodebuild-axi settings --key PRODUCT_BUNDLE_IDENTIFIER",
|
|
46
|
+
"xcodebuild-axi settings --all # every setting, hundreds of lines",
|
|
47
|
+
]);
|
|
48
|
+
}
|
|
49
|
+
const project = requireProject();
|
|
50
|
+
const scheme = await requireScheme(project, getFlag(args, "--scheme"), "settings");
|
|
51
|
+
const configuration = getFlag(args, "--configuration");
|
|
52
|
+
const { stdout } = await runMetadata([
|
|
53
|
+
...project.flags,
|
|
54
|
+
"-scheme",
|
|
55
|
+
scheme,
|
|
56
|
+
...(configuration ? ["-configuration", configuration] : []),
|
|
57
|
+
forIndex ? "-showBuildSettingsForIndex" : "-showBuildSettings",
|
|
58
|
+
"-json",
|
|
59
|
+
]);
|
|
60
|
+
if (forIndex) {
|
|
61
|
+
return reportIndexSettings(stdout, scheme, getFlag(args, "--file"), hasFlag(args, "--full"));
|
|
62
|
+
}
|
|
63
|
+
const settings = parseSettings(stdout);
|
|
64
|
+
if (all) {
|
|
65
|
+
return renderOutput([
|
|
66
|
+
renderFields({ scheme, settings: Object.keys(settings).length }),
|
|
67
|
+
renderFields({ ...settings }),
|
|
68
|
+
]);
|
|
69
|
+
}
|
|
70
|
+
const found = {};
|
|
71
|
+
const missing = [];
|
|
72
|
+
for (const key of keys) {
|
|
73
|
+
const value = settings[key];
|
|
74
|
+
if (value === undefined)
|
|
75
|
+
missing.push(key);
|
|
76
|
+
else
|
|
77
|
+
found[key] = value;
|
|
78
|
+
}
|
|
79
|
+
const blocks = [renderFields({ scheme })];
|
|
80
|
+
if (Object.keys(found).length > 0) {
|
|
81
|
+
blocks.push(renderFields({ settings: found }));
|
|
82
|
+
}
|
|
83
|
+
if (missing.length > 0) {
|
|
84
|
+
// A key that does not exist is an answer, not an error — say so plainly
|
|
85
|
+
// rather than returning an empty block the agent has to re-query to trust.
|
|
86
|
+
blocks.push(renderFields({ unset: missing.join(",") }));
|
|
87
|
+
blocks.push(renderHelp([
|
|
88
|
+
`Run \`xcodebuild-axi settings --scheme ${scheme} --all\` to see every key this scheme resolves`,
|
|
89
|
+
]));
|
|
90
|
+
}
|
|
91
|
+
return renderOutput(blocks);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* `-showBuildSettingsForIndex` is the one query in this family whose full
|
|
95
|
+
* output is never worth printing: it repeats the entire Swift driver command
|
|
96
|
+
* line for every source file in the scheme. Report the shape, or one file.
|
|
97
|
+
*/
|
|
98
|
+
function reportIndexSettings(stdout, scheme, file, full) {
|
|
99
|
+
const start = stdout.indexOf("{");
|
|
100
|
+
let parsed;
|
|
101
|
+
try {
|
|
102
|
+
parsed = JSON.parse(stdout.slice(start < 0 ? 0 : start));
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
parsed = {};
|
|
106
|
+
}
|
|
107
|
+
const targets = Object.entries(parsed);
|
|
108
|
+
if (targets.length === 0) {
|
|
109
|
+
return renderOutput([
|
|
110
|
+
renderFields({
|
|
111
|
+
scheme,
|
|
112
|
+
index_settings: "none — the scheme builds no indexable sources",
|
|
113
|
+
}),
|
|
114
|
+
]);
|
|
115
|
+
}
|
|
116
|
+
if (file === undefined) {
|
|
117
|
+
return renderOutput([
|
|
118
|
+
renderFields({ scheme }),
|
|
119
|
+
renderList("targets", targets.map(([target, files]) => ({
|
|
120
|
+
target,
|
|
121
|
+
files: Object.keys(files).length,
|
|
122
|
+
}))),
|
|
123
|
+
renderHelp([
|
|
124
|
+
"Add `--file <path>` to see the compiler settings for one source file",
|
|
125
|
+
]),
|
|
126
|
+
]);
|
|
127
|
+
}
|
|
128
|
+
const match = findFile(targets, file);
|
|
129
|
+
if (!match) {
|
|
130
|
+
// The path is the caller's, so echo what was searched rather than making
|
|
131
|
+
// them guess whether the file or the scheme was wrong.
|
|
132
|
+
throw new AxiError(`No index settings for '${file}' in scheme ${scheme}`, "NOT_FOUND", [
|
|
133
|
+
`the scheme indexes ${plural(targets.reduce((sum, [, files]) => sum + Object.keys(files).length, 0), "file")} across ${plural(targets.length, "target")}`,
|
|
134
|
+
`Run \`xcodebuild-axi settings --scheme ${scheme} --for-index\` to see the targets`,
|
|
135
|
+
]);
|
|
136
|
+
}
|
|
137
|
+
const [target, path, settings] = match;
|
|
138
|
+
// swiftASTCommandArguments alone is several hundred entries of compiler flags.
|
|
139
|
+
const rendered = Object.fromEntries(Object.entries(settings).map(([key, value]) => [
|
|
140
|
+
key,
|
|
141
|
+
Array.isArray(value) && !full
|
|
142
|
+
? `${plural(value.length, "entry", "entries")} — pass --full to list them`
|
|
143
|
+
: value,
|
|
144
|
+
]));
|
|
145
|
+
return renderOutput([
|
|
146
|
+
renderFields({ scheme, target, file: relativeToCwd(path) }),
|
|
147
|
+
renderFields(rendered),
|
|
148
|
+
]);
|
|
149
|
+
}
|
|
150
|
+
/** Match on suffix, so a repo-relative path works as well as an absolute one. */
|
|
151
|
+
function findFile(targets, file) {
|
|
152
|
+
const needle = file.replace(/^\.\//, "");
|
|
153
|
+
for (const [target, files] of targets) {
|
|
154
|
+
for (const [path, settings] of Object.entries(files)) {
|
|
155
|
+
if (path === file || path.endsWith(`/${needle}`)) {
|
|
156
|
+
return [target, path, settings];
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
162
|
+
function plural(count, one, many = `${one}s`) {
|
|
163
|
+
return `${count} ${count === 1 ? one : many}`;
|
|
164
|
+
}
|
|
165
|
+
function relativeToCwd(path) {
|
|
166
|
+
const cwd = `${process.cwd()}/`;
|
|
167
|
+
return path.startsWith(cwd) ? path.slice(cwd.length) : path;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* `-showBuildSettings -json` emits an array of one object per target, each
|
|
171
|
+
* with a `buildSettings` map. Later targets win on collision, which matches
|
|
172
|
+
* the order xcodebuild itself resolves them in.
|
|
173
|
+
*/
|
|
174
|
+
function parseSettings(stdout) {
|
|
175
|
+
const start = stdout.indexOf("[");
|
|
176
|
+
if (start === -1)
|
|
177
|
+
return {};
|
|
178
|
+
let parsed;
|
|
179
|
+
try {
|
|
180
|
+
parsed = JSON.parse(stdout.slice(start));
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
return {};
|
|
184
|
+
}
|
|
185
|
+
const merged = {};
|
|
186
|
+
for (const entry of parsed) {
|
|
187
|
+
Object.assign(merged, entry.buildSettings ?? {});
|
|
188
|
+
}
|
|
189
|
+
return merged;
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/commands/settings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const SETUP_HELP = "usage: xcodebuild-axi setup hooks [flags]\nInstalls session-start hooks so an agent sees this project's schemes and last\nrun before it does anything (AXI principle 7). Covers Claude Code, Codex, and\nOpenCode.\nflags[3]:\n --project install into this repository instead of your home directory\n --status report what is installed, writing nothing\n --uninstall remove the hooks this tool installed\nexamples:\n xcodebuild-axi setup hooks\n xcodebuild-axi setup hooks --project\n xcodebuild-axi setup hooks --status\n";
|
|
2
|
+
export declare function setupCommand(args: string[]): Promise<string>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { installSessionStartHooks, sessionStartHookStatus, uninstallSessionStartHooks, } from "axi-sdk-js";
|
|
2
|
+
import { AxiError } from "../errors.js";
|
|
3
|
+
import { renderFields, renderHelp, renderOutput } from "../toon.js";
|
|
4
|
+
import { hasFlag, positionals, rejectUnknownFlags } from "../args.js";
|
|
5
|
+
export const SETUP_HELP = `usage: xcodebuild-axi setup hooks [flags]
|
|
6
|
+
Installs session-start hooks so an agent sees this project's schemes and last
|
|
7
|
+
run before it does anything (AXI principle 7). Covers Claude Code, Codex, and
|
|
8
|
+
OpenCode.
|
|
9
|
+
flags[3]:
|
|
10
|
+
--project install into this repository instead of your home directory
|
|
11
|
+
--status report what is installed, writing nothing
|
|
12
|
+
--uninstall remove the hooks this tool installed
|
|
13
|
+
examples:
|
|
14
|
+
xcodebuild-axi setup hooks
|
|
15
|
+
xcodebuild-axi setup hooks --project
|
|
16
|
+
xcodebuild-axi setup hooks --status
|
|
17
|
+
`;
|
|
18
|
+
const FLAGS = ["--project", "--status", "--uninstall"];
|
|
19
|
+
/**
|
|
20
|
+
* Passed explicitly rather than left to the SDK to infer.
|
|
21
|
+
*
|
|
22
|
+
* `inferHookOptions` reads the marker out of `process.argv[1]` and only
|
|
23
|
+
* matches a `dist/bin/<name>.js` path, so it works from the installed binary
|
|
24
|
+
* and throws everywhere else — `npm run dev -- setup hooks --status` failed
|
|
25
|
+
* with "unable to infer a hook marker from the current process". The installed
|
|
26
|
+
* binary infers this exact string, so stating it changes nothing there and
|
|
27
|
+
* makes `--status` and `--uninstall` work from a dev checkout too.
|
|
28
|
+
*
|
|
29
|
+
* Install is still correctly refused from a `.ts` entrypoint: the SDK's own
|
|
30
|
+
* policy rejects one, which is right — a hook wired to a tsx path would break
|
|
31
|
+
* as soon as the checkout moved.
|
|
32
|
+
*/
|
|
33
|
+
const MARKER = "xcodebuild-axi";
|
|
34
|
+
export async function setupCommand(args) {
|
|
35
|
+
rejectUnknownFlags(args, "setup", FLAGS);
|
|
36
|
+
const [target] = positionals(args, []);
|
|
37
|
+
if (target !== "hooks") {
|
|
38
|
+
throw new AxiError(target === undefined
|
|
39
|
+
? "setup needs a target"
|
|
40
|
+
: `Unknown setup target '${target}'`, "VALIDATION_ERROR", ["xcodebuild-axi setup hooks"]);
|
|
41
|
+
}
|
|
42
|
+
const scope = hasFlag(args, "--project")
|
|
43
|
+
? "project"
|
|
44
|
+
: "user";
|
|
45
|
+
if (hasFlag(args, "--status")) {
|
|
46
|
+
const status = sessionStartHookStatus({ scope, marker: MARKER });
|
|
47
|
+
return renderOutput([
|
|
48
|
+
renderFields({
|
|
49
|
+
setup: "status",
|
|
50
|
+
scope,
|
|
51
|
+
claude: status.claude?.installed
|
|
52
|
+
? (status.claude.path ?? "installed")
|
|
53
|
+
: "not installed",
|
|
54
|
+
codex: status.codex?.installed
|
|
55
|
+
? (status.codex.path ?? "installed")
|
|
56
|
+
: "not installed",
|
|
57
|
+
opencode: status.opencode?.installed
|
|
58
|
+
? (status.opencode.path ?? "installed")
|
|
59
|
+
: "not installed",
|
|
60
|
+
}),
|
|
61
|
+
]);
|
|
62
|
+
}
|
|
63
|
+
if (hasFlag(args, "--uninstall")) {
|
|
64
|
+
await uninstallSessionStartHooks({ scope, marker: MARKER });
|
|
65
|
+
return renderOutput([renderFields({ setup: "hooks removed", scope })]);
|
|
66
|
+
}
|
|
67
|
+
await installSessionStartHooks({ scope, marker: MARKER });
|
|
68
|
+
const status = sessionStartHookStatus({ scope, marker: MARKER });
|
|
69
|
+
return renderOutput([
|
|
70
|
+
renderFields({
|
|
71
|
+
setup: "hooks installed or already up to date",
|
|
72
|
+
scope,
|
|
73
|
+
claude: status.claude?.path ?? "skipped",
|
|
74
|
+
codex: status.codex?.path ?? "skipped",
|
|
75
|
+
opencode: status.opencode?.path ?? "skipped",
|
|
76
|
+
}),
|
|
77
|
+
renderHelp([
|
|
78
|
+
"Start a new agent session to pick them up",
|
|
79
|
+
"Run `xcodebuild-axi setup hooks --status` to verify",
|
|
80
|
+
"Run `xcodebuild-axi setup hooks --uninstall` to remove them",
|
|
81
|
+
]),
|
|
82
|
+
]);
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/commands/setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const SIM_HELP = "usage: xcodebuild-axi sim [list|boot|shutdown|erase] [name|udid] [flags]\nInspects and drives simulators. With no subcommand, lists the booted ones.\nsubcommands[4]:\n list every available simulator\n boot <name|udid> boot one, or no-op if it is already booted\n shutdown <name|udid> shut one down, or no-op if it already is; --all for every booted one\n erase <name|udid> erase one back to factory state; --all for every shut-down one\nflags[3]:\n --runtime <name> filter the list, e.g. \"iOS 26.5\"\n --booted list only booted simulators\n --all apply shutdown or erase to every eligible simulator\nexamples:\n xcodebuild-axi sim\n xcodebuild-axi sim list --runtime \"iOS 26.5\"\n xcodebuild-axi sim boot \"iPhone 17 Pro\"\n xcodebuild-axi sim shutdown --all\n";
|
|
2
|
+
export declare function simCommand(args: string[]): Promise<string>;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { AxiError } from "../errors.js";
|
|
2
|
+
import { findSimulator, listSimulators, simctl, } from "../simctl.js";
|
|
3
|
+
import { renderFields, renderHelp, renderList, renderOutput } from "../toon.js";
|
|
4
|
+
import { getFlag, hasFlag, positionals, rejectUnknownFlags } from "../args.js";
|
|
5
|
+
export const SIM_HELP = `usage: xcodebuild-axi sim [list|boot|shutdown|erase] [name|udid] [flags]
|
|
6
|
+
Inspects and drives simulators. With no subcommand, lists the booted ones.
|
|
7
|
+
subcommands[4]:
|
|
8
|
+
list every available simulator
|
|
9
|
+
boot <name|udid> boot one, or no-op if it is already booted
|
|
10
|
+
shutdown <name|udid> shut one down, or no-op if it already is; --all for every booted one
|
|
11
|
+
erase <name|udid> erase one back to factory state; --all for every shut-down one
|
|
12
|
+
flags[3]:
|
|
13
|
+
--runtime <name> filter the list, e.g. "iOS 26.5"
|
|
14
|
+
--booted list only booted simulators
|
|
15
|
+
--all apply shutdown or erase to every eligible simulator
|
|
16
|
+
examples:
|
|
17
|
+
xcodebuild-axi sim
|
|
18
|
+
xcodebuild-axi sim list --runtime "iOS 26.5"
|
|
19
|
+
xcodebuild-axi sim boot "iPhone 17 Pro"
|
|
20
|
+
xcodebuild-axi sim shutdown --all
|
|
21
|
+
`;
|
|
22
|
+
const FLAGS = ["--runtime", "--booted", "--all"];
|
|
23
|
+
export async function simCommand(args) {
|
|
24
|
+
rejectUnknownFlags(args, "sim", FLAGS, ["--runtime"]);
|
|
25
|
+
const [subcommand, target] = positionals(args, ["--runtime"]);
|
|
26
|
+
switch (subcommand ?? "booted") {
|
|
27
|
+
case "booted":
|
|
28
|
+
return listBooted();
|
|
29
|
+
case "list":
|
|
30
|
+
return listAll(args);
|
|
31
|
+
case "boot":
|
|
32
|
+
return boot(target);
|
|
33
|
+
case "shutdown":
|
|
34
|
+
return shutdown(args, target);
|
|
35
|
+
case "erase":
|
|
36
|
+
return erase(args, target);
|
|
37
|
+
default:
|
|
38
|
+
throw new AxiError(`Unknown sim subcommand '${subcommand}'`, "VALIDATION_ERROR", ["valid subcommands are list, boot, shutdown, erase"]);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function toRows(simulators) {
|
|
42
|
+
return simulators.map((simulator) => ({
|
|
43
|
+
name: simulator.name,
|
|
44
|
+
runtime: simulator.runtime,
|
|
45
|
+
state: simulator.state,
|
|
46
|
+
udid: simulator.udid,
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
/** The no-subcommand view: what is running right now, which is the thing that costs money. */
|
|
50
|
+
async function listBooted() {
|
|
51
|
+
const booted = (await listSimulators()).filter((simulator) => simulator.state === "booted");
|
|
52
|
+
if (booted.length === 0) {
|
|
53
|
+
return renderOutput([
|
|
54
|
+
renderFields({ booted: "0 simulators running" }),
|
|
55
|
+
renderHelp([
|
|
56
|
+
'Run `xcodebuild-axi sim boot "<name>"` to start one',
|
|
57
|
+
"Run `xcodebuild-axi sim list` to see what is available",
|
|
58
|
+
]),
|
|
59
|
+
]);
|
|
60
|
+
}
|
|
61
|
+
return renderOutput([
|
|
62
|
+
renderList("booted", toRows(booted)),
|
|
63
|
+
renderHelp(["Run `xcodebuild-axi sim shutdown --all` to stop them"]),
|
|
64
|
+
]);
|
|
65
|
+
}
|
|
66
|
+
async function listAll(args) {
|
|
67
|
+
const runtime = getFlag(args, "--runtime")?.toLowerCase();
|
|
68
|
+
let simulators = await listSimulators();
|
|
69
|
+
if (runtime) {
|
|
70
|
+
simulators = simulators.filter((simulator) => simulator.runtime.toLowerCase().includes(runtime));
|
|
71
|
+
}
|
|
72
|
+
if (hasFlag(args, "--booted")) {
|
|
73
|
+
simulators = simulators.filter((simulator) => simulator.state === "booted");
|
|
74
|
+
}
|
|
75
|
+
if (simulators.length === 0) {
|
|
76
|
+
return renderOutput([
|
|
77
|
+
renderFields({
|
|
78
|
+
simulators: runtime
|
|
79
|
+
? `0 simulators match runtime '${runtime}'`
|
|
80
|
+
: "0 simulators available",
|
|
81
|
+
}),
|
|
82
|
+
renderHelp(["Install a runtime in Xcode > Settings > Components"]),
|
|
83
|
+
]);
|
|
84
|
+
}
|
|
85
|
+
const booted = simulators.filter((simulator) => simulator.state === "booted").length;
|
|
86
|
+
return renderOutput([
|
|
87
|
+
renderFields({ count: simulators.length, booted }),
|
|
88
|
+
renderList("simulators", toRows(simulators)),
|
|
89
|
+
renderHelp(['Run `xcodebuild-axi sim boot "<name>"` to start one']),
|
|
90
|
+
]);
|
|
91
|
+
}
|
|
92
|
+
async function resolveTarget(target, verb) {
|
|
93
|
+
if (target === undefined) {
|
|
94
|
+
throw new AxiError(`sim ${verb} needs a simulator name or udid`, "VALIDATION_ERROR", [
|
|
95
|
+
`xcodebuild-axi sim ${verb} "iPhone 17 Pro"`,
|
|
96
|
+
"Run `xcodebuild-axi sim list` to see the names",
|
|
97
|
+
]);
|
|
98
|
+
}
|
|
99
|
+
const simulators = await listSimulators();
|
|
100
|
+
const found = findSimulator(simulators, target);
|
|
101
|
+
if (!found) {
|
|
102
|
+
const names = [
|
|
103
|
+
...new Set(simulators.map((simulator) => simulator.name)),
|
|
104
|
+
].slice(0, 12);
|
|
105
|
+
throw new AxiError(`No simulator matching '${target}'`, "SIMULATOR_NOT_FOUND", [`available: ${names.join(", ")}`]);
|
|
106
|
+
}
|
|
107
|
+
return found;
|
|
108
|
+
}
|
|
109
|
+
// Mutations are idempotent: booting a booted simulator is the state the agent
|
|
110
|
+
// asked for, so it is a no-op at exit 0, not an error (AXI principle 6).
|
|
111
|
+
async function boot(target) {
|
|
112
|
+
const simulator = await resolveTarget(target, "boot");
|
|
113
|
+
if (simulator.state === "booted") {
|
|
114
|
+
return renderFields({
|
|
115
|
+
sim: `${simulator.name} already booted (no-op)`,
|
|
116
|
+
udid: simulator.udid,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
const { exitCode, stderr } = await simctl(["boot", simulator.udid]);
|
|
120
|
+
if (exitCode !== 0 && !/current state: Booted/i.test(stderr)) {
|
|
121
|
+
throw new AxiError(`Could not boot ${simulator.name}`, "UNKNOWN", [
|
|
122
|
+
firstLine(stderr),
|
|
123
|
+
]);
|
|
124
|
+
}
|
|
125
|
+
return renderOutput([
|
|
126
|
+
renderFields({
|
|
127
|
+
sim: `${simulator.name} booted`,
|
|
128
|
+
runtime: simulator.runtime,
|
|
129
|
+
udid: simulator.udid,
|
|
130
|
+
}),
|
|
131
|
+
renderHelp([
|
|
132
|
+
`Run \`xcodebuild-axi test --device "${simulator.name}"\` to test on it`,
|
|
133
|
+
]),
|
|
134
|
+
]);
|
|
135
|
+
}
|
|
136
|
+
async function shutdown(args, target) {
|
|
137
|
+
if (hasFlag(args, "--all")) {
|
|
138
|
+
const booted = (await listSimulators()).filter((simulator) => simulator.state === "booted");
|
|
139
|
+
if (booted.length === 0) {
|
|
140
|
+
return renderFields({ sim: "0 simulators were running (no-op)" });
|
|
141
|
+
}
|
|
142
|
+
await simctl(["shutdown", "all"]);
|
|
143
|
+
return renderFields({
|
|
144
|
+
sim: `${booted.length} shut down`,
|
|
145
|
+
names: booted.map((s) => s.name),
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
const simulator = await resolveTarget(target, "shutdown");
|
|
149
|
+
if (simulator.state !== "booted") {
|
|
150
|
+
return renderFields({ sim: `${simulator.name} already shut down (no-op)` });
|
|
151
|
+
}
|
|
152
|
+
const { exitCode, stderr } = await simctl(["shutdown", simulator.udid]);
|
|
153
|
+
if (exitCode !== 0 && !/current state: Shutdown/i.test(stderr)) {
|
|
154
|
+
throw new AxiError(`Could not shut down ${simulator.name}`, "UNKNOWN", [
|
|
155
|
+
firstLine(stderr),
|
|
156
|
+
]);
|
|
157
|
+
}
|
|
158
|
+
return renderFields({ sim: `${simulator.name} shut down` });
|
|
159
|
+
}
|
|
160
|
+
async function erase(args, target) {
|
|
161
|
+
if (hasFlag(args, "--all")) {
|
|
162
|
+
const { exitCode, stderr } = await simctl(["erase", "all"]);
|
|
163
|
+
if (exitCode !== 0) {
|
|
164
|
+
throw new AxiError("Could not erase all simulators", "UNKNOWN", [
|
|
165
|
+
firstLine(stderr),
|
|
166
|
+
]);
|
|
167
|
+
}
|
|
168
|
+
return renderFields({ sim: "all shut-down simulators erased" });
|
|
169
|
+
}
|
|
170
|
+
const simulator = await resolveTarget(target, "erase");
|
|
171
|
+
const { exitCode, stderr } = await simctl(["erase", simulator.udid]);
|
|
172
|
+
if (exitCode !== 0) {
|
|
173
|
+
// simctl refuses to erase a running device; that is a real precondition,
|
|
174
|
+
// so name the command that satisfies it.
|
|
175
|
+
if (/Unable to erase.*booted|current state: Booted/i.test(stderr)) {
|
|
176
|
+
throw new AxiError(`${simulator.name} is booted, so it cannot be erased`, "VALIDATION_ERROR", [`Run \`xcodebuild-axi sim shutdown "${simulator.name}"\` first`]);
|
|
177
|
+
}
|
|
178
|
+
throw new AxiError(`Could not erase ${simulator.name}`, "UNKNOWN", [
|
|
179
|
+
firstLine(stderr),
|
|
180
|
+
]);
|
|
181
|
+
}
|
|
182
|
+
return renderFields({ sim: `${simulator.name} erased` });
|
|
183
|
+
}
|
|
184
|
+
function firstLine(text) {
|
|
185
|
+
return text.trim().split("\n")[0] ?? "";
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=sim.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sim.js","sourceRoot":"","sources":["../../../src/commands/sim.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const TEST_HELP = "usage: xcodebuild-axi test [flags]\nRuns a scheme's tests and reports the counts plus only the failures.\nflags[66]:\n --scheme <name> scheme to act on (required only when the project has more than one)\n --target <name> build a target instead of a scheme; repeatable (project only)\n --all-targets build every target in the project (project only)\n --device <name> simulator or device name, e.g. \"iPhone 17 Pro\" (default: newest simulator)\n --destination <spec> raw xcodebuild destination specifier, passed through untouched\n --configuration <name> build configuration (default: the scheme's own)\n --sdk <name> base SDK, e.g. iphonesimulator\n --arch <arch> architecture to build; repeatable or comma-separated\n --toolchain <name> toolchain identifier or name\n --xcconfig <path> apply build settings from this file as overrides\n --derived-data <path> derived data directory\n --jobs <n> maximum concurrent build operations\n --setting KEY=VALUE build setting override; repeatable or comma-separated\n --sign allow code signing (off by default, so simulator builds need no team)\n --allow-provisioning let xcodebuild talk to the developer portal for profiles\n --sanitizer <name> address, thread, or undefined; repeatable or comma-separated\n --timing report per-command build timings\n --destination-timeout <secs> how long to wait for the destination device\n --parallelize-targets build independent targets in parallel\n --hide-script-env omit shell script environment variables from the log\n --skip-unavailable-actions skip scheme actions that cannot run instead of failing\n --max-errors <n> errors to list before summarizing the rest (default: 20)\n --full list every warning instead of the first 10\n --codesize <dir> write a code size profile to this directory\n --log-level <level> quiet, normal, or verbose \u2014 how much lands in the log file\n --bundle-version <n> result bundle format version (default: xcodebuild's own)\n --stream <path> also write xcodebuild's live result stream here\n --offline resolve using only the versions already in Package.resolved\n --cache <path> clone remote packages into this directory\n --package-cache <path> shared package cache directory (across projects)\n --no-auto-resolve never resolve automatically; fail if Package.resolved is stale\n --skip-package-updates use the packages already cloned, without checking for updates\n --no-package-cache ignore the shared package repository cache\n --skip-plugin-validation trust build plugins without prompting\n --skip-signature-validation do not verify package signatures\n --package-auth <kind> keychain or netrc\n --registry-url <url> default package registry\n --scm-to-registry <kind> none, identity, or swift-package-registry\n --fingerprint-policy <kind> strict or warn\n --signing-entity-policy <kind> strict or warn\n --scm-provider <kind> system or xcode\n --test-plan <name> test plan to run\n --only <id> run only this test/class/target; repeatable or comma-separated\n --skip <id> skip this test/class/target; repeatable or comma-separated\n --coverage collect code coverage and report the overall percentage\n --without-building test already-built products (test-without-building)\n --xctestrun <path> test from an .xctestrun file instead of a scheme\n --parallel <n> exact number of parallel test runners\n --no-parallel disable parallel testing\n --iterations <n> run the tests this many times\n --retry retry failures, up to --iterations (default 3)\n --until-failure repeat until something fails, up to --iterations (default 100)\n --language <iso639> run in this language\n --region <iso3166> run in this region\n --diagnostics collect verbose diagnostics on failure\n --perf-diagnostics collect performance traces and memgraphs for performance tests\n --relaunch relaunch the process between repetitions\n --only-configuration <name> run only this test configuration; repeatable\n --skip-configuration <name> skip this test configuration; repeatable\n --max-workers <n> cap on parallel test runners\n --max-sim-destinations <n> cap on simulator destinations tested concurrently\n --max-device-destinations <n> cap on device destinations tested concurrently\n --default-test-timeout <secs> default per-test allowance when timeouts are on\n --test-products <path> where to find the built test products\n --test-timeout <secs> per-test execution allowance (default: 300, 0 disables)\n --max-failures <n> failures to list before summarizing the rest (default: 20)\nexit:\n 0 all tests passed, 1 a test or the build failed, 2 usage error\nexamples:\n xcodebuild-axi test\n xcodebuild-axi test --scheme MyApp --device \"iPhone 17 Pro\"\n xcodebuild-axi test --scheme MyApp --only MyAppTests/CheckoutTests\n xcodebuild-axi test --scheme MyApp --coverage\n";
|
|
2
|
+
export declare function testCommand(args: string[]): Promise<string>;
|