@dbx-tools/projen 0.9.105 → 0.9.108
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/README.md
CHANGED
|
@@ -584,30 +584,37 @@ release [options]
|
|
|
584
584
|
|
|
585
585
|
#### Options
|
|
586
586
|
|
|
587
|
-
| Option
|
|
588
|
-
|
|
|
589
|
-
| `--root <
|
|
590
|
-
| `--branch <
|
|
591
|
-
| `--prefix <
|
|
592
|
-
| `--remote <
|
|
593
|
-
| `--python-root <
|
|
594
|
-
| `--validate <
|
|
595
|
-
| `--
|
|
596
|
-
| `--
|
|
597
|
-
| `--
|
|
598
|
-
|
|
|
599
|
-
|
|
|
600
|
-
| `--
|
|
601
|
-
| `--
|
|
602
|
-
| `--no-
|
|
603
|
-
| `--
|
|
604
|
-
| `--
|
|
605
|
-
| `--release
|
|
606
|
-
| `--
|
|
607
|
-
| `--
|
|
608
|
-
| `--
|
|
609
|
-
| `--
|
|
610
|
-
| `--
|
|
611
|
-
| `--
|
|
587
|
+
| Option | Description |
|
|
588
|
+
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
589
|
+
| `--root <value>` | Repository or workspace root (env: PROJEN_RELEASE_ROOT) |
|
|
590
|
+
| `--branch <value>` | Release branch (default: "main", env: PROJEN_RELEASE_BRANCH) |
|
|
591
|
+
| `--prefix <value>` | Release tag prefix (default: "v", env: PROJEN_RELEASE_PREFIX) |
|
|
592
|
+
| `--remote <value>` | Git remote (default: "origin", env: PROJEN_RELEASE_REMOTE) |
|
|
593
|
+
| `--python-root <value>` | Python package root for local publish (default: "packages/py", env: PROJEN_RELEASE_PYTHON_ROOT) |
|
|
594
|
+
| `--validate <value>` | Repeatable task to run before pushing (default: [], env: PROJEN_RELEASE_VALIDATE) |
|
|
595
|
+
| `--bump` | Create and synchronize a patch version bump (default: true, env: PROJEN_RELEASE_BUMP) |
|
|
596
|
+
| `--no-bump` | Disable create and synchronize a patch version bump |
|
|
597
|
+
| `--publish <value>` | Publication scope (choices: "auto", "npm", "pypi", "local", "none", default: "auto", env: PROJEN_RELEASE_PUBLISH) |
|
|
598
|
+
| `-i, --install <value>` | Local workspace dependency installation (choices: "auto", "always", "never", default: "auto", env: PROJEN_RELEASE_INSTALL) |
|
|
599
|
+
| `-n, --npm` | Build and publish npm packages (default: true, env: PROJEN_RELEASE_NPM) |
|
|
600
|
+
| `--no-npm` | Disable build and publish npm packages |
|
|
601
|
+
| `--pypi` | Build and publish Python packages (default: true, env: PROJEN_RELEASE_PYPI) |
|
|
602
|
+
| `--no-pypi` | Disable build and publish python packages |
|
|
603
|
+
| `--docs` | Build and deploy documentation (env: PROJEN_RELEASE_DOCS) |
|
|
604
|
+
| `--no-docs` | Disable build and deploy documentation |
|
|
605
|
+
| `--validation` | Run optional release validation tasks before publishing (default: true, env: PROJEN_RELEASE_VALIDATION) |
|
|
606
|
+
| `--no-validation` | Disable run optional release validation tasks before publishing |
|
|
607
|
+
| `--release-notes` | Write release notes before tagging (default: true, env: PROJEN_RELEASE_RELEASE_NOTES) |
|
|
608
|
+
| `--no-release-notes` | Disable write release notes before tagging |
|
|
609
|
+
| `--release-notes-text <value>` | Write supplied release-note Markdown without invoking Genie (env: PROJEN_RELEASE_RELEASE_NOTES_TEXT) |
|
|
610
|
+
| `--release-notes-file <value>` | Copy release-note Markdown from this file without invoking Genie (env: PROJEN_RELEASE_RELEASE_NOTES_FILE) |
|
|
611
|
+
| `--release-notes-instructions <value>` | Append instructions to the Genie release-note prompt (env: PROJEN_RELEASE_RELEASE_NOTES_INSTRUCTIONS) |
|
|
612
|
+
| `--demo-deploy` | Deploy the AppKit demo after tagging and local publication (env: PROJEN_RELEASE_DEMO_DEPLOY) |
|
|
613
|
+
| `--no-demo-deploy` | Disable deploy the appkit demo after tagging and local publication |
|
|
614
|
+
| `--profile <value>` | Explicit Databricks CLI profile for demo deployment |
|
|
615
|
+
| `--local-publish` | Publish to configured local registries (default: true, env: PROJEN_RELEASE_LOCAL_PUBLISH) |
|
|
616
|
+
| `--no-local-publish` | Disable publish to configured local registries |
|
|
617
|
+
| `--local-registry <value>` | Local npm registry selection: auto, false, or URL (default: "auto", env: PROJEN_RELEASE_LOCAL_REGISTRY) |
|
|
618
|
+
| `--local-pypi <value>` | Local devpi registry selection: auto, false, or URL (default: "auto", env: PROJEN_RELEASE_LOCAL_PYPI) |
|
|
612
619
|
|
|
613
620
|
<!-- cli-reference:end -->
|
package/index.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
4
|
|
|
5
5
|
export const PACKAGE_IDENTIFIER = "@dbx-tools/projen";
|
|
6
|
-
export const PACKAGE_VERSION = "0.9.
|
|
6
|
+
export const PACKAGE_VERSION = "0.9.108";
|
|
7
7
|
export * as barrels from "./src/barrels.ts";
|
|
8
8
|
export * as bunApp from "./src/bun-app.ts";
|
|
9
9
|
export * as bunWorkflow from "./src/bun-workflow.ts";
|
package/package.json
CHANGED
|
@@ -30,9 +30,10 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@clack/prompts": "^1.7.0",
|
|
33
|
-
"@dbx-tools/
|
|
34
|
-
"@dbx-tools/
|
|
35
|
-
"@dbx-tools/
|
|
33
|
+
"@dbx-tools/cli-args": "^0.9.108",
|
|
34
|
+
"@dbx-tools/core": "^0.9.108",
|
|
35
|
+
"@dbx-tools/path": "^0.9.108",
|
|
36
|
+
"@dbx-tools/shared-core": "^0.9.108",
|
|
36
37
|
"commander": "^15.0.0",
|
|
37
38
|
"concurrently": "^10.0.3",
|
|
38
39
|
"constructs": "^10.6.0",
|
|
@@ -44,7 +45,7 @@
|
|
|
44
45
|
"ts-to-zod": "^5.1.0",
|
|
45
46
|
"typescript": "^5.9.3",
|
|
46
47
|
"yaml": "^2.9.0",
|
|
47
|
-
"zod": "
|
|
48
|
+
"zod": "4.3.6"
|
|
48
49
|
},
|
|
49
50
|
"devEngines": {
|
|
50
51
|
"packageManager": {
|
|
@@ -54,7 +55,7 @@
|
|
|
54
55
|
},
|
|
55
56
|
"main": "index.ts",
|
|
56
57
|
"license": "Apache-2.0",
|
|
57
|
-
"version": "0.9.
|
|
58
|
+
"version": "0.9.108",
|
|
58
59
|
"types": "index.ts",
|
|
59
60
|
"type": "module",
|
|
60
61
|
"exports": {
|
package/src/project-py.ts
CHANGED
|
@@ -613,7 +613,9 @@ export class DBXToolsPythonWorkspace extends Component {
|
|
|
613
613
|
run: [
|
|
614
614
|
'bun node_modules/@dbx-tools/projen/tasks/publish-python.ts "$RELEASE_VERSION"',
|
|
615
615
|
`--root ${JSON.stringify(this.repository.root)}`,
|
|
616
|
-
|
|
616
|
+
allPublications
|
|
617
|
+
.map((publication) => `--package ${JSON.stringify(publication.directory)}`)
|
|
618
|
+
.join(" "),
|
|
617
619
|
"--output .release/python --package-directories",
|
|
618
620
|
].join(" \\\n "),
|
|
619
621
|
},
|
package/tasks/barrels.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env -S bun
|
|
2
2
|
/** Generate package barrels once or keep affected barrels current in watch mode. */
|
|
3
3
|
import { sep } from "node:path";
|
|
4
|
-
import { parseArgs } from "node:util";
|
|
5
4
|
import { log, object, stringUtils } from "@dbx-tools/shared-core";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { runTaskMain, taskCommand, taskOptions } from "./cli.ts";
|
|
7
|
+
import { TaskDirectoriesOptionSchema, TaskWatchOptionSchema } from "./options.ts";
|
|
6
8
|
import { generateBarrels } from "../src/barrels.ts";
|
|
7
9
|
import { recordedPackages } from "../src/packages.ts";
|
|
8
10
|
import { watchLoop, watchRoots } from "../src/watch.ts";
|
|
@@ -35,15 +37,21 @@ function warnUnownedChanges(changed: readonly string[]): void {
|
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
export
|
|
39
|
-
|
|
40
|
+
export const BarrelsOptionsSchema = z.object({
|
|
41
|
+
watch: TaskWatchOptionSchema,
|
|
42
|
+
dir: TaskDirectoriesOptionSchema.describe("Repeatable package directory to rebuild"),
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
export async function main(args: string[] = process.argv.slice(2)): Promise<void> {
|
|
46
|
+
const values = await taskOptions(
|
|
47
|
+
taskCommand(
|
|
48
|
+
import.meta.url,
|
|
49
|
+
"Generate package barrels once or keep them current",
|
|
50
|
+
BarrelsOptionsSchema,
|
|
51
|
+
),
|
|
52
|
+
BarrelsOptionsSchema,
|
|
40
53
|
args,
|
|
41
|
-
|
|
42
|
-
watch: { type: "boolean" },
|
|
43
|
-
dir: { type: "string", multiple: true },
|
|
44
|
-
},
|
|
45
|
-
strict: false,
|
|
46
|
-
});
|
|
54
|
+
);
|
|
47
55
|
|
|
48
56
|
if (values.watch) {
|
|
49
57
|
// Watch the package roots; a source edit inside a package rebuilds just that
|
|
@@ -70,9 +78,7 @@ export function main(args: string[] = process.argv.slice(2)): void {
|
|
|
70
78
|
},
|
|
71
79
|
);
|
|
72
80
|
} else {
|
|
73
|
-
const dirs =
|
|
74
|
-
? values.dir.filter((value): value is string => typeof value === "string")
|
|
75
|
-
: [];
|
|
81
|
+
const dirs = values.dir;
|
|
76
82
|
const n = generateBarrels(dirs.length ? { dirs } : undefined);
|
|
77
83
|
logger.success(
|
|
78
84
|
n === 0 ? "barrels already up to date" : `updated ${stringUtils.pluralize(n, "barrel")}`,
|
|
@@ -80,4 +86,4 @@ export function main(args: string[] = process.argv.slice(2)): void {
|
|
|
80
86
|
}
|
|
81
87
|
}
|
|
82
88
|
|
|
83
|
-
|
|
89
|
+
await runTaskMain(import.meta, main);
|
package/tasks/bump.ts
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import * as projectUtils from "@dbx-tools/core/project-utils";
|
|
8
8
|
import { log } from "@dbx-tools/shared-core";
|
|
9
|
-
import {
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
import { runTaskMain, taskCommand, taskOptions, taskRoot } from "./cli.ts";
|
|
11
|
+
import { TaskRootOptionSchema } from "./options.ts";
|
|
10
12
|
import { runTaskCommand } from "../src/_task-command.ts";
|
|
11
13
|
import {
|
|
12
14
|
resolveNextVersion,
|
|
@@ -16,35 +18,38 @@ import {
|
|
|
16
18
|
|
|
17
19
|
const logger = log.logger("projen:bump");
|
|
18
20
|
|
|
19
|
-
export
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
.
|
|
23
|
-
.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
.option("--no-synth", "write VERSION without synchronizing generated files")
|
|
29
|
-
.action((opts: { level: VersionLevel; synth: boolean }) => {
|
|
30
|
-
const root = projectUtils.root() ?? process.cwd();
|
|
31
|
-
const next = resolveNextVersion(root, opts.level);
|
|
21
|
+
export const BumpOptionsSchema = z.object({
|
|
22
|
+
root: TaskRootOptionSchema,
|
|
23
|
+
level: z
|
|
24
|
+
.enum(["patch", "minor", "major"])
|
|
25
|
+
.default("patch")
|
|
26
|
+
.describe("Semantic version increment")
|
|
27
|
+
.meta({ short: "l" }),
|
|
28
|
+
synth: z.boolean().default(true).describe("Synchronize generated workspace versions"),
|
|
29
|
+
});
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
export async function main(args: string[] = process.argv.slice(2)): Promise<void> {
|
|
32
|
+
const options = await taskOptions(
|
|
33
|
+
taskCommand(
|
|
34
|
+
import.meta.url,
|
|
35
|
+
"Increment VERSION and synchronize generated workspace versions",
|
|
36
|
+
BumpOptionsSchema,
|
|
37
|
+
),
|
|
38
|
+
BumpOptionsSchema,
|
|
39
|
+
args,
|
|
40
|
+
);
|
|
41
|
+
const root = taskRoot(options.root ?? projectUtils.root());
|
|
42
|
+
const level: VersionLevel = options.level;
|
|
43
|
+
const next = resolveNextVersion(root, level);
|
|
35
44
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
// Package manifests are generated during the first synthesis, while
|
|
39
|
-
// cross-package derived artifacts can read those manifests earlier in
|
|
40
|
-
// the same pass. A second pass makes the new version visible to every
|
|
41
|
-
// generator and leaves release validation on a converged tree.
|
|
42
|
-
runTaskCommand(root, process.execPath, [".projenrc.ts"]);
|
|
43
|
-
}
|
|
44
|
-
logger.success(`workspace version synchronized at ${next.version}`);
|
|
45
|
-
});
|
|
45
|
+
logger.info(`bump ${next.base} -> ${next.version} (${level})`);
|
|
46
|
+
writeWorkspaceVersion(root, next.version);
|
|
46
47
|
|
|
47
|
-
|
|
48
|
+
if (options.synth) {
|
|
49
|
+
runTaskCommand(root, process.execPath, [".projenrc.ts"]);
|
|
50
|
+
runTaskCommand(root, process.execPath, [".projenrc.ts"]);
|
|
51
|
+
}
|
|
52
|
+
logger.success(`workspace version synchronized at ${next.version}`);
|
|
48
53
|
}
|
|
49
54
|
|
|
50
|
-
|
|
55
|
+
await runTaskMain(import.meta, main);
|
package/tasks/clean.ts
CHANGED
|
@@ -2,12 +2,30 @@
|
|
|
2
2
|
/** Interactively remove generated files and installed dependency directories. */
|
|
3
3
|
import { relative } from "node:path";
|
|
4
4
|
import { log, stringUtils } from "@dbx-tools/shared-core";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { runTaskMain, taskCommand, taskOptions } from "./cli.ts";
|
|
5
7
|
import { listGeneratedFiles, listNodeModulesDirs, removePaths } from "../src/clean.ts";
|
|
6
8
|
import { repoRoot, toPosix } from "../src/packages.ts";
|
|
7
9
|
|
|
8
10
|
const logger = log.logger("projen:clean");
|
|
11
|
+
export const CleanOptionsSchema = z.object({
|
|
12
|
+
yes: z
|
|
13
|
+
.boolean()
|
|
14
|
+
.default(false)
|
|
15
|
+
.describe("Remove every generated and dependency path without prompting")
|
|
16
|
+
.meta({ short: "y", env: [] }),
|
|
17
|
+
});
|
|
18
|
+
|
|
9
19
|
export async function main(args: string[] = process.argv.slice(2)): Promise<void> {
|
|
10
|
-
const yes =
|
|
20
|
+
const { yes } = await taskOptions(
|
|
21
|
+
taskCommand(
|
|
22
|
+
import.meta.url,
|
|
23
|
+
"Remove generated files and dependency directories",
|
|
24
|
+
CleanOptionsSchema,
|
|
25
|
+
),
|
|
26
|
+
CleanOptionsSchema,
|
|
27
|
+
args,
|
|
28
|
+
);
|
|
11
29
|
|
|
12
30
|
const files = listGeneratedFiles();
|
|
13
31
|
const nodeModules = listNodeModulesDirs();
|
|
@@ -69,4 +87,4 @@ export async function main(args: string[] = process.argv.slice(2)): Promise<void
|
|
|
69
87
|
clack.outro(`removed ${stringUtils.pluralize(n, "path")} - ${regenHint(removedNodeModules)}`);
|
|
70
88
|
}
|
|
71
89
|
|
|
72
|
-
|
|
90
|
+
await runTaskMain(import.meta, main);
|
package/tasks/cli.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/** Shared Commander and entrypoint integration for Projen task CLIs. */
|
|
2
|
+
import { basename, extname, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
4
|
+
import { addArgs, parseArgs, type CliArgsOptions } from "@dbx-tools/cli-args";
|
|
5
|
+
import * as projectUtils from "@dbx-tools/core/project-utils";
|
|
6
|
+
import { stringUtils } from "@dbx-tools/shared-core";
|
|
7
|
+
import { Command } from "commander";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
|
|
10
|
+
/** Stable task name derived from its source filename. */
|
|
11
|
+
export function taskName(moduleUrl: string): string {
|
|
12
|
+
const file = basename(fileURLToPath(moduleUrl));
|
|
13
|
+
return file.slice(0, -extname(file).length);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Config resolution shared by task schemas. */
|
|
17
|
+
export function taskCliArgsOptions(moduleUrl: string): CliArgsOptions {
|
|
18
|
+
const prefix = [...stringUtils.tokenize(taskName(moduleUrl))].join("_").toUpperCase();
|
|
19
|
+
return {
|
|
20
|
+
cwd: process.cwd(),
|
|
21
|
+
prefix: `PROJEN_${prefix}`,
|
|
22
|
+
sources: ["env", "dotenv"],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Create a task command and bind every Zod-owned option through cli-args. */
|
|
27
|
+
export function taskCommand<T extends z.ZodRawShape>(
|
|
28
|
+
moduleUrl: string,
|
|
29
|
+
description: string,
|
|
30
|
+
schema: z.ZodObject<T>,
|
|
31
|
+
): Command {
|
|
32
|
+
return addArgs(
|
|
33
|
+
new Command().name(taskName(moduleUrl)).description(description),
|
|
34
|
+
schema,
|
|
35
|
+
taskCliArgsOptions(moduleUrl),
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Parse one task's flags and layered environment values through its schema. */
|
|
40
|
+
export async function taskOptions<T extends z.ZodRawShape>(
|
|
41
|
+
command: Command,
|
|
42
|
+
schema: z.ZodObject<T>,
|
|
43
|
+
argv: readonly string[] = process.argv.slice(2),
|
|
44
|
+
): Promise<z.output<z.ZodObject<T>>> {
|
|
45
|
+
await command.parseAsync([...argv], { from: "user" });
|
|
46
|
+
return parseArgs(command, schema);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Read one already-parsed task command through its owning Zod schema. */
|
|
50
|
+
export function parsedTaskOptions<T extends z.ZodRawShape>(
|
|
51
|
+
command: Command,
|
|
52
|
+
schema: z.ZodObject<T>,
|
|
53
|
+
): z.output<z.ZodObject<T>> {
|
|
54
|
+
return parseArgs(command, schema);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Read positional arguments after Commander has parsed one task command. */
|
|
58
|
+
export function taskPositionals(command: Command): readonly unknown[] {
|
|
59
|
+
return command.processedArgs;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Resolve the explicit task root or discover the current project root. */
|
|
63
|
+
export function taskRoot(root?: string): string {
|
|
64
|
+
return resolve(root ?? projectUtils.root() ?? process.cwd());
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** True when an imported task module is the active Bun or Node entrypoint. */
|
|
68
|
+
export function isTaskMain(meta: ImportMeta): boolean {
|
|
69
|
+
if (meta.main) return true;
|
|
70
|
+
const entry = process.argv[1];
|
|
71
|
+
return Boolean(entry && pathToFileURL(resolve(entry)).href === meta.url);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Run a task only when its module is the active process entrypoint. */
|
|
75
|
+
export async function runTaskMain(
|
|
76
|
+
meta: ImportMeta,
|
|
77
|
+
main: () => void | Promise<void>,
|
|
78
|
+
): Promise<void> {
|
|
79
|
+
if (isTaskMain(meta)) await main();
|
|
80
|
+
}
|
|
@@ -5,6 +5,7 @@ import { availableParallelism } from "node:os";
|
|
|
5
5
|
import { join, resolve } from "node:path";
|
|
6
6
|
import * as exec from "@dbx-tools/core/exec";
|
|
7
7
|
import { log } from "@dbx-tools/shared-core";
|
|
8
|
+
import { runTaskMain } from "./cli.ts";
|
|
8
9
|
|
|
9
10
|
const logger = log.logger("projen:compile");
|
|
10
11
|
|
|
@@ -142,4 +143,4 @@ async function compileCustomPackage(pkg: {
|
|
|
142
143
|
return result!;
|
|
143
144
|
}
|
|
144
145
|
|
|
145
|
-
|
|
146
|
+
await runTaskMain(import.meta, main);
|
package/tasks/dev-watch.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env -S bun
|
|
2
2
|
/** Restart a development command after relevant workspace changes settle. */
|
|
3
3
|
import { isAbsolute, relative, resolve } from "node:path";
|
|
4
|
-
import { configUtils } from "@dbx-tools/core";
|
|
5
4
|
import * as exec from "@dbx-tools/core/exec";
|
|
6
5
|
import { watch as pathWatch } from "@dbx-tools/path";
|
|
7
6
|
import { log } from "@dbx-tools/shared-core";
|
|
8
|
-
import {
|
|
7
|
+
import { CommanderError } from "commander";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import { parsedTaskOptions, runTaskMain, taskCommand, taskPositionals } from "./cli.ts";
|
|
9
10
|
import {
|
|
10
11
|
DEV_RESTART_DEBOUNCE_MS,
|
|
11
12
|
DEV_RESTART_KEY,
|
|
@@ -30,73 +31,57 @@ export interface DevWatchOptions {
|
|
|
30
31
|
readonly serverWatchDisabled: boolean;
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
export const DevWatchOptionsSchema = z.object({
|
|
35
|
+
debounceMs: z.coerce
|
|
36
|
+
.number()
|
|
37
|
+
.int()
|
|
38
|
+
.nonnegative("Debounce must be a non-negative number of milliseconds")
|
|
39
|
+
.default(DEV_RESTART_DEBOUNCE_MS)
|
|
40
|
+
.describe("Quiet period before restarting the command"),
|
|
41
|
+
restartKey: z
|
|
42
|
+
.string()
|
|
43
|
+
.refine((value) => Array.from(value).length === 1, "Restart key must be exactly one character")
|
|
44
|
+
.default(DEV_RESTART_KEY)
|
|
45
|
+
.describe("Interactive immediate-restart key"),
|
|
46
|
+
serverWatchDisabled: z
|
|
47
|
+
.boolean()
|
|
48
|
+
.default(false)
|
|
49
|
+
.describe("Run the command once without watching")
|
|
50
|
+
.meta({ env: SERVER_WATCH_DISABLED_ENV }),
|
|
51
|
+
});
|
|
52
|
+
|
|
33
53
|
interface WorkspacePackage {
|
|
34
54
|
readonly dir: string;
|
|
35
55
|
readonly name?: string;
|
|
36
56
|
}
|
|
37
57
|
|
|
38
|
-
function debounceMilliseconds(value: string): number {
|
|
39
|
-
const parsed = configUtils.toNumber(value);
|
|
40
|
-
if (parsed === undefined || parsed < 0) {
|
|
41
|
-
throw new InvalidArgumentError("must be a non-negative number of milliseconds");
|
|
42
|
-
}
|
|
43
|
-
return parsed;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function singleKey(value: string): string {
|
|
47
|
-
if (Array.from(value).length !== 1) {
|
|
48
|
-
throw new InvalidArgumentError("must be exactly one character");
|
|
49
|
-
}
|
|
50
|
-
return value;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
58
|
/** Parse watcher flags while passing every token after the command through unchanged. */
|
|
54
|
-
export function parseDevWatchOptions(args: string[]): DevWatchOptions {
|
|
55
|
-
const program =
|
|
59
|
+
export function parseDevWatchOptions(args: readonly string[]): DevWatchOptions {
|
|
60
|
+
const program = taskCommand(
|
|
61
|
+
import.meta.url,
|
|
62
|
+
"Restart a development command after watched changes settle",
|
|
63
|
+
DevWatchOptionsSchema,
|
|
64
|
+
)
|
|
56
65
|
.name(DEV_WATCH_TASK)
|
|
57
|
-
.description("Restart a development command after watched changes settle")
|
|
58
66
|
.exitOverride()
|
|
59
67
|
.configureOutput({
|
|
60
68
|
writeErr: (message) => {
|
|
61
|
-
if (
|
|
69
|
+
if (process.argv[1]) process.stderr.write(message);
|
|
62
70
|
},
|
|
63
71
|
})
|
|
64
72
|
.enablePositionalOptions()
|
|
65
73
|
.passThroughOptions()
|
|
66
|
-
.addOption(
|
|
67
|
-
new Option("--debounce-ms <milliseconds>", "quiet period before restart")
|
|
68
|
-
.default(DEV_RESTART_DEBOUNCE_MS)
|
|
69
|
-
.argParser(debounceMilliseconds),
|
|
70
|
-
)
|
|
71
|
-
.addOption(
|
|
72
|
-
new Option("--restart-key <key>", "interactive immediate-restart key")
|
|
73
|
-
.default(DEV_RESTART_KEY)
|
|
74
|
-
.argParser(singleKey),
|
|
75
|
-
)
|
|
76
|
-
.addOption(
|
|
77
|
-
new Option(
|
|
78
|
-
"--server-watch-disabled",
|
|
79
|
-
`run the command once without watching (${SERVER_WATCH_DISABLED_ENV})`,
|
|
80
|
-
),
|
|
81
|
-
)
|
|
82
74
|
.argument("<command>")
|
|
83
75
|
.argument("[args...]")
|
|
84
|
-
.parse(["
|
|
85
|
-
const options = program
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
serverWatchDisabled?: boolean;
|
|
89
|
-
}>();
|
|
90
|
-
const [command, commandArgs = []] = program.processedArgs as [string, string[]?];
|
|
91
|
-
const serverWatchDisabled =
|
|
92
|
-
options.serverWatchDisabled === true ||
|
|
93
|
-
configUtils.boolean(undefined, SERVER_WATCH_DISABLED_ENV, configUtils.ENV_ONLY) === true;
|
|
94
|
-
if (serverWatchDisabled) process.env[SERVER_WATCH_DISABLED_ENV] = "1";
|
|
76
|
+
.parse([...args], { from: "user" });
|
|
77
|
+
const options = parsedTaskOptions(program, DevWatchOptionsSchema);
|
|
78
|
+
const [command, commandArgs = []] = taskPositionals(program) as [string, string[]?];
|
|
79
|
+
if (options.serverWatchDisabled) process.env[SERVER_WATCH_DISABLED_ENV] = "1";
|
|
95
80
|
return {
|
|
96
81
|
command: [command, ...commandArgs],
|
|
97
82
|
debounceMs: options.debounceMs,
|
|
98
83
|
restartKey: options.restartKey,
|
|
99
|
-
serverWatchDisabled,
|
|
84
|
+
serverWatchDisabled: options.serverWatchDisabled,
|
|
100
85
|
};
|
|
101
86
|
}
|
|
102
87
|
|
|
@@ -336,4 +321,4 @@ export async function main(args: string[] = process.argv.slice(2)): Promise<void
|
|
|
336
321
|
await complete;
|
|
337
322
|
}
|
|
338
323
|
|
|
339
|
-
|
|
324
|
+
await runTaskMain(import.meta, main);
|
package/tasks/options.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** Shared Zod option fields for Projen task CLIs. */
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
/** Optional repository or workspace root. */
|
|
5
|
+
export const TaskRootOptionSchema = z
|
|
6
|
+
.string()
|
|
7
|
+
.trim()
|
|
8
|
+
.min(1)
|
|
9
|
+
.optional()
|
|
10
|
+
.describe("Repository or workspace root");
|
|
11
|
+
|
|
12
|
+
/** Required project directory. */
|
|
13
|
+
export const TaskProjectOptionSchema = z.string().trim().min(1).describe("Project directory");
|
|
14
|
+
|
|
15
|
+
/** Check generated state without writing changes. */
|
|
16
|
+
export const TaskCheckOptionSchema = z
|
|
17
|
+
.boolean()
|
|
18
|
+
.default(false)
|
|
19
|
+
.describe("Check generated state without writing changes");
|
|
20
|
+
|
|
21
|
+
/** Force work even when fingerprints or generated state appear current. */
|
|
22
|
+
export const TaskForceOptionSchema = z
|
|
23
|
+
.boolean()
|
|
24
|
+
.default(false)
|
|
25
|
+
.describe("Force regeneration even when outputs appear current");
|
|
26
|
+
|
|
27
|
+
/** Keep a task running and react to changes. */
|
|
28
|
+
export const TaskWatchOptionSchema = z
|
|
29
|
+
.boolean()
|
|
30
|
+
.default(false)
|
|
31
|
+
.describe("Watch inputs and keep generated state current");
|
|
32
|
+
|
|
33
|
+
/** Validate publication artifacts without uploading them. */
|
|
34
|
+
export const TaskDryRunOptionSchema = z
|
|
35
|
+
.boolean()
|
|
36
|
+
.default(false)
|
|
37
|
+
.describe("Validate artifacts without publishing them");
|
|
38
|
+
|
|
39
|
+
/** Optional output directory. */
|
|
40
|
+
export const TaskOutputOptionSchema = z
|
|
41
|
+
.string()
|
|
42
|
+
.trim()
|
|
43
|
+
.min(1)
|
|
44
|
+
.optional()
|
|
45
|
+
.describe("Output directory");
|
|
46
|
+
|
|
47
|
+
/** Positive worker concurrency. */
|
|
48
|
+
export const TaskConcurrencyOptionSchema = z.coerce
|
|
49
|
+
.number()
|
|
50
|
+
.int()
|
|
51
|
+
.positive()
|
|
52
|
+
.optional()
|
|
53
|
+
.describe("Maximum concurrent workers");
|
|
54
|
+
|
|
55
|
+
/** Repeatable package or directory selection. */
|
|
56
|
+
export const TaskDirectoriesOptionSchema = z
|
|
57
|
+
.array(z.string().trim().min(1))
|
|
58
|
+
.default([])
|
|
59
|
+
.describe("Repeatable package or directory selection");
|
package/tasks/projenrc.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
/** Resynthesize when the root definition or configured generator inputs change. */
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { log } from "@dbx-tools/shared-core";
|
|
5
|
+
import { runTaskMain } from "./cli.ts";
|
|
5
6
|
import { repoRoot, syncResynthPaths } from "../src/packages.ts";
|
|
6
7
|
import { runSynth } from "../src/scaffold.ts";
|
|
7
8
|
import { watchLoop } from "../src/watch.ts";
|
|
@@ -38,4 +39,4 @@ export function main(): void {
|
|
|
38
39
|
);
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
await runTaskMain(import.meta, main);
|
package/tasks/publish-npm.ts
CHANGED
|
@@ -16,7 +16,9 @@ import { join, relative, resolve } from "node:path";
|
|
|
16
16
|
import * as exec from "@dbx-tools/core/exec";
|
|
17
17
|
import * as projectUtils from "@dbx-tools/core/project-utils";
|
|
18
18
|
import { log } from "@dbx-tools/shared-core";
|
|
19
|
-
import {
|
|
19
|
+
import { z } from "zod";
|
|
20
|
+
import { runTaskMain, taskCommand, taskOptions } from "./cli.ts";
|
|
21
|
+
import { TaskDryRunOptionSchema } from "./options.ts";
|
|
20
22
|
import { runTaskCommand } from "../src/_task-command.ts";
|
|
21
23
|
|
|
22
24
|
const DEFAULT_REGISTRY = "https://registry.npmjs.org";
|
|
@@ -451,18 +453,27 @@ export async function publishNpmArchives(options: {
|
|
|
451
453
|
}
|
|
452
454
|
|
|
453
455
|
/** Parse npm archive publication options and execute the publisher. */
|
|
454
|
-
export
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
.
|
|
459
|
-
.
|
|
460
|
-
.
|
|
461
|
-
.
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
456
|
+
export const PublishNpmOptionsSchema = z.object({
|
|
457
|
+
directory: z.string().trim().min(1).describe("Directory containing npm archives"),
|
|
458
|
+
version: z.string().trim().min(1).optional().describe("Expected npm release version"),
|
|
459
|
+
registry: z
|
|
460
|
+
.string()
|
|
461
|
+
.trim()
|
|
462
|
+
.min(1)
|
|
463
|
+
.optional()
|
|
464
|
+
.describe("npm registry URL")
|
|
465
|
+
.meta({ env: "NPM_CONFIG_REGISTRY" }),
|
|
466
|
+
dryRun: TaskDryRunOptionSchema,
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
/** Parse task options and publish validated npm release archives. */
|
|
470
|
+
export async function main(args: string[] = process.argv.slice(2)): Promise<void> {
|
|
471
|
+
const options = await taskOptions(
|
|
472
|
+
taskCommand(import.meta.url, "Publish validated npm release archives", PublishNpmOptionsSchema),
|
|
473
|
+
PublishNpmOptionsSchema,
|
|
474
|
+
args,
|
|
475
|
+
);
|
|
476
|
+
await publishNpmArchives(options);
|
|
466
477
|
}
|
|
467
478
|
|
|
468
|
-
|
|
479
|
+
await runTaskMain(import.meta, main);
|