Skip to content

Commit 7c966c3

Browse files
TomKalinaTomáš Kalina
andauthored
fix(create-app): preserve existing arg list when patching Podfile (#703)
* fix(create-app): preserve existing arg list when patching Podfile `updatePodfile` ran a regex that matched `config = use_native_modules!` plus the whitespace after `!`, but not any existing argument tuple. That works for Community-CLI Podfile templates (call has no argument), but Expo's prebuild template calls it with `config_command` as the argument. The patch then inserted Rock's array right before the existing `(config_command)`, leaving two consecutive call expressions on the same line — invalid Ruby: config = use_native_modules!(['npx', 'rock', 'config', '-p', 'ios'])(config_command) ^ unexpected '(' Every subsequent `pod install` (and `rock run:ios`) failed on Expo projects after `npm create rock`. Fix: extend the regex to also consume any existing parenthesized argument list, so it gets replaced in full. On Community-CLI Podfiles the optional group matches nothing — behaviour is unchanged. On Expo prebuild Podfiles the existing `(config_command)` is now consumed and replaced cleanly. Adds four `updatePodfile` test cases: - Community-CLI template (bare `use_native_modules!`) - Expo prebuild template (`use_native_modules!(config_command)`) - Idempotency on an already-patched Podfile - Missing Podfile is a no-op The `updatePodfile` function is now exported for testability, mirroring the existing `updateAndroidBuildGradle` export. Fixes #702 * chore: add changeset --------- Co-authored-by: Tomáš Kalina <tomas.kalina@team.blue>
1 parent bfe317d commit 7c966c3

3 files changed

Lines changed: 85 additions & 4 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'create-rock': patch
3+
---
4+
5+
fix(create-app): preserve existing arg list when patching Podfile

packages/create-app/src/lib/utils/__tests__/initInExistingProject.test.ts

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as fs from 'node:fs';
22
import * as path from 'node:path';
33
import { cleanup, getTempDirectory, writeFiles } from '@rock-js/test-helpers';
44
import * as tools from '@rock-js/tools';
5-
import { updateAndroidBuildGradle } from '../initInExistingProject.js';
5+
import { updateAndroidBuildGradle, updatePodfile } from '../initInExistingProject.js';
66

77
const directory = getTempDirectory('test_updateAndroidBuildGradle');
88

@@ -120,3 +120,73 @@ describe('updateAndroidBuildGradle', () => {
120120
);
121121
});
122122
});
123+
124+
describe('updatePodfile', () => {
125+
it('replaces a bare `use_native_modules!` call (Community-CLI template)', () => {
126+
const content = `
127+
target 'App' do
128+
config = use_native_modules!
129+
130+
use_react_native!(:path => config[:reactNativePath])
131+
end
132+
`;
133+
const expected = `
134+
target 'App' do
135+
config = use_native_modules!(['npx', 'rock', 'config', '-p', 'ios'])
136+
137+
use_react_native!(:path => config[:reactNativePath])
138+
end
139+
`;
140+
writeFiles(directory, { 'ios/Podfile': content });
141+
updatePodfile(directory, 'ios');
142+
143+
expect(
144+
fs.readFileSync(path.join(directory, 'ios/Podfile'), 'utf8'),
145+
).toStrictEqual(expected);
146+
});
147+
148+
it('replaces a `use_native_modules!(config_command)` call (Expo prebuild template, regression test for #702)', () => {
149+
const content = `
150+
target 'App' do
151+
config_command = ['node', '--no-warnings', '--eval', "require('expo/bin/autolinking')"]
152+
config = use_native_modules!(config_command)
153+
154+
use_react_native!(:path => config[:reactNativePath])
155+
end
156+
`;
157+
const expected = `
158+
target 'App' do
159+
config_command = ['node', '--no-warnings', '--eval', "require('expo/bin/autolinking')"]
160+
config = use_native_modules!(['npx', 'rock', 'config', '-p', 'ios'])
161+
162+
use_react_native!(:path => config[:reactNativePath])
163+
end
164+
`;
165+
writeFiles(directory, { 'ios/Podfile': content });
166+
updatePodfile(directory, 'ios');
167+
168+
expect(
169+
fs.readFileSync(path.join(directory, 'ios/Podfile'), 'utf8'),
170+
).toStrictEqual(expected);
171+
});
172+
173+
it('is idempotent — running on an already-patched Podfile is a no-op', () => {
174+
const content = `
175+
target 'App' do
176+
config = use_native_modules!(['npx', 'rock', 'config', '-p', 'ios'])
177+
end
178+
`;
179+
writeFiles(directory, { 'ios/Podfile': content });
180+
updatePodfile(directory, 'ios');
181+
182+
expect(
183+
fs.readFileSync(path.join(directory, 'ios/Podfile'), 'utf8'),
184+
).toStrictEqual(content);
185+
});
186+
187+
it('does nothing when there is no Podfile', () => {
188+
// No Podfile written; updatePodfile should return without throwing.
189+
expect(() => updatePodfile(directory, 'ios')).not.toThrow();
190+
});
191+
});
192+

packages/create-app/src/lib/utils/initInExistingProject.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,15 +271,21 @@ Please update the "Bundle React Native code and images" build phase manually wit
271271
);
272272
}
273273

274-
function updatePodfile(projectRoot: string, sourceDir: string) {
274+
export function updatePodfile(projectRoot: string, sourceDir: string) {
275275
const filePath = path.join(projectRoot, sourceDir, 'Podfile');
276276
if (!fs.existsSync(filePath)) {
277277
return;
278278
}
279279
const content = fs.readFileSync(filePath, 'utf8');
280+
// Replace `config = use_native_modules!` together with any existing
281+
// argument list. The Community-CLI Podfile template calls it with no
282+
// arguments (`use_native_modules!`), but the Expo prebuild template
283+
// passes its own autolinking command in (`use_native_modules!(config_command)`).
284+
// Without consuming that argument the previous regex left it dangling
285+
// on the line and produced invalid Ruby — see issue #702.
280286
const replaced = content.replace(
281-
/(config\s*=\s*use_native_modules!)(\s*)/g,
282-
"$1(['npx', 'rock', 'config', '-p', 'ios'])$2",
287+
/(config\s*=\s*use_native_modules!)(\s*\([^)]*\))?/g,
288+
"$1(['npx', 'rock', 'config', '-p', 'ios'])",
283289
);
284290
if (
285291
!content.includes(`(['npx', 'rock', 'config', '-p', 'ios'])`) &&

0 commit comments

Comments
 (0)