@@ -12,8 +12,67 @@ import {
1212 LinkModuleResult ,
1313} from "./link-modules.js" ;
1414
15+ function determineInfoPlistPath ( frameworkPath : string ) {
16+ const checkedPaths = new Array < string > ( ) ;
17+
18+ // First, assume it is an "unversioned" framework that keeps its Info.plist in
19+ // the root. This is the convention for iOS, tvOS, and friends.
20+ let infoPlistPath = path . join ( frameworkPath , "Info.plist" ) ;
21+
22+ if ( fs . existsSync ( infoPlistPath ) ) {
23+ return infoPlistPath ;
24+ }
25+ checkedPaths . push ( infoPlistPath ) ;
26+
27+ // Next, assume it is a "versioned" framework that keeps its Info.plist
28+ // under a subdirectory. This is the convention for macOS.
29+ infoPlistPath = path . join (
30+ frameworkPath ,
31+ "Versions/Current/Resources/Info.plist" ,
32+ ) ;
33+
34+ if ( fs . existsSync ( infoPlistPath ) ) {
35+ return infoPlistPath ;
36+ }
37+ checkedPaths . push ( infoPlistPath ) ;
38+
39+ throw new Error (
40+ [
41+ `Unable to locate an Info.plist file within framework. Checked the following paths:` ,
42+ ...checkedPaths . map ( ( checkedPath ) => `- ${ checkedPath } ` ) ,
43+ ] . join ( "\n" ) ,
44+ ) ;
45+ }
46+
47+ /**
48+ * Resolves the Info.plist file within a framework and reads its contents.
49+ */
50+ export async function readInfoPlist ( frameworkPath : string ) {
51+ let infoPlistPath : string ;
52+ try {
53+ infoPlistPath = determineInfoPlistPath ( frameworkPath ) ;
54+ } catch ( cause ) {
55+ throw new Error (
56+ `Unable to read Info.plist for framework at path "${ frameworkPath } ", as an Info.plist file couldn't be found.` ,
57+ { cause } ,
58+ ) ;
59+ }
60+
61+ let contents : string ;
62+ try {
63+ contents = await fs . promises . readFile ( infoPlistPath , "utf-8" ) ;
64+ } catch ( cause ) {
65+ throw new Error (
66+ `Unable to read Info.plist for framework at path "${ frameworkPath } ", due to a file system error.` ,
67+ { cause } ,
68+ ) ;
69+ }
70+
71+ return { infoPlistPath, contents } ;
72+ }
73+
1574type UpdateInfoPlistOptions = {
16- filePath : string ;
75+ frameworkPath : string ;
1776 oldLibraryName : string ;
1877 newLibraryName : string ;
1978} ;
@@ -22,17 +81,15 @@ type UpdateInfoPlistOptions = {
2281 * Update the Info.plist file of an xcframework to use the new library name.
2382 */
2483export async function updateInfoPlist ( {
25- filePath ,
84+ frameworkPath ,
2685 oldLibraryName,
2786 newLibraryName,
2887} : UpdateInfoPlistOptions ) {
29- const infoPlistContents = await fs . promises . readFile ( filePath , "utf-8" ) ;
88+ const { infoPlistPath, contents } = await readInfoPlist ( frameworkPath ) ;
89+
3090 // TODO: Use a proper plist parser
31- const updatedContents = infoPlistContents . replaceAll (
32- oldLibraryName ,
33- newLibraryName ,
34- ) ;
35- await fs . promises . writeFile ( filePath , updatedContents , "utf-8" ) ;
91+ const updatedContents = contents . replaceAll ( oldLibraryName , newLibraryName ) ;
92+ await fs . promises . writeFile ( infoPlistPath , updatedContents , "utf-8" ) ;
3693}
3794
3895export async function linkXcframework ( {
@@ -126,7 +183,7 @@ export async function linkXcframework({
126183 ) ;
127184 // Update the Info.plist file for the framework
128185 await updateInfoPlist ( {
129- filePath : path . join ( newFrameworkPath , "Info.plist" ) ,
186+ frameworkPath : newFrameworkPath ,
130187 oldLibraryName,
131188 newLibraryName,
132189 } ) ;
0 commit comments