Skip to content
This repository was archived by the owner on May 20, 2025. It is now read-only.

Commit 0c2aa44

Browse files
author
max-mironov
authored
Improved logic for searching plist file path for iOS postlink.js (#666)
* Improved logic for searching plist file path for iOS postlink.js Added Xcode package for parsing xcodeproj file and retrieving correct plist file related to the project. This should also fix issue described here: #661 * Improved logic for searching plist file path for iOS postlink.js Added logic to narrow xcode 'getBuildProperty' function results to specified Product_Name property. This should help us to chsose correct project from pbxproj file when we have several projects defined. * Added logic to try to get 'Release' build of ProductName matching the package name first and if it doesn't exist then try to get any other if existing
1 parent beb514d commit 0c2aa44

File tree

2 files changed

+81
-3
lines changed

2 files changed

+81
-3
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"code-push": "1.8.0-beta",
2121
"glob": "^5.0.15",
2222
"inquirer": "1.1.2",
23-
"plist": "1.2.0"
23+
"plist": "1.2.0",
24+
"xcode": "0.9.1"
2425
},
2526
"devDependencies": {
2627
"archiver": "latest",

scripts/postlink/ios/postlink.js

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ var glob = require("glob");
33
var inquirer = require('inquirer');
44
var path = require("path");
55
var plist = require("plist");
6+
var xcode = require("xcode");
7+
68
var package = require('../../../../../package.json');
79

810
var ignoreNodeModules = { ignore: "node_modules/**" };
@@ -49,9 +51,12 @@ if (~appDelegateContents.indexOf(newJsCodeLocationAssignmentStatement)) {
4951
jsCodeLocationPatch);
5052
}
5153

52-
var plistPath = glob.sync(`**/${package.name}/*Info.plist`, ignoreNodeModules)[0];
54+
var plistPath = getPlistPath();
55+
5356
if (!plistPath) {
54-
console.log("Couldn't find .plist file");
57+
console.log(`Couldn't find .plist file. You might need to update it manually \
58+
Please refer to plugin configuration section for iOS at \
59+
https://github.com/microsoft/react-native-code-push#plugin-configuration-ios`);
5560
return;
5661
}
5762

@@ -94,3 +99,75 @@ function findFileByAppName(array, appName) {
9499

95100
return null;
96101
}
102+
103+
function getDefaultPlistPath() {
104+
//this is old logic in case we are unable to find PLIST from xcode/pbxproj - at least we can fallback to default solution
105+
return glob.sync(`**/${package.name}/*Info.plist`, ignoreNodeModules)[0];
106+
}
107+
108+
// This is enhanced version of standard implementation of xcode 'getBuildProperty' function
109+
// but allows us to narrow results by PRODUCT_NAME property also.
110+
// So we suppose that proj name should be the same as package name, otherwise fallback to default plist path searching logic
111+
function getBuildSettingsPropertyMatchingTargetProductName(parsedXCodeProj, prop, targetProductName, build){
112+
var target;
113+
var COMMENT_KEY = /_comment$/;
114+
var PRODUCT_NAME_PROJECT_KEY = 'PRODUCT_NAME';
115+
116+
if (!targetProductName){
117+
return target;
118+
}
119+
120+
var configs = parsedXCodeProj.pbxXCBuildConfigurationSection();
121+
for (var configName in configs) {
122+
if (!COMMENT_KEY.test(configName)) {
123+
var config = configs[configName];
124+
if ( (build && config.name === build) || (build === undefined) ) {
125+
if (config.buildSettings[prop] !== undefined && config.buildSettings[PRODUCT_NAME_PROJECT_KEY] == targetProductName) {
126+
target = config.buildSettings[prop];
127+
}
128+
}
129+
}
130+
}
131+
return target;
132+
}
133+
134+
function getPlistPath(){
135+
var xcodeProjectPaths = glob.sync(`**/*.xcodeproj/project.pbxproj`, ignoreNodeModules);
136+
if (!xcodeProjectPaths){
137+
return getDefaultPlistPath();
138+
}
139+
140+
if (xcodeProjectPaths.length !== 1) {
141+
console.log('Could not determine correct xcode proj path to retrieve related plist file, there are multiple xcodeproj under the solution.');
142+
return getDefaultPlistPath();
143+
}
144+
145+
var xcodeProjectPath = xcodeProjectPaths[0];
146+
var parsedXCodeProj;
147+
148+
try {
149+
var proj = xcode.project(xcodeProjectPath);
150+
//use sync version because there are some problems with async version of xcode lib as of current version
151+
parsedXCodeProj = proj.parseSync();
152+
}
153+
catch(e) {
154+
console.log('Couldn\'t read info.plist path from xcode project - error: ' + e.message);
155+
return getDefaultPlistPath();
156+
}
157+
158+
var INFO_PLIST_PROJECT_KEY = 'INFOPLIST_FILE';
159+
var RELEASE_BUILD_PROPERTY_NAME = "Release";
160+
var targetProductName = package ? package.name : null;
161+
162+
//Try to get 'Release' build of ProductName matching the package name first and if it doesn't exist then try to get any other if existing
163+
var plistPathValue = getBuildSettingsPropertyMatchingTargetProductName(parsedXCodeProj, INFO_PLIST_PROJECT_KEY, targetProductName, RELEASE_BUILD_PROPERTY_NAME) ||
164+
getBuildSettingsPropertyMatchingTargetProductName(parsedXCodeProj, INFO_PLIST_PROJECT_KEY, targetProductName) ||
165+
parsedXCodeProj.getBuildProperty(INFO_PLIST_PROJECT_KEY, RELEASE_BUILD_PROPERTY_NAME) ||
166+
parsedXCodeProj.getBuildProperty(INFO_PLIST_PROJECT_KEY);
167+
168+
if (!plistPathValue){
169+
return getDefaultPlistPath();
170+
}
171+
172+
return path.resolve(path.dirname(xcodeProjectPath), '..', plistPathValue);
173+
}

0 commit comments

Comments
 (0)