Skip to content
This repository has been archived by the owner on Oct 7, 2024. It is now read-only.

Commit

Permalink
Improved logic for searching plist file path for iOS postlink.js (mic…
Browse files Browse the repository at this point in the history
…rosoft#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: microsoft#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
  • Loading branch information
max-mironov authored Feb 21, 2017
1 parent beb514d commit 0c2aa44
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 3 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"code-push": "1.8.0-beta",
"glob": "^5.0.15",
"inquirer": "1.1.2",
"plist": "1.2.0"
"plist": "1.2.0",
"xcode": "0.9.1"
},
"devDependencies": {
"archiver": "latest",
Expand Down
81 changes: 79 additions & 2 deletions scripts/postlink/ios/postlink.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ var glob = require("glob");
var inquirer = require('inquirer');
var path = require("path");
var plist = require("plist");
var xcode = require("xcode");

var package = require('../../../../../package.json');

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

var plistPath = glob.sync(`**/${package.name}/*Info.plist`, ignoreNodeModules)[0];
var plistPath = getPlistPath();

if (!plistPath) {
console.log("Couldn't find .plist file");
console.log(`Couldn't find .plist file. You might need to update it manually \
Please refer to plugin configuration section for iOS at \
https://github.com/microsoft/react-native-code-push#plugin-configuration-ios`);
return;
}

Expand Down Expand Up @@ -94,3 +99,75 @@ function findFileByAppName(array, appName) {

return null;
}

function getDefaultPlistPath() {
//this is old logic in case we are unable to find PLIST from xcode/pbxproj - at least we can fallback to default solution
return glob.sync(`**/${package.name}/*Info.plist`, ignoreNodeModules)[0];
}

// This is enhanced version of standard implementation of xcode 'getBuildProperty' function
// but allows us to narrow results by PRODUCT_NAME property also.
// So we suppose that proj name should be the same as package name, otherwise fallback to default plist path searching logic
function getBuildSettingsPropertyMatchingTargetProductName(parsedXCodeProj, prop, targetProductName, build){
var target;
var COMMENT_KEY = /_comment$/;
var PRODUCT_NAME_PROJECT_KEY = 'PRODUCT_NAME';

if (!targetProductName){
return target;
}

var configs = parsedXCodeProj.pbxXCBuildConfigurationSection();
for (var configName in configs) {
if (!COMMENT_KEY.test(configName)) {
var config = configs[configName];
if ( (build && config.name === build) || (build === undefined) ) {
if (config.buildSettings[prop] !== undefined && config.buildSettings[PRODUCT_NAME_PROJECT_KEY] == targetProductName) {
target = config.buildSettings[prop];
}
}
}
}
return target;
}

function getPlistPath(){
var xcodeProjectPaths = glob.sync(`**/*.xcodeproj/project.pbxproj`, ignoreNodeModules);
if (!xcodeProjectPaths){
return getDefaultPlistPath();
}

if (xcodeProjectPaths.length !== 1) {
console.log('Could not determine correct xcode proj path to retrieve related plist file, there are multiple xcodeproj under the solution.');
return getDefaultPlistPath();
}

var xcodeProjectPath = xcodeProjectPaths[0];
var parsedXCodeProj;

try {
var proj = xcode.project(xcodeProjectPath);
//use sync version because there are some problems with async version of xcode lib as of current version
parsedXCodeProj = proj.parseSync();
}
catch(e) {
console.log('Couldn\'t read info.plist path from xcode project - error: ' + e.message);
return getDefaultPlistPath();
}

var INFO_PLIST_PROJECT_KEY = 'INFOPLIST_FILE';
var RELEASE_BUILD_PROPERTY_NAME = "Release";
var targetProductName = package ? package.name : null;

//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
var plistPathValue = getBuildSettingsPropertyMatchingTargetProductName(parsedXCodeProj, INFO_PLIST_PROJECT_KEY, targetProductName, RELEASE_BUILD_PROPERTY_NAME) ||
getBuildSettingsPropertyMatchingTargetProductName(parsedXCodeProj, INFO_PLIST_PROJECT_KEY, targetProductName) ||
parsedXCodeProj.getBuildProperty(INFO_PLIST_PROJECT_KEY, RELEASE_BUILD_PROPERTY_NAME) ||
parsedXCodeProj.getBuildProperty(INFO_PLIST_PROJECT_KEY);

if (!plistPathValue){
return getDefaultPlistPath();
}

return path.resolve(path.dirname(xcodeProjectPath), '..', plistPathValue);
}

0 comments on commit 0c2aa44

Please sign in to comment.