UNPKG

4.24 kBPlain TextView Raw
1import fs from 'fs';
2import inquirer from 'inquirer';
3import path from 'path';
4import yeoman from 'yeoman-environment';
5import { install } from '../../shared/npm';
6
7const loadGenerator = (root: string, rootPkg: string) => {
8 return new Promise<any>((resolve, reject) => {
9 fs.readFile(rootPkg, 'utf8', (err, data) => {
10 if (err) {
11 reject(err);
12 } else {
13 const json = JSON.parse(data);
14 const deps = json.dependencies || json.devDependencies || {};
15 const generators = Object.keys(deps)
16 .filter((name) => {
17 if (!/^generator-|^@[^/]+\/generator-/.test(name)) {
18 return false;
19 }
20 const generatorPath = path.join(root, 'node_modules', name);
21 return fs.existsSync(generatorPath);
22 })
23 .map((name) => {
24 const generatorPkgPath = path.join(
25 root,
26 'node_modules',
27 name,
28 'package.json'
29 );
30 const generatorPkgData = fs.readFileSync(generatorPkgPath, 'utf8');
31 const generatorPkgJson = JSON.parse(generatorPkgData);
32 const desc = generatorPkgJson.description;
33
34 return { name, desc };
35 });
36 resolve(generators);
37 }
38 });
39 });
40};
41
42const run = (ctx: any, name: string) => {
43 const root = ctx.root;
44 const yeomanEnv = yeoman.createEnv();
45 let generatorEntry = path.join(root, 'node_modules', name, 'app/index.js');
46
47 if (!fs.existsSync(generatorEntry)) {
48 generatorEntry = path.join(
49 root,
50 'node_modules',
51 name,
52 'generators',
53 'app/index.js'
54 );
55 }
56 yeomanEnv.register(require.resolve(generatorEntry), name);
57 yeomanEnv.run(name, ctx, (err) => {
58 ctx.reporter && ctx.reporter.reportInitResult()
59 if (err) {
60 ctx.logger.error(err);
61 } else {
62 ctx.logger.debug('create project success!');
63 }
64 });
65};
66
67module.exports = (ctx: any) => {
68 ctx.commander.register('init', 'Create a new project', () => {
69 const { root, rootPkg, args } = ctx;
70 const { generator } = args;
71 loadGenerator(root, rootPkg).then(async (generators: any) => {
72 // feflow init 简化逻辑直接安装并使用脚手架
73 if (generator && /^generator-|^@[^/]+\/generator-/.test(generator)) {
74 const isGeneratorInstalled = generators.some((item: any) => {
75 return item.name === generator
76 });
77 if (generators.length && isGeneratorInstalled) {
78 run(ctx, generator);
79 return;
80 } else {
81 const askIfInstallGenerator = [
82 {
83 type: 'confirm',
84 name: 'ifInstall',
85 message: `You have not installed the generator ${generator},if you want to install and use ?`,
86 default: true
87 }
88 ];
89 const answer = await inquirer.prompt(askIfInstallGenerator);
90 if (answer.ifInstall) {
91 const packageManager = ctx.config && ctx.config.packageManager;
92 install(
93 packageManager,
94 ctx.root,
95 'install',
96 generator,
97 false,
98 true
99 ).then(() => {
100 ctx.logger.info(`install success`);
101 run(ctx, generator);
102 });
103 return;
104 }
105 }
106 }
107 const options = generators.map((item: any) => {
108 return item.desc;
109 });
110 if (generators.length) {
111 inquirer
112 .prompt([
113 {
114 type: 'list',
115 name: 'desc',
116 message: '您想要创建哪种类型的工程?',
117 choices: options
118 }
119 ])
120 .then((answer: any) => {
121 let name;
122 generators.map((item: any) => {
123 if (item.desc === answer.desc) {
124 name = item.name;
125 }
126 });
127 ctx.reporter.report('init', name)
128 name && run(ctx, name);
129 });
130 } else {
131 ctx.logger.warn(
132 'You have not installed a template yet, ' +
133 ' please use install command. Guide: https://github.com/Tencent/feflow'
134 );
135 }
136 });
137 });
138};