@struggler/cli 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/command/deploy.js +16 -2
- package/command/init.js +10 -7
- package/command/refresh.js +15 -5
- package/command/upload.js +7 -3
- package/index.js +9 -2
- package/lib/deploy.js +32 -18
- package/lib/i18n.js +68 -0
- package/package.json +1 -1
package/command/deploy.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
const init = require('./init');
|
|
2
2
|
const upload = require('./upload');
|
|
3
3
|
const refresh = require('./refresh');
|
|
4
|
+
const chalk = require('chalk');
|
|
4
5
|
const { collectDeployFiles, createSummary, finalizeOutput } = require('../lib/deploy');
|
|
5
6
|
const { getDir } = require('../lib/config');
|
|
6
7
|
const { createIgnoreMatcher } = require('../lib/ignore');
|
|
7
8
|
const { printMessage } = require('../lib/output');
|
|
9
|
+
const { getLocale } = require('../lib/i18n');
|
|
8
10
|
|
|
9
11
|
async function main(options) {
|
|
10
12
|
const startedAt = Date.now();
|
|
@@ -47,7 +49,8 @@ async function main(options) {
|
|
|
47
49
|
suppressOutput: true,
|
|
48
50
|
});
|
|
49
51
|
} else {
|
|
50
|
-
|
|
52
|
+
const { messages } = getLocale(options && options.lang);
|
|
53
|
+
printMessage(options, ` ${chalk.dim(`↩ ${messages.deploySkipRefresh}`)}`);
|
|
51
54
|
}
|
|
52
55
|
|
|
53
56
|
const deploySummary = finalizeOutput(createSummary('deploy', Boolean(options.dryRun), [
|
|
@@ -68,7 +71,18 @@ async function main(options) {
|
|
|
68
71
|
excludedPatterns: ignoreMatcher.patterns,
|
|
69
72
|
}), options, manifestExtra);
|
|
70
73
|
|
|
71
|
-
|
|
74
|
+
const { messages } = getLocale(options && options.lang);
|
|
75
|
+
const uploadOk = uploadSummary.failedCount === 0;
|
|
76
|
+
const refreshOk = options.skipRefresh || refreshSummary.failedCount === 0;
|
|
77
|
+
const allOk = uploadOk && refreshOk;
|
|
78
|
+
printMessage(options, '');
|
|
79
|
+
printMessage(options, ` ${allOk ? chalk.green('✓') : chalk.red('✗')} ${chalk.bold(messages.deployDone)}`);
|
|
80
|
+
printMessage(options, '');
|
|
81
|
+
printMessage(options, ` ${chalk.dim(messages.deployUploadLabel)} ${chalk.green(uploadSummary.succeededCount)} / ${uploadSummary.total} ${messages.deployFileUnit}`);
|
|
82
|
+
if (!options.skipRefresh) {
|
|
83
|
+
printMessage(options, ` ${chalk.dim(messages.deployRefreshLabel)} ${chalk.green(refreshSummary.succeededCount)} / ${refreshSummary.total} ${messages.deployUnit}`);
|
|
84
|
+
}
|
|
85
|
+
printMessage(options, '');
|
|
72
86
|
return deploySummary;
|
|
73
87
|
}
|
|
74
88
|
|
package/command/init.js
CHANGED
|
@@ -4,21 +4,23 @@ let { getJsonData, setJsonData, setSyncJsonData, directoryExists } = require('..
|
|
|
4
4
|
let path = require('path')
|
|
5
5
|
const { formatDate } = require('../lib/date');
|
|
6
6
|
const { printMessage } = require('../lib/output');
|
|
7
|
+
const { getLocale } = require('../lib/i18n');
|
|
7
8
|
|
|
8
9
|
function init(qiniuConfigPath, options){
|
|
10
|
+
const { messages } = getLocale(options && options.lang);
|
|
9
11
|
if (!directoryExists(qiniuConfigPath)){
|
|
10
|
-
printMessage(options, chalk.
|
|
11
|
-
printMessage(options, chalk.
|
|
12
|
+
printMessage(options, chalk.yellow(` ⚠ ${messages.initTemplateCreated}`));
|
|
13
|
+
printMessage(options, ` ${chalk.dim(qiniuConfigPath)}`);
|
|
12
14
|
if (options.dryRun) {
|
|
13
|
-
printMessage(options,
|
|
15
|
+
printMessage(options, chalk.dim(messages.initDryRunCreate(qiniuConfigPath)));
|
|
14
16
|
return
|
|
15
17
|
}
|
|
16
18
|
setSyncJsonData(qiniuConfigPath, getJsonData(path.resolve(__dirname, '../def/qiniu.json')))
|
|
17
19
|
}
|
|
18
|
-
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
function main(options){
|
|
23
|
+
const { messages } = getLocale(options && options.lang);
|
|
22
24
|
let configPath = getConfig(options)
|
|
23
25
|
let qiniuConfigPath = getQiniuConfig(options)
|
|
24
26
|
init(qiniuConfigPath, options)
|
|
@@ -29,11 +31,12 @@ function main(options){
|
|
|
29
31
|
config.publicPath = `${qiniuConfig.path || ''}/${versionPrefix}/`
|
|
30
32
|
config.base = `${domain || ''}${qiniuConfig.path || ''}/${versionPrefix}/`
|
|
31
33
|
if (options.dryRun) {
|
|
32
|
-
printMessage(options,
|
|
33
|
-
printMessage(options, JSON.stringify(config, null, 2))
|
|
34
|
+
printMessage(options, chalk.dim(messages.initDryRunWrite(configPath)));
|
|
35
|
+
printMessage(options, chalk.dim(JSON.stringify(config, null, 2)));
|
|
34
36
|
return config
|
|
35
37
|
}
|
|
36
|
-
printMessage(options,
|
|
38
|
+
printMessage(options, ` ${chalk.green('✓')} ${messages.initConfigUpdated}`);
|
|
39
|
+
printMessage(options, ` ${chalk.dim(configPath)}`);
|
|
37
40
|
setJsonData(configPath, config)
|
|
38
41
|
return config
|
|
39
42
|
}
|
package/command/refresh.js
CHANGED
|
@@ -14,6 +14,8 @@ const {
|
|
|
14
14
|
toRemoteKey,
|
|
15
15
|
} = require('../lib/deploy');
|
|
16
16
|
const { printMessage } = require('../lib/output');
|
|
17
|
+
const { createProgressBar } = require('../lib/progress');
|
|
18
|
+
const { getLocale } = require('../lib/i18n');
|
|
17
19
|
|
|
18
20
|
async function main(options, runtime = {}) {
|
|
19
21
|
const qiniuConfig = getJsonData(getQiniuConfig(options))
|
|
@@ -50,7 +52,8 @@ async function main(options, runtime = {}) {
|
|
|
50
52
|
|
|
51
53
|
ensureRequiredConfig(
|
|
52
54
|
{ ...qiniuConfig, 'publicPath(config.json)': prefix },
|
|
53
|
-
['accessKey', 'secretKey', 'domain', 'publicPath(config.json)']
|
|
55
|
+
['accessKey', 'secretKey', 'domain', 'publicPath(config.json)'],
|
|
56
|
+
options
|
|
54
57
|
);
|
|
55
58
|
|
|
56
59
|
var accessKey = qiniuConfig.accessKey
|
|
@@ -72,13 +75,16 @@ async function main(options, runtime = {}) {
|
|
|
72
75
|
});
|
|
73
76
|
}
|
|
74
77
|
|
|
78
|
+
const bar = createProgressBar(plans.length, {
|
|
79
|
+
json: options.json,
|
|
80
|
+
suppressOutput: runtime.suppressOutput,
|
|
81
|
+
});
|
|
82
|
+
|
|
75
83
|
const results = [];
|
|
76
84
|
for (const plan of plans) {
|
|
77
85
|
try {
|
|
78
86
|
await refresh(plan);
|
|
79
|
-
|
|
80
|
-
printMessage(options, `[refreshed] ${plan.target}`);
|
|
81
|
-
}
|
|
87
|
+
bar.tick({ filename: plan.target });
|
|
82
88
|
results.push({
|
|
83
89
|
ok: true,
|
|
84
90
|
localFile: plan.localFile,
|
|
@@ -86,6 +92,7 @@ async function main(options, runtime = {}) {
|
|
|
86
92
|
target: plan.target,
|
|
87
93
|
});
|
|
88
94
|
} catch (error) {
|
|
95
|
+
bar.tick({ filename: plan.target, failed: true });
|
|
89
96
|
results.push({
|
|
90
97
|
ok: false,
|
|
91
98
|
localFile: plan.localFile,
|
|
@@ -96,13 +103,16 @@ async function main(options, runtime = {}) {
|
|
|
96
103
|
}
|
|
97
104
|
}
|
|
98
105
|
|
|
106
|
+
bar.finish();
|
|
107
|
+
|
|
99
108
|
const summary = createSummary('refresh', false, results, startedAt, {
|
|
100
109
|
prefix,
|
|
101
110
|
excludedPatterns,
|
|
102
111
|
});
|
|
103
112
|
const finalSummary = runtime.suppressOutput ? summary : finalizeOutput(summary, options, runtime.manifestExtra);
|
|
104
113
|
if (finalSummary.failedCount > 0) {
|
|
105
|
-
|
|
114
|
+
const { messages } = getLocale(options && options.lang);
|
|
115
|
+
throw new Error(messages.refreshFailed(summary.failedCount));
|
|
106
116
|
}
|
|
107
117
|
|
|
108
118
|
return finalSummary;
|
package/command/upload.js
CHANGED
|
@@ -18,6 +18,7 @@ const {
|
|
|
18
18
|
const { printMessage } = require('../lib/output');
|
|
19
19
|
const { computeFileMd5, readCache, writeCache, isCacheHit, updateCacheEntry } = require('../lib/cache');
|
|
20
20
|
const { createProgressBar } = require('../lib/progress');
|
|
21
|
+
const { getLocale } = require('../lib/i18n');
|
|
21
22
|
|
|
22
23
|
async function main(options, runtime = {}) {
|
|
23
24
|
const qiniuConfig = getJsonData(getQiniuConfig(options))
|
|
@@ -75,7 +76,8 @@ async function main(options, runtime = {}) {
|
|
|
75
76
|
|
|
76
77
|
ensureRequiredConfig(
|
|
77
78
|
{ ...qiniuConfig, 'publicPath(config.json)': prefix },
|
|
78
|
-
['accessKey', 'secretKey', 'Bucket', 'zone', 'domain', 'publicPath(config.json)']
|
|
79
|
+
['accessKey', 'secretKey', 'Bucket', 'zone', 'domain', 'publicPath(config.json)'],
|
|
80
|
+
options
|
|
79
81
|
);
|
|
80
82
|
|
|
81
83
|
var accessKey = qiniuConfig.accessKey
|
|
@@ -100,7 +102,8 @@ async function main(options, runtime = {}) {
|
|
|
100
102
|
formUploader.putFile(uploadToken, plan.key, plan.localFile, putExtra, async function (respErr, respBody, respInfo) {
|
|
101
103
|
if (respErr || respInfo.statusCode !== 200) {
|
|
102
104
|
if (attempt < 3) {
|
|
103
|
-
|
|
105
|
+
const { messages } = getLocale(options && options.lang);
|
|
106
|
+
printMessage(options, messages.uploadRetrying(plan.localFile, attempt + 1));
|
|
104
107
|
try {
|
|
105
108
|
const retryResult = await upload(plan, attempt + 1);
|
|
106
109
|
resolve(retryResult);
|
|
@@ -184,7 +187,8 @@ async function main(options, runtime = {}) {
|
|
|
184
187
|
});
|
|
185
188
|
const finalSummary = runtime.suppressOutput ? summary : finalizeOutput(summary, options, runtime.manifestExtra);
|
|
186
189
|
if (finalSummary.failedCount > 0) {
|
|
187
|
-
|
|
190
|
+
const { messages } = getLocale(options && options.lang);
|
|
191
|
+
throw new Error(messages.uploadFailed(summary.failedCount));
|
|
188
192
|
}
|
|
189
193
|
|
|
190
194
|
return finalSummary;
|
package/index.js
CHANGED
|
@@ -19,7 +19,7 @@ if (!shouldUseJson({ json: isJsonMode })) {
|
|
|
19
19
|
|
|
20
20
|
// 输出Logo
|
|
21
21
|
if (!isJsonMode) {
|
|
22
|
-
console.log(magentaBright(figlet.textSync("struggler-cli", {
|
|
22
|
+
console.log(magentaBright(figlet.textSync("struggler-cli", { font: "Small" })), "\n")
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
function formatItems(items, getLeft, getRight) {
|
|
@@ -97,6 +97,13 @@ program.parseAsync().catch(error => {
|
|
|
97
97
|
printJson({ ok: false, error: error.message || String(error) })
|
|
98
98
|
return
|
|
99
99
|
}
|
|
100
|
-
|
|
100
|
+
const { redBright, dim } = require('chalk')
|
|
101
|
+
const { messages } = getLocale(lang)
|
|
102
|
+
const msg = error.message || String(error)
|
|
103
|
+
console.error('')
|
|
104
|
+
console.error(redBright(` ✗ ${messages.errorTitle}`))
|
|
105
|
+
console.error('')
|
|
106
|
+
msg.split('\n').forEach(line => console.error(` ${dim(line)}`))
|
|
107
|
+
console.error('')
|
|
101
108
|
process.exitCode = 1
|
|
102
109
|
})
|
package/lib/deploy.js
CHANGED
|
@@ -3,6 +3,7 @@ const chalk = require('chalk');
|
|
|
3
3
|
const { listFiles } = require('./files');
|
|
4
4
|
const { createIgnoreMatcher } = require('./ignore');
|
|
5
5
|
const { printMessage, writeManifest, shouldUseJson, printJson } = require('./output');
|
|
6
|
+
const { getLocale } = require('./i18n');
|
|
6
7
|
|
|
7
8
|
const DEFAULT_CONCURRENCY = 5;
|
|
8
9
|
|
|
@@ -65,9 +66,10 @@ function createSummary(action, dryRun, results, startedAt, extra = {}) {
|
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
function logPlan(action, items, options) {
|
|
68
|
-
|
|
69
|
+
const { messages } = getLocale(options && options.lang);
|
|
70
|
+
printMessage(options, messages.dryRunPlan(action, items.length));
|
|
69
71
|
items.forEach((item) => {
|
|
70
|
-
printMessage(options,
|
|
72
|
+
printMessage(options, ` ${item.localFile} -> ${item.target}`);
|
|
71
73
|
});
|
|
72
74
|
}
|
|
73
75
|
|
|
@@ -77,40 +79,44 @@ function formatDuration(ms) {
|
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
function logSummary(summary, options) {
|
|
82
|
+
const { messages } = getLocale(options && options.lang);
|
|
80
83
|
const allOk = summary.failedCount === 0;
|
|
81
84
|
const isDryRun = summary.dryRun;
|
|
82
85
|
const skipped = summary.skippedCount || 0;
|
|
83
86
|
const uploaded = summary.succeededCount - skipped;
|
|
84
87
|
|
|
85
88
|
const statusIcon = allOk ? chalk.green('✓') : chalk.red('✗');
|
|
86
|
-
const
|
|
87
|
-
|
|
89
|
+
const actionDoneLabel = summary.action === 'upload'
|
|
90
|
+
? messages.uploadDone
|
|
91
|
+
: summary.action === 'refresh'
|
|
92
|
+
? messages.refreshDone
|
|
93
|
+
: messages.deployDone;
|
|
94
|
+
const modeTag = isDryRun ? chalk.yellow(` [${messages.dryRunLabel}]`) : '';
|
|
88
95
|
|
|
89
96
|
printMessage(options, '');
|
|
90
|
-
printMessage(options, ` ${statusIcon} ${chalk.bold(
|
|
97
|
+
printMessage(options, ` ${statusIcon} ${chalk.bold(actionDoneLabel)}${modeTag} ${chalk.dim(formatDuration(summary.durationMs))}`);
|
|
91
98
|
printMessage(options, '');
|
|
92
99
|
|
|
93
100
|
const rows = [];
|
|
94
101
|
if (summary.action === 'upload') {
|
|
95
|
-
rows.push([chalk.dim(
|
|
102
|
+
rows.push([chalk.dim(messages.uploadLabel), chalk.green(`${uploaded} ${messages.uploadFileUnit}`)]);
|
|
96
103
|
if (skipped > 0) {
|
|
97
|
-
rows.push([chalk.dim(
|
|
104
|
+
rows.push([chalk.dim(messages.uploadSkippedLabel), chalk.cyan(`${skipped} ${messages.uploadFileUnit}`) + chalk.dim(` (${messages.uploadCacheHint})`)]);
|
|
98
105
|
}
|
|
99
106
|
if (summary.failedCount > 0) {
|
|
100
|
-
rows.push([chalk.dim(
|
|
107
|
+
rows.push([chalk.dim(messages.uploadFailedLabel), chalk.red(`${summary.failedCount} ${messages.uploadFileUnit}`)]);
|
|
101
108
|
}
|
|
102
|
-
rows.push([chalk.dim(
|
|
109
|
+
rows.push([chalk.dim(messages.uploadTotalLabel), chalk.white(`${summary.total} ${messages.uploadFileUnit}`)]);
|
|
103
110
|
} else {
|
|
104
|
-
rows.push([chalk.dim(
|
|
111
|
+
rows.push([chalk.dim(messages.refreshSucceededLabel), chalk.green(`${summary.succeededCount} ${messages.refreshUnit}`)]);
|
|
105
112
|
if (summary.failedCount > 0) {
|
|
106
|
-
rows.push([chalk.dim(
|
|
113
|
+
rows.push([chalk.dim(messages.refreshFailedLabel), chalk.red(`${summary.failedCount} ${messages.refreshUnit}`)]);
|
|
107
114
|
}
|
|
108
|
-
rows.push([chalk.dim(
|
|
115
|
+
rows.push([chalk.dim(messages.refreshTotalLabel), chalk.white(`${summary.total} ${messages.refreshUnit}`)]);
|
|
109
116
|
}
|
|
110
117
|
|
|
111
|
-
const labelWidth = 4;
|
|
112
118
|
rows.forEach(([label, value]) => {
|
|
113
|
-
printMessage(options, ` ${label
|
|
119
|
+
printMessage(options, ` ${label} ${value}`);
|
|
114
120
|
});
|
|
115
121
|
printMessage(options, '');
|
|
116
122
|
|
|
@@ -124,7 +130,7 @@ function logSummary(summary, options) {
|
|
|
124
130
|
|
|
125
131
|
const uploadedItems = (summary.succeeded || []).filter((item) => !item.skipped && item.target);
|
|
126
132
|
if (uploadedItems.length > 0) {
|
|
127
|
-
printMessage(options, ` ${chalk.dim(
|
|
133
|
+
printMessage(options, ` ${chalk.dim(`─── ${messages.uploadLinksTitle} ───`)}`);
|
|
128
134
|
printMessage(options, '');
|
|
129
135
|
uploadedItems.forEach((item) => {
|
|
130
136
|
printMessage(options, ` ${chalk.cyan(item.target)}`);
|
|
@@ -156,17 +162,25 @@ function finalizeOutput(summary, options, extra = {}) {
|
|
|
156
162
|
} else {
|
|
157
163
|
logSummary(finalSummary, options);
|
|
158
164
|
if (finalSummary.manifestPath) {
|
|
159
|
-
|
|
165
|
+
const { messages } = getLocale(options && options.lang);
|
|
166
|
+
printMessage(options, ` ${chalk.dim(messages.manifestWritten)} ${finalSummary.manifestPath}`);
|
|
160
167
|
}
|
|
161
168
|
}
|
|
162
169
|
|
|
163
170
|
return finalSummary;
|
|
164
171
|
}
|
|
165
172
|
|
|
166
|
-
function ensureRequiredConfig(config, requiredFields) {
|
|
173
|
+
function ensureRequiredConfig(config, requiredFields, options) {
|
|
167
174
|
const missingFields = requiredFields.filter((field) => !config[field]);
|
|
168
175
|
if (missingFields.length > 0) {
|
|
169
|
-
|
|
176
|
+
const { messages } = getLocale(options && options.lang);
|
|
177
|
+
const lines = [
|
|
178
|
+
messages.errorMissingConfig,
|
|
179
|
+
...missingFields.map((f) => ` · ${f}`),
|
|
180
|
+
'',
|
|
181
|
+
messages.errorMissingConfigHint,
|
|
182
|
+
];
|
|
183
|
+
throw new Error(lines.join('\n'));
|
|
170
184
|
}
|
|
171
185
|
}
|
|
172
186
|
|
package/lib/i18n.js
CHANGED
|
@@ -1,6 +1,40 @@
|
|
|
1
1
|
const LANGUAGES = {
|
|
2
2
|
zh: {
|
|
3
3
|
appDescription: '用于将前端打包产物上传到七牛云 OSS 的命令行工具。',
|
|
4
|
+
messages: {
|
|
5
|
+
initTemplateCreated: '七牛配置不存在,已生成模版,请填写必要信息:',
|
|
6
|
+
initConfigUpdated: '配置已更新:',
|
|
7
|
+
initDryRunCreate: (p) => `[预览] 将创建配置模版:${p}`,
|
|
8
|
+
initDryRunWrite: (p) => `[预览] 将写入配置:${p}`,
|
|
9
|
+
uploadRetrying: (file, attempt) => `${file} 上传失败,正在进行第 ${attempt} 次重试`,
|
|
10
|
+
uploadDone: '上传完成',
|
|
11
|
+
uploadLabel: '上传',
|
|
12
|
+
uploadSkippedLabel: '跳过',
|
|
13
|
+
uploadFailedLabel: '失败',
|
|
14
|
+
uploadTotalLabel: '合计',
|
|
15
|
+
uploadCacheHint: '缓存命中,无变更',
|
|
16
|
+
uploadLinksTitle: '已上传文件链接',
|
|
17
|
+
uploadFileUnit: '个文件',
|
|
18
|
+
uploadFailed: (n) => `上传完成,${n} 个失败`,
|
|
19
|
+
refreshDone: '刷新完成',
|
|
20
|
+
refreshSucceededLabel: '成功',
|
|
21
|
+
refreshFailedLabel: '失败',
|
|
22
|
+
refreshTotalLabel: '合计',
|
|
23
|
+
refreshUnit: '个',
|
|
24
|
+
refreshFailed: (n) => `刷新完成,${n} 个失败`,
|
|
25
|
+
deployDone: '部署完成',
|
|
26
|
+
deploySkipRefresh: '刷新步骤已跳过 (--skip-refresh)',
|
|
27
|
+
deployUploadLabel: '上传',
|
|
28
|
+
deployRefreshLabel: '刷新',
|
|
29
|
+
deployFileUnit: '个文件',
|
|
30
|
+
deployUnit: '个',
|
|
31
|
+
errorTitle: '出错了',
|
|
32
|
+
errorMissingConfig: '配置不完整,以下字段缺失或为空:',
|
|
33
|
+
errorMissingConfigHint: '请检查 command/qiniu.json 和 command/config.json,或运行 struggler-cli init 初始化配置。',
|
|
34
|
+
dryRunLabel: '预览',
|
|
35
|
+
dryRunPlan: (action, n) => `[预览] ${action} 计划 (${n} 个文件)`,
|
|
36
|
+
manifestWritten: '清单已写入:',
|
|
37
|
+
},
|
|
4
38
|
options: {
|
|
5
39
|
version: '显示版本号。',
|
|
6
40
|
config: '指定上传配置文件路径。',
|
|
@@ -40,6 +74,40 @@ const LANGUAGES = {
|
|
|
40
74
|
},
|
|
41
75
|
en: {
|
|
42
76
|
appDescription: 'CLI to upload front-end build files to Qiniu Cloud OSS.',
|
|
77
|
+
messages: {
|
|
78
|
+
initTemplateCreated: 'Qiniu config not found, template created. Please fill in the required fields:',
|
|
79
|
+
initConfigUpdated: 'Config updated:',
|
|
80
|
+
initDryRunCreate: (p) => `[dry-run] would create template: ${p}`,
|
|
81
|
+
initDryRunWrite: (p) => `[dry-run] would write config: ${p}`,
|
|
82
|
+
uploadRetrying: (file, attempt) => `${file} upload failed, retrying (attempt ${attempt})`,
|
|
83
|
+
uploadDone: 'Upload complete',
|
|
84
|
+
uploadLabel: 'Uploaded',
|
|
85
|
+
uploadSkippedLabel: 'Skipped',
|
|
86
|
+
uploadFailedLabel: 'Failed',
|
|
87
|
+
uploadTotalLabel: 'Total',
|
|
88
|
+
uploadCacheHint: 'cached, no changes',
|
|
89
|
+
uploadLinksTitle: 'Uploaded file links',
|
|
90
|
+
uploadFileUnit: 'files',
|
|
91
|
+
uploadFailed: (n) => `Upload finished with ${n} failures`,
|
|
92
|
+
refreshDone: 'Refresh complete',
|
|
93
|
+
refreshSucceededLabel: 'Succeeded',
|
|
94
|
+
refreshFailedLabel: 'Failed',
|
|
95
|
+
refreshTotalLabel: 'Total',
|
|
96
|
+
refreshUnit: '',
|
|
97
|
+
refreshFailed: (n) => `Refresh finished with ${n} failures`,
|
|
98
|
+
deployDone: 'Deploy complete',
|
|
99
|
+
deploySkipRefresh: 'Refresh step skipped (--skip-refresh)',
|
|
100
|
+
deployUploadLabel: 'Upload',
|
|
101
|
+
deployRefreshLabel: 'Refresh',
|
|
102
|
+
deployFileUnit: 'files',
|
|
103
|
+
deployUnit: '',
|
|
104
|
+
errorTitle: 'Error',
|
|
105
|
+
errorMissingConfig: 'Incomplete config, the following fields are missing or empty:',
|
|
106
|
+
errorMissingConfigHint: 'Check command/qiniu.json and command/config.json, or run struggler-cli init.',
|
|
107
|
+
dryRunLabel: 'dry-run',
|
|
108
|
+
dryRunPlan: (action, n) => `[dry-run] ${action} plan (${n} files)`,
|
|
109
|
+
manifestWritten: 'Manifest written:',
|
|
110
|
+
},
|
|
43
111
|
options: {
|
|
44
112
|
version: 'Display the version number.',
|
|
45
113
|
config: 'Specify the path to the upload configuration file.',
|