UNPKG

6.47 kBJavaScriptView Raw
1'use strict'
2
3/**
4 * 文件说明:
5 * ----------------------------------------
6 * 创建用户: leo
7 * 创建日期 2019/5/21
8 */
9
10const shell = require('shelljs')
11const {join} = require('path')
12const spawn = require('cross-spawn')
13const signale = require('signale')
14const inquirer = require('inquirer')
15const constants = require('../config/constants')
16const {runForPkgs} = require('../config/build')
17const {findPkgs} = require('../config/utils')
18const getUserConfig = require('../config/get-user-config')
19
20function getUpdatedRepos(lernaPath, args = '') {
21 const ret = shell.exec(`${lernaPath} changed --include-merged-tags ${args}`, {silent: false})
22 .stdout
23
24 return ret
25 .split('\n')
26 .map((line) => line.replace('- ', ''))
27 .filter((line) => line !== '')
28}
29
30async function publish({cwd = process.cwd()}) {
31 // if (
32 // !shell
33 // .exec('npm config get registry', {silent: true})
34 // .stdout.includes('https://registry.npmjs.org/')
35 // ) {
36 // signale.error('Failed: set npm registry to https://registry.npmjs.org/ first')
37 // process.exit(1)
38 // }
39
40 const user = shell.exec('npm whoami --registry https://registry.npmjs.org/', {silent: true})
41 .stdout
42
43 if (user.trim() !== constants.username) {
44 signale.error(`
45 npm账号不对,请用公司账号登录
46 `)
47 process.exit(1)
48 }
49
50 const lernaPath = join(__dirname, '../node_modules/.bin/lerna')
51 const updatedRepos = getUpdatedRepos(lernaPath)
52 const rootUserConfig = getUserConfig({cwd})
53
54 const forceUpdatePkgs = []
55 const publishPkgNames = []
56
57 const pkgs = findPkgs({
58 cwd,
59 packagesPatterns: rootUserConfig.packagesPatterns,
60 ignoreNoBuild: false,
61 cb: (pkg) => {
62 const {pkgPath} = pkg
63 const {pkgJson} = pkg
64 const userConfig = getUserConfig({cwd: pkgPath})
65
66 if (pkgJson && !userConfig.noPublish) {
67 const update = updatedRepos.findIndex((repo) => repo === pkgJson.name) > -1
68
69 if (update) {
70 publishPkgNames.push(pkgJson.name)
71 } else {
72 forceUpdatePkgs.push({
73 name: pkgJson.name,
74 value: pkgJson.name,
75 version: pkgJson.version,
76 pkgPath,
77 pkgJson,
78 update,
79 })
80 }
81 }
82 pkg.name = pkg.pkgJson.name
83
84 return pkg
85 },
86 })
87
88 if (publishPkgNames.length) {
89 signale.info(`有改动的包: ${publishPkgNames.join(', ')}`)
90 } else {
91 signale.info(`没有改动的包`)
92 }
93
94 let forceUpdateNames = []
95
96 if (forceUpdatePkgs.length) {
97 const res = await inquirer.prompt([
98 {
99 name: 'isForceUpdate',
100 message: `是否需要强制更新包`,
101 default: false,
102 type: 'confirm',
103 },
104 {
105 name: 'forceUpdateNames',
106 message: `选择强制更新的包`,
107 type: 'checkbox',
108 choices: forceUpdatePkgs,
109 when: (answers) => answers.isForceUpdate,
110 },
111 ])
112
113 forceUpdateNames = res.forceUpdateNames || []
114 }
115
116 let publishRepos = []
117
118 if (forceUpdateNames.length) {
119 publishRepos = getUpdatedRepos(lernaPath, `--force-publish=${forceUpdateNames.join(',')}`)
120 } else {
121 publishRepos = getUpdatedRepos(lernaPath)
122 }
123
124 if (!publishRepos.length) {
125 signale.warn('没有要更新的包')
126 process.exit(1)
127 }
128 const publishPackages = []
129
130 pkgs.forEach((pkg) => {
131 const index = publishRepos.indexOf(pkg.name)
132 if (index > -1) {
133 publishPackages.push(pkg)
134 }
135 })
136
137 try {
138 await runForPkgs({
139 cwd,
140 watch: false,
141 pkgs: publishPackages,
142 rootUserConfig,
143 })
144 } catch (e) {
145 signale.error(e)
146 process.exit(1)
147 }
148
149 const {useConventionalCommits} = await inquirer.prompt({
150 message: '是否使用常规提交',
151 default: true,
152 type: 'confirm',
153 name: 'useConventionalCommits',
154 })
155
156 const versionArgs = ['publish', '--include-merged-tags']
157
158 if (useConventionalCommits) {
159 versionArgs.push('--conventional-commits')
160 }
161
162 if (publishRepos.length) {
163 versionArgs.push(`--force-publish=${publishRepos.join(',')}`)
164 }
165
166 signale.info(`要发布的包: ${publishRepos.join(', ')}`)
167 const cp = spawn(lernaPath, versionArgs, {
168 stdio: 'inherit',
169 cwd,
170 })
171 cp.on('error', (err) => {
172 signale.error(err)
173 })
174 cp.on('close', async (code) => {
175 signale.info('code', code)
176 if (code === 1) {
177 signale.error('Failed: lerna publish')
178 process.exit(1)
179 }
180
181 const {isSyncTaobao} = await inquirer.prompt({
182 message: '是否同步淘宝源',
183 default: true,
184 type: 'confirm',
185 name: 'isSyncTaobao',
186 })
187
188 if (isSyncTaobao) {
189 syncTaobao(publishRepos, cwd)
190 }
191 })
192}
193
194function syncTaobao(publishRepos = [], cwd = process.cwd()) {
195 if (!publishRepos.length) {
196 signale.error('not find publishRepos')
197 process.exit(1)
198 }
199
200 signale.info(`同步淘宝源: ${publishRepos.join(', ')}`)
201
202 const cnpmPath = join(__dirname, '../node_modules/.bin/cnpm')
203
204 const {status, error} = spawn.sync(cnpmPath, ['sync', ...publishRepos], {
205 stdio: 'inherit',
206 cwd,
207 })
208
209 if (status === 1) {
210 signale.error(error || 'sync error')
211 process.exit(1)
212 }
213
214 signale.success('同步成功')
215}
216
217// function publishToNpm(publishRepos) {
218// publishRepos.forEach((updatePkg) => {
219// shell.cd(updatePkg.pkgPath)
220// const {version} = updatePkg
221// if (version.includes('-rc.') || version.includes('-beta.') || version.includes('-alpha.')) {
222// signale.info(`[${updatePkg.value}] npm publish --tag next`)
223// shell.exec(`npm publish --tag next`)
224// } else {
225// signale.info(`[${updatePkg.value}] npm publish`)
226// shell.exec(`npm publish`)
227// }
228// })
229// }
230
231module.exports = publish