-
Notifications
You must be signed in to change notification settings - Fork 1
/
cli.js
132 lines (115 loc) · 4.29 KB
/
cli.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env node
require('dotenv').config()
const OSS = require('ali-oss')
const glob = require('glob')
const ora = require('ora')
const normalize = require('normalize-path')
const relative = require('relative')
if (process.env.OSS_ACCESS_KEY_ID == null) {
ora().fail('[upload-oss] No .env file found, uploading canceled!\nSee: https://www.npmjs.com/package/@jarvisniu/upload-oss#usage')
process.exit()
}
const client = new OSS({
accessKeyId: process.env.OSS_ACCESS_KEY_ID,
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
region: process.env.OSS_REGION,
bucket: process.env.OSS_BUCKET,
})
const args = require('minimist')(process.argv.slice(2))
const OUTPUT_DIR = args['output-dir'] || process.env['output-dir'] || 'dist'
const OSS_BASE_DIR = args['oss-base-dir'] || '/'
const CLEAN = args.clean || false
// Stop if unknown args were provided
const allowedArgs = ['_', 'output-dir', 'oss-base-dir', 'clean']
Object.keys(args).forEach(arg => {
if (!allowedArgs.includes(arg)) {
ora().fail(`[upload-oss] Unknown arg "${arg}" provided, program stopped!`)
process.exit()
}
})
// '[====>-------] [ 2/18] Message'
function progressMsg (index, count, msg) {
const BAR_LEN = 10
const num = String(index)
const len = String(count).length
const doneLen = Math.floor((index / count) * BAR_LEN)
const restLen = BAR_LEN - doneLen
const barMsg = '='.repeat(doneLen) + '>' + '-'.repeat(restLen)
const numMsg = num.padStart(len) + '/' + count
return `[${ barMsg }] [${ numMsg }] ${ msg }`
}
function listLocalFiles () {
return new Promise(function (resolve, reject) {
glob(normalize(OUTPUT_DIR + '/**/*'), { nodir: true }, async (err, files) => {
if (err) reject(err)
resolve(files.map(file => ({
localPath: file,
relativePath: relative.toBase(OUTPUT_DIR, file),
})))
})
})
}
async function main () {
let localFiles = await listLocalFiles()
// Sort 'index.html' to the last, then site will not crash during upload
localFiles.sort((a, b) => {
if (a.relativePath === 'index.html') return 1
else if (b.relativePath === 'index.html') return -1
})
if (localFiles.length === 0) {
ora().fail('[upload-oss] No local files found, uploading canceled!')
return
}
await uploadOss(localFiles)
if (CLEAN) await cleanOss(localFiles)
}
async function uploadOss (localFiles) {
console.log(`[upload-oss] Uploading files from local directory ${ OUTPUT_DIR }/ to target directory ${ OSS_BASE_DIR }/`)
const spinner = ora().start()
for (let i = 0, len = localFiles.length; i < len; i++) {
const file = localFiles[i]
try {
const ossPath = normalize(OSS_BASE_DIR + '/' + file.relativePath)
spinner.text = progressMsg(i, len, `Uploading ${ file.relativePath }`)
await client.put(ossPath, file.localPath)
} catch (err) {
spinner.fail(progressMsg(i, len, `Upload ${ file.relativePath } failed.`))
ora().fail(`[upload-oss] Error: ${err.message} Uploading canceled!`)
process.exit()
}
}
spinner.succeed(progressMsg(localFiles.length, localFiles.length, `Upload completed!`))
}
async function cleanOss (localFiles) {
if (/\/?^$/.test(OSS_BASE_DIR)) {
console.log(`[upload-oss] oss-base-dir not set, clean is canceled.`)
return
}
const relativeLocalPaths = localFiles.map(item => item.relativePath)
const listResp = await client.list({
'prefix': normalize(OSS_BASE_DIR) + '/',
'max-keys': 1000,
})
const ossFilePaths = listResp.objects.map(item => item.name)
// get redundant files
const redundantOssFilePaths = ossFilePaths.filter(ossFilePath => {
const relativeOssFilePath = relative.toBase(OSS_BASE_DIR, ossFilePath)
return !relativeLocalPaths.includes(relativeOssFilePath)
})
console.log([
`Local files count: ${ localFiles.length },`,
`OSS files count: ${ ossFilePaths.length },`,
`redundant files count: ${ redundantOssFilePaths.length }`,
`(${ Math.round(redundantOssFilePaths.length / ossFilePaths.length * 100) }%).`,
].join(' '))
if (redundantOssFilePaths.length === 0) {
console.log('There is no redundant files, skip cleaning.')
} else {
const spinner = ora().start(`Cleaning OSS path ${ OSS_BASE_DIR }/`)
await client.deleteMulti(redundantOssFilePaths)
spinner.succeed(`Cleaning OSS completed`)
}
}
if (require.main === module) {
main()
}