UNPKG

5.4 kBJavaScriptView Raw
1const {
2 generator,
3 clone,
4 getOptions
5} = require('../index')
6const {
7 localpath
8} = require('../lib/utils/localpath')
9const {
10 evaluate
11} = require('../lib/utils/eval')
12const fse = require('fs-extra');
13const debug = require('debug')('create')
14const path = require('path')
15const async = require('async')
16
17const exists = fse.existsSync
18
19module.exports = {
20 name: 'create',
21 description: 'Create a weex project',
22 run: async ({
23 logger,
24 parameters,
25 inquirer,
26 meta
27 }) => {
28 const first = parameters.first
29 const second = parameters.second
30 const options = parameters.options
31 const globalConfig = options.__config
32
33 // Support types from prompt-for which was used before
34 const promptMapping = {
35 string: 'input',
36 boolean: 'confirm'
37 };
38
39 const showHelp = async () => {
40 let params = {
41 commandend: 'Create a weex project',
42 commands: [{
43 heading: ['Usage', 'Description']
44 },
45 {
46 key: 'create [project-name]',
47 description: 'Create a official weex project'
48 },
49 {
50 key: 'create <template-name | git-repo> [project-name]',
51 description: 'Create a project from specify template name or git repository'
52 }
53 ],
54 options: {
55 'Base': [{
56 key: '--no-cache',
57 description: 'Fetching latest template with no cache.'
58 }, {
59 key: '--clone',
60 description: 'If true use git clone instead of an http download. While this can be a bit slower, it does allow private repositories to be used if the appropriate SSH keys are setup'
61 }],
62 'Miscellaneous:': [{
63 key: '-v, --version',
64 description: 'Output the version number'
65 },
66 {
67 key: '-h, --help',
68 description: 'Show help'
69 }
70 ]
71 }
72 }
73 meta.generateHelp(params)
74 }
75
76 const askQuestion = async (name, templatePath) => {
77 debug(`Render from local path ${templatePath}`)
78 const meta = getOptions(name, templatePath)
79 let propmts = []
80 let keys = Object.keys(meta.prompts)
81 keys.forEach(key => {
82 let prompt = meta.prompts[key]
83 promptDefault = typeof prompt.default !== 'undefined' ? prompt.default : ''
84 propmts.push({
85 type: promptMapping[prompt.type] || prompt.type,
86 name: key,
87 message: prompt.message || prompt.label || key,
88 default: promptDefault,
89 choices: prompt.choices || [],
90 validate: prompt.validate || (() => true)
91 })
92 })
93 let answer = await inquirer.prompt(propmts)
94 // assign metadata to answer
95 return Object.assign(meta, answer)
96 }
97
98 if (options.version || options.v) { // version from package.json
99
100 logger.info(`${require("../package.json").version}`);
101
102 } else if (options.help || options.h) {
103 await showHelp()
104 } else {
105 let templateName = globalConfig.defaultWeexTemplate || 'webpack'
106 let projectName
107 if (!first) {
108 logger.warn('You need to provide all the required parameters.')
109 logger.error('Project name cannot be empty.')
110 await showHelp()
111 return
112 }
113 if (first && second) {
114 templateName = first
115 projectName = second
116 } else if (first) {
117 projectName = first
118 }
119 let target = path.resolve(projectName);
120 if (exists(target)) {
121 let res = await inquirer.prompt([{
122 type: 'confirm',
123 message: 'Target directory exists. Continue?',
124 name: 'yes'
125 }])
126 if (res.yes) {
127 let spinner = logger.spin(`Remove ${target} ...`);
128 await fse.remove(target);
129 spinner.stop();
130 } else {
131 return
132 }
133 }
134 if (localpath.isLocalPath(templateName)) {
135 const templatePath = localpath.getTemplatePath(templateName);
136 if (exists(templatePath)) {
137 let answer = await askQuestion(projectName, templatePath)
138 let metadata = Object.assign(answer, {
139 destDirName: projectName,
140 inPlace: target === process.cwd(),
141 noEscape: true
142 })
143 await generator(templatePath, target, metadata)
144 } else {
145 logger.error(`Local template "${templatePath}" not found.`);
146 }
147 } else {
148 const hasHash = /\//.test(templateName)
149 if (!hasHash) {
150 // fetch from official repo
151 templateName = `${globalConfig.defaultWeexTemplateRepo || 'weex-templates'}/${templateName}`
152 }
153 const templatesTarget = path.join(globalConfig.templatePath, templateName)
154 let spinner = logger.spin(`Download from ${templateName} repo ...`);
155 const templatePath = await clone(templateName, templatesTarget, {
156 cache: exists(templatesTarget) && (typeof options.cache === 'boolean' ? options.cache : true),
157 clone: options.clone || false
158 })
159 spinner.stop();
160 let answer = await askQuestion(projectName, templatePath)
161 let metadata = Object.assign(answer, {
162 destDirName: projectName,
163 inPlace: target === process.cwd(),
164 noEscape: true
165 })
166 await generator(templatePath, target, metadata)
167
168 }
169
170 }
171 }
172}
\No newline at end of file