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.
Files changed (131) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/LICENSE +21 -0
  3. package/README.md +304 -0
  4. package/dist/bin/xcodebuild-axi.d.ts +2 -0
  5. package/dist/bin/xcodebuild-axi.js +8 -0
  6. package/dist/bin/xcodebuild-axi.js.map +1 -0
  7. package/dist/src/action.d.ts +68 -0
  8. package/dist/src/action.js +373 -0
  9. package/dist/src/action.js.map +1 -0
  10. package/dist/src/archive.d.ts +33 -0
  11. package/dist/src/archive.js +77 -0
  12. package/dist/src/archive.js.map +1 -0
  13. package/dist/src/args.d.ts +23 -0
  14. package/dist/src/args.js +123 -0
  15. package/dist/src/args.js.map +1 -0
  16. package/dist/src/auth.d.ts +11 -0
  17. package/dist/src/auth.js +51 -0
  18. package/dist/src/auth.js.map +1 -0
  19. package/dist/src/cli.d.ts +20 -0
  20. package/dist/src/cli.js +132 -0
  21. package/dist/src/cli.js.map +1 -0
  22. package/dist/src/commands/analyze.d.ts +2 -0
  23. package/dist/src/commands/analyze.js +32 -0
  24. package/dist/src/commands/analyze.js.map +1 -0
  25. package/dist/src/commands/archive.d.ts +2 -0
  26. package/dist/src/commands/archive.js +63 -0
  27. package/dist/src/commands/archive.js.map +1 -0
  28. package/dist/src/commands/build.d.ts +2 -0
  29. package/dist/src/commands/build.js +60 -0
  30. package/dist/src/commands/build.js.map +1 -0
  31. package/dist/src/commands/clean.d.ts +2 -0
  32. package/dist/src/commands/clean.js +39 -0
  33. package/dist/src/commands/clean.js.map +1 -0
  34. package/dist/src/commands/coverage.d.ts +2 -0
  35. package/dist/src/commands/coverage.js +111 -0
  36. package/dist/src/commands/coverage.js.map +1 -0
  37. package/dist/src/commands/destinations.d.ts +2 -0
  38. package/dist/src/commands/destinations.js +56 -0
  39. package/dist/src/commands/destinations.js.map +1 -0
  40. package/dist/src/commands/export.d.ts +2 -0
  41. package/dist/src/commands/export.js +170 -0
  42. package/dist/src/commands/export.js.map +1 -0
  43. package/dist/src/commands/find.d.ts +2 -0
  44. package/dist/src/commands/find.js +70 -0
  45. package/dist/src/commands/find.js.map +1 -0
  46. package/dist/src/commands/home.d.ts +9 -0
  47. package/dist/src/commands/home.js +97 -0
  48. package/dist/src/commands/home.js.map +1 -0
  49. package/dist/src/commands/info.d.ts +2 -0
  50. package/dist/src/commands/info.js +95 -0
  51. package/dist/src/commands/info.js.map +1 -0
  52. package/dist/src/commands/localize.d.ts +2 -0
  53. package/dist/src/commands/localize.js +121 -0
  54. package/dist/src/commands/localize.js.map +1 -0
  55. package/dist/src/commands/migrate.d.ts +8 -0
  56. package/dist/src/commands/migrate.js +177 -0
  57. package/dist/src/commands/migrate.js.map +1 -0
  58. package/dist/src/commands/packages.d.ts +2 -0
  59. package/dist/src/commands/packages.js +108 -0
  60. package/dist/src/commands/packages.js.map +1 -0
  61. package/dist/src/commands/platforms.d.ts +2 -0
  62. package/dist/src/commands/platforms.js +379 -0
  63. package/dist/src/commands/platforms.js.map +1 -0
  64. package/dist/src/commands/result.d.ts +2 -0
  65. package/dist/src/commands/result.js +100 -0
  66. package/dist/src/commands/result.js.map +1 -0
  67. package/dist/src/commands/schemes.d.ts +2 -0
  68. package/dist/src/commands/schemes.js +39 -0
  69. package/dist/src/commands/schemes.js.map +1 -0
  70. package/dist/src/commands/settings.d.ts +2 -0
  71. package/dist/src/commands/settings.js +191 -0
  72. package/dist/src/commands/settings.js.map +1 -0
  73. package/dist/src/commands/setup.d.ts +2 -0
  74. package/dist/src/commands/setup.js +84 -0
  75. package/dist/src/commands/setup.js.map +1 -0
  76. package/dist/src/commands/sim.d.ts +2 -0
  77. package/dist/src/commands/sim.js +187 -0
  78. package/dist/src/commands/sim.js.map +1 -0
  79. package/dist/src/commands/test.d.ts +2 -0
  80. package/dist/src/commands/test.js +317 -0
  81. package/dist/src/commands/test.js.map +1 -0
  82. package/dist/src/commands/testplans.d.ts +8 -0
  83. package/dist/src/commands/testplans.js +75 -0
  84. package/dist/src/commands/testplans.js.map +1 -0
  85. package/dist/src/commands/tests.d.ts +13 -0
  86. package/dist/src/commands/tests.js +154 -0
  87. package/dist/src/commands/tests.js.map +1 -0
  88. package/dist/src/commands/xcframework.d.ts +2 -0
  89. package/dist/src/commands/xcframework.js +77 -0
  90. package/dist/src/commands/xcframework.js.map +1 -0
  91. package/dist/src/context.d.ts +23 -0
  92. package/dist/src/context.js +72 -0
  93. package/dist/src/context.js.map +1 -0
  94. package/dist/src/destination.d.ts +50 -0
  95. package/dist/src/destination.js +174 -0
  96. package/dist/src/destination.js.map +1 -0
  97. package/dist/src/errors.d.ts +6 -0
  98. package/dist/src/errors.js +55 -0
  99. package/dist/src/errors.js.map +1 -0
  100. package/dist/src/packages.d.ts +31 -0
  101. package/dist/src/packages.js +117 -0
  102. package/dist/src/packages.js.map +1 -0
  103. package/dist/src/report.d.ts +20 -0
  104. package/dist/src/report.js +39 -0
  105. package/dist/src/report.js.map +1 -0
  106. package/dist/src/scheme.d.ts +22 -0
  107. package/dist/src/scheme.js +66 -0
  108. package/dist/src/scheme.js.map +1 -0
  109. package/dist/src/simctl.d.ts +33 -0
  110. package/dist/src/simctl.js +85 -0
  111. package/dist/src/simctl.js.map +1 -0
  112. package/dist/src/surface.d.ts +55 -0
  113. package/dist/src/surface.js +350 -0
  114. package/dist/src/surface.js.map +1 -0
  115. package/dist/src/toon.d.ts +34 -0
  116. package/dist/src/toon.js +79 -0
  117. package/dist/src/toon.js.map +1 -0
  118. package/dist/src/version.d.ts +1 -0
  119. package/dist/src/version.js +24 -0
  120. package/dist/src/version.js.map +1 -0
  121. package/dist/src/xccov.d.ts +25 -0
  122. package/dist/src/xccov.js +78 -0
  123. package/dist/src/xccov.js.map +1 -0
  124. package/dist/src/xcodebuild.d.ts +65 -0
  125. package/dist/src/xcodebuild.js +163 -0
  126. package/dist/src/xcodebuild.js.map +1 -0
  127. package/dist/src/xcresult.d.ts +96 -0
  128. package/dist/src/xcresult.js +156 -0
  129. package/dist/src/xcresult.js.map +1 -0
  130. package/package.json +75 -0
  131. package/skills/xcodebuild-axi/SKILL.md +64 -0
