@dsh-workbench/module-tools 1.1.7 → 1.1.9
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/README.md +5 -2
- package/bin/dsh-wb-module.mjs +1 -0
- package/package.json +2 -2
- package/src/market-index.mjs +86 -92
- package/src/release-util.mjs +8 -0
- package/src/release.mjs +21 -2
package/README.md
CHANGED
|
@@ -30,8 +30,11 @@ pnpm design check # 设计底稿有没有空格、README 有没有落后
|
|
|
30
30
|
没带 note 又没记录时 `release` 在跑任何门禁之前就拦下。
|
|
31
31
|
日志写在确认之后,发失败不回滚:这一版已经记下了,下一次发布直接用。
|
|
32
32
|
`package.json` 缺 `files` 里的 `CHANGELOG.md` 一样拦下;`author` 没写时从本机 `git config` 补进 manifest,索引与产物都带上。
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
标签只住在市集条目上(`metadata.labels`),**不写进 `package.json`**:清单的键是协议定死的
|
|
34
|
+
(`apiVersion` / `unit` / `title` / `card` / `tools` / `host` / `needs`),往里塞私货 check 会判红。
|
|
35
|
+
发布时带 `--label <短词>`(可重复,最多两个):它并进索引条目的 `metadata.labels`;
|
|
36
|
+
不传就沿用老清单里已经写过的(`dsh.workbench.market.labels`,只在读那一侧认)。
|
|
37
|
+
标题 / 署名 / 说明仍保持索引里现有的那份不动。
|
|
35
38
|
要换署名时带 `--author "姓名 <邮箱>"`(或只给姓名):它写回 `package.json`,索引、产物与提交都用它,
|
|
36
39
|
`--refresh` 时也一样。**发布本身不改市集里的标题 / 署名 / 说明**:这些元数据只由 `--refresh`(或显式 `--author`)写,
|
|
37
40
|
避免一台还没更新的机器发新版时把别人刚改的元数据盖回去。一个包名归第一次发布的人(条目文件里的 `owner`):换署名发同名会被拒,
|
package/bin/dsh-wb-module.mjs
CHANGED
|
@@ -61,6 +61,7 @@ const RELEASE_HELP = `
|
|
|
61
61
|
--registry <url> --access restricted|public --npmrc <文件>
|
|
62
62
|
--license <id> --out <目录> --git <remote>
|
|
63
63
|
--author <署名> 换署名(姓名,或 姓名 <邮箱>);写回 package.json
|
|
64
|
+
--label <短词> 给市集条目打标签(1–2 个,可重复);写回 package.json
|
|
64
65
|
--changelog-note <文字> --changelog-type added|changed|fixed|removed|security|deprecated
|
|
65
66
|
这一版还没有更新日志时写进 CHANGELOG.md(文件不在先建)
|
|
66
67
|
--index auto|none|<目录|git 地址> 发布后要更新的索引源
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dsh-workbench/module-tools",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.9",
|
|
4
4
|
"description": "模块包的构建与门禁工具:build(单文件 ESM 宿主侧 + 套 loader 壳的浏览器侧)、check(契约/产物边界/源码边界/卡片渲染)。模块包不再各带一份构建脚本。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"semver": "^7.8.5",
|
|
34
34
|
"typescript": "5.9.3",
|
|
35
35
|
"typescript-eslint": "^8.71.0",
|
|
36
|
-
"@dsh-workbench/shared": "1.1.
|
|
36
|
+
"@dsh-workbench/shared": "1.1.9"
|
|
37
37
|
},
|
|
38
38
|
"repository": {
|
|
39
39
|
"type": "git",
|
package/src/market-index.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { cpSync, copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
1
|
+
import { cpSync, copyFileSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
2
|
import { dirname, join, resolve } from 'node:path';
|
|
4
3
|
import { isDeepStrictEqual } from 'node:util';
|
|
5
4
|
|
|
@@ -11,15 +10,12 @@ import {
|
|
|
11
10
|
collectMarketEntryFiles,
|
|
12
11
|
gitUrlOk,
|
|
13
12
|
marketArtifactPath,
|
|
14
|
-
marketArtifactPathFor,
|
|
15
13
|
marketArtifactRoot,
|
|
14
|
+
marketEntryFileOf,
|
|
16
15
|
marketEntryFilesOfLegacy,
|
|
17
|
-
marketEntryPath,
|
|
18
|
-
marketMetaDocOf,
|
|
19
|
-
marketMetaPath,
|
|
20
16
|
marketSourceKey,
|
|
21
|
-
marketVersionDocOf,
|
|
22
17
|
parseMarketIndexJson,
|
|
18
|
+
sortMarketVersions,
|
|
23
19
|
} from '@dsh-workbench/shared/host';
|
|
24
20
|
|
|
25
21
|
const MARKET_DIR = 'market';
|
|
@@ -182,48 +178,12 @@ function ensureVersionFree(workdir, dir, input) {
|
|
|
182
178
|
}
|
|
183
179
|
}
|
|
184
180
|
|
|
185
|
-
function writeEntryFile(workdir, dir, entry
|
|
186
|
-
const
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
if (isDeepStrictEqual(current, doc)) return rel;
|
|
192
|
-
throw new MarketIndexError(
|
|
193
|
-
`索引里已经有 ${entry.name}@${version.version}(${rel})—— 换个版本号再发`,
|
|
194
|
-
'market-owner',
|
|
195
|
-
);
|
|
196
|
-
}
|
|
197
|
-
mkdirSync(dirname(file), { recursive: true });
|
|
198
|
-
writeFileSync(file, `${JSON.stringify(doc, null, 2)}\n`);
|
|
199
|
-
return rel;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function metaEpochOf(workdir, dir, name) {
|
|
203
|
-
const root = join(workdir, dir, name);
|
|
204
|
-
if (!existsSync(root)) return 0;
|
|
205
|
-
let epoch = 0;
|
|
206
|
-
for (const item of readdirSync(root)) {
|
|
207
|
-
if (!item.startsWith('meta-') || !item.endsWith('.json')) continue;
|
|
208
|
-
try {
|
|
209
|
-
const doc = JSON.parse(readFileSync(join(root, item), 'utf8'));
|
|
210
|
-
if (typeof doc.epoch === 'number' && doc.epoch > epoch) epoch = doc.epoch;
|
|
211
|
-
} catch {
|
|
212
|
-
continue;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
return epoch;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
function writeMetaFile(workdir, dir, entry, at) {
|
|
219
|
-
const epoch = metaEpochOf(workdir, dir, entry.name) + 1;
|
|
220
|
-
const suffix = randomBytes(3).toString('hex');
|
|
221
|
-
const doc = marketMetaDocOf(entry, epoch, Math.floor(at / 1000));
|
|
222
|
-
const rel = marketMetaPath(dir, entry.name, epoch, suffix);
|
|
223
|
-
const file = join(workdir, ...rel.split('/'));
|
|
224
|
-
mkdirSync(dirname(file), { recursive: true });
|
|
225
|
-
writeFileSync(file, `${JSON.stringify(doc, null, 2)}\n`);
|
|
226
|
-
return rel;
|
|
181
|
+
function writeEntryFile(workdir, dir, entry) {
|
|
182
|
+
const file = marketEntryFileOf(entry, dir);
|
|
183
|
+
const target = join(workdir, ...file.path.split('/'));
|
|
184
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
185
|
+
writeFileSync(target, file.text);
|
|
186
|
+
return file.path;
|
|
227
187
|
}
|
|
228
188
|
|
|
229
189
|
function migrateLegacyIndex(workdir, dir) {
|
|
@@ -344,14 +304,30 @@ function textListOf(value) {
|
|
|
344
304
|
: [];
|
|
345
305
|
}
|
|
346
306
|
|
|
307
|
+
function recordOf(value) {
|
|
308
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export function labelsOfManifest(manifest) {
|
|
312
|
+
const dsh = recordOf(recordOf(manifest).dsh);
|
|
313
|
+
const workbench = recordOf(dsh.workbench);
|
|
314
|
+
return textListOf(recordOf(workbench.market).labels);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export function mergeEntryLabels(entry, labels) {
|
|
318
|
+
if (!Array.isArray(labels) || labels.length === 0) return entry;
|
|
319
|
+
const wanted = [...labels];
|
|
320
|
+
if (isDeepStrictEqual(entry.metadata?.labels ?? [], wanted)) return entry;
|
|
321
|
+
return { ...entry, metadata: { ...(entry.metadata ?? {}), labels: wanted } };
|
|
322
|
+
}
|
|
323
|
+
|
|
347
324
|
export function entryMetaOf(manifest) {
|
|
348
325
|
const author = authorOf(manifest);
|
|
349
326
|
const homepage = typeof manifest.homepage === 'string' ? manifest.homepage.trim() : '';
|
|
350
327
|
const keywords = textListOf(manifest.keywords);
|
|
351
|
-
const
|
|
352
|
-
const marketRecord = market !== null && typeof market === 'object' && !Array.isArray(market) ? market : {};
|
|
328
|
+
const marketRecord = recordOf(manifest.dsh?.workbench?.market);
|
|
353
329
|
const category = typeof marketRecord.category === 'string' ? marketRecord.category.trim() : '';
|
|
354
|
-
const labels =
|
|
330
|
+
const labels = labelsOfManifest(manifest);
|
|
355
331
|
const order = manifest.dsh?.workbench?.card?.order;
|
|
356
332
|
const unit = unitOf(manifest);
|
|
357
333
|
const title = titleOf(manifest);
|
|
@@ -373,21 +349,22 @@ export function entryMetaOf(manifest) {
|
|
|
373
349
|
}
|
|
374
350
|
|
|
375
351
|
export function indexEntryOf(input) {
|
|
376
|
-
const
|
|
377
|
-
const dsh = manifest.engines?.dsh;
|
|
378
|
-
const owner = authorTextOf(manifest);
|
|
352
|
+
const owner = authorTextOf(input.manifest);
|
|
379
353
|
return {
|
|
380
|
-
name: manifest.name,
|
|
354
|
+
name: input.manifest.name,
|
|
381
355
|
...(owner === '' ? {} : { owner }),
|
|
382
|
-
...entryMetaOf(manifest),
|
|
383
|
-
versions: [
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
356
|
+
...entryMetaOf(input.manifest),
|
|
357
|
+
versions: [versionRecordOf(input)],
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
export function versionRecordOf(input) {
|
|
362
|
+
const dsh = input.manifest.engines?.dsh;
|
|
363
|
+
return {
|
|
364
|
+
version: input.version,
|
|
365
|
+
publishTimestamp: Math.floor(input.at / 1000),
|
|
366
|
+
source: input.source,
|
|
367
|
+
...(typeof dsh === 'string' && dsh.trim() !== '' ? { engines: { dsh: dsh.trim() } } : {}),
|
|
391
368
|
};
|
|
392
369
|
}
|
|
393
370
|
|
|
@@ -590,11 +567,11 @@ function remoteHeadOf(exec, workdir, branch) {
|
|
|
590
567
|
return line.split(/\s+/)[0] ?? '';
|
|
591
568
|
}
|
|
592
569
|
|
|
593
|
-
function copyArtifacts(root, workdir, name,
|
|
570
|
+
function copyArtifacts(root, workdir, name, manifest) {
|
|
594
571
|
if (!SAFE_PACKAGE_NAME.test(name)) {
|
|
595
572
|
throw new MarketIndexError(`包名不是合法 npm 名,没法当产物目录:${JSON.stringify(name)}`, 'index-write');
|
|
596
573
|
}
|
|
597
|
-
const path =
|
|
574
|
+
const path = marketArtifactRoot(name);
|
|
598
575
|
const dest = join(workdir, path);
|
|
599
576
|
rmSync(dest, { recursive: true, force: true });
|
|
600
577
|
mkdirSync(dest, { recursive: true });
|
|
@@ -637,22 +614,6 @@ export function marketClaim({ plan, exec, home, name, unit, publisher }) {
|
|
|
637
614
|
});
|
|
638
615
|
}
|
|
639
616
|
|
|
640
|
-
const META_KEYS = ['title', 'description', 'author', 'owner', 'homepage', 'icon', 'metadata'];
|
|
641
|
-
|
|
642
|
-
function withCurrentMeta(entry, current, update) {
|
|
643
|
-
if (current === undefined) return entry;
|
|
644
|
-
const next = { ...entry };
|
|
645
|
-
if (!update) {
|
|
646
|
-
for (const key of META_KEYS) {
|
|
647
|
-
if (key === 'owner') continue;
|
|
648
|
-
if (current[key] === undefined) delete next[key];
|
|
649
|
-
else next[key] = current[key];
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
if (current.owner !== undefined) next.owner = current.owner;
|
|
653
|
-
return next;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
617
|
export function updateMarketIndex(options) {
|
|
657
618
|
const { plan, exec, home, root, manifest, version, publish, now, resume, onStep } = options;
|
|
658
619
|
const unit = options.unit ?? unitOf(manifest);
|
|
@@ -677,11 +638,19 @@ export function updateMarketIndex(options) {
|
|
|
677
638
|
if (plan.source.localPath === undefined) {
|
|
678
639
|
const fetched = runGit(exec, workdir, ['fetch', 'origin', branch], { allowFailure: true });
|
|
679
640
|
if (fetched.status === 0) runGit(exec, workdir, ['reset', '--hard', `origin/${branch}`], { allowFailure: true });
|
|
680
|
-
runGit(exec, workdir, ['clean', '-fd', '--',
|
|
641
|
+
runGit(exec, workdir, ['clean', '-fd', '--', marketArtifactRoot(manifest.name), dir], {
|
|
681
642
|
allowFailure: true,
|
|
682
643
|
});
|
|
683
644
|
}
|
|
684
|
-
|
|
645
|
+
const file = join(workdir, dir, `${manifest.name}.json`);
|
|
646
|
+
if (existsSync(file)) {
|
|
647
|
+
const kept = JSON.parse(readFileSync(file, 'utf8'));
|
|
648
|
+
const versions = (Array.isArray(kept.versions) ? kept.versions : []).filter(
|
|
649
|
+
(one) => one?.version !== version,
|
|
650
|
+
);
|
|
651
|
+
if (versions.length === 0) rmSync(file, { force: true });
|
|
652
|
+
else writeFileSync(file, `${JSON.stringify({ ...kept, versions }, null, 2)}\n`);
|
|
653
|
+
}
|
|
685
654
|
} else {
|
|
686
655
|
assertClean(exec, workdir);
|
|
687
656
|
}
|
|
@@ -719,7 +688,7 @@ export function updateMarketIndex(options) {
|
|
|
719
688
|
const done = replicatePush(exec, workdir, branch, baseSha, () => {
|
|
720
689
|
ensureClaimFree(workdir, dir, claimInput);
|
|
721
690
|
migrateLegacyIndex(workdir, dir);
|
|
722
|
-
artifactPath = copyArtifacts(root, workdir, manifest.name,
|
|
691
|
+
artifactPath = copyArtifacts(root, workdir, manifest.name, manifest);
|
|
723
692
|
report({ phase: 'artifacts-copied' });
|
|
724
693
|
artifactSha = commitOf(exec, workdir, `chore(release): ${entryName}`, identityOf(manifest));
|
|
725
694
|
report({ phase: 'artifacts-committed', artifactCommit: artifactSha });
|
|
@@ -740,15 +709,32 @@ export function updateMarketIndex(options) {
|
|
|
740
709
|
if (source === undefined) throw new MarketIndexError('这个出口没有可写进索引的 source(tarball 不进索引)', 'index-write');
|
|
741
710
|
if (source.type === 'npm' && source.registry === 'https://registry.npmjs.org/') delete source.registry;
|
|
742
711
|
}
|
|
743
|
-
const
|
|
712
|
+
const versionRecord = versionRecordOf({ manifest, version, source, at: now() });
|
|
744
713
|
report({ phase: 'index' });
|
|
745
714
|
const indexed = replicatePush(exec, workdir, branch, baseSha, () => {
|
|
746
715
|
if (plan.policy !== 'artifacts-in-repo') migrateLegacyIndex(workdir, dir);
|
|
747
716
|
ensureClaimFree(workdir, dir, claimInput);
|
|
717
|
+
ensureVersionFree(workdir, dir, claimInput);
|
|
748
718
|
const current = readWorktreeIndex(workdir, dir).plugins.find((one) => one.name === manifest.name);
|
|
749
|
-
const
|
|
750
|
-
|
|
751
|
-
|
|
719
|
+
const owner = authorTextOf(manifest);
|
|
720
|
+
let next;
|
|
721
|
+
if (current === undefined) {
|
|
722
|
+
next = {
|
|
723
|
+
name: manifest.name,
|
|
724
|
+
...(owner === '' ? {} : { owner }),
|
|
725
|
+
...entryMetaOf(manifest),
|
|
726
|
+
versions: [versionRecord],
|
|
727
|
+
};
|
|
728
|
+
} else {
|
|
729
|
+
next = { ...current, versions: sortMarketVersions([versionRecord, ...current.versions]) };
|
|
730
|
+
if (options.metadata === true) {
|
|
731
|
+
const merged = { ...next, ...entryMetaOf(manifest) };
|
|
732
|
+
if (current.owner !== undefined) merged.owner = current.owner;
|
|
733
|
+
next = merged;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
next = mergeEntryLabels(next, options.labels);
|
|
737
|
+
writeEntryFile(workdir, dir, next);
|
|
752
738
|
indexSha = commitOf(exec, workdir, `chore(market): ${entryName}`, identityOf(manifest));
|
|
753
739
|
report({ phase: 'index-committed', indexCommit: indexSha });
|
|
754
740
|
return indexSha;
|
|
@@ -830,10 +816,18 @@ export function refreshMarketEntry(options) {
|
|
|
830
816
|
if (isDeepStrictEqual(next, existing)) {
|
|
831
817
|
return { ...base, updated: false, unchanged: true, version: latest, phase: 'done' };
|
|
832
818
|
}
|
|
833
|
-
const at = Date.now();
|
|
834
819
|
const baseSha = revOf(exec, workdir, 'HEAD');
|
|
835
820
|
const done = replicatePush(exec, workdir, branch, baseSha, () => {
|
|
836
|
-
|
|
821
|
+
const fresh = readWorktreeIndex(workdir, dir).plugins.find((one) => one.name === manifest.name);
|
|
822
|
+
if (fresh === undefined) {
|
|
823
|
+
throw new MarketIndexError(`${manifest.name} 还不在索引里 —— 先正常发一版`, 'index-write');
|
|
824
|
+
}
|
|
825
|
+
const updated = { ...fresh };
|
|
826
|
+
for (const key of ['title', 'description', 'author', 'homepage', 'metadata']) {
|
|
827
|
+
if (Object.hasOwn(meta, key)) updated[key] = meta[key];
|
|
828
|
+
else delete updated[key];
|
|
829
|
+
}
|
|
830
|
+
writeEntryFile(workdir, dir, updated);
|
|
837
831
|
return commitOf(exec, workdir, `chore(market): refresh ${manifest.name}`, identityOf(manifest));
|
|
838
832
|
});
|
|
839
833
|
if (!done.ok) throw new MarketIndexError(done.reason, done.code);
|
package/src/release-util.mjs
CHANGED
|
@@ -58,6 +58,14 @@ export function argValue(args, flag) {
|
|
|
58
58
|
return at === -1 ? undefined : args[at + 1];
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
export function argValues(args, flag) {
|
|
62
|
+
const values = [];
|
|
63
|
+
for (let at = 0; at < args.length; at += 1) {
|
|
64
|
+
if (args[at] === flag) values.push(args[at + 1] ?? '');
|
|
65
|
+
}
|
|
66
|
+
return values;
|
|
67
|
+
}
|
|
68
|
+
|
|
61
69
|
export function hasFlag(args, flag) {
|
|
62
70
|
return args.includes(flag);
|
|
63
71
|
}
|
package/src/release.mjs
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
ReleaseError,
|
|
26
26
|
ResumableError,
|
|
27
27
|
argValue,
|
|
28
|
+
argValues,
|
|
28
29
|
defaultExec,
|
|
29
30
|
dshHomeOf,
|
|
30
31
|
hasFlag,
|
|
@@ -52,6 +53,7 @@ import {
|
|
|
52
53
|
authorTextOf,
|
|
53
54
|
claimProblemText,
|
|
54
55
|
identityOf,
|
|
56
|
+
labelsOfManifest,
|
|
55
57
|
marketClaim,
|
|
56
58
|
marketVersionExists,
|
|
57
59
|
missingPublisherText,
|
|
@@ -262,6 +264,11 @@ export async function runRelease({
|
|
|
262
264
|
if (!CHANGELOG_KINDS.includes(changelogKind)) {
|
|
263
265
|
throw new ReleaseError(`--changelog-type 只认 ${CHANGELOG_KINDS.join(' / ')}(收到「${changelogKind}」)`);
|
|
264
266
|
}
|
|
267
|
+
const askedLabels = [...new Set(argValues(args, '--label').map((one) => String(one).trim()))];
|
|
268
|
+
if (askedLabels.some((one) => one === '' || /[\r\n]/u.test(one))) {
|
|
269
|
+
throw new ReleaseError('--label 只认一行短词:不能是空的');
|
|
270
|
+
}
|
|
271
|
+
if (askedLabels.length > 2) throw new ReleaseError('--label 最多两个 —— 一个模块的标签是 1–2 个短词');
|
|
265
272
|
const manifest = readManifest(root);
|
|
266
273
|
const unit = manifest?.dsh?.workbench?.unit;
|
|
267
274
|
if (typeof unit !== 'string' || unit === '') throw new ReleaseError('这不是一个 wb 模块包(没有 dsh.workbench.unit)');
|
|
@@ -313,6 +320,9 @@ export async function runRelease({
|
|
|
313
320
|
emit(out, json, summary);
|
|
314
321
|
return summary;
|
|
315
322
|
}
|
|
323
|
+
const labels = askedLabels;
|
|
324
|
+
const labelsForIndex = labels.length > 0 ? labels : labelsOfManifest(manifest);
|
|
325
|
+
const labelsChange = verify || labels.length === 0 ? undefined : `标签 ← ${labels.join(' · ')}`;
|
|
316
326
|
const explicitApplied = explicitAuthor !== undefined && !verify && !dryRun;
|
|
317
327
|
if (explicitApplied) {
|
|
318
328
|
manifest.author = explicitAuthor;
|
|
@@ -343,7 +353,7 @@ export async function runRelease({
|
|
|
343
353
|
}
|
|
344
354
|
const authored = authorChangeOf(root, manifest, exec);
|
|
345
355
|
if (hasFlag(args, '--refresh')) {
|
|
346
|
-
if (dryRun) throw new ReleaseError('--refresh 没有预览:它只改索引里的标题 / 作者 / 说明');
|
|
356
|
+
if (dryRun) throw new ReleaseError('--refresh 没有预览:它只改索引里的标题 / 作者 / 说明 / 标签');
|
|
347
357
|
if (target !== 'market') throw new ReleaseError('--refresh 只对市场索引有意义(--target market)');
|
|
348
358
|
if (indexPlan === undefined) {
|
|
349
359
|
throw new ReleaseError('没有可写的 git 索引源 —— 用 --index <仓库> 指定,或先在「模块市场 → 发现」里初始化索引');
|
|
@@ -369,8 +379,13 @@ export async function runRelease({
|
|
|
369
379
|
},
|
|
370
380
|
changes:
|
|
371
381
|
result.updated === true
|
|
372
|
-
? [
|
|
382
|
+
? [
|
|
383
|
+
'市集元数据已刷新',
|
|
384
|
+
...(explicitAuthor === undefined ? [] : ['author ← --author']),
|
|
385
|
+
...(labelsChange === undefined ? [] : [labelsChange]),
|
|
386
|
+
]
|
|
373
387
|
: [],
|
|
388
|
+
...(labels.length === 0 ? {} : { labels }),
|
|
374
389
|
install: '',
|
|
375
390
|
text:
|
|
376
391
|
result.updated === true
|
|
@@ -481,6 +496,7 @@ export async function runRelease({
|
|
|
481
496
|
publish,
|
|
482
497
|
publisher: authorTextOf(manifestNow),
|
|
483
498
|
metadata: authorChange !== undefined,
|
|
499
|
+
...(labelsForIndex.length === 0 ? {} : { labels: labelsForIndex }),
|
|
484
500
|
exec,
|
|
485
501
|
home,
|
|
486
502
|
now: () => Date.now(),
|
|
@@ -489,6 +505,7 @@ export async function runRelease({
|
|
|
489
505
|
let changelogChange;
|
|
490
506
|
const changesOf = (version) => [
|
|
491
507
|
...(authorChange === undefined ? [] : [authorChange]),
|
|
508
|
+
...(labelsChange === undefined ? [] : [labelsChange]),
|
|
492
509
|
...(version === manifest.version ? [] : [`version → ${version}`]),
|
|
493
510
|
...(changelogChange === undefined ? [] : [changelogChange]),
|
|
494
511
|
];
|
|
@@ -708,6 +725,7 @@ export async function runRelease({
|
|
|
708
725
|
version,
|
|
709
726
|
files,
|
|
710
727
|
changes: changesOf(version),
|
|
728
|
+
...(labels.length === 0 ? {} : { labels }),
|
|
711
729
|
...(changelogReport === undefined ? {} : { changelog: changelogReport }),
|
|
712
730
|
install: '',
|
|
713
731
|
market: indexPreviewOf(manifest.name, version),
|
|
@@ -730,6 +748,7 @@ export async function runRelease({
|
|
|
730
748
|
publish: {},
|
|
731
749
|
publisher,
|
|
732
750
|
metadata: authorChange !== undefined,
|
|
751
|
+
...(labelsForIndex.length === 0 ? {} : { labels: labelsForIndex }),
|
|
733
752
|
exec,
|
|
734
753
|
home,
|
|
735
754
|
now: () => Date.now(),
|