1 | 'use strict';
|
2 |
|
3 | const { join } = require('path');
|
4 | const fse = require('fs-extra');
|
5 | const chalk = require('chalk');
|
6 | const execa = require('execa');
|
7 | const ora = require('ora');
|
8 |
|
9 | const stopProcess = require('./utils/stop-process');
|
10 | const { trackUsage, captureStderr } = require('./utils/usage');
|
11 | const packageJSON = require('./resources/json/package.json');
|
12 | const databaseJSON = require('./resources/json/database.json.js');
|
13 |
|
14 | module.exports = async function createProject(
|
15 | scope,
|
16 | { connection, dependencies }
|
17 | ) {
|
18 | console.log('Creating files.');
|
19 |
|
20 | const { rootPath } = scope;
|
21 | const resources = join(__dirname, 'resources');
|
22 |
|
23 | try {
|
24 |
|
25 | await fse.copy(join(resources, 'files'), rootPath);
|
26 |
|
27 |
|
28 | const dotFiles = await fse.readdir(join(resources, 'dot-files'));
|
29 | await Promise.all(
|
30 | dotFiles.map(name => {
|
31 | return fse.copy(
|
32 | join(resources, 'dot-files', name),
|
33 | join(rootPath, `.${name}`)
|
34 | );
|
35 | })
|
36 | );
|
37 |
|
38 |
|
39 | await fse.writeJSON(
|
40 | join(rootPath, 'package.json'),
|
41 | packageJSON({
|
42 | strapiDependencies: scope.strapiDependencies,
|
43 | additionalsDependencies: dependencies,
|
44 | strapiVersion: scope.strapiVersion,
|
45 | projectName: scope.name,
|
46 | uuid: scope.uuid,
|
47 | }),
|
48 | {
|
49 | spaces: 2,
|
50 | }
|
51 | );
|
52 |
|
53 |
|
54 | await fse.ensureDir(join(rootPath, 'node_modules'));
|
55 |
|
56 | await Promise.all(
|
57 | ['development', 'staging', 'production'].map(env => {
|
58 | return fse.writeJSON(
|
59 | join(rootPath, `config/environments/${env}/database.json`),
|
60 | databaseJSON({
|
61 | connection,
|
62 | env,
|
63 | }),
|
64 | { spaces: 2 }
|
65 | );
|
66 | })
|
67 | );
|
68 | } catch (err) {
|
69 | await fse.remove(scope.rootPath);
|
70 | throw err;
|
71 | }
|
72 |
|
73 | const installPrefix = chalk.yellow('Installing dependencies:');
|
74 | const loader = ora(installPrefix).start();
|
75 |
|
76 | const logInstall = (chunk = '') => {
|
77 | loader.text = `${installPrefix} ${chunk
|
78 | .toString()
|
79 | .split('\n')
|
80 | .join(' ')}`;
|
81 | };
|
82 |
|
83 | try {
|
84 | if (scope.installDependencies !== false) {
|
85 | const runner = runInstall(scope);
|
86 |
|
87 | runner.stdout.on('data', logInstall);
|
88 | runner.stderr.on('data', logInstall);
|
89 |
|
90 | await runner;
|
91 | }
|
92 |
|
93 | loader.stop();
|
94 | console.log(`Dependencies installed ${chalk.green('successfully')}.`);
|
95 | } catch (error) {
|
96 | loader.stop();
|
97 | await trackUsage({
|
98 | event: 'didNotInstallProjectDependencies',
|
99 | scope,
|
100 | error: error.stderr.slice(-1024),
|
101 | });
|
102 |
|
103 | console.error(`${chalk.red('Error')} while installing dependencies:`);
|
104 | console.error(error.stderr);
|
105 |
|
106 | await captureStderr('didNotInstallProjectDependencies', error);
|
107 |
|
108 | console.log(chalk.black.bgWhite(' Keep trying! '));
|
109 | console.log();
|
110 | console.log(
|
111 | chalk.bold(
|
112 | 'Oh, it seems that you encountered errors while installing dependencies in your project.'
|
113 | )
|
114 | );
|
115 | console.log(`Don't give up, your project was created correctly.`);
|
116 | console.log(
|
117 | `Fix the issues mentionned in the installation errors and try to run the following command:`
|
118 | );
|
119 | console.log();
|
120 | console.log(
|
121 | `cd ${chalk.green(rootPath)} && ${chalk.cyan(
|
122 | scope.useYarn ? 'yarn' : 'npm'
|
123 | )} install`
|
124 | );
|
125 | console.log();
|
126 |
|
127 | stopProcess();
|
128 | }
|
129 |
|
130 | await trackUsage({ event: 'didCreateProject', scope });
|
131 |
|
132 | console.log();
|
133 | console.log(`Your application was created at ${chalk.green(rootPath)}.\n`);
|
134 |
|
135 | const cmd = chalk.cyan(scope.useYarn ? 'yarn' : 'npm run');
|
136 |
|
137 | console.log('Available commands in your project:');
|
138 | console.log();
|
139 | console.log(` ${cmd} develop`);
|
140 | console.log(' Start Strapi in watch mode.');
|
141 | console.log();
|
142 | console.log(` ${cmd} start`);
|
143 | console.log(' Start Strapi without watch mode.');
|
144 | console.log();
|
145 | console.log(` ${cmd} build`);
|
146 | console.log(' Build Strapi admin panel.');
|
147 | console.log();
|
148 | console.log(` ${cmd} strapi`);
|
149 | console.log(` Display all available commands.`);
|
150 | console.log();
|
151 | console.log('You can start by doing:');
|
152 | console.log();
|
153 | console.log(` ${chalk.cyan('cd')} ${rootPath}`);
|
154 | console.log(` ${cmd} develop`);
|
155 | console.log();
|
156 | };
|
157 |
|
158 | const installArguments = ['install', '--production', '--no-optional'];
|
159 | function runInstall({ rootPath, useYarn }) {
|
160 | if (useYarn) {
|
161 | return execa('yarnpkg', installArguments, {
|
162 | cwd: rootPath,
|
163 | stdin: 'ignore',
|
164 | });
|
165 | }
|
166 |
|
167 | return execa('npm', installArguments, { cwd: rootPath, stdin: 'ignore' });
|
168 | }
|