@@ -0,0 +1,56 @@
1
+ import { requireProject } from "../context.js";
2
+ import { requireScheme } from "../scheme.js";
3
+ import { listDestinations } from "../destination.js";
4
+ import { renderFields, renderHelp, renderList, renderOutput } from "../toon.js";
5
+ import { getFlag, hasFlag, rejectUnknownFlags } from "../args.js";
6
+ export const DESTINATIONS_HELP = `usage: xcodebuild-axi destinations [flags]
7
+ Lists the destinations a scheme can actually run on.
8
+ flags[3]:
9
+ --scheme <name> scheme to inspect (required only when the project has more than one)
10
+ --all include ineligible destinations, which xcodebuild hides the reason for
11
+ --simulators simulators only
12
+ examples:
13
+ xcodebuild-axi destinations
14
+ xcodebuild-axi destinations --scheme MyApp --simulators
15
+ `;
16
+ const FLAGS = ["--scheme", "--all", "--simulators"];
17
+ export async function destinationsCommand(args) {
18
+ rejectUnknownFlags(args, "destinations", FLAGS, ["--scheme"]);
19
+ const project = requireProject();
20
+ const scheme = await requireScheme(project, getFlag(args, "--scheme"), "destinations");
21
+ const all = hasFlag(args, "--all");
22
+ const simulatorsOnly = hasFlag(args, "--simulators");
23
+ let destinations = await listDestinations(project, scheme);
24
+ if (!all)
25
+ destinations = destinations.filter((d) => d.eligible);
26
+ if (simulatorsOnly)
27
+ destinations = destinations.filter((d) => d.platform.includes("Simulator"));
28
+ if (destinations.length === 0) {
29
+ return renderOutput([
30
+ renderFields({
31
+ destinations: `0 runnable destinations for scheme '${scheme}'`,
32
+ }),
33
+ renderHelp([
34
+ "Run `xcodebuild-axi destinations --scheme " +
35
+ scheme +
36
+ " --all` to include ineligible ones",
37
+ "Check that the matching simulator runtime is installed in Xcode > Settings > Components",
38
+ ]),
39
+ ]);
40
+ }
41
+ const rows = destinations.map((destination) => ({
42
+ name: destination.name,
43
+ platform: destination.platform.replace("Simulator", "Sim"),
44
+ os: destination.os,
45
+ ...(all ? { eligible: destination.eligible ? "yes" : "no" } : {}),
46
+ }));
47
+ return renderOutput([
48
+ renderFields({ scheme }),
49
+ renderList("destinations", rows),
50
+ renderHelp([
51
+ `Run \`xcodebuild-axi test --scheme ${scheme} --device "<name>"\` to run there`,
52
+ `Run \`xcodebuild-axi build --scheme ${scheme}\` to use the newest simulator automatically`,
53
+ ]),
54
+ ]);
55
+ }
56
+ //# sourceMappingURL=destinations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"destinations.js","sourceRoot":"","sources":["../../../src/commands/destinations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAElE,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;CAShC,CAAC;AAEF,MAAM,KAAK,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,cAAc,CAAU,CAAC;AAE7D,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAAc;IACtD,kBAAkB,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAE9D,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,MAAM,aAAa,CAChC,OAAO,EACP,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,EACzB,cAAc,CACf,CAAC;IACF,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACnC,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAErD,IAAI,YAAY,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC3D,IAAI,CAAC,GAAG;QAAE,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAChE,IAAI,cAAc;QAChB,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;IAE9E,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,YAAY,CAAC;YAClB,YAAY,CAAC;gBACX,YAAY,EAAE,uCAAuC,MAAM,GAAG;aAC/D,CAAC;YACF,UAAU,CAAC;gBACT,4CAA4C;oBAC1C,MAAM;oBACN,oCAAoC;gBACtC,yFAAyF;aAC1F,CAAC;SACH,CAAC,CAAC;IACL,CAAC;IAED,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAC9C,IAAI,EAAE,WAAW,CAAC,IAAI;QACtB,QAAQ,EAAE,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC;QAC1D,EAAE,EAAE,WAAW,CAAC,EAAE;QAClB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClE,CAAC,CAAC,CAAC;IAEJ,OAAO,YAAY,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,UAAU,CAAC,cAAc,EAAE,IAAI,CAAC;QAChC,UAAU,CAAC;YACT,sCAAsC,MAAM,mCAAmC;YAC/E,uCAAuC,MAAM,8CAA8C;SAC5F,CAAC;KACH,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const EXPORT_HELP: string;
2
+ export declare function exportCommand(args: string[]): Promise<string>;
@@ -0,0 +1,170 @@
1
+ import { existsSync, mkdtempSync, readdirSync, writeFileSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join, resolve } from "node:path";
4
+ import { AxiError, mapXcodebuildError } from "../errors.js";
5
+ import { EXPORT_METHODS, exportOptionsPlist, readArchiveInfo, } from "../archive.js";
6
+ import { authArgs, AUTH_FLAGS, AUTH_FLAG_HELP, AUTH_VALUE_FLAGS, } from "../auth.js";
7
+ import { requireProject } from "../context.js";
8
+ import { artifactDir, runBuild } from "../xcodebuild.js";
9
+ import { transcriptTail } from "../report.js";
10
+ import { duration, renderFields, renderHelp, renderOutput, tildePath, } from "../toon.js";
11
+ import { getFlag, hasFlag, positionals, rejectUnknownFlags } from "../args.js";
12
+ export const EXPORT_HELP = `usage: xcodebuild-axi export <path.xcarchive> [flags]
13
+ Exports a built archive into a distributable product.
14
+ flags[11]:
15
+ --method <name> ${EXPORT_METHODS.join(", ")}
16
+ --team <id> Developer team ID to sign with
17
+ --options <path> a hand-written export options plist, instead of --method
18
+ --output <path> where to write the export (default: the tool's cache)
19
+ --notarized export an archive Apple has already notarized
20
+ --allow-provisioning let xcodebuild fetch profiles from the developer portal
21
+ --signing-style <name> manual or automatic
22
+ ${AUTH_FLAG_HELP}
23
+ note:
24
+ --method writes the export options plist for you, which is otherwise an XML
25
+ file you have to author by hand. Pass --options to supply your own instead.
26
+ examples:
27
+ xcodebuild-axi export build/MyApp.xcarchive --method release-testing
28
+ xcodebuild-axi export build/MyApp.xcarchive --method app-store-connect --team ABCDE12345
29
+ xcodebuild-axi export build/MyApp.xcarchive --options ExportOptions.plist
30
+ `;
31
+ const FLAGS = [
32
+ "--method",
33
+ "--team",
34
+ "--options",
35
+ "--output",
36
+ "--notarized",
37
+ "--allow-provisioning",
38
+ "--signing-style",
39
+ ...AUTH_FLAGS,
40
+ ];
41
+ const VALUE_FLAGS = [
42
+ "--method",
43
+ "--team",
44
+ "--options",
45
+ "--output",
46
+ "--signing-style",
47
+ ...AUTH_VALUE_FLAGS,
48
+ ];
49
+ export async function exportCommand(args) {
50
+ rejectUnknownFlags(args, "export", FLAGS, VALUE_FLAGS);
51
+ const [rawArchive] = positionals(args, VALUE_FLAGS);
52
+ if (rawArchive === undefined) {
53
+ throw new AxiError("export needs a path to an .xcarchive", "VALIDATION_ERROR", [
54
+ "xcodebuild-axi export <path.xcarchive> --method release-testing",
55
+ "`xcodebuild-axi archive` prints the path it wrote",
56
+ ]);
57
+ }
58
+ const archivePath = resolve(expandTilde(rawArchive));
59
+ if (!existsSync(archivePath)) {
60
+ throw new AxiError(`No archive at ${rawArchive}`, "RESULT_NOT_FOUND", [
61
+ "Run `xcodebuild-axi archive --scheme <name>` to create one",
62
+ ]);
63
+ }
64
+ const notarized = hasFlag(args, "--notarized");
65
+ const method = getFlag(args, "--method");
66
+ const optionsPath = getFlag(args, "--options");
67
+ if (!notarized && method === undefined && optionsPath === undefined) {
68
+ throw new AxiError("export needs --method or --options", "VALIDATION_ERROR", [
69
+ `valid methods: ${EXPORT_METHODS.join(", ")}`,
70
+ "xcodebuild-axi export <path.xcarchive> --method release-testing",
71
+ ]);
72
+ }
73
+ if (method !== undefined &&
74
+ !EXPORT_METHODS.includes(method)) {
75
+ throw new AxiError(`Unknown export method '${method}'`, "VALIDATION_ERROR", [`valid methods: ${EXPORT_METHODS.join(", ")}`]);
76
+ }
77
+ const project = requireProject();
78
+ const outputPath = getFlag(args, "--output") ??
79
+ join(artifactDir(project), `${basenameOf(archivePath)}-export`);
80
+ const plistPath = optionsPath ?? (method ? writeGeneratedPlist(args, method) : undefined);
81
+ const run = await runBuild({
82
+ args: [
83
+ notarized ? "-exportNotarizedApp" : "-exportArchive",
84
+ "-archivePath",
85
+ archivePath,
86
+ "-exportPath",
87
+ outputPath,
88
+ ...(plistPath ? ["-exportOptionsPlist", plistPath] : []),
89
+ ...(hasFlag(args, "--allow-provisioning")
90
+ ? ["-allowProvisioningUpdates"]
91
+ : []),
92
+ ...authArgs(args, "export"),
93
+ ],
94
+ label: `${basenameOf(archivePath)}-export`,
95
+ project,
96
+ });
97
+ const succeeded = run.exitCode === 0;
98
+ if (!succeeded) {
99
+ const mapped = mapXcodebuildError(run.tail);
100
+ if (mapped) {
101
+ throw new AxiError(mapped.message, mapped.code, [
102
+ ...mapped.suggestions,
103
+ `full transcript: ${tildePath(run.logPath)}`,
104
+ ]);
105
+ }
106
+ }
107
+ const info = await readArchiveInfo(archivePath);
108
+ const products = succeeded ? listProducts(outputPath) : [];
109
+ const blocks = [
110
+ renderFields({
111
+ export: succeeded ? "succeeded" : "failed",
112
+ archive: tildePath(archivePath),
113
+ ...(method ? { method } : {}),
114
+ ...(info?.bundleIdentifier ? { bundle_id: info.bundleIdentifier } : {}),
115
+ ...(info?.marketingVersion ? { version: info.marketingVersion } : {}),
116
+ duration: duration(run.seconds),
117
+ }),
118
+ ];
119
+ if (products.length > 0) {
120
+ blocks.push(renderFields({ products }));
121
+ blocks.push(renderFields({ output: tildePath(outputPath) }));
122
+ }
123
+ else if (succeeded) {
124
+ // Exit zero with an empty export directory is the shape a silently wrong
125
+ // options plist produces; say so rather than implying a product exists.
126
+ blocks.push(renderFields({ products: `0 files written to ${tildePath(outputPath)}` }));
127
+ }
128
+ if (!succeeded) {
129
+ const tail = transcriptTail(run.tail);
130
+ if (tail)
131
+ blocks.push(tail);
132
+ }
133
+ blocks.push(renderFields({ log: tildePath(run.logPath) }));
134
+ if (!succeeded) {
135
+ process.exitCode = 1;
136
+ blocks.push(renderHelp([
137
+ "Signing is the usual cause — pass `--team <id>`, or `--allow-provisioning` to fetch profiles",
138
+ ]));
139
+ }
140
+ return renderOutput(blocks);
141
+ }
142
+ function writeGeneratedPlist(args, method) {
143
+ const dir = mkdtempSync(join(tmpdir(), "xcodebuild-axi-export-"));
144
+ const path = join(dir, "ExportOptions.plist");
145
+ const team = getFlag(args, "--team");
146
+ const signingStyle = getFlag(args, "--signing-style");
147
+ writeFileSync(path, exportOptionsPlist({
148
+ method,
149
+ ...(team !== undefined ? { teamID: team } : {}),
150
+ ...(signingStyle !== undefined ? { signingStyle } : {}),
151
+ }));
152
+ return path;
153
+ }
154
+ function listProducts(outputPath) {
155
+ try {
156
+ return readdirSync(outputPath).filter((entry) => !entry.startsWith("."));
157
+ }
158
+ catch {
159
+ return [];
160
+ }
161
+ }
162
+ function basenameOf(path) {
163
+ const last = path.split("/").filter(Boolean).pop() ?? "archive";
164
+ return last.replace(/\.xcarchive$/, "");
165
+ }
166
+ function expandTilde(path) {
167
+ const home = process.env["HOME"];
168
+ return home && path.startsWith("~/") ? `${home}${path.slice(1)}` : path;
169
+ }
170
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../../src/commands/export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const FIND_HELP = "usage: xcodebuild-axi find <name> [flags]\nResolves an executable or library to its full path in the active toolchain \u2014\nthe same lookup `xcrun` does, without the guesswork about which SDK.\nflags[3]:\n --library look for a library instead of an executable\n --sdk <name> SDK to search, e.g. iphoneos\n --toolchain <name> toolchain to search\nexamples:\n xcodebuild-axi find clang\n xcodebuild-axi find swiftc --sdk iphonesimulator\n xcodebuild-axi find libLTO.dylib --library\n";
2
+ export declare function findCommand(args: string[]): Promise<string>;
@@ -0,0 +1,70 @@
1
+ import { AxiError } from "../errors.js";
2
+ import { runMetadata, stripPreamble } from "../xcodebuild.js";
3
+ import { renderFields, renderHelp, renderOutput, tildePath } from "../toon.js";
4
+ import { getFlag, positionals, rejectUnknownFlags } from "../args.js";
5
+ export const FIND_HELP = `usage: xcodebuild-axi find <name> [flags]
6
+ Resolves an executable or library to its full path in the active toolchain —
7
+ the same lookup \`xcrun\` does, without the guesswork about which SDK.
8
+ flags[3]:
9
+ --library look for a library instead of an executable
10
+ --sdk <name> SDK to search, e.g. iphoneos
11
+ --toolchain <name> toolchain to search
12
+ examples:
13
+ xcodebuild-axi find clang
14
+ xcodebuild-axi find swiftc --sdk iphonesimulator
15
+ xcodebuild-axi find libLTO.dylib --library
16
+ `;
17
+ const FLAGS = ["--library", "--sdk", "--toolchain"];
18
+ const VALUE_FLAGS = ["--sdk", "--toolchain"];
19
+ export async function findCommand(args) {
20
+ rejectUnknownFlags(args, "find", FLAGS, VALUE_FLAGS);
21
+ const [name] = positionals(args, VALUE_FLAGS);
22
+ if (name === undefined) {
23
+ throw new AxiError("find needs a name to look for", "VALIDATION_ERROR", [
24
+ "xcodebuild-axi find clang",
25
+ "xcodebuild-axi find libz.tbd --library --sdk iphoneos",
26
+ ]);
27
+ }
28
+ const library = args.includes("--library");
29
+ const sdk = getFlag(args, "--sdk");
30
+ const toolchain = getFlag(args, "--toolchain");
31
+ const { stdout, stderr, exitCode } = await runMetadata([
32
+ library ? "-find-library" : "-find-executable",
33
+ name,
34
+ ...(sdk ? ["-sdk", sdk] : []),
35
+ ...(toolchain ? ["-toolchain", toolchain] : []),
36
+ ]);
37
+ const found = stripPreamble(stdout)
38
+ .split("\n")
39
+ .map((line) => line.trim())
40
+ .find((line) => line.startsWith("/"));
41
+ if (exitCode !== 0 || !found) {
42
+ // "Not here" is an answer, but a nonzero exit means the lookup itself
43
+ // failed, so keep it an error rather than a definitive empty state.
44
+ throw new AxiError(`No ${library ? "library" : "executable"} named '${name}'${sdk ? ` in SDK ${sdk}` : ""}`, "NOT_FOUND", [
45
+ library
46
+ ? "`--library` searches the toolchain's usr/lib, so pass the file name, e.g. libLTO.dylib"
47
+ : "Run `xcodebuild-axi info --sdks` to see the installed SDKs",
48
+ ...detail(stderr),
49
+ ]);
50
+ }
51
+ return renderOutput([
52
+ renderFields({
53
+ [library ? "library" : "executable"]: name,
54
+ path: tildePath(found),
55
+ ...(sdk ? { sdk } : {}),
56
+ }),
57
+ renderHelp([]),
58
+ ]);
59
+ }
60
+ /** xcodebuild prefixes its refusals with a timestamped line about a temp
61
+ * result bundle nobody will ever open; `stripPreamble` already drops it. */
62
+ function detail(stderr) {
63
+ const line = stripPreamble(stderr)
64
+ .split("\n")
65
+ .map((entry) => entry.trim())
66
+ // A bare "'name' not found." only restates the message above it.
67
+ .find((entry) => entry.length > 0 && !/not found\.?$/.test(entry));
68
+ return line ? [line] : [];
69
+ }
70
+ //# sourceMappingURL=find.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find.js","sourceRoot":"","sources":["../../../src/commands/find.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The no-argument view (AXI principles 7 and 8).
3
+ *
4
+ * This is what a session-start hook injects into every conversation, so it has
5
+ * to be both immediately useful and ruthlessly cheap: what is here, what can
6
+ * be built, and how the last run went. Nothing that needs a build, and nothing
7
+ * that takes more than a moment — `-list -json` and one result bundle read.
8
+ */
9
+ export declare function homeCommand(): Promise<string>;
@@ -0,0 +1,97 @@
1
+ import { readdirSync, statSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { resolveProject } from "../context.js";
4
+ import { listSchemes } from "../scheme.js";
5
+ import { artifactDir } from "../xcodebuild.js";
6
+ import { readTestSummary, describeDevice } from "../xcresult.js";
7
+ import { relativeTime, renderFields, renderHelp, renderOutput, tildePath, } from "../toon.js";
8
+ const MAX_SCHEMES_SHOWN = 12;
9
+ /**
10
+ * The no-argument view (AXI principles 7 and 8).
11
+ *
12
+ * This is what a session-start hook injects into every conversation, so it has
13
+ * to be both immediately useful and ruthlessly cheap: what is here, what can
14
+ * be built, and how the last run went. Nothing that needs a build, and nothing
15
+ * that takes more than a moment — `-list -json` and one result bundle read.
16
+ */
17
+ export async function homeCommand() {
18
+ const project = resolveProject();
19
+ if (!project) {
20
+ return renderOutput([
21
+ renderFields({
22
+ project: `no Xcode project in ${tildePath(process.cwd())}`,
23
+ }),
24
+ renderHelp([
25
+ "cd to a directory holding a .xcworkspace, .xcodeproj, or Package.swift",
26
+ "Run `xcodebuild-axi --help` for the full command list",
27
+ ]),
28
+ ]);
29
+ }
30
+ const [schemeInfo, lastRun] = await Promise.all([
31
+ listSchemes(project).catch(() => undefined),
32
+ describeLastRun(project),
33
+ ]);
34
+ const schemes = schemeInfo?.schemes ?? [];
35
+ const shown = schemes.slice(0, MAX_SCHEMES_SHOWN);
36
+ const blocks = [
37
+ renderFields({
38
+ [project.kind]: project.name,
39
+ // Count and names as separate fields: a "12: A,B,C" value contains a
40
+ // colon, which TOON then has to quote, costing more than the field it
41
+ // saved.
42
+ scheme_count: schemes.length,
43
+ schemes: schemes.length === 0 ? "none shared" : shown,
44
+ }),
45
+ ];
46
+ if (lastRun)
47
+ blocks.push(renderFields({ last: lastRun }));
48
+ const hints = [];
49
+ const example = schemes.length === 1 ? "" : " --scheme <name>";
50
+ if (schemes.length > 0) {
51
+ hints.push(`Run \`xcodebuild-axi build${example}\` to build`);
52
+ hints.push(`Run \`xcodebuild-axi test${example}\` to run tests`);
53
+ }
54
+ if (schemes.length > shown.length) {
55
+ hints.push(`Run \`xcodebuild-axi schemes\` for all ${schemes.length} schemes`);
56
+ }
57
+ blocks.push(renderHelp(hints));
58
+ return renderOutput(blocks);
59
+ }
60
+ /**
61
+ * Summarize the most recent run this tool recorded for the project.
62
+ *
63
+ * Read from our own artifact directory rather than anywhere in the repo, so
64
+ * the home view never reports on a bundle some other tool left behind and
65
+ * never reaches into a working tree.
66
+ */
67
+ async function describeLastRun(project) {
68
+ const dir = artifactDir(project);
69
+ let newest;
70
+ try {
71
+ for (const entry of readdirSync(dir)) {
72
+ if (!entry.endsWith(".xcresult"))
73
+ continue;
74
+ const path = join(dir, entry);
75
+ const mtime = statSync(path).mtimeMs;
76
+ if (!newest || mtime > newest.mtime)
77
+ newest = { path, mtime };
78
+ }
79
+ }
80
+ catch {
81
+ return undefined;
82
+ }
83
+ if (!newest)
84
+ return undefined;
85
+ const summary = await readTestSummary(newest.path).catch(() => undefined);
86
+ const when = relativeTime(newest.mtime / 1000);
87
+ if (!summary || summary.totalTestCount === undefined) {
88
+ return `${when} — build, see \`xcodebuild-axi result ${tildePath(newest.path)}\``;
89
+ }
90
+ const failed = summary.failedTests ?? 0;
91
+ const device = describeDevice(summary.devicesAndConfigurations?.[0]?.device);
92
+ const verdict = failed > 0
93
+ ? `${failed} failed, ${summary.passedTests ?? 0} passed`
94
+ : `${summary.passedTests ?? 0} passed`;
95
+ return `${summary.title ?? "test"} on ${device} — ${verdict} (${when})`;
96
+ }
97
+ //# sourceMappingURL=home.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"home.js","sourceRoot":"","sources":["../../../src/commands/home.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const INFO_HELP = "usage: xcodebuild-axi info [flags]\nReports the toolchain this machine will build with.\nflags[2]:\n --sdks list every installed SDK\n --platform <name> filter the SDK list, e.g. iphoneos\nexamples:\n xcodebuild-axi info\n xcodebuild-axi info --sdks --platform iphonesimulator\n";
2
+ export declare function infoCommand(args: string[]): Promise<string>;
@@ -0,0 +1,95 @@
1
+ import { execFile } from "node:child_process";
2
+ import { runMetadata } from "../xcodebuild.js";
3
+ import { listSimulators } from "../simctl.js";
4
+ import { renderFields, renderHelp, renderOutput, tildePath } from "../toon.js";
5
+ import { getFlag, hasFlag, rejectUnknownFlags } from "../args.js";
6
+ export const INFO_HELP = `usage: xcodebuild-axi info [flags]
7
+ Reports the toolchain this machine will build with.
8
+ flags[2]:
9
+ --sdks list every installed SDK
10
+ --platform <name> filter the SDK list, e.g. iphoneos
11
+ examples:
12
+ xcodebuild-axi info
13
+ xcodebuild-axi info --sdks --platform iphonesimulator
14
+ `;
15
+ const FLAGS = ["--sdks", "--platform"];
16
+ export async function infoCommand(args) {
17
+ rejectUnknownFlags(args, "info", FLAGS, ["--platform"]);
18
+ const [version, developerDir, sdks, simulators] = await Promise.all([
19
+ readVersion(),
20
+ readDeveloperDir(),
21
+ readSdks(),
22
+ listSimulators().catch(() => []),
23
+ ]);
24
+ const platform = getFlag(args, "--platform")?.toLowerCase();
25
+ const filtered = platform
26
+ ? sdks.filter((sdk) => (sdk.platform ?? "").toLowerCase().includes(platform))
27
+ : sdks;
28
+ const runtimes = [
29
+ ...new Set(simulators.map((simulator) => simulator.runtime)),
30
+ ].sort();
31
+ // `--sdks` is a different question from `info`, so it answers only that
32
+ // one. Reprinting the toolchain header cost more than the SDK list itself
33
+ // when this was measured — and a canonical name already carries its own
34
+ // platform and version, so one column says what three did.
35
+ if (hasFlag(args, "--sdks") || platform !== undefined) {
36
+ const names = [
37
+ ...new Set(filtered.map((sdk) => sdk.canonicalName).filter((name) => !!name)),
38
+ ].sort();
39
+ if (names.length === 0) {
40
+ return renderOutput([
41
+ renderFields({
42
+ sdks: `0 of ${sdks.length} installed SDKs match platform '${platform}'`,
43
+ }),
44
+ renderHelp(["Run `xcodebuild-axi info --sdks` to list them all"]),
45
+ ]);
46
+ }
47
+ return renderOutput([
48
+ renderFields({
49
+ ...(platform ? { platform } : {}),
50
+ sdks: names,
51
+ }),
52
+ ]);
53
+ }
54
+ return renderOutput([
55
+ renderFields({
56
+ xcode: version.version,
57
+ build: version.build,
58
+ developer_dir: tildePath(developerDir),
59
+ sdks: sdks.length,
60
+ simulators: simulators.length,
61
+ ...(runtimes.length > 0 ? { runtimes } : {}),
62
+ }),
63
+ renderHelp(["Run `xcodebuild-axi info --sdks` to list the installed SDKs"]),
64
+ ]);
65
+ }
66
+ async function readVersion() {
67
+ const { stdout } = await runMetadata(["-version"]);
68
+ const lines = stdout.trim().split("\n");
69
+ return {
70
+ version: (lines[0] ?? "unknown").replace(/^Xcode\s*/, ""),
71
+ build: (lines[1] ?? "").replace(/^Build version\s*/, ""),
72
+ };
73
+ }
74
+ async function readSdks() {
75
+ const { stdout } = await runMetadata(["-showsdks", "-json"]);
76
+ const start = stdout.indexOf("[");
77
+ if (start === -1)
78
+ return [];
79
+ try {
80
+ // Only the base SDKs matter for choosing what to build against; the
81
+ // sub-SDK entries triple the row count and answer nothing.
82
+ return JSON.parse(stdout.slice(start)).filter((sdk) => sdk.isBaseSdk !== false);
83
+ }
84
+ catch {
85
+ return [];
86
+ }
87
+ }
88
+ function readDeveloperDir() {
89
+ return new Promise((resolvePromise) => {
90
+ execFile("xcode-select", ["-p"], { encoding: "utf-8" }, (error, stdout) => {
91
+ resolvePromise(error ? (process.env["DEVELOPER_DIR"] ?? "unknown") : stdout.trim());
92
+ });
93
+ });
94
+ }
95
+ //# sourceMappingURL=info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"info.js","sourceRoot":"","sources":["../../../src/commands/info.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const LOCALIZE_HELP = "usage: xcodebuild-axi localize export|import [flags]\nMoves XLIFF localization catalogs in and out of a project.\nflags[6]:\n --path <path> the .xcloc directory to write, or the one to import (required for import)\n --language <code> ISO 639-1 language to export; repeatable or comma-separated\n --default-language <code> the language translations are made from\n --screenshots include localization screenshots in the export\n --merge merge the import into existing translations instead of replacing\n --scheme <name> limit the export to one scheme's targets\nnote:\n Export writes one .xcloc bundle per language. Without --path they land in the\n tool's cache and the path is printed.\nexit:\n 0 succeeded, 1 xcodebuild refused, 2 usage error\nexamples:\n xcodebuild-axi localize export --language fr,de\n xcodebuild-axi localize export --path build/loc --default-language en\n xcodebuild-axi localize import --path build/loc/fr.xcloc --merge\n";
2
+ export declare function localizeCommand(args: string[]): Promise<string>;