rork-xcode 0.10.0 → 0.12.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/README.md +60 -2
- package/dist/index.d.ts +346 -29
- package/dist/index.js +821 -102
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -100,7 +100,7 @@ const text = project.build();
|
|
|
100
100
|
|
|
101
101
|
### Targets and build settings
|
|
102
102
|
|
|
103
|
-
`getBuildSetting` resolves hierarchically the way Xcode does
|
|
103
|
+
`getBuildSetting` resolves hierarchically the way Xcode does, reading the target's default configuration first and the project-level configuration below it. Writes go to every configuration of the target, so Debug and Release stay consistent.
|
|
104
104
|
|
|
105
105
|
```ts
|
|
106
106
|
const app = project.findMainAppTarget("ios"); // "macos" | "tvos" | "watchos" | "visionos"
|
|
@@ -114,6 +114,13 @@ for (const target of project.nativeTargets()) {
|
|
|
114
114
|
}
|
|
115
115
|
```
|
|
116
116
|
|
|
117
|
+
`resolveBuildSetting` reads the same layers and expands the `$(NAME)` and `${NAME}` references in the value. Referenced settings resolve through the chain, `$(inherited)` continues from the next layer down, and `$(TARGET_NAME)` falls back to the target's name, so the template's `PRODUCT_NAME = "$(TARGET_NAME)"` resolves without any setup. References the document cannot answer (build-system paths like `$(BUILT_PRODUCTS_DIR)`) stay verbatim unless a caller-supplied lookup answers them, so nothing is invented.
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
app?.resolveBuildSetting("PRODUCT_NAME"); // "DemoApp", from PRODUCT_NAME = "$(TARGET_NAME)"
|
|
121
|
+
app?.resolveBuildSetting("WIDGET_ID"); // "com.example.demo.widget", through PRODUCT_BUNDLE_IDENTIFIER
|
|
122
|
+
```
|
|
123
|
+
|
|
117
124
|
`project.targets()` returns every target kind. Aggregate targets (`PBXAggregateTarget`) and legacy external-build-tool targets (`PBXLegacyTarget`) share the full target surface, from configurations and build settings to phases and dependency wiring.
|
|
118
125
|
|
|
119
126
|
```ts
|
|
@@ -273,6 +280,27 @@ const text = scheme.build();
|
|
|
273
280
|
|
|
274
281
|
Underneath, the document is a plain tree of elements with ordered attributes and children, reachable through `scheme.root` and `scheme.elements(name)`, so anything the typed surface does not cover stays one property away. `parseXcscheme` and `buildXcscheme` remain available for working with the tree directly. Attribute order is preserved and meaningful, which is how byte-identical round-trips fall out. Comments are kept, attribute values resolve the character references Xcode writes (`"`, `&`, ` ` and friends), and the writer re-escapes them identically.
|
|
275
282
|
|
|
283
|
+
## Workspaces
|
|
284
|
+
|
|
285
|
+
A `.xcworkspace` directory carries a `contents.xcworkspacedata` file listing the projects and folders the workspace shows, in the same XML dialect scheme files use, with the same round-trip contract. An Xcode-written file rebuilds byte for byte, any other input reaches the canonical layout in one build, and malformed input fails with a typed error carrying line and column.
|
|
286
|
+
|
|
287
|
+
`Xcworkspace` is the model. Its flagship read resolves which projects the workspace references, so tooling stops globbing directory trees and asks the file that already knows:
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
import { Xcworkspace } from "rork-xcode";
|
|
291
|
+
|
|
292
|
+
const workspace = Xcworkspace.parse(xcworkspacedataText);
|
|
293
|
+
|
|
294
|
+
workspace.projectFilePaths(); // ["DemoApp.xcodeproj", "Pods/Pods.xcodeproj"]
|
|
295
|
+
|
|
296
|
+
workspace.addFileRef("group:Vendor/Vendor.xcodeproj");
|
|
297
|
+
const text = workspace.build();
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Group locations compose through their enclosing groups, container locations anchor at the workspace's directory, and absolute locations pass through. The resolution is textual, because the library never touches the filesystem, so locations only a running Xcode can resolve (`self` and `developer`) stay out of the list. `Xcworkspace.create` produces the document Xcode writes for a new workspace, file references come back as typed views through `fileRefs()`, and `parseXcworkspace` and `buildXcworkspace` remain available for working with the tree directly.
|
|
301
|
+
|
|
302
|
+
The other files inside a `.xcworkspace`, such as `WorkspaceSettings.xcsettings` and `IDEWorkspaceChecks.plist` under `xcshareddata`, are standard property lists rather than this dialect. [`rork-plist`](https://www.npmjs.com/package/rork-plist) parses and writes them with the same round-trip discipline, and the two libraries compose.
|
|
303
|
+
|
|
276
304
|
## Xcconfig files
|
|
277
305
|
|
|
278
306
|
Build settings do not only live in the pbxproj. Projects push them into `.xcconfig` files referenced through `baseConfigurationReference`, and the xcconfig module reads and writes that format with the fidelity the rest of the library promises. The format is hand-authored with no canonical layout, so the contract here is losslessness. Parsing and building an untouched file reproduces it byte for byte, including comments, blank lines, column alignment, and line endings. Malformed lines fail loudly with a typed error carrying line and column rather than being dropped, so a file the parser accepts is a file it fully understood.
|
|
@@ -314,6 +342,24 @@ project.registerXcconfig(reference, Xcconfig.parse(text));
|
|
|
314
342
|
app.getBuildSetting("SDKROOT"); // now sees values the xcconfig defines
|
|
315
343
|
```
|
|
316
344
|
|
|
345
|
+
## Build-setting references
|
|
346
|
+
|
|
347
|
+
Values reference other build settings as `$(NAME)` and `${NAME}`, in the pbxproj, in xcconfig files, and in Info.plist templates. The syntax is Xcode's own, down to the `:` operators, and Xcode's app templates write values in exactly this shape, for example `PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.$(PRODUCT_NAME:rfc1034identifier)`. `expandBuildSettingReferences` evaluates the syntax through a caller-supplied lookup, so the same code serves all three formats. Substituted text expands recursively, names may themselves contain references (`$(SETTING_$(VARIANT))`), cycles stay finite, and a reference the lookup cannot answer stays verbatim, so partial resolution loses no information.
|
|
348
|
+
|
|
349
|
+
```ts
|
|
350
|
+
import { expandBuildSettingReferences } from "rork-xcode";
|
|
351
|
+
|
|
352
|
+
// A value as found in a project file. The references and their operators
|
|
353
|
+
// are part of the document, so the expander takes them from the text
|
|
354
|
+
// rather than from options.
|
|
355
|
+
const found = "com.example.$(PRODUCT_NAME:rfc1034identifier)";
|
|
356
|
+
|
|
357
|
+
expandBuildSettingReferences(found, (name) => (name === "PRODUCT_NAME" ? "My App" : undefined));
|
|
358
|
+
// "com.example.My-App"
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
The `:` operators are honored for `lower`, `upper`, `rfc1034identifier` (the mapping into RFC 1034 host-name characters that bundle identifiers need), `c99extidentifier`, and `default=`. A reference carrying any other operator stays verbatim rather than expanding to a wrongly transformed value. The model composes the expander with settings resolution as `target.resolveBuildSetting(key)`, described under [Targets and build settings](#targets-and-build-settings).
|
|
362
|
+
|
|
317
363
|
## Performance
|
|
318
364
|
|
|
319
365
|
`rork-xcode` is measured against the pbxproj parsers on npm, [`@bacons/xcode`](https://www.npmjs.com/package/@bacons/xcode) (its `/json` parse/build entry point) and [`xcode`](https://www.npmjs.com/package/xcode) (the long-standing package used by native build tooling), on three documents: two real Xcode-written projects from the test suite and a deterministically generated five-target app with 800 source files. It is the fastest at both operations on every document, with zero dependencies.
|
|
@@ -331,6 +377,17 @@ app.getBuildSetting("SDKROOT"); // now sees values the xcconfig defines
|
|
|
331
377
|
| build | app, Xcode 16 | **37.5 µs** | 113.6 µs (3.0×) | 71.3 µs (1.9×) |
|
|
332
378
|
| build | generated app | **0.98 ms** | 85.98 ms (87.7×) | 1.20 ms (1.2×) |
|
|
333
379
|
|
|
380
|
+
The XML dialect files measure against `@bacons/xcode`, the one other npm package that parses and writes them (the `xcode` package has no scheme or workspace support):
|
|
381
|
+
|
|
382
|
+
| Operation | Document | `rork-xcode` | `@bacons/xcode` |
|
|
383
|
+
| --------- | --------------------------- | ------------ | --------------- |
|
|
384
|
+
| parse | app scheme (3.3 KiB) | **28.1 µs** | 108.7 µs (3.9×) |
|
|
385
|
+
| parse | actions scheme (5.8 KiB) | **46.7 µs** | 185.7 µs (4.0×) |
|
|
386
|
+
| parse | grouped workspace (0.7 KiB) | **4.7 µs** | 20.5 µs (4.3×) |
|
|
387
|
+
| build | app scheme | **7.1 µs** | 8.0 µs (1.1×) |
|
|
388
|
+
| build | actions scheme | **11.9 µs** | 13.8 µs (1.2×) |
|
|
389
|
+
| build | grouped workspace | **2.2 µs** | 3.0 µs (1.4×) |
|
|
390
|
+
|
|
334
391
|
Measured on an Apple M5 Max, Node.js 24, single thread, with `@bacons/xcode` 1.0.0-alpha.33 and `xcode` 3.0.1. Multipliers are relative to `rork-xcode` on the same row; the ordering also holds on Bun. Reproduce with `pnpm bench:compare`, which interleaves the libraries in round-robin batches and reports the median, after verifying that every library round-trips every fixture.
|
|
335
392
|
|
|
336
393
|
### Key performance features
|
|
@@ -339,13 +396,14 @@ Measured on an Apple M5 Max, Node.js 24, single thread, with `@bacons/xcode` 1.0
|
|
|
339
396
|
- **Comments skip in bulk.** Reference comments are a sizable share of a canonical document's bytes, so comment bodies are jumped with `indexOf` instead of being scanned per character.
|
|
340
397
|
- **Linear comment derivation.** Building the `/* … */` annotations uses reverse indexes over the object graph (build file → phase, configuration list → owner), so serialization stays linear on projects with thousands of objects.
|
|
341
398
|
- **Memoized rendering.** Quoting decisions for the repeated key vocabulary and rendered uuid references are cached per document, halving the quote scans on reference-heavy sections.
|
|
399
|
+
- **Single-scan XML writing.** Attribute values pass one character-class test, and the near-universal value with nothing to escape returns as-is. The same machinery validates what XML cannot carry, and error paths are resolved only when a build actually fails, so correctness checks cost nothing on the happy path.
|
|
342
400
|
|
|
343
401
|
## Verification
|
|
344
402
|
|
|
345
403
|
- The committed fixture corpus spans project generations from Xcode 3 to Xcode 16, captured from real projects with identifiers neutralized: synchronized folders with both exception-set kinds, classic groups, variant groups, aggregate and legacy targets, reference proxies, build rules, Swift packages, and a ~100 KiB multiplatform framework project.
|
|
346
404
|
- Documents already in current Xcode's layout must round-trip byte for byte, and documents from other tool generations must normalize to a byte-stable fixed point with unchanged values.
|
|
347
405
|
- On macOS, the suite cross-validates every fixture and its rebuilt form with `plutil`, Apple's own property list parser and the empirical ground truth for what Apple tooling accepts.
|
|
348
|
-
- A corpus sweep (`pnpm corpus`) walks every Xcode project, scheme, and xcconfig on the machine, verifies each one parses and reaches a byte-stable fixed point (byte-exact losslessness for xcconfig, which has no canonical layout), exercises the object model against every project, and cross-validates a sample against plutil's own reading.
|
|
406
|
+
- A corpus sweep (`pnpm corpus`) walks every Xcode project, scheme, workspace, and xcconfig on the machine, verifies each one parses and reaches a byte-stable fixed point (byte-exact losslessness for xcconfig, which has no canonical layout), exercises the object model against every project, and cross-validates a sample against plutil's own reading.
|
|
349
407
|
- CI runs the full gate on Linux and macOS, and executes the built artifact on the oldest supported Node to enforce the `engines` floor.
|
|
350
408
|
|
|
351
409
|
## Releasing
|
package/dist/index.d.ts
CHANGED
|
@@ -82,13 +82,14 @@ declare function buildPbxproj(root: PbxprojObject): string;
|
|
|
82
82
|
* @module
|
|
83
83
|
*/
|
|
84
84
|
/**
|
|
85
|
-
* Location of a parse failure inside the source text
|
|
85
|
+
* Location of a parse failure inside the source text, shared by every
|
|
86
|
+
* parse error the library throws.
|
|
86
87
|
*
|
|
87
88
|
* Offsets count UTF-16 code units from the start of the string (the same
|
|
88
89
|
* units `String.prototype.slice` uses), so editors and log tooling can jump
|
|
89
90
|
* straight to the failure.
|
|
90
91
|
*/
|
|
91
|
-
interface
|
|
92
|
+
interface TextPosition {
|
|
92
93
|
/** Zero-based character offset into the source string. */
|
|
93
94
|
offset: number;
|
|
94
95
|
/** One-based line number. */
|
|
@@ -96,6 +97,12 @@ interface PbxprojErrorPosition {
|
|
|
96
97
|
/** One-based column number, in characters from the start of the line. */
|
|
97
98
|
column: number;
|
|
98
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* The name {@link TextPosition} carried before the scheme, workspace, and
|
|
102
|
+
* xcconfig parsers shared it. Kept as an alias so existing annotations
|
|
103
|
+
* keep compiling.
|
|
104
|
+
*/
|
|
105
|
+
type PbxprojErrorPosition = TextPosition;
|
|
99
106
|
/**
|
|
100
107
|
* Thrown when the source text is not a well-formed OpenStep-style property
|
|
101
108
|
* list (the format of `project.pbxproj` files).
|
|
@@ -106,7 +113,7 @@ interface PbxprojErrorPosition {
|
|
|
106
113
|
*/
|
|
107
114
|
declare class PbxprojParseError extends Error {
|
|
108
115
|
/** Where in the source text parsing failed. */
|
|
109
|
-
readonly position:
|
|
116
|
+
readonly position: TextPosition;
|
|
110
117
|
/**
|
|
111
118
|
* @param message Failure description without location. The location is
|
|
112
119
|
* appended automatically.
|
|
@@ -125,7 +132,26 @@ declare class PbxprojParseError extends Error {
|
|
|
125
132
|
*/
|
|
126
133
|
declare class XcschemeParseError extends Error {
|
|
127
134
|
/** Where in the source text parsing failed. */
|
|
128
|
-
readonly position:
|
|
135
|
+
readonly position: TextPosition;
|
|
136
|
+
/**
|
|
137
|
+
* @param message Failure description without location. The location is
|
|
138
|
+
* appended automatically.
|
|
139
|
+
* @param source Full source text, used to compute the position.
|
|
140
|
+
* @param offset Character offset of the failure inside `source`.
|
|
141
|
+
*/
|
|
142
|
+
constructor(message: string, source: string, offset: number);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Thrown when the source text is not a well-formed workspace data file
|
|
146
|
+
* (the XML dialect of `contents.xcworkspacedata` files).
|
|
147
|
+
*
|
|
148
|
+
* The message always embeds the line and column of the failure, and the
|
|
149
|
+
* same information is available in structured form on {@link position}
|
|
150
|
+
* for programmatic use.
|
|
151
|
+
*/
|
|
152
|
+
declare class XcworkspaceParseError extends Error {
|
|
153
|
+
/** Where in the source text parsing failed. */
|
|
154
|
+
readonly position: TextPosition;
|
|
129
155
|
/**
|
|
130
156
|
* @param message Failure description without location. The location is
|
|
131
157
|
* appended automatically.
|
|
@@ -144,7 +170,7 @@ declare class XcschemeParseError extends Error {
|
|
|
144
170
|
*/
|
|
145
171
|
declare class XcconfigParseError extends Error {
|
|
146
172
|
/** Where in the source text parsing failed. */
|
|
147
|
-
readonly position:
|
|
173
|
+
readonly position: TextPosition;
|
|
148
174
|
/**
|
|
149
175
|
* @param message Failure description without location. The location is
|
|
150
176
|
* appended automatically.
|
|
@@ -170,6 +196,23 @@ declare class XcschemeBuildError extends Error {
|
|
|
170
196
|
*/
|
|
171
197
|
constructor(message: string, path: string);
|
|
172
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* Thrown when a workspace element cannot be written as XML.
|
|
201
|
+
*
|
|
202
|
+
* Raised for element and attribute names that are not valid XML names and
|
|
203
|
+
* for attribute values carrying control characters XML 1.0 cannot encode.
|
|
204
|
+
* The {@link path} pinpoints the offending element inside the tree.
|
|
205
|
+
*/
|
|
206
|
+
declare class XcworkspaceBuildError extends Error {
|
|
207
|
+
/** Path to the offending element from the root, e.g. `Workspace.FileRef[0]`. */
|
|
208
|
+
readonly path: string;
|
|
209
|
+
/**
|
|
210
|
+
* @param message Failure description without location. The element path
|
|
211
|
+
* is appended automatically.
|
|
212
|
+
* @param path Path to the offending element from the root.
|
|
213
|
+
*/
|
|
214
|
+
constructor(message: string, path: string);
|
|
215
|
+
}
|
|
173
216
|
/**
|
|
174
217
|
* Thrown by the object model when an operation cannot proceed, because the
|
|
175
218
|
* document lacks the structure the operation needs (no objects dictionary,
|
|
@@ -207,6 +250,73 @@ declare class PbxprojBuildError extends Error {
|
|
|
207
250
|
constructor(message: string, path: string);
|
|
208
251
|
}
|
|
209
252
|
//#endregion
|
|
253
|
+
//#region src/expansion.d.ts
|
|
254
|
+
/**
|
|
255
|
+
* Expansion of `$(NAME)` and `${NAME}` build-setting references.
|
|
256
|
+
*
|
|
257
|
+
* Values in the pbxproj, in xcconfig files, and in Info.plist templates
|
|
258
|
+
* reference other build settings, and every consumer that needs the
|
|
259
|
+
* resolved string ends up re-implementing the substitution informally.
|
|
260
|
+
* The expander here is a pure function over a caller-supplied lookup, so
|
|
261
|
+
* the same code serves all three formats. The model composes it with
|
|
262
|
+
* settings resolution in `Target.resolveBuildSetting`.
|
|
263
|
+
*
|
|
264
|
+
* @module
|
|
265
|
+
*/
|
|
266
|
+
/**
|
|
267
|
+
* The value a reference expands to, or `undefined` to leave the
|
|
268
|
+
* reference in place. Returning the empty string expands to nothing,
|
|
269
|
+
* which is how Xcode itself treats settings that exist but are empty.
|
|
270
|
+
*/
|
|
271
|
+
type BuildSettingLookup = (name: string) => string | undefined;
|
|
272
|
+
interface ExpandBuildSettingOptions {
|
|
273
|
+
/**
|
|
274
|
+
* Whether lookup answers are expanded again, which is the default and
|
|
275
|
+
* suits lookups reading raw stored values. A lookup that resolves
|
|
276
|
+
* references itself, like the model's layered resolution, turns this
|
|
277
|
+
* off so text it deliberately left verbatim is not reinterpreted in
|
|
278
|
+
* the outer value's context.
|
|
279
|
+
*/
|
|
280
|
+
expandLookupValues?: boolean;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Expands every `$(NAME)` and `${NAME}` reference in a value through the
|
|
284
|
+
* lookup. Substituted text is expanded again, so references are followed
|
|
285
|
+
* through chains of values, and reference names may themselves contain
|
|
286
|
+
* references (`$(SETTING_$(VARIANT))`), which expand innermost first.
|
|
287
|
+
*
|
|
288
|
+
* A lookup answer of `undefined` leaves the reference in the output
|
|
289
|
+
* verbatim, so partial resolution loses no information. A reference
|
|
290
|
+
* whose expansion would recurse into itself also stays verbatim, which
|
|
291
|
+
* keeps cyclic definitions finite. Xcode's `:` operators are honored for
|
|
292
|
+
* the forms below, and a reference carrying any other operator stays
|
|
293
|
+
* verbatim rather than expanding to a wrongly transformed value.
|
|
294
|
+
*
|
|
295
|
+
* The supported operators are `lower` and `upper` for case mapping,
|
|
296
|
+
* `rfc1034identifier` and `c99extidentifier` for the identifier
|
|
297
|
+
* mappings bundle identifiers and product module names use, and
|
|
298
|
+
* `default=value` for substituting a fallback when the setting resolves
|
|
299
|
+
* empty or is not known to the lookup.
|
|
300
|
+
*/
|
|
301
|
+
declare function expandBuildSettingReferences(value: string, lookup: BuildSettingLookup, options?: ExpandBuildSettingOptions): string;
|
|
302
|
+
/**
|
|
303
|
+
* The transforming operators the expander supports, keyed by the name
|
|
304
|
+
* they are written with. `default=` is not listed because it carries an
|
|
305
|
+
* argument and substitutes rather than transforms, so the reference
|
|
306
|
+
* expansion handles it structurally.
|
|
307
|
+
*/
|
|
308
|
+
declare const OPERATOR_TRANSFORMS: {
|
|
309
|
+
c99extidentifier: (value: string) => string;
|
|
310
|
+
lower: (value: string) => string;
|
|
311
|
+
rfc1034identifier: (value: string) => string;
|
|
312
|
+
upper: (value: string) => string;
|
|
313
|
+
};
|
|
314
|
+
/**
|
|
315
|
+
* A transforming operator name honored in `$(NAME:operator)` references,
|
|
316
|
+
* alongside the structural `default=`.
|
|
317
|
+
*/
|
|
318
|
+
type BuildSettingOperator = keyof typeof OPERATOR_TRANSFORMS;
|
|
319
|
+
//#endregion
|
|
210
320
|
//#region src/model/isa.d.ts
|
|
211
321
|
/**
|
|
212
322
|
* Names and well-known values of the pbxproj object vocabulary.
|
|
@@ -593,6 +703,16 @@ interface BuildStyleProperties extends PbxprojObject {
|
|
|
593
703
|
}
|
|
594
704
|
//#endregion
|
|
595
705
|
//#region src/model/target.d.ts
|
|
706
|
+
interface ResolveBuildSettingOptions {
|
|
707
|
+
/**
|
|
708
|
+
* Answers references the document itself cannot, for example
|
|
709
|
+
* `$(BUILT_PRODUCTS_DIR)` when the caller knows the build layout. The
|
|
710
|
+
* lookup is consulted after the setting layers and before the built-in
|
|
711
|
+
* `$(TARGET_NAME)` fallback, and a reference it leaves unanswered
|
|
712
|
+
* stays verbatim in the result.
|
|
713
|
+
*/
|
|
714
|
+
lookup?: BuildSettingLookup;
|
|
715
|
+
}
|
|
596
716
|
/**
|
|
597
717
|
* The behavior every target kind shares. A target of any kind carries
|
|
598
718
|
* build configurations and settings, build phases, and dependencies, and
|
|
@@ -637,6 +757,22 @@ declare class Target<Properties extends TargetProperties = TargetProperties> ext
|
|
|
637
757
|
* reads as `undefined`.
|
|
638
758
|
*/
|
|
639
759
|
getBuildSetting(key: string): string | undefined;
|
|
760
|
+
/**
|
|
761
|
+
* Reads a build setting like {@link getBuildSetting} and expands the
|
|
762
|
+
* `$(NAME)` and `${NAME}` references in it. Referenced settings resolve
|
|
763
|
+
* through the same layering, `$(inherited)` and a setting referencing
|
|
764
|
+
* itself continue from the next layer down the way Xcode composes
|
|
765
|
+
* values, and `$(TARGET_NAME)` falls back to the target's name, so the
|
|
766
|
+
* common `PRODUCT_NAME = "$(TARGET_NAME)"` resolves without any caller
|
|
767
|
+
* setup.
|
|
768
|
+
*
|
|
769
|
+
* References the model cannot resolve (build-system paths like
|
|
770
|
+
* `$(BUILT_PRODUCTS_DIR)`, environment values) stay in the result
|
|
771
|
+
* verbatim unless the caller's lookup answers them, so no information
|
|
772
|
+
* is invented. See {@link expandBuildSettingReferences} for the
|
|
773
|
+
* operator forms honored during expansion.
|
|
774
|
+
*/
|
|
775
|
+
resolveBuildSetting(key: string, options?: ResolveBuildSettingOptions): string | undefined;
|
|
640
776
|
/**
|
|
641
777
|
* Writes a build setting on every configuration of the target, so Debug
|
|
642
778
|
* and Release stay consistent.
|
|
@@ -2033,61 +2169,100 @@ declare class XcodeObject<Properties extends PbxprojObject = PbxprojObject> {
|
|
|
2033
2169
|
*/
|
|
2034
2170
|
declare function parsePbxproj(text: string): PbxprojValue;
|
|
2035
2171
|
//#endregion
|
|
2036
|
-
//#region src/
|
|
2172
|
+
//#region src/xml/types.d.ts
|
|
2037
2173
|
/**
|
|
2038
|
-
* The node model of
|
|
2174
|
+
* The node model of Xcode's XML dialect, shared by scheme files
|
|
2175
|
+
* (`.xcscheme`) and workspace data files (`contents.xcworkspacedata`).
|
|
2039
2176
|
*
|
|
2040
|
-
* A parsed
|
|
2177
|
+
* A parsed document is a tree of plain objects. Elements carry ordered
|
|
2041
2178
|
* attributes and child nodes, and comments survive as their own nodes.
|
|
2042
2179
|
* All state lives in this tree. There is no wrapper to keep in sync, so
|
|
2043
|
-
* callers mutate nodes directly and serialize whatever the tree
|
|
2044
|
-
* says.
|
|
2180
|
+
* callers mutate nodes directly and serialize whatever the tree
|
|
2181
|
+
* currently says.
|
|
2045
2182
|
*
|
|
2046
2183
|
* @module
|
|
2047
2184
|
*/
|
|
2048
2185
|
/**
|
|
2049
|
-
* An XML element of a
|
|
2186
|
+
* An XML element of a document.
|
|
2050
2187
|
*
|
|
2051
2188
|
* Attribute order is preserved and meaningful. The writer emits
|
|
2052
2189
|
* attributes in insertion order, which is how Xcode-written files
|
|
2053
2190
|
* round-trip byte-identically. Assigning an existing key keeps its
|
|
2054
2191
|
* position, and adding a new key appends it.
|
|
2055
2192
|
*/
|
|
2056
|
-
interface
|
|
2057
|
-
/** Tag name, for example `Scheme` or `
|
|
2193
|
+
interface XmlElement {
|
|
2194
|
+
/** Tag name, for example `Scheme` or `FileRef`. */
|
|
2058
2195
|
name: string;
|
|
2059
2196
|
/** Attribute values by name, in document order. */
|
|
2060
2197
|
attributes: Record<string, string>;
|
|
2061
2198
|
/** Child elements and comments, in document order. */
|
|
2062
|
-
children:
|
|
2199
|
+
children: XmlNode[];
|
|
2063
2200
|
}
|
|
2064
2201
|
/**
|
|
2065
|
-
* A comment inside a
|
|
2066
|
-
* hand-edited and tool-generated
|
|
2067
|
-
*
|
|
2202
|
+
* A comment inside a document. Xcode never writes comments, but
|
|
2203
|
+
* hand-edited and tool-generated files can carry them, and dropping them
|
|
2204
|
+
* would make round-trips lossy.
|
|
2068
2205
|
*/
|
|
2069
|
-
interface
|
|
2206
|
+
interface XmlComment {
|
|
2070
2207
|
/** The comment text between `<!--` and `-->`, verbatim. */
|
|
2071
2208
|
comment: string;
|
|
2072
2209
|
}
|
|
2210
|
+
/**
|
|
2211
|
+
* Any node an element can contain.
|
|
2212
|
+
*/
|
|
2213
|
+
type XmlNode = XmlElement | XmlComment;
|
|
2214
|
+
/**
|
|
2215
|
+
* A parsed document, made of its root element plus any comments sitting
|
|
2216
|
+
* outside it. Xcode writes only the root, so the comment lists are
|
|
2217
|
+
* almost always empty, but files that carry them round-trip without
|
|
2218
|
+
* loss.
|
|
2219
|
+
*/
|
|
2220
|
+
interface XmlDocument {
|
|
2221
|
+
/** Comments before the root element. */
|
|
2222
|
+
leading: XmlComment[];
|
|
2223
|
+
/** The root element. */
|
|
2224
|
+
root: XmlElement;
|
|
2225
|
+
/** Comments after the root element. */
|
|
2226
|
+
trailing: XmlComment[];
|
|
2227
|
+
}
|
|
2228
|
+
/**
|
|
2229
|
+
* Whether a node is an element rather than a comment.
|
|
2230
|
+
*/
|
|
2231
|
+
declare function isXmlElement(node: XmlNode): node is XmlElement;
|
|
2232
|
+
/**
|
|
2233
|
+
* Collects elements of the given name anywhere under a root, in document
|
|
2234
|
+
* order, root included. Passing no name collects every element. Scheme
|
|
2235
|
+
* and workspace models both build their typed views over this query.
|
|
2236
|
+
*/
|
|
2237
|
+
declare function xmlElements(root: XmlElement, name?: string): XmlElement[];
|
|
2238
|
+
//#endregion
|
|
2239
|
+
//#region src/scheme/types.d.ts
|
|
2240
|
+
/**
|
|
2241
|
+
* An XML element of a scheme document.
|
|
2242
|
+
*
|
|
2243
|
+
* Attribute order is preserved and meaningful. The writer emits
|
|
2244
|
+
* attributes in insertion order, which is how Xcode-written files
|
|
2245
|
+
* round-trip byte-identically. Assigning an existing key keeps its
|
|
2246
|
+
* position, and adding a new key appends it.
|
|
2247
|
+
*/
|
|
2248
|
+
type XcschemeElement = XmlElement;
|
|
2249
|
+
/**
|
|
2250
|
+
* A comment inside a scheme document. Xcode never writes comments, but
|
|
2251
|
+
* hand-edited and tool-generated schemes can carry them, and dropping
|
|
2252
|
+
* them would make round-trips lossy.
|
|
2253
|
+
*/
|
|
2254
|
+
type XcschemeComment = XmlComment;
|
|
2073
2255
|
/**
|
|
2074
2256
|
* Any node a scheme element can contain.
|
|
2075
2257
|
*/
|
|
2076
|
-
type XcschemeNode =
|
|
2258
|
+
type XcschemeNode = XmlNode;
|
|
2077
2259
|
/**
|
|
2078
2260
|
* A parsed scheme file, made of its root element plus any comments
|
|
2079
2261
|
* sitting outside it. Xcode writes only the root, so the comment lists
|
|
2080
2262
|
* are almost always empty, but files that carry them round-trip without
|
|
2081
2263
|
* loss.
|
|
2082
2264
|
*/
|
|
2083
|
-
|
|
2084
|
-
/** Comments before the root element. */
|
|
2085
|
-
leading: XcschemeComment[];
|
|
2086
|
-
/** The `Scheme` element. */
|
|
2087
|
-
root: XcschemeElement;
|
|
2088
|
-
/** Comments after the root element. */
|
|
2089
|
-
trailing: XcschemeComment[];
|
|
2090
|
-
}
|
|
2265
|
+
type XcschemeDocument = XmlDocument;
|
|
2091
2266
|
/**
|
|
2092
2267
|
* Whether a node is an element rather than a comment.
|
|
2093
2268
|
*/
|
|
@@ -2095,7 +2270,8 @@ declare function isXcschemeElement(node: XcschemeNode): node is XcschemeElement;
|
|
|
2095
2270
|
//#endregion
|
|
2096
2271
|
//#region src/scheme/build.d.ts
|
|
2097
2272
|
/**
|
|
2098
|
-
* Serializes a scheme document to the text of a `.xcscheme` file
|
|
2273
|
+
* Serializes a scheme document to the text of a `.xcscheme` file in
|
|
2274
|
+
* Xcode's canonical layout.
|
|
2099
2275
|
*
|
|
2100
2276
|
* @throws XcschemeBuildError for element or attribute names that are not
|
|
2101
2277
|
* XML names and for attribute values carrying unencodable control
|
|
@@ -2280,6 +2456,147 @@ declare function parseXcscheme(text: string): XcschemeDocument;
|
|
|
2280
2456
|
*/
|
|
2281
2457
|
declare function generateObjectId(seed: string, existing: ReadonlySet<string>): string;
|
|
2282
2458
|
//#endregion
|
|
2459
|
+
//#region src/workspace/build.d.ts
|
|
2460
|
+
/**
|
|
2461
|
+
* Serializes a workspace document to the text of a
|
|
2462
|
+
* `contents.xcworkspacedata` file in Xcode's canonical layout.
|
|
2463
|
+
*
|
|
2464
|
+
* @throws XcworkspaceBuildError for element or attribute names that are
|
|
2465
|
+
* not XML names and for attribute values carrying unencodable control
|
|
2466
|
+
* characters, with the path of the offending node.
|
|
2467
|
+
*/
|
|
2468
|
+
declare function buildXcworkspace(document: XmlDocument): string;
|
|
2469
|
+
//#endregion
|
|
2470
|
+
//#region src/workspace/model.d.ts
|
|
2471
|
+
/**
|
|
2472
|
+
* A workspace location string split at its kind prefix, so
|
|
2473
|
+
* `group:Pods/Pods.xcodeproj` reads as the kind `group` and the path
|
|
2474
|
+
* `Pods/Pods.xcodeproj`. A location without a kind prefix reads as
|
|
2475
|
+
* `group`, which is how Xcode treats a bare path.
|
|
2476
|
+
*/
|
|
2477
|
+
interface WorkspaceLocation {
|
|
2478
|
+
/** The anchor the path is relative to, for example `group`. */
|
|
2479
|
+
kind: string;
|
|
2480
|
+
/** The path after the kind prefix. */
|
|
2481
|
+
path: string;
|
|
2482
|
+
}
|
|
2483
|
+
/**
|
|
2484
|
+
* Splits a location attribute into its kind and path. Xcode writes the
|
|
2485
|
+
* kinds `group` (relative to the enclosing group), `container` (relative
|
|
2486
|
+
* to the directory containing the `.xcworkspace`), `absolute`, `self`
|
|
2487
|
+
* (the containing `.xcodeproj` itself), and `developer` (inside the
|
|
2488
|
+
* developer directory).
|
|
2489
|
+
*/
|
|
2490
|
+
declare function parseWorkspaceLocation(location: string): WorkspaceLocation;
|
|
2491
|
+
/**
|
|
2492
|
+
* A `FileRef` element with property-style attribute access. File
|
|
2493
|
+
* references are the elements workspace edits touch, since each one
|
|
2494
|
+
* names a project or folder the workspace shows. The view reads and
|
|
2495
|
+
* writes the element's attributes directly, so it never goes stale and
|
|
2496
|
+
* needs no separate save step.
|
|
2497
|
+
*/
|
|
2498
|
+
declare class WorkspaceFileRef {
|
|
2499
|
+
/** The underlying element inside the document tree. */
|
|
2500
|
+
readonly element: XmlElement;
|
|
2501
|
+
constructor(element: XmlElement);
|
|
2502
|
+
/**
|
|
2503
|
+
* The reference's location attribute, when present, for example
|
|
2504
|
+
* `group:Pods/Pods.xcodeproj`.
|
|
2505
|
+
*/
|
|
2506
|
+
get location(): string | undefined;
|
|
2507
|
+
set location(value: string);
|
|
2508
|
+
}
|
|
2509
|
+
interface CreateXcworkspaceOptions {
|
|
2510
|
+
/**
|
|
2511
|
+
* The location of each file reference the workspace lists, in order,
|
|
2512
|
+
* for example `group:DemoApp.xcodeproj`. An omitted list creates an
|
|
2513
|
+
* empty workspace to add references to.
|
|
2514
|
+
*/
|
|
2515
|
+
locations?: string[];
|
|
2516
|
+
}
|
|
2517
|
+
/**
|
|
2518
|
+
* A workspace document with typed access to the elements editing flows
|
|
2519
|
+
* touch.
|
|
2520
|
+
*
|
|
2521
|
+
* The model is a thin layer over the node tree. All state lives in the
|
|
2522
|
+
* document itself, and {@link build} serializes whatever the tree
|
|
2523
|
+
* currently says, so typed edits and direct tree edits compose freely.
|
|
2524
|
+
*
|
|
2525
|
+
* ```ts
|
|
2526
|
+
* const workspace = Xcworkspace.parse(xcworkspacedataText);
|
|
2527
|
+
* workspace.projectFilePaths(); // ["DemoApp.xcodeproj", "Pods/Pods.xcodeproj"]
|
|
2528
|
+
* ```
|
|
2529
|
+
*/
|
|
2530
|
+
declare class Xcworkspace {
|
|
2531
|
+
/** The underlying parsed document. */
|
|
2532
|
+
readonly document: XmlDocument;
|
|
2533
|
+
constructor(document: XmlDocument);
|
|
2534
|
+
/**
|
|
2535
|
+
* Parses the text of a `contents.xcworkspacedata` file into a
|
|
2536
|
+
* workspace model.
|
|
2537
|
+
*
|
|
2538
|
+
* @throws XcworkspaceParseError when the text is not a well-formed
|
|
2539
|
+
* workspace document, with the line and column of the failure.
|
|
2540
|
+
*/
|
|
2541
|
+
static parse(text: string): Xcworkspace;
|
|
2542
|
+
/**
|
|
2543
|
+
* Creates the workspace document Xcode writes, listing the given
|
|
2544
|
+
* locations as file references.
|
|
2545
|
+
*/
|
|
2546
|
+
static create(options?: CreateXcworkspaceOptions): Xcworkspace;
|
|
2547
|
+
/**
|
|
2548
|
+
* The document's `Workspace` element.
|
|
2549
|
+
*/
|
|
2550
|
+
get root(): XmlElement;
|
|
2551
|
+
/**
|
|
2552
|
+
* Serializes the workspace to the text of a `contents.xcworkspacedata`
|
|
2553
|
+
* file in Xcode's canonical layout.
|
|
2554
|
+
*/
|
|
2555
|
+
build(): string;
|
|
2556
|
+
/**
|
|
2557
|
+
* Collects elements of the given name anywhere in the document, in
|
|
2558
|
+
* document order. Passing no name collects every element.
|
|
2559
|
+
*/
|
|
2560
|
+
elements(name?: string): XmlElement[];
|
|
2561
|
+
/**
|
|
2562
|
+
* The views of every file reference in the document, in document
|
|
2563
|
+
* order, references nested inside groups included.
|
|
2564
|
+
*/
|
|
2565
|
+
fileRefs(): WorkspaceFileRef[];
|
|
2566
|
+
/**
|
|
2567
|
+
* Appends a file reference to the workspace's top level and returns
|
|
2568
|
+
* its view.
|
|
2569
|
+
*/
|
|
2570
|
+
addFileRef(location: string): WorkspaceFileRef;
|
|
2571
|
+
/**
|
|
2572
|
+
* Removes a file reference from whichever element holds it. Returns
|
|
2573
|
+
* whether the reference was found and removed.
|
|
2574
|
+
*/
|
|
2575
|
+
removeFileRef(reference: WorkspaceFileRef): boolean;
|
|
2576
|
+
/**
|
|
2577
|
+
* The paths of every `.xcodeproj` the workspace references, in
|
|
2578
|
+
* document order, resolved relative to the directory containing the
|
|
2579
|
+
* `.xcworkspace`. Group locations compose through their enclosing
|
|
2580
|
+
* groups, container locations anchor at the workspace's directory, and
|
|
2581
|
+
* absolute locations pass through unchanged.
|
|
2582
|
+
*
|
|
2583
|
+
* The resolution is textual. The library never touches the
|
|
2584
|
+
* filesystem, so locations that only the running Xcode can resolve
|
|
2585
|
+
* (`self` and `developer`) are not listed.
|
|
2586
|
+
*/
|
|
2587
|
+
projectFilePaths(): string[];
|
|
2588
|
+
}
|
|
2589
|
+
//#endregion
|
|
2590
|
+
//#region src/workspace/parse.d.ts
|
|
2591
|
+
/**
|
|
2592
|
+
* Parses the text of a `contents.xcworkspacedata` file into its node
|
|
2593
|
+
* tree.
|
|
2594
|
+
*
|
|
2595
|
+
* @throws XcworkspaceParseError when the text is not a well-formed
|
|
2596
|
+
* workspace document, with the line and column of the failure.
|
|
2597
|
+
*/
|
|
2598
|
+
declare function parseXcworkspace(text: string): XmlDocument;
|
|
2599
|
+
//#endregion
|
|
2283
2600
|
//#region src/xcconfig/build.d.ts
|
|
2284
2601
|
/**
|
|
2285
2602
|
* Serializes a document back to `.xcconfig` text.
|
|
@@ -2296,4 +2613,4 @@ declare function buildXcconfig(document: XcconfigDocument): string;
|
|
|
2296
2613
|
*/
|
|
2297
2614
|
declare function parseXcconfig(source: string): XcconfigDocument;
|
|
2298
2615
|
//#endregion
|
|
2299
|
-
export { type AddNativeTargetOptions, AggregateTarget, type ApplePlatform, AppleScriptBuildPhase, BuildConfiguration, type BuildConfigurationProperties, BuildFile, BuildFileExceptionSet, type BuildFileProperties, BuildPhase, type BuildPhaseIsa, BuildPhaseMembershipExceptionSet, type BuildPhaseMembershipExceptionSetProperties, type BuildPhaseOf, type BuildPhaseProperties, BuildRule, type BuildRuleProperties, type BuildSettings, BuildStyle, type BuildStyleProperties, BuildableReference, ConfigurationList, type ConfigurationListProperties, ContainerItemProxy, type ContainerItemProxyProperties, CopyFilesBuildPhase, type CopyFilesBuildPhaseProperties, CopyFilesDestination, type CreateXcschemeOptions, ExceptionSet, type ExceptionSetProperties, FileReference, type FileReferenceProperties, FrameworksBuildPhase, Group, type GroupProperties, HeadersBuildPhase, Isa, type IsaValue, LegacyTarget, type LegacyTargetProperties, LocalSwiftPackageReference, type LocalSwiftPackageReferenceProperties, NativeTarget, type NativeTargetProperties, type PbxprojArray, PbxprojBuildError, type PbxprojErrorPosition, type PbxprojObject, PbxprojParseError, type PbxprojValue, ProductType, type ProjectIssue, type ProjectIssueKind, ReferenceProxy, type ReferenceProxyProperties, RemoteSwiftPackageReference, type RemoteSwiftPackageReferenceProperties, ResourcesBuildPhase, RezBuildPhase, RootProject, type RootProjectProperties, ShellScriptBuildPhase, type ShellScriptBuildPhaseProperties, SourcesBuildPhase, SwiftPackageProductDependency, type SwiftPackageProductDependencyProperties, SwiftPackageReference, type SwiftPackageReferenceProperties, SyncRootGroup, type SyncRootGroupProperties, Target, TargetDependency, type TargetDependencyProperties, type TargetProperties, VariantGroup, VersionGroup, type VersionGroupProperties, type ViewByIsa, type ViewOf, Xcconfig, type XcconfigAssignment, type XcconfigBlank, type XcconfigComment, type XcconfigCondition, type XcconfigDocument, type XcconfigInclude, type XcconfigIncludeResolver, XcconfigParseError, type XcconfigSettingsOptions, type XcconfigStatement, XcodeModelError, XcodeObject, XcodeProject, Xcscheme, XcschemeBuildError, type XcschemeComment, type XcschemeDocument, type XcschemeElement, type XcschemeNode, XcschemeParseError, buildPbxproj, buildXcconfig, buildXcscheme, createXcscheme, generateObjectId, isXcschemeElement, parseApplePlatform, parsePbxproj, parseXcconfig, parseXcscheme, xcschemeElements };
|
|
2616
|
+
export { type AddNativeTargetOptions, AggregateTarget, type ApplePlatform, AppleScriptBuildPhase, BuildConfiguration, type BuildConfigurationProperties, BuildFile, BuildFileExceptionSet, type BuildFileProperties, BuildPhase, type BuildPhaseIsa, BuildPhaseMembershipExceptionSet, type BuildPhaseMembershipExceptionSetProperties, type BuildPhaseOf, type BuildPhaseProperties, BuildRule, type BuildRuleProperties, type BuildSettingLookup, type BuildSettingOperator, type BuildSettings, BuildStyle, type BuildStyleProperties, BuildableReference, ConfigurationList, type ConfigurationListProperties, ContainerItemProxy, type ContainerItemProxyProperties, CopyFilesBuildPhase, type CopyFilesBuildPhaseProperties, CopyFilesDestination, type CreateXcschemeOptions, type CreateXcworkspaceOptions, ExceptionSet, type ExceptionSetProperties, type ExpandBuildSettingOptions, FileReference, type FileReferenceProperties, FrameworksBuildPhase, Group, type GroupProperties, HeadersBuildPhase, Isa, type IsaValue, LegacyTarget, type LegacyTargetProperties, LocalSwiftPackageReference, type LocalSwiftPackageReferenceProperties, NativeTarget, type NativeTargetProperties, type PbxprojArray, PbxprojBuildError, type PbxprojErrorPosition, type PbxprojObject, PbxprojParseError, type PbxprojValue, ProductType, type ProjectIssue, type ProjectIssueKind, ReferenceProxy, type ReferenceProxyProperties, RemoteSwiftPackageReference, type RemoteSwiftPackageReferenceProperties, type ResolveBuildSettingOptions, ResourcesBuildPhase, RezBuildPhase, RootProject, type RootProjectProperties, ShellScriptBuildPhase, type ShellScriptBuildPhaseProperties, SourcesBuildPhase, SwiftPackageProductDependency, type SwiftPackageProductDependencyProperties, SwiftPackageReference, type SwiftPackageReferenceProperties, SyncRootGroup, type SyncRootGroupProperties, Target, TargetDependency, type TargetDependencyProperties, type TargetProperties, type TextPosition, VariantGroup, VersionGroup, type VersionGroupProperties, type ViewByIsa, type ViewOf, WorkspaceFileRef, type WorkspaceLocation, Xcconfig, type XcconfigAssignment, type XcconfigBlank, type XcconfigComment, type XcconfigCondition, type XcconfigDocument, type XcconfigInclude, type XcconfigIncludeResolver, XcconfigParseError, type XcconfigSettingsOptions, type XcconfigStatement, XcodeModelError, XcodeObject, XcodeProject, Xcscheme, XcschemeBuildError, type XcschemeComment, type XcschemeDocument, type XcschemeElement, type XcschemeNode, XcschemeParseError, Xcworkspace, XcworkspaceBuildError, XcworkspaceParseError, type XmlComment, type XmlDocument, type XmlElement, type XmlNode, buildPbxproj, buildXcconfig, buildXcscheme, buildXcworkspace, createXcscheme, expandBuildSettingReferences, generateObjectId, isXcschemeElement, isXmlElement, parseApplePlatform, parsePbxproj, parseWorkspaceLocation, parseXcconfig, parseXcscheme, parseXcworkspace, xcschemeElements, xmlElements };
|