Skip to content

Conversation

@kraenhansen
Copy link
Collaborator

Fixes #126 by using a proper plist parser (@expo/plist) and also handles converting binary plists to xml before updating.

@kraenhansen kraenhansen self-assigned this Oct 21, 2025
@kraenhansen kraenhansen added enhancement New feature or request Host 🏡 Our `react-native-node-api-modules` package labels Oct 21, 2025
@kraenhansen kraenhansen requested a review from Copilot October 21, 2025 08:34
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR replaces manual plist string manipulation with the @expo/plist parser library and adds support for converting binary plist files to XML format before modification. This addresses issue #126 by providing proper plist parsing and handling of binary plist formats.

Key changes:

  • Replaced custom createPlistContent() with @expo/plist library's build() method
  • Modified readInfoPlist() to accept a file path parameter and use plist.parse() instead of returning raw string contents
  • Added binary-to-XML conversion step in updateInfoPlist() using the plutil command-line tool

Reviewed Changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.

File Description
packages/host/package.json Added @expo/plist dependency
packages/host/src/node/prebuilds/apple.ts Replaced custom plist generation with @expo/plist library
packages/host/src/node/cli/apple.ts Refactored plist reading/updating to use proper parser and handle binary format conversion
packages/host/src/node/cli/apple.test.ts Updated tests to reflect API changes and added binary plist conversion test

Comment on lines 78 to 94
// Convert to XML format if needed
await spawn("plutil", ["-convert", "xml1", infoPlistPath], {
outputMode: "inherit",
});
const contents = await readInfoPlist(infoPlistPath);
Copy link

Copilot AI Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The plutil conversion command will silently succeed even if the file is already in XML format, but if it fails (e.g., corrupted file, invalid plist), the error won't be captured effectively with outputMode: "inherit". Consider adding error handling or validation after the conversion to ensure the plist is in a valid state before attempting to parse it.

Suggested change
// Convert to XML format if needed
await spawn("plutil", ["-convert", "xml1", infoPlistPath], {
outputMode: "inherit",
});
const contents = await readInfoPlist(infoPlistPath);
// Convert to XML format if needed, and validate conversion
try {
await spawn("plutil", ["-convert", "xml1", infoPlistPath], {
outputMode: "inherit",
});
} catch (plutilError) {
throw new Error(`Failed to convert Info.plist to XML format at "${infoPlistPath}".`, { cause: plutilError });
}
let contents: Record<string, unknown>;
try {
contents = await readInfoPlist(infoPlistPath);
} catch (parseError) {
throw new Error(`Info.plist at "${infoPlistPath}" is not a valid plist after conversion.`, { cause: parseError });
}

Copilot uses AI. Check for mistakes.
});
const contents = await readInfoPlist(infoPlistPath);
if (contents.CFBundleExecutable === oldLibraryName) {
contents.CFBundleExecutable = newLibraryName;
Copy link

Copilot AI Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The conditional check prevents updating if CFBundleExecutable doesn't match oldLibraryName, but this silently skips the update without any indication. Consider logging a warning or throwing an error if the expected value doesn't match, as this could indicate an unexpected plist state or incorrect parameters.

Suggested change
contents.CFBundleExecutable = newLibraryName;
contents.CFBundleExecutable = newLibraryName;
} else {
throw new Error(
`CFBundleExecutable in Info.plist at "${infoPlistPath}" is "${contents.CFBundleExecutable}", expected "${oldLibraryName}". Aborting update.`
);

Copilot uses AI. Check for mistakes.
Comment on lines 93 to 128
const binaryPlistContents = Buffer.from(
"YnBsaXN0MDDfEBUBAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4cICEiIyQiJSYnJChfEBNCdWlsZE1hY2hpbmVPU0J1aWxkXxAZQ0ZCdW5kbGVEZXZlbG9wbWVudFJlZ2lvbl8QEkNGQnVuZGxlRXhlY3V0YWJsZV8QEkNGQnVuZGxlSWRlbnRpZmllcl8QHUNGQnVuZGxlSW5mb0RpY3Rpb25hcnlWZXJzaW9uXxATQ0ZCdW5kbGVQYWNrYWdlVHlwZV8QGkNGQnVuZGxlU2hvcnRWZXJzaW9uU3RyaW5nXxARQ0ZCdW5kbGVTaWduYXR1cmVfEBpDRkJ1bmRsZVN1cHBvcnRlZFBsYXRmb3Jtc18QD0NGQnVuZGxlVmVyc2lvbl8QFUNTUmVzb3VyY2VzRmlsZU1hcHBlZFpEVENvbXBpbGVyXxAPRFRQbGF0Zm9ybUJ1aWxkXkRUUGxhdGZvcm1OYW1lXxARRFRQbGF0Zm9ybVZlcnNpb25aRFRTREtCdWlsZFlEVFNES05hbWVXRFRYY29kZVxEVFhjb2RlQnVpbGRfEBBNaW5pbXVtT1NWZXJzaW9uXlVJRGV2aWNlRmFtaWx5VjI0RzIzMVdFbmdsaXNoVWFkZG9uXxAPZXhhbXBsZV82LmFkZG9uUzYuMFRGTVdLUzEuMFQ/Pz8/oR9fEA9pUGhvbmVTaW11bGF0b3IJXxAiY29tLmFwcGxlLmNvbXBpbGVycy5sbHZtLmNsYW5nLjFfMFYyMkMxNDZfEA9pcGhvbmVzaW11bGF0b3JUMTguMl8QE2lwaG9uZXNpbXVsYXRvcjE4LjJUMTYyMFgxNkM1MDMyYaEpEAEACAA1AEsAZwB8AJEAsQDHAOQA+AEVAScBPwFKAVwBawF/AYoBlAGcAakBvAHLAdIB2gHgAfIB9gH7Af8CBAIGAhgCGQI+AkUCVwJcAnICdwKAAoIAAAAAAAACAQAAAAAAAAAqAAAAAAAAAAAAAAAAAAAChA==",
"base64",
);
Copy link

Copilot AI Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The base64-encoded binary plist lacks documentation explaining what it represents or how it was generated. Add a comment describing the plist's content (e.g., 'Binary plist containing CFBundleExecutable: "addon"') and how to regenerate it if needed, to improve test maintainability.

Copilot uses AI. Check for mistakes.
cursor[bot]

This comment was marked as outdated.

@kraenhansen kraenhansen force-pushed the kh/handle-binary-plists branch 2 times, most recently from b85ffa9 to c6fbffd Compare October 21, 2025 10:35
@kraenhansen kraenhansen force-pushed the kh/handle-binary-plists branch from c6fbffd to eb8ac71 Compare October 21, 2025 11:10
@kraenhansen kraenhansen merged commit ac3ee34 into main Oct 21, 2025
7 checks passed
@kraenhansen kraenhansen deleted the kh/handle-binary-plists branch October 21, 2025 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request Host 🏡 Our `react-native-node-api-modules` package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Breaking Plist by carefully picking library name

2 participants