forked from atliq/react-native-app-starter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
executable file
·267 lines (233 loc) · 8.27 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
#! /usr/bin/env node
const fs = require("fs");
const os = require("os");
const shell = require("shelljs");
const { program } = require("commander");
const cliSelect = require("cli-select");
const { cwd } = require("process");
program.parse();
const programOptions = program.opts();
const main = async (repositoryUrl, directoryName, husky) => {
console.log(`Creating new project ${directoryName}`);
console.log(`Installing Yarn`);
shell.exec("npm install -g yarn", (code, stdout, stderr) => {
console.log(stdout);
});
if (directoryName.match(/[<>:"\/\\|?*\x00-\x1F]/)) {
return console.error(`
Invalid directory name.
Usage : 'npx react-native-app-starter name_of_app'
`);
}
const randomNameGenerator = (num) => {
let res = "";
for (let i = 0; i < num; i++) {
const random = Math.floor(Math.random() * 27);
res += String.fromCharCode(97 + random);
}
return res;
};
//Get the name of the app-directory to make
let tmpDir = "temp" + randomNameGenerator(5);
try {
shell.exec(`git clone ${repositoryUrl} ${tmpDir}`);
//2. get the json from package.json
const packageJsonRaw = fs.readFileSync(`${tmpDir}/package.json`);
const packageJson = JSON.parse(packageJsonRaw);
const dependencyList = Object.keys(packageJson.dependencies);
const devDependencyList = Object.keys(packageJson.devDependencies);
console.log("Now, installing react-native...");
const shellOptions = {
cwd: `${process.cwd()}/${directoryName}`,
};
shell.exec(
`echo N | npx @react-native-community/cli init ${directoryName}`
);
//3. Installing the dependencies.
console.log("installing... ", dependencyList);
shell.exec(`yarn add ${dependencyList.join(" ")}`, shellOptions);
shell.exec(`yarn add -D ${devDependencyList.join(" ")}`, shellOptions);
if (!husky) {
shell.exec(`yarn remove husky`, shellOptions);
}
const projectDirectories = directoryName.split("/");
shell.ls(`${tmpDir}/android/app/src/main/res/drawable/`).forEach((file) => {
shell.cp(
"-rf",
`${tmpDir}/android/app/src/main/res/drawable/${file}`,
`${directoryName}/android/app/src/main/res/drawable/`
);
});
shell
.ls(`${tmpDir}/ios/boilerPlateTypescript/Images.xcassets/`)
.forEach((file) => {
shell.cp(
"-rf",
`${tmpDir}/ios/boilerPlateTypescript/Images.xcassets/${file}`,
`${directoryName}/ios/${
projectDirectories[projectDirectories.length - 1]
}/Images.xcassets/`
);
});
shell.mv(`${tmpDir}/App`, `${directoryName}`);
shell.mv(`${tmpDir}/.env`, `${directoryName}`);
shell.mv(`${tmpDir}/fastlane`, `${directoryName}`);
if (os.type() === "Darwin") {
shell.exec(`pod install --project-directory=ios`, {
cwd: `${process.cwd()}/${directoryName}`,
});
} else {
console.log("iOS setup only supported in Mac OS.");
}
if (husky) {
shell.exec(`npx husky install`, shellOptions);
shell.rm("-rf", `${directoryName}/.husky`);
shell.mv(`${tmpDir}/.husky`, `${directoryName}`);
}
if (repositoryUrl === tsURL) {
shell.rm("-rf", `${directoryName}/index.js`);
shell.mv(`${tmpDir}/index.js`, `${directoryName}`);
shell.rm("-rf", `${directoryName}/App.tsx`);
} else {
shell.rm("-rf", `${directoryName}/App.js`);
}
shell.rm("-rf", `${directoryName}/babel.config.js`);
shell.rm("-rf", `${directoryName}/tsconfig.json`);
shell.mv(`${tmpDir}/babel.config.js`, `${directoryName}`);
shell.mv(`${tmpDir}/tsconfig.json`, `${directoryName}`);
shell.mv(`${tmpDir}/moduleResolver.js`, `${directoryName}`);
shell.mv(`${tmpDir}/modules.json`, `${directoryName}`);
shell.mv(`${tmpDir}/postinstall`, `${directoryName}`);
shell.mv(`${tmpDir}/.prettierrc.js`, `${directoryName}`);
shell.mv(`${tmpDir}/env.config`, `${directoryName}`);
shell.mv(`${tmpDir}/react-native-config.d.ts`, `${directoryName}`);
console.log("Adding additional scripts...");
addScripts(directoryName, husky);
if (husky) {
console.log("Installing husky hooks");
shell.exec("yarn", "prepare", shellOptions);
}
console.log("Setting up .gitignore");
shell.exec(
`echo "\n.env\n\!**/fastlane/.env" >> ${directoryName}/.gitignore`
);
console.log(`Application generated... its ready to use.
To get started,
- cd ${directoryName}
- npm run dev
`);
// console.log(
// 'Please, add "postinstall": "sh postinstall" in script to package.json '
// );
// - If not start try to delete watchman watches by running following command:
// - watchman watch-del-all
// - Then start metro server clearing its cache by running following command:
// - yarn start --clear-cache
// the rest of your app goes here
} catch {
// handle error
} finally {
try {
if (tmpDir) {
fs.rmSync(tmpDir, { recursive: true });
}
} catch (e) {
console.error(
`An error has occurred while removing the temp folder at ${tmpDir}. Please remove it manually. Error: ${e}`
);
}
}
};
const addScripts = (directory, husky) => {
let packageJSON = JSON.parse(
fs.readFileSync(`${directory}/package.json`, "utf8")
);
let scripts = packageJSON.scripts;
scripts = {
...scripts,
postinstall: "sh postinstall",
lint: "eslint .",
"lint:fix": "eslint . --fix",
prepare: "husky install",
"bundle-android":
"npx react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle",
"bundle-ios":
"npx react-native bundle --entry-file index.js --platform ios --dev false --bundle-output ios/main.jsbundle",
"release-ios-changelog":
"yarn install && yarn run generate-changelog && fastlane ios beta",
"release-android-changelog":
"yarn install && yarn run generate-changelog && fastlane android beta",
"release-ios-changelog-bump":
"yarn install && yarn run generate-changelog-bump && fastlane ios beta",
"release-android-changelog-bump":
"yarn install && yarn run generate-changelog-bump && fastlane android beta",
"generate-changelog":
'fastlane changelog build_changelog bump_type:"patch"',
"generate-changelog-bump": "fastlane changelog build_changelog",
"release-ios": "yarn install && fastlane ios beta",
"release-android": "yarn install && fastlane android beta",
release:
"yarn run generate-changelog && yarn run release-android && yarn run release-ios",
"release-bump":
"yarn run generate-changelog-bump && yarn run release-android && yarn run release-ios",
};
if (!husky) {
delete scripts.prepare;
}
packageJSON.scripts = scripts;
fs.writeFileSync(
`${directory}/package.json`,
JSON.stringify(packageJSON, null, 2)
);
console.log("Added scripts to package.json");
};
const tsURL = "https://github.com/atliq/react-native-boilerplate-ts.git";
let directoryName = process.argv[2];
if (!directoryName || directoryName.length === 0) {
const readline = require("readline").createInterface({
input: process.stdin,
output: process.stdout,
});
readline.question(`What's your project name?`, (name) => {
console.log(`Hi ${name}!`);
readline.close();
directoryName = name;
console.log(`Do you want to install husky`);
cliSelect({
values: ["Yes", "No"],
}).then((husky) => {
console.log(husky);
if (husky.value === "Yes") {
main(tsURL, directoryName, true);
} else {
main(tsURL, directoryName, false);
}
});
if (programOptions.ts) {
console.log("Generating... Typescript Template");
return main(tsURL, directoryName);
}
});
return;
}
if (directoryName.match(/[<>:"\/\\|?*\x00-\x1F]/)) {
return console.error(`
Invalid directory name.
Usage : '@atliq/react-native-starter name_of_app'
`);
}
if (programOptions.ts) {
console.log("Generating... Typescript Template");
return main(tsURL, directoryName);
}
console.log(`Do you want to install husky`);
cliSelect({
values: ["Yes", "No"],
}).then((husky) => {
console.log(husky);
if (husky.value === "Yes") {
main(tsURL, directoryName, true);
} else {
main(tsURL, directoryName, false);
}
});