Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/podfile-patch-preserve-args.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'create-rock': patch
---

fix(create-app): preserve existing arg list when patching Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as fs from 'node:fs';
import * as path from 'node:path';
import { cleanup, getTempDirectory, writeFiles } from '@rock-js/test-helpers';
import * as tools from '@rock-js/tools';
import { updateAndroidBuildGradle } from '../initInExistingProject.js';
import { updateAndroidBuildGradle, updatePodfile } from '../initInExistingProject.js';

const directory = getTempDirectory('test_updateAndroidBuildGradle');

Expand Down Expand Up @@ -120,3 +120,73 @@ describe('updateAndroidBuildGradle', () => {
);
});
});

describe('updatePodfile', () => {
it('replaces a bare `use_native_modules!` call (Community-CLI template)', () => {
const content = `
target 'App' do
config = use_native_modules!

use_react_native!(:path => config[:reactNativePath])
end
`;
const expected = `
target 'App' do
config = use_native_modules!(['npx', 'rock', 'config', '-p', 'ios'])

use_react_native!(:path => config[:reactNativePath])
end
`;
writeFiles(directory, { 'ios/Podfile': content });
updatePodfile(directory, 'ios');

expect(
fs.readFileSync(path.join(directory, 'ios/Podfile'), 'utf8'),
).toStrictEqual(expected);
});

it('replaces a `use_native_modules!(config_command)` call (Expo prebuild template, regression test for #702)', () => {
const content = `
target 'App' do
config_command = ['node', '--no-warnings', '--eval', "require('expo/bin/autolinking')"]
config = use_native_modules!(config_command)

use_react_native!(:path => config[:reactNativePath])
end
`;
const expected = `
target 'App' do
config_command = ['node', '--no-warnings', '--eval', "require('expo/bin/autolinking')"]
config = use_native_modules!(['npx', 'rock', 'config', '-p', 'ios'])

use_react_native!(:path => config[:reactNativePath])
end
`;
writeFiles(directory, { 'ios/Podfile': content });
updatePodfile(directory, 'ios');

expect(
fs.readFileSync(path.join(directory, 'ios/Podfile'), 'utf8'),
).toStrictEqual(expected);
});

it('is idempotent — running on an already-patched Podfile is a no-op', () => {
const content = `
target 'App' do
config = use_native_modules!(['npx', 'rock', 'config', '-p', 'ios'])
end
`;
writeFiles(directory, { 'ios/Podfile': content });
updatePodfile(directory, 'ios');

expect(
fs.readFileSync(path.join(directory, 'ios/Podfile'), 'utf8'),
).toStrictEqual(content);
});

it('does nothing when there is no Podfile', () => {
// No Podfile written; updatePodfile should return without throwing.
expect(() => updatePodfile(directory, 'ios')).not.toThrow();
});
});

12 changes: 9 additions & 3 deletions packages/create-app/src/lib/utils/initInExistingProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,15 +271,21 @@ Please update the "Bundle React Native code and images" build phase manually wit
);
}

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