UNPKG

@conecli/cone-cli

Version:

松果编辑器命令行工具

250 lines (230 loc) 5.79 kB
const shell = require('shelljs') const ora = require('ora') const os = require('os') const path = require('path') const fs = require('fs-extra') const rm = require('rimraf').sync const spawn = require('child_process').spawn const logger = require('./logger') const chalk = require('chalk') const semver = require('semver') /** * 递归查找存在.cone文件的目录 * @returns 返回路径 */ exports.getWorkspacePath = () => { let currentPath = process.cwd() const findCone = (p) => { if ( shell.test('-f', `${p}${path.sep}.cone`) || '' === p || path.sep === p ) { return p } return findCone(p.substring(0, p.lastIndexOf(path.sep))) } return findCone(currentPath) } /** * 基于配置下载模板 * @param {*} name * @param {*} config * @param dest 下载模板存放位置 * @returns */ exports.downloadRepoByConfig = (name, config, dest) => { const gitUrl = config['url'] const gitBranch = config['branch'] return exports.downloadRepo(gitUrl, gitBranch, dest, name) } /** * clone一个git仓库 * @param {*} url * @param {*} branch * @param {*} dest */ exports.downloadGit = (url, branch, dest) => { return new Promise((resolve, reject) => { if (url && dest) { const cmd = `git clone -b ${branch} ${url} "${dest}"` const output = shell.exec(cmd, { silent: true }) const gitPath = path.resolve(dest, '.git') fs.removeSync(gitPath) if (output.code == 0) { resolve() } else { reject({ message: output.stderr }) } } else { reject({ message: `url or dest is empty` }) } }) } /** * 下载仓库 * @param url * @param branch * @param tmp * @param callback */ exports.downloadRepo = (url, branch, tmp, name = '') => { return new Promise((resolve, reject) => { const spinner = ora(`downloading template ${name}`) spinner.start() // Remove if local template exists if (fs.existsSync(tmp)) { rm(tmp) } exports .downloadGit(url, branch, tmp) .then(() => { spinner.stop() resolve(true) }) .catch((err2) => { spinner.stop() reject({ code: -1, message: 'Failed to download template ' + url + ': ' + err2.message.trim(), }) }) }) } exports.copySync = (dest, target) => { if (fs.existsSync(dest)) { fs.copySync(dest, target) } else { logger.fatal(`Could not locate supplied dir: ${chalk.green(dest)}`) } } /** * Spawns a child process and runs the specified command * By default, runs in the CWD and inherits stdio * Options are the same as node's child_process.spawn * @param {string} cmd * @param {array<string>} args * @param {object} options */ exports.runCommand = (cmd, args, options) => { return new Promise((resolve, reject) => { const spwan = spawn( cmd, args, Object.assign( { cwd: process.cwd(), stdio: 'inherit', shell: true, }, options ) ) spwan.on('exit', () => { resolve() }) }) } /** * Runs `npm install` in the project directory * @param {string} cwd Path of the created project directory * @param {object} data Data */ exports.installDependencies = (cwd, executable = 'npm', color) => { console.log(`\n\n# ${color('Installing project dependencies ...')}`) console.log('# -----------------------\n') return exports.runCommand(executable, ['install'], { cwd, }) } /** * Prints the final message with instructions of necessary next steps. * @param {Object} data Data from questionnaire. */ exports.printMessage = (data, { green, yellow, blue }) => { const message = ` # ${green('Project initialization finished!')} # ----------------------- To get started: ${yellow(`${data.inPlace ? '' : `cd ${data.destDirName}\n `}yarn start`)} ${blue('Create Project is Done!')} ` console.log(message) } exports.readFile = (path) => { let result = '' try { result = fs.readFileSync(path, 'utf8') } catch (err) {} return result } exports.writeFile = (path, txt) => { try { fs.writeFileSync(path, txt) } catch (err) { console.log(err) } } /** * 初始化git仓库并初始化提交 * @param {*} commitMsg */ exports.initGit = (commitMsg = 'InitCommit') => { console.log(`Initializing git repository...`) const output = shell.exec('git init -b master') if (output.code != 0) { console.log(output.stderr) } else { if (shell.exec('git add .', { silent: true }).code == 0) { shell.exec(`git commit -m '${commitMsg}'`, { silent: true }) } } } function extractVersion(str) { if (!str) { return null } const versionPattern = /v\d+\.\d+\.\d+/ const match = str.match(versionPattern) return match ? match[0] : null } function checkNeedInstallCaddy() { console.log('正在检查Caddy安装情况') const output = shell.exec('caddy version', { silent: true }) if (output.code == 0) { const version = extractVersion(output.stdout) if (version && semver.gte(version, '2.0.0')) { console.log('当前Caddy版本为:', version) return false } } else { console.log(output.stderr) } return true } exports.initCaddy = () => { // 只在Mac系统上安装Caddy if (os.platform() !== 'darwin') { return } if (checkNeedInstallCaddy()) { console.log( 'Caddy未安装或者版本不满足要求,正在安装Caddy,执行命令为:brew install caddy' ) const output = shell.exec('brew install caddy', { silent: true }) if (output.code !== 0) { console.log(output.stderr) } if (checkNeedInstallCaddy()) { logger.fatal( `安装Caddy失败,请手动安装:\n安装前建议先执行:brew update 更新brew;然后再执行:brew install caddy 安装caddy,如果是M2芯片的Mac电脑并且执行 brew install caddy 安装失败可以尝试执行:arch -arm64 brew install caddy 安装` ) } else { logger.success(`安装Caddy成功`) } } }