super-project-cli
Version:
CLI for creating project based on Super Project.
259 lines (240 loc) • 7.79 kB
JavaScript
// Initializing new super-project project
const fs = require('fs-extra')
const path = require('path')
const inquirer = require('inquirer')
// const ora = require('ora')
const npmEmail = require('npm-email')
const downloadNpmPackage = require('download-npm-package')
const clc = require('cli-color')
// const mv = require("mv")
const ncp = require('ncp')
const request = require('request')
const mergeJson = require('../lib/merge-json')
const getLocales = require('../lib/get-locales')
const spinner = require('../lib/spinner')
const {
templatePackageName
} = require('../lib/vars')
const run = async () => {
let waiting
const l = await getLocales()
const tmp = path.resolve(process.cwd(), `.SPTMP${(new Date()).valueOf()}`)
const urlFileIgnore = 'https://raw.githubusercontent.com/websage-team/sp-boilerplate/master/.gitignore'
console.log(``)
console.log(l.welcome)
console.log(``)
// ========================================================================
// 询问基础信息
const projectInfo = await inquirer.prompt({
type: 'input',
name: 'name',
message: l.project_name,
validate: (input) => {
if (input === 0 || input) return true
return l.project_name_required
}
})
// ========================================================================
// 检查目标目录是否存在
const dest = path.resolve(process.cwd(), projectInfo.name)
if (fs.existsSync(dest)) {
const overwrite = await inquirer.prompt({
type: 'list',
name: 'value',
message: l.confirm_remove_exist_dir,
choices: [
'remove',
'overwrite',
'abort'
].map(value => ({
name: l[`confirm_remove_exist_dir_${value}`],
value
}))
})
switch (overwrite.value) {
case 'remove': {
waiting = spinner(l.removing_exist_dir)
try {
await fs.remove(dest)
} catch (err) { }
waiting.finish()
console.log(``)
console.log(l.input_infos)
break
}
case 'abort': {
console.log(l.aborted)
return
}
}
}
// ========================================================================
// 询问其他基础信息
Object.assign(
projectInfo,
await inquirer.prompt([
{
type: 'input',
name: 'description',
message: l.project_description
},
{
type: 'input',
name: 'author.name',
message: l.project_author_name
}
])
)
// ========================================================================
// 按用户名查询NPM对应账户的email
let defaultEmail
if (projectInfo.author.name) {
waiting = spinner(l.please_wait)
try {
defaultEmail = await npmEmail(projectInfo.author.name.toLowerCase())
} catch (err) { }
waiting.stop()
}
Object.assign(
projectInfo.author,
await inquirer.prompt({
type: 'input',
name: 'email',
message: l.project_author_email,
default: defaultEmail
})
)
// console.log(projectInfo)
// ========================================================================
// [TODO] 选择模板
/* react
* *...*
*/
const spType = 'react'
projectInfo.superProject = {
type: spType
}
// ========================================================================
// 从 NPM 下载 sp-boilerplate
console.log(``)
waiting = spinner(l.downloading_template)
try {
await downloadNpmPackage({
arg: templatePackageName[spType],
dir: tmp
})
} catch (err) { }
// ========================================================================
// 复制下载内容
await new Promise((resolve, reject) => {
ncp(
path.resolve(tmp, templatePackageName[spType]),
path.resolve(dest),
{
clobber: true
},
function (err) {
if (err) return reject(err)
resolve()
}
)
})
// ========================================================================
// 删除临时目录
await fs.remove(tmp)
// ========================================================================
// 下载 .gitignore
const path_gitignore = path.resolve(dest, '.gitignore')
await fs.remove(path_gitignore)
await new Promise((resolve/*, reject*/) => {
request
.get(urlFileIgnore)
.on('response', function (response) {
resolve(response)
})
.pipe(
fs.createWriteStream(path_gitignore)
)
// request(
// urlFileIgnore,
// (error, response, body) => {
// if (error) {
// console.log(error)
// return resolve()
// }
// if (response.statusCode === 200) {
// console.log(body)
// }
// }
// )
})
waiting.finish()
// ========================================================================
// 将基础信息写入 package.json
/* 重置部分基础信息
* version -> 0.1.0
*/
const pathPackageJson = path.resolve(dest, 'package.json')
const infoString = await new Promise((resolve, reject) =>
fs.readFile(
pathPackageJson,
'utf-8',
(err, data) => {
if (err) return reject(err)
resolve(data)
}
)
)
await new Promise((resolve, reject) =>
fs.writeFile(
pathPackageJson,
mergeJson(infoString, {
...projectInfo,
version: "1.0.0"
}),
'utf-8',
(err, data) => {
if (err) return reject(err)
resolve(data)
}
)
)
// ========================================================================
// 列出命令
console.log(``)
console.log(l.init_complete_next_steps)
const colorCmd = msg => clc.cyan(msg);
[
[
l.step_install_pm2_globally,
`npm install -g pm2`,
`yarn global add pm2`
],
[
l.step_goto_dir,
`cd ${projectInfo.name}`
],
[
l.step_install_dependencies,
`npm install --no-save`,
`yarn`
],
[
l.step_run_dev,
`npm run dev`,
`yarn dev`
],
`${l.step_visit} http://localhost:3000`
].forEach((msg, index) => {
const prefix = `${clc.green(index + 1)}. `
if (Array.isArray(msg)) {
console.log(`${prefix}${msg[0]} [${msg.slice(1).map(cmd => colorCmd(cmd)).join(' || ')}]`)
} else {
console.log(`${prefix}${msg}`)
}
})
// ========================================================================
console.log(``)
}
run()