· 6 years ago · Apr 30, 2019, 05:02 PM
1'use strict';
2
3import chalk from 'chalk';
4import elegantSpinner from 'elegant-spinner';
5import fs from 'fs';
6import inquirer from 'inquirer';
7import logUpdate from 'log-update';
8import shell from 'shelljs';
9import Table from 'cli-table3';
10import validate from 'validate-npm-package-name';
11
12import boilerplate from '../../config.json';
13import { showBanner } from '../../external/banner';
14import { validateInstallation } from '../../utils/validations';
15
16let availableCommands = new Table();
17let frame = elegantSpinner();
18
19let projectName;
20let projectConfig;
21let projectTemplate;
22
23// Prompt for choosing additional features (ESLint, JSHint, JSLint, Prettier)
24let installFeature = (wantfeature, template) => {
25 if (wantfeature) {
26 inquirer
27 .prompt([
28 {
29 name: 'feature',
30 type: 'list',
31 message: 'Please select additional feature',
32 choices: ['ESLint', 'JSHint', 'JSLint', 'Prettier'],
33 },
34 ])
35 .then(answer => {
36 if (answer.feature === 'ESLint') {
37 if (template === 'nuxt') {
38 shell.echo('Installing ESLint for your nuxt template : server');
39 shell.cd(`${projectName}/server`);
40 shell.exec('npm install eslint', { silent: true });
41 shell.cd('../..');
42 } else {
43 // configuring client
44 shell.echo(
45 'Installing ESLint for your ' + template + ' template : client',
46 );
47 shell.cd(`${projectName}/client`);
48 shell.exec('npm install eslint', { silent: true });
49 shell.cd('../..');
50 //configuring server
51 shell.echo(
52 'Installing ESLint for your ' + template + ' template : server',
53 );
54 shell.cd(`${projectName}/server`);
55 shell.exec('npm install eslint', { silent: true });
56 shell.cd('../..');
57 }
58 } else if (answer.feature === 'JSHint') {
59 if (template === 'nuxt') {
60 shell.echo('Installing JSHint for your nuxt template : server');
61 shell.cd(`${projectName}/server`);
62 shell.exec('npm install jshint', { silent: true });
63 shell.cd('../..');
64 } else {
65 // configuring client
66 shell.echo(
67 'Installing JSHint for your ' + template + ' template : client',
68 );
69 shell.cd(`${projectName}/client`);
70 shell.exec('npm install jshint', { silent: true });
71 shell.cd('../..');
72 //configuring server
73 shell.echo(
74 'Installing JSHint for your ' + template + ' template : server',
75 );
76 shell.cd(`${projectName}/server`);
77 shell.exec('npm install jshint', { silent: true });
78 shell.cd('../..');
79 }
80 } else if (answer.feature === 'JSLint') {
81 if (template === 'nuxt') {
82 shell.echo('Installing JSLint for your nuxt template : server');
83 shell.cd(`${projectName}/server`);
84 shell.exec('npm install jslint', { silent: true });
85 shell.cd('../..');
86 } else {
87 // configuring client
88 shell.echo(
89 'Installing JSLint for your ' + template + ' template : client',
90 );
91 shell.cd(`${projectName}/client`);
92 shell.exec('npm install jslint', { silent: true });
93 shell.cd('../..');
94 //configuring server
95 shell.echo(
96 'Installing JSLint for your ' + template + ' template : server',
97 );
98 shell.cd(`${projectName}/server`);
99 shell.exec('npm install jslint', { silent: true });
100 shell.cd('../..');
101 }
102 } else if (answer.feature === 'Prettier') {
103 if (template === 'nuxt') {
104 shell.echo('Installing Prettier for your nuxt template : server');
105 shell.cd(`${projectName}/server`);
106 shell.exec('npm install prettier', { silent: true });
107 shell.cd('../..');
108 } else {
109 // configuring client
110 shell.echo(
111 'Installing Prettier for your ' + template + ' template : client',
112 );
113 shell.cd(`${projectName}/client`);
114 shell.exec('npm install prettier', { silent: true });
115 shell.cd('../..');
116 //configuring server
117 shell.echo(
118 '\nInstalling Prettier for your ' +
119 template +
120 ' template : server',
121 );
122 shell.cd(`${projectName}/server`);
123 shell.exec('npm install prettier', { silent: true });
124 shell.cd('../..');
125 }
126 }
127 });
128 } else {
129 console.log('Continue..');
130 }
131};
132
133let showTables = () => {
134 console.log(chalk.yellow('\n Available commands:-'));
135
136 availableCommands.push(
137 {
138 'mevn version': 'Current CLI version',
139 },
140 {
141 'mevn serve': 'To launch client/server',
142 },
143 {
144 'mevn add:package': 'Add additional packages',
145 },
146 {
147 'mevn generate': 'To generate config files',
148 },
149 {
150 'mevn create:component <name>': 'Create new components',
151 },
152 {
153 'mevn codesplit <name>': 'Lazy load components',
154 },
155 {
156 'mevn create:git-repo': 'Create a GitHub Repo',
157 },
158 {
159 'mevn dockerize': 'Launch within docker containers',
160 },
161 {
162 'mevn deploy': 'Deploy the app to Heroku',
163 },
164 );
165 console.log(availableCommands.toString());
166
167 console.log(
168 chalk.cyanBright(
169 `\n\n Make sure that you've done ${chalk.greenBright(
170 `cd ${projectName}`,
171 )}`,
172 ),
173 );
174 console.log(chalk.redBright('\n warning:'));
175 console.log(' Do not delete mevn.json file');
176};
177
178let fetchTemplate = async template => {
179 try {
180 await validateInstallation('git');
181
182 shell.exec(
183 `${boilerplate[template]} ${projectName}`,
184 { silent: true },
185 { async: true },
186 );
187
188 let fetchSpinner = setInterval(() => {
189 logUpdate('Fetching the boilerplate ' + chalk.cyan.bold.dim(frame()));
190 }, 50);
191
192 setTimeout(() => {
193 console.log('\n');
194 clearInterval(fetchSpinner);
195 logUpdate.clear();
196 showTables();
197 }, 5000);
198
199 fs.writeFileSync(
200 `./${projectName}/mevn.json`,
201 projectConfig.join('\n').toString(),
202 );
203
204 if (template) {
205 setTimeout(() => {
206 console.log('\n');
207
208 inquirer
209 .prompt([
210 {
211 name: 'wantfeature',
212 type: 'list',
213 message: 'Do you want any additional features?',
214 choices: ['Yes', 'No'],
215 },
216 ])
217 .then(async choice => {
218 if (choice.wantfeature === 'Yes') {
219 console.log(choice.wantfeature, projectTemplate);
220 await installFeature(choice.wantfeature, projectTemplate);
221 } else if (choice.wantfeature === 'No') {
222 console.log('Okay. Not installing..');
223 }
224 }).then(async() => {
225 if (projectTemplate == 'nuxt') {
226 await inquirer
227 .prompt([
228 {
229 name: 'mode',
230 type: 'list',
231 message: 'Choose your preferred mode',
232 choices: ['Universal', 'SPA'],
233 },
234 ])
235 .then(choice => {
236 if (choice.mode === 'Universal') {
237 let configFile = fs
238 .readFileSync(`./${projectName}/nuxt.config.js`, 'utf8')
239 .toString()
240 .split('\n');
241 let index = configFile.indexOf(
242 configFile.find(line => line.includes('mode')),
243 );
244 configFile[index] = ` mode: 'universal',`;
245
246 fs.writeFileSync(
247 `./${projectName}/nuxt.config.js`,
248 configFile.join('\n'),
249 );
250 }
251 showTables();
252 });
253 }
254 })
255
256 }, 5000);
257 }
258 } catch (error) {
259 throw error;
260 }
261};
262
263exports.initializeProject = appName => {
264 showBanner();
265 console.log('\n');
266
267 let initialSpinner = setInterval(() => {
268 logUpdate('Initializing ' + chalk.cyan.bold.dim(frame()));
269 }, 50);
270
271 setTimeout(() => {
272 const hasMultipleProjectNameArgs =
273 process.argv[4] && !process.argv[4].startsWith('-');
274 // Validation for multiple directory names
275 if (hasMultipleProjectNameArgs) {
276 console.log(
277 chalk.red.bold(
278 '\n Kindly provide only one argument as the directory name!!',
279 ),
280 );
281 process.exit(1);
282 }
283
284 const validationResult = validate(appName);
285 if (!validationResult.validForNewPackages) {
286 console.error(
287 `Could not create a project called ${chalk.red(
288 `"${appName}"`,
289 )} because of npm naming restrictions:`,
290 );
291 process.exit(1);
292 }
293
294 if (fs.existsSync(appName)) {
295 console.error(
296 chalk.red.bold(`\n Directory ${appName} already exists in path!`),
297 );
298 process.exit(1);
299 }
300
301 clearInterval(initialSpinner);
302 logUpdate.clear();
303 projectName = appName;
304
305 inquirer
306 .prompt([
307 {
308 name: 'template',
309 type: 'list',
310 message: 'Please select one',
311 choices: ['basic', 'pwa', 'graphql', 'Nuxt-js'],
312 },
313 ])
314 .then(choice => {
315 projectConfig = [
316 '{',
317 `"name": "${appName}",`,
318 `"template": "${choice.template}"`,
319 '}',
320 ];
321 if (choice.template === 'Nuxt-js') {
322 choice.template = 'nuxt';
323 projectTemplate = 'nuxt';
324 }
325 else {
326 projectTemplate = choice.template;
327 }
328 fetchTemplate(choice.template);
329 });
330 }, 1000);
331};
332
333// inquirer
334// .prompt([
335// {
336// name: 'mode',
337// type: 'list',
338// message: 'Choose your preferred mode',
339// choices: ['Universal', 'SPA'],
340// },
341// ])
342// .then(choice => {
343// if (choice.mode === 'Universal') {
344// let configFile = fs
345// .readFileSync(`./${projectName}/nuxt.config.js`, 'utf8')
346// .toString()
347// .split('\n');
348// let index = configFile.indexOf(
349// configFile.find(line => line.includes('mode')),
350// );
351// configFile[index] = ` mode: 'universal',`;
352
353// fs.writeFileSync(
354// `./${projectName}/nuxt.config.js`,
355// configFile.join('\n'),
356// );
357// }
358// showTables();
359// });