UNPKG

8.19 kBJavaScriptView Raw
1#! /usr/bin/env node
2const path = require('path');
3const fs = require('fs');
4const readline = require('readline');
5const help = require('./helper');
6const shell = require('shelljs');
7const colors = require('colors');
8const cwdPath = process.cwd();
9const package = require('../package.json');
10const templatePath = path.resolve(__dirname, '../template');
11const templateComponentPath = path.resolve(__dirname, '../cmp_template');
12const program = require('../utils/commander');
13
14const FILENAMEREGX = (() => {
15 let regstr = '';
16 /**
17 * 二进制文件后缀,在rename的时候用来过滤
18 */
19 ['png', 'jpg', 'jpeg', 'bmp', 'webp', 'jar', 'gif', 'ttf', 'dll', 'svg'].forEach(e => {
20 regstr += e + '|';
21 });
22 regstr = `\.(${regstr.slice(0, -1)})`;
23 return new RegExp(regstr);
24})();
25
26
27
28/**
29 *
30 * @param {string} path
31 * @returns {boolean} 路径是否存在
32 */
33function fsExistsSync(path) {
34 try {
35 fs.accessSync(path, fs.F_OK);
36 } catch (e) {
37 return false;
38 }
39 return true;
40}
41/**
42 * copy file from templatePath to targetPath
43 *
44 * @param {string} templatePath
45 * @param {string} targetPath
46 */
47function copyFile(templatePath, targetPath) {
48 fs.writeFileSync(targetPath, fs.readFileSync(templatePath));
49}
50
51function confirmOverride() {
52 const terminal = readline.createInterface({
53 input: process.stdin,
54 output: process.stdout
55 });
56 return new Promise((resolve, reject) => {
57 terminal.question('Floder is already exits, do you want override it ? yes/no ', answer => {
58 if (answer === 'yes' || answer === 'y') {
59 resolve(true);
60 terminal.close();
61 } else {
62 process.exit();
63 }
64 });
65 });
66}
67/**
68 * copy template
69 *
70 * @param {string} templatePath
71 * @param {string} targetPath
72 * @returns {boolean}
73 */
74function copyTemplate(templatePath, targetPath) {
75 try {
76 if (fs.statSync(templatePath).isDirectory() && !fsExistsSync(targetPath)) {
77 fs.mkdirSync(targetPath);
78 }
79
80 const subpaths = fs.readdirSync(templatePath);
81 subpaths.forEach(subpath => {
82 const tarPath = path.resolve(targetPath, subpath);
83 const tempPath = path.resolve(templatePath, subpath);
84
85 if (fs.statSync(tempPath).isDirectory()) {
86 copyTemplate(tempPath, tarPath);
87 } else {
88 copyFile(tempPath, tarPath);
89 }
90 });
91 } catch (error) {
92 console.log(error);
93 return false;
94 }
95 return true;
96}
97/**
98 * rename project
99 *
100 * @param {string} targetPath
101 * @param {string} projectName
102 */
103function renameProject(targetPath, projectName) {
104 try {
105 const paths = fs.readdirSync(targetPath);
106 paths.forEach(subpath => {
107 const subfile = path.resolve(targetPath, subpath);
108 const newPath = subfile.replace(/MoleStarter/gim, projectName);
109 if (!fs.statSync(subfile).isFile()) {
110 if (subpath !== 'images') {
111 fs.renameSync(subfile, newPath);
112 renameProject(newPath, projectName);
113 }
114 } else {
115 if (!FILENAMEREGX.test(subfile)) {
116 fs.renameSync(subfile, newPath);
117 fs.writeFileSync(
118 newPath,
119 fs
120 .readFileSync(newPath)
121 .toString()
122 .replace(/MoleStarter/gim, projectName)
123 );
124 }
125 }
126 });
127 } catch (error) {
128 console.log(error);
129 }
130}
131function renameComponent(targetPath, projectName) {
132 try {
133 const paths = fs.readdirSync(targetPath);
134 paths.forEach(subpath => {
135 const subfile = path.resolve(targetPath, subpath);
136 const newPath = subfile.replace(/MoleUI/gim, projectName);
137 if (!fs.statSync(subfile).isFile()) {
138 if (subpath !== 'images') {
139 fs.renameSync(subfile, newPath);
140 renameComponent(newPath, projectName);
141 }
142 } else {
143 if (!FILENAMEREGX.test(subfile)) {
144 fs.renameSync(subfile, newPath);
145 fs.writeFileSync(
146 newPath,
147 fs
148 .readFileSync(newPath)
149 .toString()
150 .replace(/MoleUI/gim, projectName)
151 );
152 }
153 }
154 });
155 } catch (error) {
156 console.log(error);
157 }
158}
159/**
160 * mole-react-native-cli
161 * @param {string} projectName
162 */
163function installDependencies(projectName) {
164 console.log('\ninstalling...');
165 if (shell.exec(`cd ${projectName} && npm install`).code) {
166 if (shell.exec(`cd ${projectName} && npm install`).code) {
167 console.log(colors.red('install dependencies failed!'));
168 } else {
169 console.log(
170 colors.yellow(
171 [
172 `Success! Created ${projectName} at ${cwdPath}.`,
173 'Inside that directory, you can run several commands and more:',
174 ' * npm run start-web: Starts you project for web.',
175 ' * npm run start-rn: Starts you project for rn.',
176 ' * npm run run-ios: Starts you project for ios.',
177 ' * npm run run-android: Starts you project for android.',
178 ' We suggest that you begin by typing:',
179 ` cd ${projectName}`,
180 ' npm run start-rn',
181 'Happy coding!'
182 ].join('\n')
183 )
184 );
185 }
186 }
187}
188
189function backupDir(templatePath, backupPath) {
190 if (fs.statSync(templatePath).isDirectory()) {
191 fs.mkdirSync(backupPath);
192 }
193 const subpaths = fs.readdirSync(templatePath);
194 subpaths.forEach(subpath => {
195 const bacPath = path.resolve(backupPath, subpath);
196 const tempPath = path.resolve(templatePath, subpath);
197 if (fs.statSync(tempPath).isDirectory()) {
198 backupDir(tempPath, bacPath);
199 } else {
200 copyFile(tempPath, bacPath);
201 }
202 });
203}
204
205function removeBackup(backupPath) {
206 shell.rm('-rf', backupPath);
207}
208/**
209 *
210 *
211 * @param {string} projectName
212 */
213// function newLatestProject(projectName) {
214// shell.exec(`git clone https://github.com/nihgwu/react-native-dva-starter.git`, error => {
215// if (!error) {
216// const tarPath = path.join(cwdPath, 'react-native-dva-starter');
217// removeGit();
218// renameProject(tarPath, projectName);
219// fs.renameSync(tarPath, projectName);
220// installDependencies(projectName);
221// } else {
222// console.log(error);
223// }
224// });
225// }
226
227async function newComponent(component){
228 // console.log("初始化的组件名称为" + component)
229 const targetPath = `${cwdPath}/${component}`;
230
231 if (fsExistsSync(targetPath)) {
232 if (await confirmOverride()) {
233 if (copyTemplate(templateComponentPath, targetPath)) {
234 renameComponent(targetPath, component);
235 console.log('🎉🎉🎉恭喜您, 组件[' + component + ']创建成功.');
236 // installDependencies(component);
237 }
238 // removeBackup(backupPath);
239 }
240 } else {
241
242 if (copyTemplate(templateComponentPath, targetPath)) {
243 renameComponent(targetPath, component);
244 console.log('🎉🎉🎉恭喜您, 组件[' + component + ']创建成功.');
245 // installDependencies(component);
246 }
247 }
248}
249
250/**
251 *
252 *
253 * @param {string} projectName
254 */
255async function newProject(projectName) {
256 const targetPath = `${cwdPath}/${projectName}`;
257 // const backupPath = `${cwdPath}/.${projectName}`;
258 if (fsExistsSync(targetPath)) {
259 if (await confirmOverride()) {
260 if (copyTemplate(templatePath, targetPath)) {
261 renameProject(targetPath, projectName);
262 installDependencies(projectName);
263 }
264 // removeBackup(backupPath);
265 }
266 } else {
267
268 if (copyTemplate(templatePath, targetPath)) {
269 renameProject(targetPath, projectName);
270 installDependencies(projectName);
271 }
272 }
273}
274
275try {
276 program.option('-h, --help', help).option('-v, --version', () => {
277 console.log(package.version);
278 });
279 program.command('project <project>').action(newProject);
280 // program.command('git <project>').action(newLatestProject);
281 program.command('component <component>').action(newComponent);
282 program.catch((...argvs) => {
283 // console.log(colors.red(`Do not use bsreact ${argvs}`));
284 shell.exec('mole-rn-cli --help')
285 //console.log('Run ' + colors.blue('bsreact --help') + ' to get the Commands that bsreact-native-cli supports');
286 });
287 program.parse(process.argv);
288} catch (error) {
289 console.log(error);
290}