Skip to content

Commit 3e6384e

Browse files
committed
feat(spm): clean scoping flags + JS-root cwd guard
Two related changes to setup-apple-spm. * `npx react-native spm clean` gains scoping flags. Default behavior is unchanged (generated dirs only). Each flag widens the deletion scope: --project also Package.swift + <App>-SPM.xcodeproj/ --derived-data also ~/Library/Developer/Xcode/DerivedData/<App>-SPM-* --cache also the current resolved-nightly cache slot under ~/Library/Caches/com.facebook.ReactNative/spm-artifacts/ --all shorthand for the three above --yes skip confirmation for destructive scopes; non-TTY auto-confirms Refactored cleanGeneratedState() to a pure gatherCleanTargets(appRoot, opts) enumerator plus a thin I/O wrapper. App name for the DerivedData glob is discovered from any *-SPM.xcodeproj actually present in appRoot, so the scope can't accidentally hit DerivedData entries that don't belong to this app. Cache slot is resolved via the same resolveCacheSlotVersion used elsewhere, so the nightly-hash-keyed slot is targeted (not a stale '1000.0.0/' or 'nightly/' label). * A guard refuses runs from the JS root of a standard RN app, where the community CLI writes autolinking.json under <projectRoot>/ios/... but every SPM script anchors on cwd. The result was a silently-broken build: the autolinker missed autolinking.json, generated an empty Autolinked package, the build compiled fine, and any native module crashed at runtime. describeRnRootMismatch returns a "cd ios && ..." message when cwd === projectRoot AND <projectRoot>/ios/ exists as a directory. Flat layouts (rn-tester) are explicitly safe — no ios/ subdir, no refusal — and covered by a regression test. * 13 new unit tests in setup-apple-spm-test.js: 9 for gatherCleanTargets (each flag in isolation, additive composition, missing-xcodeproj edge case) and 4 for describeRnRootMismatch (RN layout triggers, subdir doesn't, flat layout doesn't, non-directory `ios` entry doesn't). 149/149 SPM tests pass.
1 parent e4deda8 commit 3e6384e

4 files changed

Lines changed: 537 additions & 17 deletions

File tree

packages/react-native/react-native.config.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,31 @@ const spmCommand /*: Command */ = {
165165
description:
166166
'JS entry file relative to app root (default: package.json "main" or index.js).',
167167
},
168+
{
169+
name: '--project',
170+
description:
171+
'[clean] Also remove Package.swift and <App>-SPM.xcodeproj/.',
172+
},
173+
{
174+
name: '--derivedData',
175+
description:
176+
"[clean] Also remove this app's DerivedData (~/Library/Developer/Xcode/DerivedData/<App>-SPM-*).",
177+
},
178+
{
179+
name: '--cache',
180+
description:
181+
'[clean] Also remove the cached xcframework slot for the current resolved version.',
182+
},
183+
{
184+
name: '--all',
185+
description:
186+
'[clean] Shorthand for --project --derivedData --cache.',
187+
},
188+
{
189+
name: '--yes',
190+
description:
191+
'[clean] Skip the confirmation prompt for destructive scopes.',
192+
},
168193
// Workaround for @react-native-community/cli: when any positional equals
169194
// "init" (including our `spm init` action), the CLI naively appends
170195
// `--platform-name <platform>` to argv. Accept and ignore it so commander
@@ -198,6 +223,11 @@ const spmCommand /*: Command */ = {
198223
['skipDownload', '--skip-download'],
199224
['forceDownload', '--force-download'],
200225
['skipXcodeproj', '--skip-xcodeproj'],
226+
['project', '--project'],
227+
['derivedData', '--derived-data'],
228+
['cache', '--cache'],
229+
['all', '--all'],
230+
['yes', '--yes'],
201231
];
202232
for (const [key, flag] of boolOpts) {
203233
if (args[key]) {

0 commit comments

Comments
 (0)