Skip to content

Commit 061dcc6

Browse files
committed
workflow: improve sync script
allow individual confirmation for each breaking update
1 parent 094681f commit 061dcc6

File tree

1 file changed

+53
-11
lines changed

1 file changed

+53
-11
lines changed

scripts/syncDeps.js

+53-11
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const semver = require('semver')
99
const globby = require('globby')
1010
const { execSync } = require('child_process')
1111
const inquirer = require('inquirer')
12+
const readline = require('readline')
1213

1314
const externalVueScopedPackages = {
1415
'@vue/test-utils': true,
@@ -47,16 +48,38 @@ const checkUpdate = (pkg, filePath, local, remote) => {
4748
if (!isNewer) {
4849
return false
4950
}
50-
const isCompat = semver.intersects(`^${local}`, `^${remote}`)
51-
console.log(
52-
`${chalk.cyan(pkg)}: ${local} => ${remote} ` +
53-
(isCompat ? `` : chalk.red.bold(`maybe breaking `)) +
54-
chalk.gray(`(${path.relative(process.cwd(), filePath)})`)
55-
)
51+
const maybeBreaking = !semver.intersects(`^${local}`, `^${remote}`)
52+
console.log(genUpdateString(pkg, filePath, local, remote, maybeBreaking))
5653
return true
5754
}
5855
}
5956

57+
const checkUpdateAsync = async (pkg, filePath, local, remote) => {
58+
if (remote !== local) {
59+
const isNewer = semver.gt(remote, local)
60+
if (!isNewer) {
61+
return false
62+
}
63+
const maybeBreaking = !semver.intersects(`^${local}`, `^${remote}`)
64+
if (!maybeBreaking) {
65+
return true
66+
}
67+
const { shouldUpdate } = await inquirer.prompt([{
68+
name: 'shouldUpdate',
69+
type: 'confirm',
70+
message: genUpdateString(pkg, filePath, local, remote, maybeBreaking) + `\n` +
71+
`Update this dependency?`
72+
}])
73+
return shouldUpdate
74+
}
75+
}
76+
77+
function genUpdateString (pkg, filePath, local, remote, maybeBreaking) {
78+
return `${chalk.cyan(pkg)}: ${local} => ${remote} ` +
79+
(maybeBreaking ? chalk.red.bold(`maybe breaking `) : ``) +
80+
chalk.gray(`(${path.relative(process.cwd(), filePath)})`)
81+
}
82+
6083
const writeCache = {}
6184
const bufferWrite = (file, content) => {
6285
writeCache[file] = content
@@ -74,15 +97,15 @@ async function syncDeps ({ local, version, skipPrompt }) {
7497
if (!local) {
7598
console.log('Syncing remote deps...')
7699
const packages = await globby(['packages/@vue/*/package.json'])
77-
await Promise.all(packages.filter(filePath => {
100+
const resolvedPackages = (await Promise.all(packages.filter(filePath => {
78101
return filePath.match(/cli-service|cli-plugin|babel-preset|eslint-config/)
79102
}).concat('package.json').map(async (filePath) => {
80103
const pkg = require(path.resolve(__dirname, '../', filePath))
81104
if (!pkg.dependencies) {
82105
return
83106
}
84-
let isUpdated = false
85107
const deps = pkg.dependencies
108+
const resolvedDeps = []
86109
for (const dep in deps) {
87110
if (dep.match(/^@vue/) && !externalVueScopedPackages[dep]) {
88111
continue
@@ -92,17 +115,36 @@ async function syncDeps ({ local, version, skipPrompt }) {
92115
continue
93116
}
94117
local = local.replace(/^\^/, '')
118+
readline.clearLine(process.stdout)
119+
readline.cursorTo(process.stdout, 0)
120+
process.stdout.write(dep)
95121
const remote = await getRemoteVersion(dep)
96-
if (remote && checkUpdate(dep, filePath, local, remote)) {
97-
deps[dep] = `^${remote}`
122+
resolvedDeps.push({
123+
dep,
124+
local,
125+
remote
126+
})
127+
}
128+
return {
129+
pkg,
130+
filePath,
131+
resolvedDeps
132+
}
133+
}))).filter(_ => _)
134+
135+
for (const { pkg, filePath, resolvedDeps } of resolvedPackages) {
136+
let isUpdated = false
137+
for (const { dep, local, remote } of resolvedDeps) {
138+
if (remote && await checkUpdateAsync(dep, filePath, local, remote)) {
139+
pkg.dependencies[dep] = `^${remote}`
98140
updatedDeps.add(dep)
99141
isUpdated = true
100142
}
101143
}
102144
if (isUpdated) {
103145
bufferWrite(filePath, JSON.stringify(pkg, null, 2) + '\n')
104146
}
105-
}))
147+
}
106148
}
107149

108150
console.log('Syncing local deps...')

0 commit comments

Comments
 (0)