UNPKG

5.39 kBJavaScriptView Raw
1#!/usr/bin/env node
2const os = require('os')
3const path = require('path')
4const chalk = require('chalk')
5const address = require('address')
6const program = require('commander')
7const Sentry = require('@sentry/node')
8const logSymbols = require('log-symbols')
9const didYouMean = require('didyoumean')
10const updateNotifier = require('update-notifier')
11
12const pkg = require('../package.json')
13const store = require('../lib/utils/store')
14const { ALL_COMMANDS } = require('../lib/constant')
15const { getProxy } = require('../lib/utils/tools/proxy')
16
17let processArgv = process.argv
18const isBeta = pkg.version.indexOf('-') > -1
19process.CLI_VERSION = pkg.version
20
21const [major, minor] = process.versions.node.split('.').slice(0, 2)
22
23// Node 版本检验提示
24if (Number(major) < 8 || (Number(major) === 8 && Number(minor) < 6)) {
25 console.log(
26 chalk.bold.red(
27 '您的 Node 版本较低,CloudBase CLI 可能无法正常运行,请升级 Node 到 v8.6.0 以上!\n'
28 )
29 )
30}
31
32// Sentry 错误上报
33Sentry.init({
34 release: pkg.version,
35 dsn: 'https://fff0077d06624655ad70d1ee25df419e@report.url.cn/sentry/1782',
36 httpsProxy: getProxy() || '',
37 serverName: os.hostname(),
38 // 忽略错误,正则匹配,
39 // ignoreErrors: [],
40 integrations: [
41 new Sentry.Integrations.OnUnhandledRejection({
42 mode: 'none'
43 })
44 ]
45})
46
47// 检查更新
48const ONE_DAY = 86400000
49// Beta 版 1 个小时检查一次,稳定版 1 天检查一次
50const CheckInterval = isBeta ? 3600000 : ONE_DAY
51
52const notifier = updateNotifier({
53 pkg,
54 distTag: isBeta ? 'beta' : 'latest',
55 // 检查更新间隔 1 天
56 updateCheckInterval: CheckInterval
57})
58
59notifier.notify({
60 isGlobal: true
61})
62
63// 测试模式
64if (processArgv.includes('-debug')) {
65 console.log(
66 chalk.bold.yellow('====\n您已经进入 debug 模式!\n移除 -debug 选项退出 debug 模式!\n====')
67 )
68}
69
70if (processArgv.includes('--tcb-test')) {
71 console.log(
72 chalk.bold.yellow(
73 '====\n您已经进入 test 模式!\n移除 --tcb-test 选项退出 test 模式!\n===='
74 )
75 )
76 try {
77 const envs = require(path.join(process.cwd(), './tcb-test.js'))
78 for (const key in envs) {
79 process.env[key] = envs[key]
80 }
81 } catch (err) {
82 console.log(err)
83 }
84}
85
86// debug 模式
87process.IS_DEBUG = processArgv.includes('-debug')
88if (processArgv.includes('completion')) {
89 return handleCompletion()
90}
91
92// 需要隐藏的选项
93const hideArgs = ['-debug', '--tcb-test', '--completion']
94hideArgs.forEach((arg) => {
95 const index = processArgv.indexOf(arg)
96 if (index > -1) {
97 processArgv.splice(index, 1)
98 }
99})
100
101// 注册命令
102require('../lib')
103
104// console.log(Object.keys(program._events))
105
106// 设置 Sentry 上报的用户 uin
107Sentry.configureScope((scope) => {
108 try {
109 const credential = store.authStore.get('credential') || {}
110 scope.setUser({
111 uin: credential.uin || '',
112 ip: address.ip() || ''
113 })
114 } catch (e) {
115 Sentry.captureException(e)
116 }
117})
118
119// 设置 options 选项
120program.option('--config-file <path>', '设置配置文件,默认为 ./cloudbaserc.js 或 .cloudbaserc.json')
121
122program.version(pkg.version, '-v, --version', '输出当前 CloudBase CLI 版本')
123
124// 处理无效命令
125program.action((cmd) => {
126 console.log(chalk.bold.red('Error: ') + `${cmd} 不是有效的命令!`)
127 didYouMean.threshold = 0.5
128 didYouMean.caseSensitive = false
129 const suggest = didYouMean(cmd, ALL_COMMANDS)
130 if (suggest) {
131 console.log(chalk.bold(`\n您是不是想使用命令:cloudbase ${suggest}\n`))
132 }
133 console.log(`使用 ${chalk.bold('cloudbase -h')} 查看所有命令~`)
134})
135
136// 修改 help 提示信息
137program._helpDescription = '输出帮助信息'
138program.on('--help', function () {
139 const tips = `\nTips:
140
141${chalk.gray('–')} 简写
142
143 ${chalk.cyan('使用 tcb 替代 cloudbase')}
144
145${chalk.gray('–')} 登录
146
147 ${chalk.cyan('$ cloudbase login')}
148
149${chalk.gray('–')} 初始化云开发项目
150
151 ${chalk.cyan('$ cloudbase init')}
152
153${chalk.gray('–')} 部署云函数
154
155 ${chalk.cyan('$ cloudbase functions:deploy')}
156
157${chalk.gray('–')} 查看命令使用介绍
158
159 ${chalk.cyan('$ cloudbase env:list -h')}`
160 console.log(tips)
161})
162
163// 当没有输入任何命令时,显示帮助信息
164if (process.argv.length < 3) {
165 program.outputHelp()
166}
167
168try {
169 program.parse(processArgv)
170} catch (e) {
171 const errMsg = `${logSymbols.error} ${e.message || '参数异常,请检查您是否使用了正确的命令!'}`
172 console.log(errMsg)
173}
174
175function errorHandler(err) {
176 process.emit('tcbError')
177 const stackIngoreErrors = ['TencentCloudSDKHttpException', 'CloudBaseError']
178 // 忽略自定义错误的错误栈
179 if (err && err.stack && !stackIngoreErrors.includes(err.name)) {
180 console.log(err.stack)
181 }
182
183 // 3 空格,兼容中文字符编码长度问题
184 if (err && err.message) {
185 let errMsg = logSymbols.error + ' ' + err.message
186 errMsg += err.requestId ? `\n${err.requestId}` : ''
187 console.log(errMsg)
188 }
189 process.emit('tcbExit')
190 setTimeout(() => {
191 process.exit(1)
192 }, 1000)
193}
194
195process.on('uncaughtException', errorHandler)
196process.on('unhandledRejection', errorHandler)