@@ -3,6 +3,8 @@ var glob = require("glob");
3
3
var inquirer = require ( 'inquirer' ) ;
4
4
var path = require ( "path" ) ;
5
5
var plist = require ( "plist" ) ;
6
+ var xcode = require ( "xcode" ) ;
7
+
6
8
var package = require ( '../../../../../package.json' ) ;
7
9
8
10
var ignoreNodeModules = { ignore : "node_modules/**" } ;
@@ -49,9 +51,12 @@ if (~appDelegateContents.indexOf(newJsCodeLocationAssignmentStatement)) {
49
51
jsCodeLocationPatch ) ;
50
52
}
51
53
52
- var plistPath = glob . sync ( `**/${ package . name } /*Info.plist` , ignoreNodeModules ) [ 0 ] ;
54
+ var plistPath = getPlistPath ( ) ;
55
+
53
56
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` ) ;
55
60
return ;
56
61
}
57
62
@@ -94,3 +99,75 @@ function findFileByAppName(array, appName) {
94
99
95
100
return null ;
96
101
}
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 = / _ c o m m e n t $ / ;
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