Skip to content

Commit ed15f83

Browse files
committed
fix shellToInvoke refresh missing reordered or unspaced attributes
1 parent 73921c3 commit ed15f83

2 files changed

Lines changed: 37 additions & 5 deletions

File tree

packages/react-native/scripts/spm/__tests__/generate-spm-xcodeproj-test.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,31 @@ describe('scheme pre-action', () => {
176176
updated,
177177
);
178178
});
179+
180+
it('refreshes shellToInvoke when it appears before scriptText', () => {
181+
const reordered = generateXcscheme(
182+
'MyApp',
183+
'TARGET_UUID',
184+
'MyApp',
185+
'SCRIPT',
186+
).replace(
187+
'scriptText = "SCRIPT"\n shellToInvoke = "/bin/bash">',
188+
'shellToInvoke = "/bin/bash"\n scriptText = "SCRIPT">',
189+
);
190+
const updated = addPreActionToScheme(reordered, 'TARGET_UUID', 'SCRIPT');
191+
expect(updated.match(/shellToInvoke/g)).toHaveLength(1);
192+
});
193+
194+
it('refreshes shellToInvoke with no spaces around the equals sign', () => {
195+
const unspaced = generateXcscheme(
196+
'MyApp',
197+
'TARGET_UUID',
198+
'MyApp',
199+
'SCRIPT',
200+
).replace('shellToInvoke = "/bin/bash"', 'shellToInvoke="/bin/bash"');
201+
const updated = addPreActionToScheme(unspaced, 'TARGET_UUID', 'SCRIPT');
202+
expect(updated.match(/shellToInvoke/g)).toHaveLength(1);
203+
});
179204
});
180205

181206
describe('sync scripts', () => {

packages/react-native/scripts/spm/generate-spm-xcodeproj.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1898,12 +1898,19 @@ function addPreActionToScheme(
18981898
// attribute names (default /bin/sh), independent of a
18991899
// PBXShellScriptBuildPhase's own shellPath (see shellScriptPhase) — pin
19001900
// it to bash too. `>` can't appear unescaped inside either attribute
1901-
// value, so it reliably closes the ActionContent open tag.
1901+
// value, so it reliably closes the ActionContent open tag. Search the
1902+
// whole open tag (not just after scriptText) and allow any spacing
1903+
// around `=`, since attribute order and formatting aren't guaranteed.
1904+
const contentOpenIdx = xmlWithScript.lastIndexOf(
1905+
'<ActionContent',
1906+
titleIdx,
1907+
);
19021908
const contentCloseIdx = xmlWithScript.indexOf('>', stIdx);
1903-
const shellToInvokeMarker = 'shellToInvoke = "';
1904-
const stiIdx = xmlWithScript.indexOf(shellToInvokeMarker, valueStart);
1905-
if (stiIdx >= 0 && stiIdx < contentCloseIdx) {
1906-
const stiValueStart = stiIdx + shellToInvokeMarker.length;
1909+
const openTag = xmlWithScript.slice(contentOpenIdx, contentCloseIdx);
1910+
const stiMatch = openTag.match(/shellToInvoke\s*=\s*"/);
1911+
if (stiMatch != null) {
1912+
const stiValueStart =
1913+
contentOpenIdx + stiMatch.index + stiMatch[0].length;
19071914
const stiValueEnd = xmlWithScript.indexOf('"', stiValueStart);
19081915
xmlWithScript =
19091916
xmlWithScript.slice(0, stiValueStart) +

0 commit comments

Comments
 (0)