UNPKG

2.89 kBJavaScriptView Raw
1/**
2 * @file plugins 相关的方法
3 * @author tracy(qiushidev@gmail.com)
4 */
5
6const path = require('path')
7const fs = require('fs')
8const execa = require('execa')
9const chalk = require('chalk')
10
11// plugin name rules
12// common:mip-cli-plugin-xxx
13// under specific scope:@somescope/mip-cli-plugin-xxx
14const pluginREG = /^(mip-|@[\w-]+\/mip-)cli-plugin-/
15
16// mip2 & mip-cli-plugin-xxx install path
17const installedPath = path.join(__dirname, '../../..')
18// const installedPath = path.resolve(__dirname, '../../../../node_modules') // for dev mode only
19
20exports.resolvePluginName = name => {
21 if (pluginREG.test(name)) {
22 return name
23 }
24
25 return `mip-cli-plugin-${name}`
26}
27
28exports.installPackage = async (targetDir, command, packageName) => {
29 const args = ['install', '--loglevel', 'error']
30 args.push(packageName)
31 await exports.executeCommand(command, args, targetDir)
32}
33
34exports.isInstalled = pkg => {
35 const packageDir = path.join(installedPath, pkg)
36 return fs.existsSync(packageDir)
37}
38
39exports.executeCommand = (command, args, targetDir) => {
40 return new Promise((resolve, reject) => {
41 const child = execa(command, args, {
42 cwd: targetDir,
43 stdio: 'inherit'
44 })
45
46 child.on('close', code => {
47 if (code !== 0) {
48 reject(new Error(`command failed: ${command} ${args.join(' ')}`))
49 return
50 }
51 resolve()
52 })
53 })
54}
55
56exports.resolve = pkg => {
57 function fix (dir) {
58 let idx = dir.lastIndexOf(pkg)
59 if (idx === -1) {
60 throw new Error('Invalid package name')
61 }
62 dir = dir.substr(0, idx + pkg.length)
63
64 return dir
65 }
66
67 // handle: plugin package without index.js as main entry
68 try {
69 return fix(require.resolve(pkg))
70 } catch (e) {
71 return path.resolve(__dirname, '..', '..', '..', pkg)
72 }
73}
74
75exports.resolveCommand = pkg => {
76 // if args[0] is full package name, covert to executable main command
77 // `mip2 mip-cli-pulgin-test` => `mip2 test`
78 return pkg.replace(pluginREG, '')
79}
80
81exports.showPluginCmdHelpInfo = () => {
82 let pluginsPkgs = exports.getPluginPackages()
83
84 if (!pluginsPkgs.length) {
85 return
86 }
87
88 console.log()
89 console.log(' User Plugin Commands:')
90 console.log()
91
92 pluginsPkgs.forEach(pkg => {
93 let cmd
94 let description
95 try {
96 cmd = exports.resolveCommand(pkg)
97 const cmdModule = require(path.join(exports.resolve(pkg), 'cli', cmd))
98 description = cmdModule.cli.config.description
99 } catch (e) {}
100
101 if (cmd) {
102 // used for left-align commands list
103 const MAGIC = 15
104 console.log(` ${pad(cmd, MAGIC)}${chalk.green(description || '')}`)
105 }
106 })
107
108 console.log()
109}
110
111exports.getPluginPackages = () => {
112 let pkgs = fs.readdirSync(installedPath)
113 return pkgs.filter(item => pluginREG.test(item))
114}
115
116function pad (str, width) {
117 let len = Math.max(0, width - str.length)
118 return str + Array(len + 1).join(' ')
119}