@guiho/mirror 3.0.0-alpha.4 → 3.0.0-alpha.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/jsr.json +1 -1
- package/library/cli.d.ts +4 -0
- package/library/cli.d.ts.map +1 -1
- package/library/cli.js +58 -6
- package/library/flags.d.ts.map +1 -1
- package/library/flags.js +2 -1
- package/library/guiho-mirror-bin.js +0 -0
- package/library/types.d.ts +1 -0
- package/library/types.d.ts.map +1 -1
- package/package.json +26 -28
- package/bin/mirror.exe +0 -0
- package/source/adapters.ts +0 -176
- package/source/cli.ts +0 -285
- package/source/config.ts +0 -224
- package/source/errors.ts +0 -17
- package/source/executor.ts +0 -39
- package/source/flags.ts +0 -84
- package/source/guiho-mirror-bin.ts +0 -8
- package/source/guiho-mirror.spec.ts +0 -501
- package/source/guiho-mirror.ts +0 -44
- package/source/plan.ts +0 -98
- package/source/reporter.ts +0 -127
- package/source/types.ts +0 -128
- package/source/version.ts +0 -39
package/jsr.json
CHANGED
package/library/cli.d.ts
CHANGED
|
@@ -20,6 +20,10 @@ export declare const createMirrorCommand: () => import("citty").CommandDef<{
|
|
|
20
20
|
type: "boolean";
|
|
21
21
|
description: string;
|
|
22
22
|
};
|
|
23
|
+
verbose: {
|
|
24
|
+
type: "boolean";
|
|
25
|
+
description: string;
|
|
26
|
+
};
|
|
23
27
|
}>;
|
|
24
28
|
export declare const runMirrorCli: (rawArgs?: string[]) => Promise<void>;
|
|
25
29
|
//# sourceMappingURL=cli.d.ts.map
|
package/library/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../source/cli.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../source/cli.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgDH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;EAa5B,CAAA;AAEJ,eAAO,MAAM,YAAY,GAAU,kBAA+B,kBAyEjE,CAAA"}
|
package/library/cli.js
CHANGED
|
@@ -18,6 +18,7 @@ const globalArgs = {
|
|
|
18
18
|
cwd: { type: 'string', description: 'Run as if Mirror started in this directory' },
|
|
19
19
|
format: { type: 'enum', options: ['text', 'json'], default: 'text', description: 'Output format' },
|
|
20
20
|
'no-color': { type: 'boolean', description: 'Disable color output' },
|
|
21
|
+
verbose: { type: 'boolean', description: 'Show full error details and stack traces' },
|
|
21
22
|
};
|
|
22
23
|
const overrideArgs = {
|
|
23
24
|
...globalArgs,
|
|
@@ -53,6 +54,7 @@ export const createMirrorCommand = () => defineCommand({
|
|
|
53
54
|
});
|
|
54
55
|
export const runMirrorCli = async (rawArgs = process.argv.slice(2)) => {
|
|
55
56
|
const effectiveArgs = rawArgs.length === 0 ? ['--help'] : rawArgs;
|
|
57
|
+
const verbose = effectiveArgs.includes('--verbose');
|
|
56
58
|
const restoreColorOutput = effectiveArgs.includes('--no-color') ? stripColorFromProcessOutput() : () => { };
|
|
57
59
|
try {
|
|
58
60
|
if (effectiveArgs.includes('--no-color'))
|
|
@@ -78,19 +80,68 @@ export const runMirrorCli = async (rawArgs = process.argv.slice(2)) => {
|
|
|
78
80
|
].join('\n') + '\n');
|
|
79
81
|
});
|
|
80
82
|
}
|
|
81
|
-
|
|
83
|
+
// Intercept console.error during runMain to suppress citty's default
|
|
84
|
+
// ugly error dump (it does console.error(error, "\n") for non-CLIErrors).
|
|
85
|
+
// We capture the error object and handle it ourselves below.
|
|
86
|
+
let capturedError = undefined;
|
|
87
|
+
const originalConsoleError = console.error;
|
|
88
|
+
console.error = (...args) => {
|
|
89
|
+
// citty prints CLIError messages as strings — let those through
|
|
90
|
+
// citty prints non-CLIError errors as objects — capture those
|
|
91
|
+
if (args.length > 0 && args[0] instanceof Error) {
|
|
92
|
+
capturedError = args[0];
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
originalConsoleError(...args);
|
|
96
|
+
};
|
|
97
|
+
const originalProcessExit = process.exit;
|
|
98
|
+
let exitCode;
|
|
99
|
+
process.exit = ((code) => {
|
|
100
|
+
// If runMain calls process.exit(1) after an error, intercept it
|
|
101
|
+
// so we can handle the error ourselves. Let exit(0) through (--help).
|
|
102
|
+
if (code !== 0 && capturedError) {
|
|
103
|
+
exitCode = code;
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
originalProcessExit(code);
|
|
107
|
+
});
|
|
108
|
+
try {
|
|
109
|
+
await runMain(createMirrorCommand(), { rawArgs: effectiveArgs });
|
|
110
|
+
}
|
|
111
|
+
finally {
|
|
112
|
+
console.error = originalConsoleError;
|
|
113
|
+
process.exit = originalProcessExit;
|
|
114
|
+
}
|
|
115
|
+
if (capturedError) {
|
|
116
|
+
handleCliError(capturedError, verbose, exitCode);
|
|
117
|
+
}
|
|
82
118
|
}
|
|
83
119
|
catch (error) {
|
|
84
|
-
|
|
85
|
-
console.error(error.message);
|
|
86
|
-
process.exit(error.exitCode);
|
|
87
|
-
}
|
|
88
|
-
throw error;
|
|
120
|
+
handleCliError(error, verbose);
|
|
89
121
|
}
|
|
90
122
|
finally {
|
|
91
123
|
restoreColorOutput();
|
|
92
124
|
}
|
|
93
125
|
};
|
|
126
|
+
const handleCliError = (error, verbose, exitCode) => {
|
|
127
|
+
if (error instanceof MirrorError) {
|
|
128
|
+
console.error(`error: ${error.message}`);
|
|
129
|
+
if (verbose)
|
|
130
|
+
console.error(error.stack);
|
|
131
|
+
process.exit(error.exitCode);
|
|
132
|
+
}
|
|
133
|
+
if (error instanceof Error) {
|
|
134
|
+
console.error(`error: ${error.message}`);
|
|
135
|
+
if (verbose)
|
|
136
|
+
console.error(error.stack);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
console.error('error: An unexpected error occurred.');
|
|
140
|
+
if (verbose)
|
|
141
|
+
console.error(error);
|
|
142
|
+
}
|
|
143
|
+
process.exit(exitCode ?? 1);
|
|
144
|
+
};
|
|
94
145
|
const createInitCommand = () => defineCommand({
|
|
95
146
|
meta: { name: 'init', description: 'Create a Mirror configuration file.' },
|
|
96
147
|
subCommands: {
|
|
@@ -214,6 +265,7 @@ const cliOptions = (rawArgs, args) => {
|
|
|
214
265
|
push: parsed.push || args['push'] === true,
|
|
215
266
|
allowDirty: parsed.allowDirty || args['allowDirty'] === true,
|
|
216
267
|
yes: parsed.yes || args['yes'] === true,
|
|
268
|
+
verbose: parsed.verbose || args['verbose'] === true,
|
|
217
269
|
};
|
|
218
270
|
};
|
|
219
271
|
const stringArg = (value) => (typeof value === 'string' ? value : undefined);
|
package/library/flags.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../source/flags.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAqB,gBAAgB,EAAgB,MAAM,SAAS,CAAA;AAehF,eAAO,MAAM,qBAAqB,GAAI,SAAS,MAAM,EAAE,KAAG,
|
|
1
|
+
{"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../source/flags.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAqB,gBAAgB,EAAgB,MAAM,SAAS,CAAA;AAehF,eAAO,MAAM,qBAAqB,GAAI,SAAS,MAAM,EAAE,KAAG,gBAuDzD,CAAA"}
|
package/library/flags.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
3
|
*/
|
|
4
4
|
import { MirrorError } from './errors';
|
|
5
|
-
const booleanFlags = new Set(['dry-run', 'commit', 'push', 'allow-dirty', 'yes', 'no-color', 'help', 'version']);
|
|
5
|
+
const booleanFlags = new Set(['dry-run', 'commit', 'push', 'allow-dirty', 'yes', 'no-color', 'verbose', 'help', 'version']);
|
|
6
6
|
const adapterNames = new Set(['package.json', 'jsr.json', 'git']);
|
|
7
7
|
const shortFlagAliases = {
|
|
8
8
|
'-dy': '--dry-run',
|
|
@@ -55,6 +55,7 @@ export const parseMirrorCliOptions = (rawArgs) => {
|
|
|
55
55
|
push: parsed['push'] === true,
|
|
56
56
|
allowDirty: parsed['allowDirty'] === true,
|
|
57
57
|
yes: parsed['yes'] === true,
|
|
58
|
+
verbose: parsed['verbose'] === true,
|
|
58
59
|
};
|
|
59
60
|
};
|
|
60
61
|
const assertAdapter = (value, flagName) => {
|
|
File without changes
|
package/library/types.d.ts
CHANGED
package/library/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../source/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAEzC,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,UAAU,GAAG,KAAK,CAAA;AACnE,MAAM,MAAM,uBAAuB,GAAG,cAAc,GAAG,UAAU,CAAA;AACjE,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAAA;AAC1C,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG,MAAM,CAAA;AACtD,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAEtD,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC;IACpC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,OAAO,CAAC;QACf,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,EAAE,uBAAuB,CAAA;KACrC,CAAC,CAAA;IACF,OAAO,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,QAAQ,CAAA;QAChB,MAAM,EAAE,iBAAiB,CAAA;QACzB,MAAM,EAAE,iBAAiB,EAAE,CAAA;QAC3B,aAAa,EAAE,MAAM,CAAA;KACtB,CAAC,CAAA;IACF,OAAO,EAAE,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAClC,GAAG,EAAE,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC9B,GAAG,EAAE,OAAO,CAAC;QACX,YAAY,EAAE,MAAM,CAAA;QACpB,MAAM,EAAE,OAAO,CAAA;QACf,IAAI,EAAE,OAAO,CAAA;QACb,WAAW,EAAE,OAAO,CAAA;KACrB,CAAC,CAAA;CACH,CAAC,CAAA;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,CAAC,CAAA;IACT,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,UAAU,CAAC,EAAE,uBAAuB,CAAA;KACrC,CAAA;IACD,OAAO,EAAE;QACP,MAAM,EAAE,QAAQ,CAAA;QAChB,MAAM,EAAE,iBAAiB,CAAA;QACzB,MAAM,EAAE,iBAAiB,EAAE,CAAA;QAC3B,YAAY,EAAE,MAAM,CAAA;KACrB,CAAA;IACD,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACzB,GAAG,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACrB,GAAG,EAAE;QACH,WAAW,EAAE,MAAM,CAAA;QACnB,MAAM,EAAE,OAAO,CAAA;QACf,IAAI,EAAE,OAAO,CAAA;QACb,UAAU,EAAE,OAAO,CAAA;KACpB,CAAA;CACF,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,CAAC,EAAE,iBAAiB,CAAA;IAC1B,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAA;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,GAAG,CAAC,EAAE,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../source/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guiho/mirror",
|
|
3
3
|
"description": "Open source project versioning for Bun, npm, JSR, and Git.",
|
|
4
|
-
"version": "3.0.0-alpha.
|
|
5
|
-
"main": "library/guiho-mirror.js",
|
|
6
|
-
"types": "library/guiho-mirror.d.ts",
|
|
7
|
-
"module": "source/guiho-mirror.ts",
|
|
4
|
+
"version": "3.0.0-alpha.9",
|
|
8
5
|
"type": "module",
|
|
9
|
-
"
|
|
6
|
+
"main": "./library/guiho-mirror.js",
|
|
7
|
+
"types": "./library/guiho-mirror.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./library/guiho-mirror.d.ts",
|
|
11
|
+
"import": "./library/guiho-mirror.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"mirror": "./library/guiho-mirror-bin.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"README.md",
|
|
19
|
+
"library/",
|
|
20
|
+
"docs/",
|
|
21
|
+
"bin/",
|
|
22
|
+
"jsr.json",
|
|
23
|
+
"CHANGELOG.md",
|
|
24
|
+
"LICENSE.md",
|
|
25
|
+
"docs.md"
|
|
26
|
+
],
|
|
10
27
|
"keywords": [
|
|
11
28
|
"bun",
|
|
12
29
|
"cli",
|
|
@@ -22,16 +39,6 @@
|
|
|
22
39
|
"url": "https://guiho.co/cg"
|
|
23
40
|
},
|
|
24
41
|
"sideEffects": false,
|
|
25
|
-
"exports": {
|
|
26
|
-
".": {
|
|
27
|
-
"types": "./library/guiho-mirror.d.ts",
|
|
28
|
-
"import": "./library/guiho-mirror.js"
|
|
29
|
-
},
|
|
30
|
-
"./source": "./source/guiho-mirror.ts"
|
|
31
|
-
},
|
|
32
|
-
"bin": {
|
|
33
|
-
"mirror": "./library/guiho-mirror-bin.js"
|
|
34
|
-
},
|
|
35
42
|
"publishConfig": {
|
|
36
43
|
"access": "public"
|
|
37
44
|
},
|
|
@@ -53,22 +60,13 @@
|
|
|
53
60
|
},
|
|
54
61
|
"repository": {
|
|
55
62
|
"type": "git",
|
|
56
|
-
"url": "git+
|
|
63
|
+
"url": "git+https://github.com/CGuiho/mirror.git",
|
|
57
64
|
"directory": "mirror"
|
|
58
65
|
},
|
|
59
66
|
"homepage": "https://github.com/CGuiho/mirror#readme",
|
|
60
|
-
"bugs":
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
"library/",
|
|
64
|
-
"source/",
|
|
65
|
-
"docs/",
|
|
66
|
-
"bin/",
|
|
67
|
-
"jsr.json",
|
|
68
|
-
"CHANGELOG.md",
|
|
69
|
-
"LICENSE.md",
|
|
70
|
-
"docs.md"
|
|
71
|
-
],
|
|
67
|
+
"bugs": {
|
|
68
|
+
"url": "https://github.com/CGuiho/mirror/issues"
|
|
69
|
+
},
|
|
72
70
|
"dependencies": {
|
|
73
71
|
"citty": "^0.2.2",
|
|
74
72
|
"semver": "^7.8.0"
|
package/bin/mirror.exe
DELETED
|
Binary file
|
package/source/adapters.ts
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { $ } from 'bun'
|
|
6
|
-
import { existsSync } from 'node:fs'
|
|
7
|
-
import type { MirrorConfig, MirrorJsonObject } from './types'
|
|
8
|
-
import { MirrorError } from './errors'
|
|
9
|
-
import { assertValidSemver, sortSemverDescending } from './version'
|
|
10
|
-
import { resolveMirrorPath } from './config'
|
|
11
|
-
|
|
12
|
-
export const supportedGitTagTemplates = ['v{version}', '{name}@{version}', '{name}/v{version}'] as const
|
|
13
|
-
|
|
14
|
-
export const readPackageJson = async (path: string): Promise<MirrorJsonObject> => readJsonObject(path, 'package.json')
|
|
15
|
-
export const readJsrJson = async (path: string): Promise<MirrorJsonObject> => readJsonObject(path, 'jsr.json')
|
|
16
|
-
|
|
17
|
-
export const writeJsonObject = async (path: string, object: MirrorJsonObject) => {
|
|
18
|
-
await Bun.write(path, `${JSON.stringify(object, null, 2)}\n`)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const readPackageVersion = async (config: MirrorConfig) => readVersionField(resolveMirrorPath(config.cwd, config.package.path), 'package.json')
|
|
22
|
-
export const readJsrVersion = async (config: MirrorConfig) => readVersionField(resolveMirrorPath(config.cwd, config.jsr.path), 'jsr.json')
|
|
23
|
-
export const readPackageName = async (config: MirrorConfig) => readNameField(resolveMirrorPath(config.cwd, config.package.path), 'package.json')
|
|
24
|
-
export const readJsrName = async (config: MirrorConfig) => readNameField(resolveMirrorPath(config.cwd, config.jsr.path), 'jsr.json')
|
|
25
|
-
|
|
26
|
-
export const writePackageVersion = async (config: MirrorConfig, nextVersion: string) =>
|
|
27
|
-
writeVersionField(resolveMirrorPath(config.cwd, config.package.path), 'package.json', nextVersion)
|
|
28
|
-
|
|
29
|
-
export const writeJsrVersion = async (config: MirrorConfig, nextVersion: string) =>
|
|
30
|
-
writeVersionField(resolveMirrorPath(config.cwd, config.jsr.path), 'jsr.json', nextVersion)
|
|
31
|
-
|
|
32
|
-
export const ensureAdapterFiles = async (config: MirrorConfig) => {
|
|
33
|
-
if (usesAdapter(config, 'package.json')) ensureFile(resolveMirrorPath(config.cwd, config.package.path), 'package.json')
|
|
34
|
-
if (usesAdapter(config, 'jsr.json')) ensureFile(resolveMirrorPath(config.cwd, config.jsr.path), 'jsr.json')
|
|
35
|
-
if (usesAdapter(config, 'git')) await ensureGitRepository(config.cwd)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export const resolveProjectName = async (config: MirrorConfig) => {
|
|
39
|
-
if (config.project.name) return config.project.name
|
|
40
|
-
if (config.project.nameSource === 'package.json') return readPackageName(config)
|
|
41
|
-
if (config.project.nameSource === 'jsr.json') return readJsrName(config)
|
|
42
|
-
return undefined
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export const readCurrentVersion = async (config: MirrorConfig, projectName?: string) => {
|
|
46
|
-
if (config.version.source === 'package.json') return readPackageVersion(config)
|
|
47
|
-
if (config.version.source === 'jsr.json') return readJsrVersion(config)
|
|
48
|
-
return readGitVersion(config, projectName)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export const readGitVersion = async (config: MirrorConfig, projectName?: string) => {
|
|
52
|
-
await ensureGitRepository(config.cwd)
|
|
53
|
-
|
|
54
|
-
const tagsOutput = await $`git -C ${config.cwd} tag --list`.text()
|
|
55
|
-
const versions = tagsOutput
|
|
56
|
-
.split(/\r?\n/)
|
|
57
|
-
.map((line) => line.trim())
|
|
58
|
-
.filter(Boolean)
|
|
59
|
-
.map((tag) => versionFromTag(config.git.tagTemplate, tag, projectName))
|
|
60
|
-
.filter((version): version is string => Boolean(version))
|
|
61
|
-
|
|
62
|
-
if (versions.length === 0) throw new MirrorError(`No Git tags match template: ${config.git.tagTemplate}`)
|
|
63
|
-
|
|
64
|
-
return sortSemverDescending(versions)[0] ?? ''
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export const renderGitTag = (template: string, version: string, projectName?: string) => {
|
|
68
|
-
assertSupportedGitTagTemplate(template)
|
|
69
|
-
assertValidSemver(version, 'Git tag version')
|
|
70
|
-
|
|
71
|
-
if (template.includes('{name}') && !projectName) throw new MirrorError(`Tag template requires a project name: ${template}`)
|
|
72
|
-
|
|
73
|
-
return template.replaceAll('{version}', version).replaceAll('{name}', projectName ?? '')
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export const versionFromTag = (template: string, tag: string, projectName?: string) => {
|
|
77
|
-
assertSupportedGitTagTemplate(template)
|
|
78
|
-
|
|
79
|
-
if (template.includes('{name}') && !projectName) throw new MirrorError(`Tag template requires a project name: ${template}`)
|
|
80
|
-
|
|
81
|
-
const escapedTemplate = escapeRegex(template)
|
|
82
|
-
.replaceAll('\\{version\\}', '(?<version>.+)')
|
|
83
|
-
.replaceAll('\\{name\\}', escapeRegex(projectName ?? ''))
|
|
84
|
-
const match = new RegExp(`^${escapedTemplate}$`).exec(tag)
|
|
85
|
-
const version = match?.groups?.['version']
|
|
86
|
-
|
|
87
|
-
if (!version) return undefined
|
|
88
|
-
|
|
89
|
-
try {
|
|
90
|
-
assertValidSemver(version, 'Git tag version')
|
|
91
|
-
return version
|
|
92
|
-
} catch {
|
|
93
|
-
return undefined
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export const assertSupportedGitTagTemplate = (template: string) => {
|
|
98
|
-
if (!(supportedGitTagTemplates as readonly string[]).includes(template)) {
|
|
99
|
-
throw new MirrorError(`Unsupported Git tag template: ${template}. Expected v{version}, {name}@{version}, or {name}/v{version}.`)
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export const isGitRepository = async (cwd: string) => {
|
|
104
|
-
try {
|
|
105
|
-
await $`git -C ${cwd} rev-parse --is-inside-work-tree`.quiet()
|
|
106
|
-
return true
|
|
107
|
-
} catch {
|
|
108
|
-
return false
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export const isGitDirty = async (cwd: string) => {
|
|
113
|
-
const output = await $`git -C ${cwd} status --porcelain`.quiet().text()
|
|
114
|
-
return output.trim().length > 0
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export const createGitCommit = async (cwd: string, paths: string[], message: string) => {
|
|
118
|
-
for (const path of paths) await $`git -C ${cwd} add ${path}`.quiet()
|
|
119
|
-
await $`git -C ${cwd} commit -m ${message}`.quiet()
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export const createGitTag = async (cwd: string, tag: string) => {
|
|
123
|
-
await $`git -C ${cwd} tag ${tag} -m ${`Release ${tag}`}`.quiet()
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export const pushGitRefs = async (cwd: string, includeCommit: boolean, includeTags: boolean) => {
|
|
127
|
-
if (includeCommit) await $`git -C ${cwd} push`.quiet()
|
|
128
|
-
if (includeTags) await $`git -C ${cwd} push --tags`.quiet()
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const readJsonObject = async (path: string, label: string): Promise<MirrorJsonObject> => {
|
|
132
|
-
ensureFile(path, label)
|
|
133
|
-
const json = await Bun.file(path).json()
|
|
134
|
-
|
|
135
|
-
if (typeof json !== 'object' || json === null || Array.isArray(json)) throw new MirrorError(`${label} must contain a JSON object: ${path}`)
|
|
136
|
-
|
|
137
|
-
return json as MirrorJsonObject
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const readVersionField = async (path: string, label: string): Promise<string> => {
|
|
141
|
-
const json = await readJsonObject(path, label)
|
|
142
|
-
const version = json['version']
|
|
143
|
-
|
|
144
|
-
if (typeof version !== 'string') throw new MirrorError(`${label} must contain a string version field: ${path}`)
|
|
145
|
-
assertValidSemver(version, `${label} version`)
|
|
146
|
-
|
|
147
|
-
return version
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const readNameField = async (path: string, label: string): Promise<string> => {
|
|
151
|
-
const json = await readJsonObject(path, label)
|
|
152
|
-
const name = json['name']
|
|
153
|
-
|
|
154
|
-
if (typeof name !== 'string' || name.length === 0) throw new MirrorError(`${label} must contain a string name field: ${path}`)
|
|
155
|
-
|
|
156
|
-
return name
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const writeVersionField = async (path: string, label: string, nextVersion: string) => {
|
|
160
|
-
const json = await readJsonObject(path, label)
|
|
161
|
-
json['version'] = nextVersion
|
|
162
|
-
await writeJsonObject(path, json)
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const ensureFile = (path: string, label: string) => {
|
|
166
|
-
if (!existsSync(path)) throw new MirrorError(`${label} file not found: ${path}`)
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const ensureGitRepository = async (cwd: string) => {
|
|
170
|
-
if (!(await isGitRepository(cwd))) throw new MirrorError(`Not a Git repository: ${cwd}`)
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const usesAdapter = (config: MirrorConfig, adapter: 'package.json' | 'jsr.json' | 'git') =>
|
|
174
|
-
config.version.source === adapter || config.version.output.includes(adapter)
|
|
175
|
-
|
|
176
|
-
const escapeRegex = (value: string) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|