1
+ /*
2
+ The script serves to generate CodePushified React Native app to reproduce issues or for testing purposes.
3
+
4
+ Requirements:
5
+ 1. npm i -g react-native-cli
6
+ 2. npm i -g code-push-cli
7
+ 3. code-push register
8
+
9
+ Usage: node create-app.js <appName> <reactNativeVersion> <reactNativeCodePushVersion>
10
+ 1. node create-app.js
11
+ 2. node create-app.js myapp
12
+
13
+ 4. node create-app.js myapp react-native@latest Microsoft/react-native-code-push
14
+
15
+ Parameters:
16
+ 1. <appName> - CodePushDemoAppTest
17
+ 2. <reactNativeVersion> - react-native@latest
18
+ 3. <reactNativeCodePushVersion> - react-native-code-push@latest
19
+ */
20
+
21
+ let fs = require ( 'fs' ) ;
22
+ let path = require ( 'path' ) ;
23
+ let nexpect = require ( './nexpect' ) ;
24
+ let child_proces = require ( 'child_process' ) ;
25
+ let execSync = child_proces . execSync ;
26
+
27
+ let args = process . argv . slice ( 2 ) ;
28
+ let appName = args [ 0 ] || 'CodePushDemoAppTest' ;
29
+
30
+ if ( fs . existsSync ( appName ) ) {
31
+ console . error ( `Folder with name "${ appName } " already exists! Please delete` ) ;
32
+ process . exit ( ) ;
33
+ }
34
+
35
+ let appNameAndroid = `${ appName } -android` ;
36
+ let appNameIOS = `${ appName } -ios` ;
37
+ let reactNativeVersion = args [ 1 ] || `react-native@${ execSync ( 'npm view react-native version' ) } ` . trim ( ) ;
38
+ let reactNativeCodePushVersion = args [ 2 ] || `react-native-code-push@${ execSync ( 'npm view react-native-code-push version' ) } ` . trim ( ) ;
39
+
40
+ console . log ( `App name: ${ appName } ` ) ;
41
+ console . log ( `React Native version: ${ reactNativeVersion } ` ) ;
42
+ console . log ( `React Native Module for CodePush version: ${ reactNativeCodePushVersion } \n` ) ;
43
+
44
+ let androidStagingDeploymentKey = null ;
45
+ let iosStagingDeploymentKey = null ;
46
+
47
+
48
+
49
+ //GENERATE START
50
+ createCodePushApp ( appNameAndroid , 'android' ) ;
51
+ createCodePushApp ( appNameIOS , 'ios' ) ;
52
+
53
+ generatePlainReactNativeApp ( appName , reactNativeVersion ) ;
54
+ process . chdir ( appName ) ;
55
+ installCodePush ( reactNativeCodePushVersion ) ;
56
+ linkCodePush ( androidStagingDeploymentKey , iosStagingDeploymentKey ) ;
57
+ //GENERATE END
58
+
59
+
60
+
61
+ function createCodePushApp ( name , platform ) {
62
+ try {
63
+ console . log ( `Creating CodePush app "${ name } " to release updates for ${ platform } ...` ) ;
64
+ execSync ( `code-push app add ${ name } ${ platform } react-native` ) ;
65
+ console . log ( `App "${ name } " has been created \n` ) ;
66
+ } catch ( e ) {
67
+ console . log ( `App "${ name } " already exists \n` ) ;
68
+ }
69
+ let deploymentKeys = JSON . parse ( execSync ( `code-push deployment ls ${ name } -k --format json` ) ) ;
70
+ let stagingDeploymentKey = deploymentKeys [ 1 ] . key ;
71
+ console . log ( `Deployment key for ${ platform } : ${ stagingDeploymentKey } ` ) ;
72
+ console . log ( `Use "code-push release-react ${ name } ${ platform } " command to release updates for ${ platform } \n` ) ;
73
+
74
+ switch ( platform ) {
75
+ case 'android' :
76
+ androidStagingDeploymentKey = stagingDeploymentKey ;
77
+ break ;
78
+ case 'ios' :
79
+ iosStagingDeploymentKey = stagingDeploymentKey ;
80
+ break ;
81
+ }
82
+ }
83
+
84
+ function generatePlainReactNativeApp ( appName , reactNativeVersion ) {
85
+ console . log ( `Installing React Native...` ) ;
86
+ execSync ( `react-native init ${ appName } --version ${ reactNativeVersion } ` ) ;
87
+ console . log ( `React Native has been installed \n` ) ;
88
+ }
89
+
90
+ function installCodePush ( reactNativeCodePushVersion ) {
91
+ console . log ( `Installing React Native Module for CodePush...` ) ;
92
+ execSync ( `npm i --save ${ reactNativeCodePushVersion } ` ) ;
93
+ console . log ( `React Native Module for CodePush has been installed \n` ) ;
94
+ }
95
+
96
+ function linkCodePush ( androidStagingDeploymentKey , iosStagingDeploymentKey ) {
97
+ console . log ( `Linking React Native Module for CodePush...` ) ;
98
+ nexpect . spawn ( `react-native link react-native-code-push` )
99
+ . wait ( "What is your CodePush deployment key for Android (hit <ENTER> to ignore)" )
100
+ . sendline ( androidStagingDeploymentKey )
101
+ . wait ( "What is your CodePush deployment key for iOS (hit <ENTER> to ignore)" )
102
+ . sendline ( iosStagingDeploymentKey )
103
+ . run ( function ( err ) {
104
+ if ( ! err ) {
105
+ console . log ( `React Native Module for CodePush has been linked \n` ) ;
106
+ setupAssets ( ) ;
107
+ }
108
+ else {
109
+ console . log ( err ) ;
110
+ }
111
+ } ) ;
112
+ }
113
+
114
+ function setupAssets ( ) {
115
+ fs . unlinkSync ( './index.ios.js' ) ;
116
+ fs . unlinkSync ( './index.android.js' ) ;
117
+
118
+ fs . writeFileSync ( 'demo.js' , fs . readFileSync ( '../CodePushDemoApp/demo.js' ) ) ;
119
+ fs . writeFileSync ( 'index.ios.js' , fs . readFileSync ( '../CodePushDemoApp/index.ios.js' ) ) ;
120
+ fs . writeFileSync ( 'index.android.js' , fs . readFileSync ( '../CodePushDemoApp/index.android.js' ) ) ;
121
+
122
+ copyRecursiveSync ( '../CodePushDemoApp/images' , './images' ) ;
123
+
124
+ fs . readFile ( 'demo.js' , 'utf8' , function ( err , data ) {
125
+ if ( err ) {
126
+ return console . error ( err ) ;
127
+ }
128
+ var result = data . replace ( / C o d e P u s h D e m o A p p / g, appName ) ;
129
+
130
+ fs . writeFile ( 'demo.js' , result , 'utf8' , function ( err ) {
131
+ if ( err ) return console . error ( err ) ;
132
+
133
+ if ( ! / ^ w i n / . test ( process . platform ) ) {
134
+ optimizeToTestInDebugMode ( ) ;
135
+ process . chdir ( '../' ) ;
136
+ grantAccess ( appName ) ;
137
+ }
138
+ console . log ( `\nReact Native app "${ appName } " has been generated and CodePushified!` ) ;
139
+ process . exit ( ) ;
140
+ } ) ;
141
+ } ) ;
142
+ }
143
+
144
+ function optimizeToTestInDebugMode ( ) {
145
+ let rnXcodeShLocationFolder = 'scripts' ;
146
+ try {
147
+ let rnVersions = JSON . parse ( execSync ( `npm view react-native versions --json` ) ) ;
148
+ let currentRNversion = JSON . parse ( fs . readFileSync ( './package.json' ) ) [ 'dependencies' ] [ 'react-native' ] ;
149
+ if ( rnVersions . indexOf ( currentRNversion ) > - 1 &&
150
+ rnVersions . indexOf ( currentRNversion ) < rnVersions . indexOf ( "0.46.0-rc.0" ) ) {
151
+ rnXcodeShLocationFolder = 'packager' ;
152
+ }
153
+ } catch ( e ) { }
154
+
155
+ execSync ( `perl -i -p0e 's/#ifdef DEBUG.*?#endif/jsCodeLocation = [CodePush bundleURL];/s' ios/${ appName } /AppDelegate.m` ) ;
156
+ execSync ( `sed -ie '17,20d' node_modules/react-native/${ rnXcodeShLocationFolder } /react-native-xcode.sh` ) ;
157
+ execSync ( `sed -ie 's/targetName.toLowerCase().contains("release")$/true/' node_modules/react-native/react.gradle` ) ;
158
+ }
159
+
160
+ function grantAccess ( folderPath ) {
161
+ execSync ( 'chown -R `whoami` ' + folderPath ) ;
162
+ execSync ( 'chmod -R 755 ' + folderPath ) ;
163
+ }
164
+
165
+ function copyRecursiveSync ( src , dest ) {
166
+ var exists = fs . existsSync ( src ) ;
167
+ var stats = exists && fs . statSync ( src ) ;
168
+ var isDirectory = exists && stats . isDirectory ( ) ;
169
+ if ( exists && isDirectory ) {
170
+ fs . mkdirSync ( dest ) ;
171
+ fs . readdirSync ( src ) . forEach ( function ( childItemName ) {
172
+ copyRecursiveSync ( path . join ( src , childItemName ) ,
173
+ path . join ( dest , childItemName ) ) ;
174
+ } ) ;
175
+ } else {
176
+ fs . linkSync ( src , dest ) ;
177
+ }
178
+ }
0 commit comments