@dbx-tools/projen 0.9.106 → 0.9.110
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 +32 -25
- package/index.ts +1 -1
- package/package.json +6 -5
- package/src/project-py.ts +3 -1
- package/tasks/barrels.ts +19 -13
- package/tasks/bump.ts +33 -28
- package/tasks/clean.ts +20 -2
- package/tasks/cli.ts +80 -0
- package/tasks/compile-workspace.ts +2 -1
- package/tasks/dev-watch.ts +35 -50
- package/tasks/options.ts +59 -0
- package/tasks/projenrc.ts +2 -1
- package/tasks/publish-npm.ts +25 -14
- package/tasks/publish-python.ts +50 -52
- package/tasks/publish.ts +37 -25
- package/tasks/python-node-bindings-watch.ts +2 -1
- package/tasks/python-node-bindings.ts +29 -16
- package/tasks/python-node-runtime-watch.ts +9 -8
- package/tasks/python-sync.ts +20 -9
- package/tasks/release-options.ts +17 -8
- package/tasks/release-version.ts +22 -15
- package/tasks/release.ts +103 -96
- package/tasks/shared-core-usage.ts +6 -1
- package/tasks/sync.ts +16 -2
- package/tasks/test-workspace.ts +27 -12
- package/tasks/ui-bundle-sizes.ts +17 -12
- package/tasks/version-check.ts +2 -1
package/tasks/publish-python.ts
CHANGED
|
@@ -17,8 +17,14 @@ import {
|
|
|
17
17
|
import { tmpdir } from "node:os";
|
|
18
18
|
import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
19
19
|
import * as projectUtils from "@dbx-tools/core/project-utils";
|
|
20
|
-
import { Command } from "commander";
|
|
21
20
|
import { parse, stringify } from "smol-toml";
|
|
21
|
+
import { z } from "zod";
|
|
22
|
+
import { runTaskMain, taskCommand, taskOptions, taskPositionals } from "./cli.ts";
|
|
23
|
+
import {
|
|
24
|
+
TaskDirectoriesOptionSchema,
|
|
25
|
+
TaskDryRunOptionSchema,
|
|
26
|
+
TaskOutputOptionSchema,
|
|
27
|
+
} from "./options.ts";
|
|
22
28
|
import { preparePythonProjectForPublication, pythonProjectInfo } from "./python-release.ts";
|
|
23
29
|
import { runTaskCommand } from "../src/_task-command.ts";
|
|
24
30
|
|
|
@@ -182,56 +188,48 @@ function buildPythonProjectsInternal(
|
|
|
182
188
|
}
|
|
183
189
|
|
|
184
190
|
/** Parse command-line publication options and run the Python release task. */
|
|
185
|
-
export
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
.
|
|
193
|
-
.
|
|
194
|
-
.
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
publishUrl: options.publishUrl,
|
|
228
|
-
root: options.root,
|
|
229
|
-
version,
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
},
|
|
233
|
-
);
|
|
234
|
-
await program.parseAsync();
|
|
191
|
+
export const PublishPythonOptionsSchema = z.object({
|
|
192
|
+
indexUrl: z.string().trim().min(1).optional().describe("devpi Simple API URL"),
|
|
193
|
+
publishUrl: z.string().trim().min(1).optional().describe("devpi writable index URL"),
|
|
194
|
+
root: z.string().trim().min(1).default("packages/py").describe("Python workspace package root"),
|
|
195
|
+
package: TaskDirectoriesOptionSchema.describe("Repeatable Python package directory to build"),
|
|
196
|
+
output: TaskOutputOptionSchema.describe("Build distributions into this directory"),
|
|
197
|
+
packageDirectories: z
|
|
198
|
+
.boolean()
|
|
199
|
+
.default(false)
|
|
200
|
+
.describe("Keep each package's distributions in its own output directory"),
|
|
201
|
+
dryRun: TaskDryRunOptionSchema,
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
/** Parse task options and build or publish Python workspace distributions. */
|
|
205
|
+
export async function main(args: string[] = process.argv.slice(2)): Promise<void> {
|
|
206
|
+
const command = taskCommand(
|
|
207
|
+
import.meta.url,
|
|
208
|
+
"Build or publish Python workspace distributions",
|
|
209
|
+
PublishPythonOptionsSchema,
|
|
210
|
+
).argument("<version>", "Python package version");
|
|
211
|
+
const options = await taskOptions(command, PublishPythonOptionsSchema, args);
|
|
212
|
+
const version = String(taskPositionals(command)[0]);
|
|
213
|
+
if (options.output) {
|
|
214
|
+
buildPythonProjects({
|
|
215
|
+
output: options.output,
|
|
216
|
+
packages: options.package.length ? options.package : undefined,
|
|
217
|
+
packageDirectories: options.packageDirectories,
|
|
218
|
+
root: options.root,
|
|
219
|
+
version,
|
|
220
|
+
});
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
if (!options.indexUrl || !options.publishUrl) {
|
|
224
|
+
throw new Error("--index-url and --publish-url are required when publishing");
|
|
225
|
+
}
|
|
226
|
+
publishPythonProjects({
|
|
227
|
+
dryRun: options.dryRun,
|
|
228
|
+
indexUrl: options.indexUrl,
|
|
229
|
+
publishUrl: options.publishUrl,
|
|
230
|
+
root: options.root,
|
|
231
|
+
version,
|
|
232
|
+
});
|
|
235
233
|
}
|
|
236
234
|
|
|
237
|
-
|
|
235
|
+
await runTaskMain(import.meta, main);
|
package/tasks/publish.ts
CHANGED
|
@@ -47,6 +47,15 @@ import { copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync
|
|
|
47
47
|
import { tmpdir } from "node:os";
|
|
48
48
|
import { delimiter, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
49
49
|
import { asyncUtils, log, object } from "@dbx-tools/shared-core";
|
|
50
|
+
import { z } from "zod";
|
|
51
|
+
import { runTaskMain, taskCommand, taskOptions, taskPositionals, taskRoot } from "./cli.ts";
|
|
52
|
+
import {
|
|
53
|
+
TaskConcurrencyOptionSchema,
|
|
54
|
+
TaskDirectoriesOptionSchema,
|
|
55
|
+
TaskDryRunOptionSchema,
|
|
56
|
+
TaskOutputOptionSchema,
|
|
57
|
+
TaskRootOptionSchema,
|
|
58
|
+
} from "./options.ts";
|
|
50
59
|
import {
|
|
51
60
|
applyPublishConfig,
|
|
52
61
|
npmReleaseMatches,
|
|
@@ -100,31 +109,34 @@ function outputDirectory(root: string, value: string | undefined): string | unde
|
|
|
100
109
|
return output;
|
|
101
110
|
}
|
|
102
111
|
|
|
112
|
+
export const PublishOptionsSchema = z.object({
|
|
113
|
+
root: TaskRootOptionSchema,
|
|
114
|
+
registry: z
|
|
115
|
+
.string()
|
|
116
|
+
.trim()
|
|
117
|
+
.min(1)
|
|
118
|
+
.optional()
|
|
119
|
+
.describe("npm registry URL")
|
|
120
|
+
.meta({ env: "NPM_CONFIG_REGISTRY" }),
|
|
121
|
+
output: TaskOutputOptionSchema,
|
|
122
|
+
exclude: TaskDirectoriesOptionSchema.describe("Repeatable workspace directory to exclude"),
|
|
123
|
+
dryRun: TaskDryRunOptionSchema,
|
|
124
|
+
skipCompile: z.boolean().default(false).describe("Reuse already validated compiled output"),
|
|
125
|
+
concurrency: TaskConcurrencyOptionSchema.default(4),
|
|
126
|
+
});
|
|
127
|
+
|
|
103
128
|
export async function main(argv: string[] = process.argv.slice(2)): Promise<void> {
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
const
|
|
115
|
-
const outputIdx = rest.indexOf("--output");
|
|
116
|
-
const output = outputDirectory(root, outputIdx >= 0 ? rest[outputIdx + 1] : undefined);
|
|
117
|
-
const dryRun = rest.includes("--dry-run");
|
|
118
|
-
const skipCompile = rest.includes("--skip-compile");
|
|
119
|
-
const concurrencyIdx = rest.indexOf("--concurrency");
|
|
120
|
-
const parsedConcurrency = Number(concurrencyIdx >= 0 ? rest[concurrencyIdx + 1] : 4);
|
|
121
|
-
if (!Number.isInteger(parsedConcurrency) || parsedConcurrency < 1) {
|
|
122
|
-
throw new Error(`--concurrency must be a positive integer, got ${String(parsedConcurrency)}`);
|
|
123
|
-
}
|
|
124
|
-
const concurrency = parsedConcurrency;
|
|
125
|
-
const excluded = new Set(
|
|
126
|
-
rest.reduce<string[]>((acc, arg, i) => (arg === "--exclude" ? [...acc, rest[i + 1]] : acc), []),
|
|
127
|
-
);
|
|
129
|
+
const command = taskCommand(
|
|
130
|
+
import.meta.url,
|
|
131
|
+
"Build and publish the current npm workspace",
|
|
132
|
+
PublishOptionsSchema,
|
|
133
|
+
).argument("<version>", "Workspace release version");
|
|
134
|
+
const options = await taskOptions(command, PublishOptionsSchema, argv);
|
|
135
|
+
const version = String(taskPositionals(command)[0]);
|
|
136
|
+
const root = taskRoot(options.root);
|
|
137
|
+
const output = outputDirectory(root, options.output);
|
|
138
|
+
const { registry, dryRun, skipCompile, concurrency } = options;
|
|
139
|
+
const excluded = new Set(options.exclude);
|
|
128
140
|
|
|
129
141
|
const path = enrichedPath(root);
|
|
130
142
|
const allMembers = recordedPackages(root)
|
|
@@ -265,4 +277,4 @@ export async function main(argv: string[] = process.argv.slice(2)): Promise<void
|
|
|
265
277
|
);
|
|
266
278
|
}
|
|
267
279
|
|
|
268
|
-
|
|
280
|
+
await runTaskMain(import.meta, main);
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { log } from "@dbx-tools/shared-core";
|
|
6
|
+
import { runTaskMain } from "./cli.ts";
|
|
6
7
|
import { runTaskCommand } from "../src/_task-command.ts";
|
|
7
8
|
import { repoRoot } from "../src/packages.ts";
|
|
8
9
|
import {
|
|
@@ -91,4 +92,4 @@ export async function main(): Promise<void> {
|
|
|
91
92
|
);
|
|
92
93
|
}
|
|
93
94
|
|
|
94
|
-
|
|
95
|
+
await runTaskMain(import.meta, main);
|
|
@@ -6,11 +6,13 @@
|
|
|
6
6
|
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
7
7
|
import { dirname, join, relative, resolve } from "node:path";
|
|
8
8
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
9
|
-
import { parseArgs } from "node:util";
|
|
10
9
|
import { log, stringUtils } from "@dbx-tools/shared-core";
|
|
11
10
|
import type { BunPlugin } from "bun";
|
|
12
11
|
import stdLibBrowser from "node-stdlib-browser";
|
|
13
12
|
import ts from "typescript";
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
import { runTaskMain, taskCommand, taskOptions } from "./cli.ts";
|
|
15
|
+
import { TaskCheckOptionSchema, TaskForceOptionSchema, TaskRootOptionSchema } from "./options.ts";
|
|
14
16
|
import { header, makeReadonly, makeWritable } from "../src/generated.ts";
|
|
15
17
|
import { publicFunctionExports } from "../src/module-exports.ts";
|
|
16
18
|
import { resolveRepoRoot } from "../src/packages.ts";
|
|
@@ -34,26 +36,37 @@ const logger = log.logger("projen:python-node-bindings");
|
|
|
34
36
|
|
|
35
37
|
type FunctionOverride = ResolvedPythonNodeFunctionOverride;
|
|
36
38
|
|
|
37
|
-
function bindingIndex(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
throw new Error(`Node binding index ${value} is not configured for ${project}`);
|
|
39
|
+
function bindingIndex(index: number, count: number, project: string): number {
|
|
40
|
+
if (index >= count) {
|
|
41
|
+
throw new Error(`Node binding index ${index} is not configured for ${project}`);
|
|
41
42
|
}
|
|
42
43
|
return index;
|
|
43
44
|
}
|
|
44
45
|
|
|
46
|
+
export const PythonNodeBindingsOptionsSchema = z.object({
|
|
47
|
+
binding: z.coerce
|
|
48
|
+
.number()
|
|
49
|
+
.int()
|
|
50
|
+
.nonnegative()
|
|
51
|
+
.optional()
|
|
52
|
+
.describe("Configured binding index within the selected project"),
|
|
53
|
+
check: TaskCheckOptionSchema,
|
|
54
|
+
force: TaskForceOptionSchema,
|
|
55
|
+
module: z.string().trim().min(1).optional().describe("Configured package module to generate"),
|
|
56
|
+
project: z.string().trim().min(1).optional().describe("Python project directory"),
|
|
57
|
+
root: TaskRootOptionSchema,
|
|
58
|
+
});
|
|
59
|
+
|
|
45
60
|
export async function main(args: string[] = process.argv.slice(2)): Promise<void> {
|
|
46
|
-
const
|
|
61
|
+
const values = await taskOptions(
|
|
62
|
+
taskCommand(
|
|
63
|
+
import.meta.url,
|
|
64
|
+
"Generate PythonMonkey runtime and typed Python wrappers",
|
|
65
|
+
PythonNodeBindingsOptionsSchema,
|
|
66
|
+
),
|
|
67
|
+
PythonNodeBindingsOptionsSchema,
|
|
47
68
|
args,
|
|
48
|
-
|
|
49
|
-
binding: { type: "string" },
|
|
50
|
-
check: { type: "boolean" },
|
|
51
|
-
force: { type: "boolean" },
|
|
52
|
-
module: { type: "string" },
|
|
53
|
-
project: { type: "string" },
|
|
54
|
-
root: { type: "string" },
|
|
55
|
-
},
|
|
56
|
-
});
|
|
69
|
+
);
|
|
57
70
|
const root = values.root ? resolve(values.root) : resolveRepoRoot();
|
|
58
71
|
if (!values.project) {
|
|
59
72
|
if (values.binding !== undefined || values.module !== undefined) {
|
|
@@ -1186,4 +1199,4 @@ function pythonRuntimeLoader(source: string): string {
|
|
|
1186
1199
|
].join("\n");
|
|
1187
1200
|
}
|
|
1188
1201
|
|
|
1189
|
-
|
|
1202
|
+
await runTaskMain(import.meta, main);
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
/** Keep the one package-owned PythonMonkey shim runtime current. */
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
4
|
import { resolve } from "node:path";
|
|
5
|
-
import { parseArgs } from "node:util";
|
|
6
5
|
import { log } from "@dbx-tools/shared-core";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { runTaskMain, taskCommand, taskOptions } from "./cli.ts";
|
|
8
|
+
import { TaskProjectOptionSchema } from "./options.ts";
|
|
7
9
|
import { runTaskCommand } from "../src/_task-command.ts";
|
|
8
10
|
import { repoRoot } from "../src/packages.ts";
|
|
9
11
|
import { watchLoop } from "../src/watch.ts";
|
|
@@ -12,13 +14,12 @@ import { withWorkspaceMutationLock } from "../src/workspace-lock.ts";
|
|
|
12
14
|
const logger = log.logger("projen:python-node-runtime-watch");
|
|
13
15
|
|
|
14
16
|
export async function main(args: string[] = process.argv.slice(2)): Promise<void> {
|
|
15
|
-
const
|
|
17
|
+
const schema = z.object({ project: TaskProjectOptionSchema });
|
|
18
|
+
const { project } = await taskOptions(
|
|
19
|
+
taskCommand(import.meta.url, "Watch and rebuild the shared Python Node runtime", schema),
|
|
20
|
+
schema,
|
|
16
21
|
args,
|
|
17
|
-
|
|
18
|
-
strict: true,
|
|
19
|
-
});
|
|
20
|
-
const project = values.project?.trim();
|
|
21
|
-
if (!project) throw new Error("--project is required");
|
|
22
|
+
);
|
|
22
23
|
|
|
23
24
|
const projectDirectory = resolve(repoRoot, project);
|
|
24
25
|
const buildScript = resolve(projectDirectory, "build-runtime.ts");
|
|
@@ -37,4 +38,4 @@ export async function main(args: string[] = process.argv.slice(2)): Promise<void
|
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
await runTaskMain(import.meta, main);
|
package/tasks/python-sync.ts
CHANGED
|
@@ -23,6 +23,13 @@ import { basename, dirname, join, resolve } from "node:path";
|
|
|
23
23
|
import * as exec from "@dbx-tools/core/exec";
|
|
24
24
|
import { withFileLock } from "@dbx-tools/core/file-lock";
|
|
25
25
|
import { parse } from "smol-toml";
|
|
26
|
+
import { z } from "zod";
|
|
27
|
+
import { runTaskMain, taskCommand, taskOptions } from "./cli.ts";
|
|
28
|
+
import {
|
|
29
|
+
TaskCheckOptionSchema,
|
|
30
|
+
TaskForceOptionSchema,
|
|
31
|
+
TaskProjectOptionSchema,
|
|
32
|
+
} from "./options.ts";
|
|
26
33
|
import { PYTHON_GENERATED_PACKAGE, PYTHON_SYNC_PACKAGE } from "../src/generated.ts";
|
|
27
34
|
|
|
28
35
|
/** AST rewriter that points absolute imports of synchronized modules at their generated package. */
|
|
@@ -50,13 +57,17 @@ interface ParsedSource {
|
|
|
50
57
|
}
|
|
51
58
|
|
|
52
59
|
export async function main(args: readonly string[] = process.argv.slice(2)): Promise<void> {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
+
const schema = z.object({
|
|
61
|
+
project: TaskProjectOptionSchema,
|
|
62
|
+
force: TaskForceOptionSchema,
|
|
63
|
+
check: TaskCheckOptionSchema,
|
|
64
|
+
});
|
|
65
|
+
const options = await taskOptions(
|
|
66
|
+
taskCommand(import.meta.url, "Synchronize pinned Git sources into Python packages", schema),
|
|
67
|
+
schema,
|
|
68
|
+
args,
|
|
69
|
+
);
|
|
70
|
+
const project = resolve(options.project);
|
|
60
71
|
const pyproject = parse(readFileSync(join(project, "pyproject.toml"), "utf8")) as {
|
|
61
72
|
tool?: {
|
|
62
73
|
uv?: { "build-backend"?: { "module-name"?: string; "module-root"?: string } };
|
|
@@ -73,7 +84,7 @@ export async function main(args: readonly string[] = process.argv.slice(2)): Pro
|
|
|
73
84
|
const generatedPackage = [moduleName, PYTHON_GENERATED_PACKAGE, PYTHON_SYNC_PACKAGE].join(".");
|
|
74
85
|
const generatedRoot = join(moduleRoot, ...generatedPackage.split("."));
|
|
75
86
|
for (const config of configs) {
|
|
76
|
-
await synchronize(config, generatedRoot, generatedPackage,
|
|
87
|
+
await synchronize(config, generatedRoot, generatedPackage, options);
|
|
77
88
|
}
|
|
78
89
|
}
|
|
79
90
|
|
|
@@ -327,4 +338,4 @@ function makeReadonly(path: string): void {
|
|
|
327
338
|
}
|
|
328
339
|
}
|
|
329
340
|
|
|
330
|
-
|
|
341
|
+
await runTaskMain(import.meta, main);
|
package/tasks/release-options.ts
CHANGED
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env -S bun
|
|
2
2
|
/** Export the current annotated release tag's step selection to GitHub Actions. */
|
|
3
3
|
import { appendFileSync } from "node:fs";
|
|
4
|
-
import {
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { runTaskMain, taskCommand, taskOptions } from "./cli.ts";
|
|
5
6
|
import { captureTaskCommand } from "../src/_task-command.ts";
|
|
6
7
|
import { parseReleaseTagAnnotation } from "../src/release-options.ts";
|
|
7
8
|
|
|
9
|
+
export const ReleaseOptionsTaskSchema = z.object({
|
|
10
|
+
tag: z.string().trim().min(1).describe("Annotated release tag"),
|
|
11
|
+
output: z.string().trim().min(1).describe("GitHub Actions output file"),
|
|
12
|
+
});
|
|
13
|
+
|
|
8
14
|
/** Verify and export a tag policy using the shared annotated-tag contract. */
|
|
9
|
-
export function main(args: string[] = process.argv.slice(2)): void {
|
|
10
|
-
const
|
|
15
|
+
export async function main(args: string[] = process.argv.slice(2)): Promise<void> {
|
|
16
|
+
const values = await taskOptions(
|
|
17
|
+
taskCommand(
|
|
18
|
+
import.meta.url,
|
|
19
|
+
"Export release tag selections to GitHub Actions",
|
|
20
|
+
ReleaseOptionsTaskSchema,
|
|
21
|
+
),
|
|
22
|
+
ReleaseOptionsTaskSchema,
|
|
11
23
|
args,
|
|
12
|
-
|
|
13
|
-
strict: true,
|
|
14
|
-
});
|
|
15
|
-
if (!values.tag || !values.output) throw new Error("--tag and --output are required");
|
|
24
|
+
);
|
|
16
25
|
const annotation = captureTaskCommand(
|
|
17
26
|
process.cwd(),
|
|
18
27
|
"git",
|
|
@@ -29,4 +38,4 @@ export function main(args: string[] = process.argv.slice(2)): void {
|
|
|
29
38
|
);
|
|
30
39
|
}
|
|
31
40
|
|
|
32
|
-
|
|
41
|
+
await runTaskMain(import.meta, main);
|
package/tasks/release-version.ts
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env -S bun
|
|
2
2
|
/** Validate one stable release version against the canonical workspace policy. */
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
|
-
import { parseArgs } from "node:util";
|
|
5
4
|
import * as projectUtils from "@dbx-tools/core/project-utils";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { runTaskMain, taskCommand, taskOptions } from "./cli.ts";
|
|
7
|
+
import { TaskRootOptionSchema } from "./options.ts";
|
|
6
8
|
import { captureTaskCommand } from "../src/_task-command.ts";
|
|
7
9
|
import { compareSemver, parseSemver, type Semver } from "../src/workspace-version.ts";
|
|
8
10
|
|
|
11
|
+
export const ReleaseVersionOptionsSchema = z.object({
|
|
12
|
+
version: z.string().trim().min(1).describe("Release version to validate"),
|
|
13
|
+
root: TaskRootOptionSchema,
|
|
14
|
+
prefix: z.array(z.string().trim().min(1)).default([]).describe("Allowed release tag prefix"),
|
|
15
|
+
assertNext: z.boolean().default(false).describe("Require a version newer than published tags"),
|
|
16
|
+
});
|
|
17
|
+
|
|
9
18
|
function publishedVersion(root: string, prefixes: readonly string[]): string | undefined {
|
|
10
19
|
let best: Semver | undefined;
|
|
11
20
|
for (const prefix of prefixes) {
|
|
@@ -46,23 +55,21 @@ export function assertReleaseVersion(
|
|
|
46
55
|
}
|
|
47
56
|
}
|
|
48
57
|
|
|
49
|
-
export function main(args: string[] = process.argv.slice(2)): void {
|
|
50
|
-
const
|
|
58
|
+
export async function main(args: string[] = process.argv.slice(2)): Promise<void> {
|
|
59
|
+
const values = await taskOptions(
|
|
60
|
+
taskCommand(
|
|
61
|
+
import.meta.url,
|
|
62
|
+
"Validate a stable workspace release version",
|
|
63
|
+
ReleaseVersionOptionsSchema,
|
|
64
|
+
),
|
|
65
|
+
ReleaseVersionOptionsSchema,
|
|
51
66
|
args,
|
|
52
|
-
|
|
53
|
-
version: { type: "string" },
|
|
54
|
-
root: { type: "string" },
|
|
55
|
-
prefix: { type: "string", multiple: true },
|
|
56
|
-
"assert-next": { type: "boolean", default: false },
|
|
57
|
-
},
|
|
58
|
-
strict: true,
|
|
59
|
-
});
|
|
60
|
-
if (!values.version) throw new Error("--version is required");
|
|
67
|
+
);
|
|
61
68
|
assertReleaseVersion(values.version, {
|
|
62
69
|
...(values.root ? { root: values.root } : {}),
|
|
63
|
-
...(values.prefix ? { prefixes: values.prefix } : {}),
|
|
64
|
-
assertNext: values
|
|
70
|
+
...(values.prefix.length ? { prefixes: values.prefix } : {}),
|
|
71
|
+
assertNext: values.assertNext,
|
|
65
72
|
});
|
|
66
73
|
}
|
|
67
74
|
|
|
68
|
-
|
|
75
|
+
await runTaskMain(import.meta, main);
|