Skip to content

Commit 312dec8

Browse files
chrfalchclaude
andcommitted
SPM docs: document --configCommand and its persistence
## Summary: The `--config-command` flag has never been documented, and the pin that keeps the in-build sync using it was added without a docs change. Cover both in spm-scripts.md: - a `--configCommand <json>` row in CLI Options, naming `RCT_SPM_AUTOLINKING_CONFIG_COMMAND` as the equivalent env var, - a short section giving the resolution order (flag -> RCT_SPM_AUTOLINKING_CONFIG_COMMAND -> the `configCommand` pinned in `.spm-injected.json` -> the default `@react-native-community/cli config`) and why the pin has to exist: the Sync SPM Autolinking phase inherits neither the flag nor the shell that exported the env var, so an unpinned command turns a successful `add` into failing builds. Also states that `deinit` drops the marker and the pin with it, - the marker's dual role in the "What to commit" table: reversal record *and* pinned configuration, - a Troubleshooting row keyed on the symptom people will search for — the build phase failing with `@react-native-community/cli config` exiting non-zero. Docs only; no behavior change. Deliberately not reformatted: this file is not Prettier-formatted on this branch, and reformatting would bury the change. ## Changelog: [Internal] - Document `spm --configCommand` and how the autolinking config command is persisted ## Test Plan: Docs only — nothing to run. Every statement was checked against the code on this branch: the marker field name (`configCommand` in `generate-spm-xcodeproj.js`), both input routes persisting (`resolveConfigCommandToPin` = flag ?? env), the pin never shadowing the env var (`resolveExplicitConfigCommand`), the actions that read it (`needsCliConfig` covers add/update/sync/scaffold), and the failure being a hard build error (config-command failure sets exit 2, which the generated build phase turns into `exit 1`). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent b4db5df commit 312dec8

1 file changed

Lines changed: 36 additions & 1 deletion

File tree

packages/react-native/scripts/spm/__doc__/spm-scripts.md

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,40 @@ accepts kebab-case equivalents (e.g. `--skip-codegen`).
137137
| `--artifacts <path>` | [advanced] Local artifact root containing complete `debug/` and `release/` cache slots |
138138
| `--download <auto\|skip\|force>` | [advanced] Artifact download policy (default: auto) |
139139
| `--skipCodegen` | [advanced] Skip the codegen step |
140+
| `--configCommand <json>` | [advanced] JSON array of the argv used to generate `autolinking.json`, overriding the default `@react-native-community/cli config` command. Also settable via the `RCT_SPM_AUTOLINKING_CONFIG_COMMAND` env var. Either way the value is remembered, so you pass it once. Example: `'["npx","expo-modules-autolinking","react-native-config","--json","--platform","ios"]'` |
141+
142+
### The autolinking config command is remembered
143+
144+
An app that replaces `@react-native-community/cli` autolinking (an Expo app,
145+
for example) has to tell `spm` how to produce `autolinking.json`. Pass the
146+
command once, on `add` or `update`:
147+
148+
```bash
149+
npx react-native spm add --configCommand '["npx","expo-modules-autolinking","react-native-config","--json","--platform","ios"]'
150+
```
151+
152+
Every action that needs `autolinking.json``add`, `update`, `scaffold`, and
153+
the build-time `sync` — resolves the command in this order:
154+
155+
1. `--configCommand`
156+
2. `RCT_SPM_AUTOLINKING_CONFIG_COMMAND`
157+
3. the `configCommand` pinned in `MyApp.xcodeproj/.spm-injected.json` by an
158+
earlier `add`/`update`
159+
4. the default `@react-native-community/cli config`
160+
161+
`add`/`update` pin whichever of the first two routes supplied the command,
162+
validated as an argv array; a later run that passes neither keeps the existing
163+
pin, and passing `--configCommand` again replaces it. The pin exists because
164+
the **Sync SPM Autolinking** build phase inherits neither your flag nor the
165+
shell that exported the env var — without it, a successful `add` is followed by
166+
failing builds, because the phase re-derives `autolinking.json` with the
167+
default command. A pin never shadows the env var, so an override in your shell
168+
still takes effect, and a pin that no longer parses is ignored in favor of the
169+
default.
170+
171+
`deinit` deletes `.spm-injected.json`, and the pin with it. A later `add`
172+
therefore falls back to the default command unless you pass `--configCommand`
173+
(or export the env var) again.
140174

141175
### Debug/Release flavor is automatic
142176

@@ -161,7 +195,7 @@ package graph, or require a second build.
161195
| Path | Commit? | Why |
162196
|------|---------|-----|
163197
| `MyApp.xcodeproj/` | Yes | Your project, with SwiftPM injected in place. Holds your signing, capabilities, Build Phases — `add` only adds SwiftPM refs/settings, additively. |
164-
| `MyApp.xcodeproj/.spm-injected.json` | Yes | Marker recording every edit `add` made, so `deinit` can surgically reverse it and re-runs stay idempotent. |
198+
| `MyApp.xcodeproj/.spm-injected.json` | Yes | Marker recording every edit `add` made, so `deinit` can surgically reverse it and re-runs stay idempotent. Also pins settings later runs and Xcode builds must reuse, such as the [autolinking config command](#the-autolinking-config-command-is-remembered). |
165199
| `build/generated/` | No | Codegen/autolinking output; regenerated |
166200
| `build/xcframeworks/` | No | Symlinks to the machine-local artifact cache |
167201
| `Package.resolved` | No | SwiftPM resolution file; machine-specific |
@@ -335,6 +369,7 @@ across apps; refresh it with `react-native spm update --download force`.
335369
| "not contained in target" | Re-run setup (regenerates file-level symlinks) |
336370
| Codegen fails | Use `--skipCodegen` to iterate on other parts |
337371
| "SPM sync failed" warning | Check Xcode build log for details; node may not be in PATH — ensure `with-environment.sh` is present |
372+
| "Sync SPM Autolinking" build phase fails: `'npx --no-install @react-native-community/cli config' exited with status 1` | This app replaces `@react-native-community/cli` autolinking (e.g. an Expo app). Re-run `spm add`/`update` with `--configCommand` (or with `RCT_SPM_AUTOLINKING_CONFIG_COMMAND` exported) so the working command is pinned for the build phase to reuse — see [The autolinking config command is remembered](#the-autolinking-config-command-is-remembered). |
338373
| Autolinking not updating on build | Touch `package.json` to force a sync, or delete `build/generated/autolinking/.spm-sync-stamp` |
339374
| Stale SwiftPM state or corrupted build | `rm -rf build/ .build/`, then `react-native spm update`, then reopen Xcode |
340375
| Want to revert to CocoaPods | `react-native spm deinit`, then `pod install` |

0 commit comments

Comments
 (0)