@dbx-tools/projen 0.9.18 → 0.9.21
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/._LICENSE +0 -0
- package/._README.md +0 -0
- package/._index.ts +0 -0
- package/._package.json +0 -0
- package/README.md +72 -88
- package/index.ts +2 -7
- package/package.json +9 -5
- package/src/.__lazy-require.ts +0 -0
- package/src/.__release-platform.ts +0 -0
- package/src/.__rust-project.ts +0 -0
- package/src/.__rust-release-workflow.ts +0 -0
- package/src/.__task-command.ts +0 -0
- package/src/._barrels.ts +0 -0
- package/src/._bun-app.ts +0 -0
- package/src/._bun-workflow.ts +0 -0
- package/src/._clean.ts +0 -0
- package/src/._codegen.ts +0 -0
- package/src/._dbx-tools-config.ts +0 -0
- package/src/._engine-root.ts +0 -0
- package/src/._generated.ts +0 -0
- package/src/._mixin.ts +0 -0
- package/src/._module-exports.ts +0 -0
- package/src/._openapi.ts +0 -0
- package/src/._packages.ts +0 -0
- package/src/._pnpm-workspace.ts +0 -0
- package/src/._project-js.ts +0 -0
- package/src/._project-predicate.ts +0 -0
- package/src/._project-py.ts +0 -0
- package/src/._project-rs.ts +0 -0
- package/src/._project.ts +0 -0
- package/src/._projen-version.ts +0 -0
- package/src/._publish.ts +0 -0
- package/src/._release-catalog.ts +0 -0
- package/src/._release-dispatch.ts +0 -0
- package/src/._release-github.ts +0 -0
- package/src/._release.ts +0 -0
- package/src/._scaffold.ts +0 -0
- package/src/._tags.ts +0 -0
- package/src/._tsconfig.ts +0 -0
- package/src/._uniffi.ts +0 -0
- package/src/._vscode.ts +0 -0
- package/src/._watch.ts +0 -0
- package/src/._workspace-lock.ts +0 -0
- package/src/._workspace-version.ts +0 -0
- package/src/_rust-release-workflow.ts +18 -582
- package/src/_task-command.ts +75 -0
- package/src/project-js.ts +2 -42
- package/src/project-py.ts +60 -162
- package/src/project-rs.ts +4 -100
- package/src/release-catalog.ts +37 -203
- package/src/release.ts +96 -775
- package/src/scaffold.ts +2 -6
- package/src/workspace-version.ts +9 -121
- package/tasks/._barrels.ts +0 -0
- package/tasks/._bump.ts +0 -0
- package/tasks/._clean.ts +0 -0
- package/tasks/._compile-workspace.ts +0 -0
- package/tasks/._local-publish.ts +0 -0
- package/tasks/._openapi.ts +0 -0
- package/tasks/._projenrc.ts +0 -0
- package/tasks/._publish-npm.ts +0 -0
- package/tasks/._publish-python.ts +0 -0
- package/tasks/._publish-uniffi-local.ts +0 -0
- package/tasks/._publish.ts +0 -0
- package/tasks/._python-registry.ts +0 -0
- package/tasks/._release-assets.ts +0 -0
- package/tasks/._release-candidate.ts +0 -0
- package/tasks/._release-manifest.ts +0 -0
- package/tasks/._release-pr.ts +0 -0
- package/tasks/._release-summary.ts +0 -0
- package/tasks/._release-version.ts +0 -0
- package/tasks/._rust.ts +0 -0
- package/tasks/._sync.ts +0 -0
- package/tasks/._uniffi-python.d.ts +0 -0
- package/tasks/._uniffi-python.js +0 -0
- package/tasks/._uniffi-release.mjs +0 -0
- package/tasks/._uniffi.ts +0 -0
- package/tasks/._version-check.ts +0 -0
- package/tasks/bump.ts +17 -34
- package/tasks/local-publish.ts +124 -117
- package/tasks/publish-npm.ts +125 -41
- package/tasks/publish-python.ts +79 -106
- package/tasks/publish-uniffi-local.ts +129 -84
- package/tasks/publish.ts +44 -139
- package/tasks/python-registry.ts +2 -9
- package/tasks/release-assets.ts +56 -65
- package/tasks/release-candidate.ts +416 -0
- package/tasks/release-manifest.ts +273 -0
- package/tasks/release-pr.ts +312 -369
- package/tasks/release-summary.ts +8 -10
- package/tasks/release-version.ts +23 -2
- package/tasks/rust.ts +8 -13
- package/tasks/uniffi-python.d.ts +2 -3
- package/tasks/uniffi-python.js +7 -20
- package/tasks/uniffi-release.mjs +19 -13
- package/tasks/uniffi.ts +15 -24
- package/tasks/version-check.ts +24 -56
- package/src/release-plan.ts +0 -269
- package/src/release-please.ts +0 -242
- package/tasks/release-bootstrap.ts +0 -59
- package/tasks/release-plan.ts +0 -89
- package/tasks/release-please.ts +0 -162
- package/tasks/release-request.ts +0 -166
- package/tasks/release-summary-units.ts +0 -75
- package/tasks/stamp-python.ts +0 -13
package/tasks/release-summary.ts
CHANGED
|
@@ -85,10 +85,6 @@ export type ReleaseSummaryRunner = (
|
|
|
85
85
|
prompt: string,
|
|
86
86
|
) => string | undefined | Promise<string | undefined>;
|
|
87
87
|
|
|
88
|
-
function capture(root: string, command: string, args: string[]): string {
|
|
89
|
-
return captureTaskCommand(root, command, args);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
88
|
function contentText(value: unknown): string | undefined {
|
|
93
89
|
if (typeof value === "string") return stringUtils.trimToNull(value) ?? undefined;
|
|
94
90
|
if (!Array.isArray(value)) return undefined;
|
|
@@ -162,7 +158,7 @@ async function runProvider(
|
|
|
162
158
|
root: string,
|
|
163
159
|
prompt: string,
|
|
164
160
|
): Promise<string | undefined> {
|
|
165
|
-
if (!
|
|
161
|
+
if (!captureTaskCommand(root, provider.command, [...provider.probeArgs])) return undefined;
|
|
166
162
|
let summary: string | undefined;
|
|
167
163
|
let previousEventKey: string | undefined;
|
|
168
164
|
const textOutput: string[] = [];
|
|
@@ -317,15 +313,17 @@ export async function generateReleaseSummary(options: {
|
|
|
317
313
|
const output = join(options.root, relativeOutput);
|
|
318
314
|
if (existsSync(output)) rmSync(output);
|
|
319
315
|
const target =
|
|
320
|
-
options.toRef &&
|
|
316
|
+
options.toRef &&
|
|
317
|
+
captureTaskCommand(options.root, "git", ["rev-parse", "--verify", options.toRef])
|
|
321
318
|
? options.toRef
|
|
322
319
|
: "HEAD";
|
|
323
320
|
const range =
|
|
324
|
-
options.fromRef &&
|
|
321
|
+
options.fromRef &&
|
|
322
|
+
captureTaskCommand(options.root, "git", ["rev-parse", "--verify", options.fromRef])
|
|
325
323
|
? `${options.fromRef}..${target}`
|
|
326
324
|
: target;
|
|
327
325
|
const scopedPaths = options.paths?.length ? [...options.paths] : ["."];
|
|
328
|
-
const commits =
|
|
326
|
+
const commits = captureTaskCommand(options.root, "git", [
|
|
329
327
|
"log",
|
|
330
328
|
"--no-merges",
|
|
331
329
|
"--format=%s%n%b",
|
|
@@ -333,7 +331,7 @@ export async function generateReleaseSummary(options: {
|
|
|
333
331
|
"--",
|
|
334
332
|
...scopedPaths,
|
|
335
333
|
]);
|
|
336
|
-
const changedFiles =
|
|
334
|
+
const changedFiles = captureTaskCommand(options.root, "git", [
|
|
337
335
|
"diff",
|
|
338
336
|
"--name-status",
|
|
339
337
|
range,
|
|
@@ -341,7 +339,7 @@ export async function generateReleaseSummary(options: {
|
|
|
341
339
|
...scopedPaths,
|
|
342
340
|
`:(exclude)${relativeOutput}`,
|
|
343
341
|
]);
|
|
344
|
-
const diffStat =
|
|
342
|
+
const diffStat = captureTaskCommand(options.root, "git", [
|
|
345
343
|
"diff",
|
|
346
344
|
"--stat",
|
|
347
345
|
range,
|
package/tasks/release-version.ts
CHANGED
|
@@ -3,7 +3,28 @@
|
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { parseArgs } from "node:util";
|
|
5
5
|
import * as projectUtils from "@dbx-tools/core/project-utils";
|
|
6
|
-
import {
|
|
6
|
+
import { captureGitTaskCommand } from "../src/_task-command.ts";
|
|
7
|
+
import { compareSemver, parseSemver, type Semver } from "../src/workspace-version.ts";
|
|
8
|
+
|
|
9
|
+
function publishedVersion(root: string, prefixes: readonly string[]): string | undefined {
|
|
10
|
+
let best: Semver | undefined;
|
|
11
|
+
for (const prefix of prefixes) {
|
|
12
|
+
const tags = captureGitTaskCommand(root, [
|
|
13
|
+
"-c",
|
|
14
|
+
"versionsort.suffix=-",
|
|
15
|
+
"tag",
|
|
16
|
+
"--sort=-version:refname",
|
|
17
|
+
"--list",
|
|
18
|
+
`${prefix}*`,
|
|
19
|
+
]);
|
|
20
|
+
for (const tag of tags.split("\n")) {
|
|
21
|
+
if (!tag.startsWith(prefix)) continue;
|
|
22
|
+
const version = parseSemver(tag.slice(prefix.length));
|
|
23
|
+
if (version && (!best || compareSemver(version, best) > 0)) best = version;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return best?.join(".");
|
|
27
|
+
}
|
|
7
28
|
|
|
8
29
|
export function assertReleaseVersion(
|
|
9
30
|
version: string,
|
|
@@ -18,7 +39,7 @@ export function assertReleaseVersion(
|
|
|
18
39
|
if (!options.assertNext) return;
|
|
19
40
|
const root = resolve(options.root ?? projectUtils.root() ?? process.cwd());
|
|
20
41
|
const prefixes = options.prefixes?.length ? options.prefixes : ["v"];
|
|
21
|
-
const current =
|
|
42
|
+
const current = publishedVersion(root, prefixes);
|
|
22
43
|
const currentParsed = current ? parseSemver(current) : undefined;
|
|
23
44
|
if (currentParsed && compareSemver(parsed, currentParsed) <= 0) {
|
|
24
45
|
throw new Error(`release version ${version} must be greater than published ${current}`);
|
package/tasks/rust.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env -S bun
|
|
2
|
-
import { spawnSync } from "node:child_process";
|
|
3
2
|
import { existsSync } from "node:fs";
|
|
4
3
|
import { dirname, isAbsolute, resolve, sep } from "node:path";
|
|
5
4
|
import { fileURLToPath } from "node:url";
|
|
6
5
|
import { log, object } from "@dbx-tools/shared-core";
|
|
6
|
+
import { runTaskCommand, taskCommandSucceeds } from "../src/_task-command.ts";
|
|
7
7
|
import { readDbxToolsConfig, repoRoot } from "../src/packages.ts";
|
|
8
8
|
import {
|
|
9
9
|
discoverRustCrates,
|
|
@@ -27,7 +27,7 @@ function rustConfig(): RustWorkspaceMapping | undefined {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
function cargoAvailable(): boolean {
|
|
30
|
-
return
|
|
30
|
+
return taskCommandSucceeds(repoRoot, "cargo", ["--version"]);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
function currentStructure(config: RustWorkspaceMapping): RustWorkspaceMapping {
|
|
@@ -74,17 +74,12 @@ function generate(binding: RustBindingMapping): void {
|
|
|
74
74
|
? ["--python", binding.python, "--python-module", binding.pythonModule ?? ""]
|
|
75
75
|
: []),
|
|
76
76
|
];
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
...targets,
|
|
84
|
-
],
|
|
85
|
-
{ cwd: repoRoot, stdio: "inherit" },
|
|
86
|
-
);
|
|
87
|
-
if (result.status !== 0) throw new Error(`binding generation exited with ${result.status}`);
|
|
77
|
+
runTaskCommand(repoRoot, process.execPath, [
|
|
78
|
+
resolve(dirname(fileURLToPath(import.meta.url)), "uniffi.ts"),
|
|
79
|
+
"--crate",
|
|
80
|
+
binding.crate,
|
|
81
|
+
...targets,
|
|
82
|
+
]);
|
|
88
83
|
}
|
|
89
84
|
|
|
90
85
|
function* iterateAffectedRustBindings(
|
package/tasks/uniffi-python.d.ts
CHANGED
|
@@ -20,13 +20,12 @@ export interface PythonProjectInfo {
|
|
|
20
20
|
/** Read the project identity and publication flag from parsed TOML metadata. */
|
|
21
21
|
export function pythonProjectInfo(source: string, toml: TomlCodec): PythonProjectInfo;
|
|
22
22
|
|
|
23
|
-
/**
|
|
24
|
-
export function
|
|
23
|
+
/** Project registry-compatible sibling requirements onto a temporary package copy. */
|
|
24
|
+
export function preparePythonProjectForPublication(
|
|
25
25
|
source: string,
|
|
26
26
|
options: {
|
|
27
27
|
readonly packages: readonly PythonPackageMapping[];
|
|
28
28
|
readonly rewriteDependencies?: boolean;
|
|
29
|
-
readonly usePackageVersions?: boolean;
|
|
30
29
|
readonly toml: TomlCodec;
|
|
31
30
|
readonly version: string;
|
|
32
31
|
},
|
package/tasks/uniffi-python.js
CHANGED
|
@@ -67,23 +67,18 @@ export const pythonProjectInfo = (source, toml) => {
|
|
|
67
67
|
};
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
-
const
|
|
71
|
-
const [major, minor] = version.split(".").map(Number);
|
|
72
|
-
const upper = major === 0 ? `0.${minor + 1}.0` : `${major + 1}.0.0`;
|
|
73
|
-
return `>=${version},<${upper}`;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
export const stampPythonProject = (
|
|
70
|
+
export const preparePythonProjectForPublication = (
|
|
77
71
|
source,
|
|
78
|
-
{ packages, rewriteDependencies = true,
|
|
72
|
+
{ packages, rewriteDependencies = true, toml, version },
|
|
79
73
|
) => {
|
|
80
74
|
const marker = source.startsWith("# ") ? source.slice(0, source.indexOf("\n")) : undefined;
|
|
81
75
|
const document = toml.parse(source);
|
|
82
76
|
const project = projectTable(document);
|
|
83
|
-
if (
|
|
84
|
-
throw new Error(
|
|
77
|
+
if (project.version !== version) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
`Python project version ${String(project.version)} does not match release ${version}`,
|
|
80
|
+
);
|
|
85
81
|
}
|
|
86
|
-
project.version = version;
|
|
87
82
|
if (rewriteDependencies) {
|
|
88
83
|
const dependencies = project.dependencies;
|
|
89
84
|
if (dependencies !== undefined && !Array.isArray(dependencies)) {
|
|
@@ -95,15 +90,7 @@ export const stampPythonProject = (
|
|
|
95
90
|
throw new Error("Python project dependencies must be strings");
|
|
96
91
|
}
|
|
97
92
|
const sibling = packages.find((candidate) => directSibling(dependency, candidate));
|
|
98
|
-
return sibling
|
|
99
|
-
? `${sibling.name}${
|
|
100
|
-
usePackageVersions
|
|
101
|
-
? sibling.uniffi
|
|
102
|
-
? `==${sibling.version}`
|
|
103
|
-
: compatibleRequirement(sibling.version)
|
|
104
|
-
: `==${version}`
|
|
105
|
-
}`
|
|
106
|
-
: dependency;
|
|
93
|
+
return sibling ? `${sibling.name}==${version}` : dependency;
|
|
107
94
|
});
|
|
108
95
|
}
|
|
109
96
|
}
|
package/tasks/uniffi-release.mjs
CHANGED
|
@@ -19,9 +19,9 @@ import { parseArgs } from "node:util";
|
|
|
19
19
|
import { spawnSync } from "node:child_process";
|
|
20
20
|
import {
|
|
21
21
|
installPythonBindings,
|
|
22
|
+
preparePythonProjectForPublication,
|
|
22
23
|
pythonBindingGeneratorArgs,
|
|
23
24
|
pythonBindingGeneratorName,
|
|
24
|
-
stampPythonProject,
|
|
25
25
|
} from "./uniffi-python.js";
|
|
26
26
|
|
|
27
27
|
const require = createRequire(import.meta.url);
|
|
@@ -327,15 +327,14 @@ const packageNodeFacade = ({ output, nodeDirectory, nodePackage, version, native
|
|
|
327
327
|
rmSync(resolve(output, "npm-facade"), { recursive: true, force: true });
|
|
328
328
|
mkdirSync(output, { recursive: true });
|
|
329
329
|
cpSync(resolve(root, nodeDirectory), facadeDirectory, { recursive: true });
|
|
330
|
+
rmSync(join(facadeDirectory, "dist"), { recursive: true, force: true });
|
|
330
331
|
const barrel = join(facadeDirectory, "index.ts");
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
),
|
|
338
|
-
);
|
|
332
|
+
const barrelVersion = /^export const PACKAGE_VERSION = "([^"]+)";$/m.exec(
|
|
333
|
+
readFileSync(barrel, "utf8"),
|
|
334
|
+
)?.[1];
|
|
335
|
+
if (barrelVersion !== version) {
|
|
336
|
+
throw new Error(`Facade PACKAGE_VERSION ${String(barrelVersion)} does not match ${version}`);
|
|
337
|
+
}
|
|
339
338
|
for (const file of readdirSync(join(facadeDirectory, "src"))) {
|
|
340
339
|
if (/\.(dll|dylib|so)$/.test(file)) {
|
|
341
340
|
rmSync(join(facadeDirectory, "src", file), { force: true });
|
|
@@ -358,11 +357,18 @@ const packageNodeFacade = ({ output, nodeDirectory, nodePackage, version, native
|
|
|
358
357
|
const workspaceManifest = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
|
|
359
358
|
const catalog = workspaceManifest.catalog ?? {};
|
|
360
359
|
const workspaceVersions = localWorkspacePackages();
|
|
361
|
-
manifest.version
|
|
362
|
-
|
|
360
|
+
if (manifest.version !== version) {
|
|
361
|
+
throw new Error(`Facade package version ${String(manifest.version)} does not match ${version}`);
|
|
362
|
+
}
|
|
363
|
+
if (manifest.private === true) throw new Error(`${manifest.name} is private`);
|
|
363
364
|
manifest.license = manifest.license === "UNLICENSED" ? "Apache-2.0" : manifest.license;
|
|
364
365
|
manifest.optionalDependencies = Object.fromEntries(
|
|
365
|
-
Object.
|
|
366
|
+
Object.entries(manifest.optionalDependencies ?? {}).map(([name, dependency]) => {
|
|
367
|
+
if (dependency !== version) {
|
|
368
|
+
throw new Error(`${manifest.name} optional dependency ${name} does not match ${version}`);
|
|
369
|
+
}
|
|
370
|
+
return [name, dependency];
|
|
371
|
+
}),
|
|
366
372
|
);
|
|
367
373
|
manifest.dependencies = Object.fromEntries(
|
|
368
374
|
Object.entries(manifest.dependencies ?? {}).map(([name, dependency]) => [
|
|
@@ -435,7 +441,7 @@ const packagePython = ({
|
|
|
435
441
|
[];
|
|
436
442
|
writeFileSync(
|
|
437
443
|
pyproject,
|
|
438
|
-
|
|
444
|
+
preparePythonProjectForPublication(readFileSync(pyproject, "utf8"), {
|
|
439
445
|
packages: workspaceBindings.flatMap((binding) =>
|
|
440
446
|
binding.pythonPackage && binding.python
|
|
441
447
|
? [{ name: binding.pythonPackage, directory: binding.python }]
|
package/tasks/uniffi.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env -S bun
|
|
2
|
-
import { spawnSync } from "node:child_process";
|
|
3
2
|
import {
|
|
4
3
|
cpSync,
|
|
5
4
|
existsSync,
|
|
@@ -16,6 +15,7 @@ import { basename, dirname, join, resolve } from "node:path";
|
|
|
16
15
|
import { fileURLToPath } from "node:url";
|
|
17
16
|
import { parseArgs } from "node:util";
|
|
18
17
|
import { installPythonBindings } from "./uniffi-python.js";
|
|
18
|
+
import { captureTaskCommand, runLoggedTaskCommand } from "../src/_task-command.ts";
|
|
19
19
|
import { makeReadonly, makeWritable, stampGenerated } from "../src/generated.ts";
|
|
20
20
|
import type { RustWorkspaceMapping } from "../src/project-rs.ts";
|
|
21
21
|
import {
|
|
@@ -62,31 +62,22 @@ const normalizedOutput = (value: string): string =>
|
|
|
62
62
|
.replace(/[ \t]+$/gm, "")
|
|
63
63
|
.trim();
|
|
64
64
|
const run = (command: string, args: string[]) => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
throw new Error(`${command} failed: ${result.error.message}`, { cause: result.error });
|
|
72
|
-
}
|
|
73
|
-
if (result.status !== 0) throw new Error(`${command} exited with ${result.status}`);
|
|
65
|
+
runLoggedTaskCommand(root, command, args, {
|
|
66
|
+
onLine: (line) => {
|
|
67
|
+
const normalized = normalizedOutput(line);
|
|
68
|
+
if (normalized) process.stdout.write(`${normalized}\n`);
|
|
69
|
+
},
|
|
70
|
+
});
|
|
74
71
|
};
|
|
75
72
|
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
if (cargoMetadata.status !== 0) {
|
|
86
|
-
throw new Error(`cargo metadata exited with ${cargoMetadata.status}`);
|
|
87
|
-
}
|
|
88
|
-
const cargoTargetRoot = (JSON.parse(cargoMetadata.stdout) as { target_directory?: unknown })
|
|
89
|
-
.target_directory;
|
|
73
|
+
const cargoTargetRoot = (
|
|
74
|
+
JSON.parse(
|
|
75
|
+
captureTaskCommand(root, "cargo", ["metadata", "--format-version", "1", "--no-deps"], {
|
|
76
|
+
check: true,
|
|
77
|
+
stderr: "inherit",
|
|
78
|
+
}),
|
|
79
|
+
) as { target_directory?: unknown }
|
|
80
|
+
).target_directory;
|
|
90
81
|
if (typeof cargoTargetRoot !== "string" || !cargoTargetRoot) {
|
|
91
82
|
throw new Error("cargo metadata returned no target_directory");
|
|
92
83
|
}
|
package/tasks/version-check.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env -S bun
|
|
2
|
-
/** Verify that every committed package version matches
|
|
2
|
+
/** Verify that every committed package version matches the root VERSION file. */
|
|
3
3
|
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
-
import {
|
|
5
|
-
import * as exec from "@dbx-tools/core/exec";
|
|
4
|
+
import { join } from "node:path";
|
|
6
5
|
import * as projectUtils from "@dbx-tools/core/project-utils";
|
|
7
6
|
import { find } from "@dbx-tools/path";
|
|
8
7
|
import { json, log, object } from "@dbx-tools/shared-core";
|
|
9
8
|
import { parse } from "smol-toml";
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
9
|
+
import { captureTaskCommand } from "../src/_task-command.ts";
|
|
10
|
+
import { recordedPackages } from "../src/packages.ts";
|
|
12
11
|
import { readWorkspaceVersion } from "../src/workspace-version.ts";
|
|
13
12
|
|
|
14
13
|
const logger = log.logger("projen:version-check");
|
|
@@ -25,90 +24,59 @@ function pythonVersion(path: string): string | undefined {
|
|
|
25
24
|
return typeof manifest.project?.version === "string" ? manifest.project.version : undefined;
|
|
26
25
|
}
|
|
27
26
|
|
|
28
|
-
function cargoVersions(root: string): Array<{ name: string; version: string
|
|
27
|
+
function cargoVersions(root: string): Array<{ name: string; version: string }> {
|
|
29
28
|
if (!existsSync(join(root, "Cargo.toml"))) return [];
|
|
30
29
|
const locked = existsSync(join(root, "Cargo.lock"));
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
stdin: "ignore",
|
|
39
|
-
check: true,
|
|
40
|
-
},
|
|
30
|
+
const metadata = json.parseRecord(
|
|
31
|
+
captureTaskCommand(
|
|
32
|
+
root,
|
|
33
|
+
"cargo",
|
|
34
|
+
["metadata", ...(locked ? ["--locked"] : []), "--format-version", "1", "--no-deps"],
|
|
35
|
+
{ check: true, stderr: "inherit" },
|
|
36
|
+
),
|
|
41
37
|
);
|
|
42
|
-
const metadata = json.parseRecord(result.stdout ?? "");
|
|
43
38
|
if (!Array.isArray(metadata?.packages)) return [];
|
|
44
39
|
return metadata.packages.flatMap((candidate) => {
|
|
45
40
|
if (
|
|
46
41
|
!object.isRecord(candidate) ||
|
|
47
42
|
typeof candidate.name !== "string" ||
|
|
48
|
-
typeof candidate.version !== "string"
|
|
49
|
-
typeof candidate.manifest_path !== "string"
|
|
43
|
+
typeof candidate.version !== "string"
|
|
50
44
|
) {
|
|
51
45
|
return [];
|
|
52
46
|
}
|
|
53
|
-
return [
|
|
54
|
-
{
|
|
55
|
-
name: candidate.name,
|
|
56
|
-
version: candidate.version,
|
|
57
|
-
path: toPosix(relative(root, dirname(candidate.manifest_path))) || ".",
|
|
58
|
-
},
|
|
59
|
-
];
|
|
47
|
+
return [{ name: candidate.name, version: candidate.version }];
|
|
60
48
|
});
|
|
61
49
|
}
|
|
62
50
|
|
|
63
51
|
function main(): void {
|
|
64
52
|
const root = projectUtils.root() ?? process.cwd();
|
|
65
|
-
const
|
|
66
|
-
const graphPath = join(root, ".projen/release-units.json");
|
|
67
|
-
const graph = existsSync(graphPath)
|
|
68
|
-
? (JSON.parse(readFileSync(graphPath, "utf8")) as ReleaseUnitGraph)
|
|
69
|
-
: undefined;
|
|
70
|
-
const units = new Map(graph?.units.map((unit) => [unit.id, unit.version]) ?? []);
|
|
71
|
-
const projects = new Map(graph?.projects.map((entry) => [entry.path, entry]) ?? []);
|
|
53
|
+
const version = readWorkspaceVersion(root);
|
|
72
54
|
const mismatches: string[] = [];
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
if (releaseProject?.unit) return units.get(releaseProject.unit);
|
|
76
|
-
return graph?.mode === "independent" ? undefined : fixedVersion;
|
|
77
|
-
};
|
|
78
|
-
const check = (name: string, path: string, actual: string | undefined): void => {
|
|
79
|
-
const version = expected(path);
|
|
80
|
-
if (version !== undefined && actual !== version) {
|
|
81
|
-
mismatches.push(`${name}: ${actual ?? "missing"} != ${version}`);
|
|
82
|
-
}
|
|
55
|
+
const check = (name: string, actual: string | undefined): void => {
|
|
56
|
+
if (actual !== version) mismatches.push(`${name}: ${actual ?? "missing"} != ${version}`);
|
|
83
57
|
};
|
|
84
58
|
|
|
85
|
-
check("package.json",
|
|
59
|
+
check("package.json", manifestVersion(join(root, "package.json")));
|
|
86
60
|
for (const pkg of recordedPackages(root)) {
|
|
87
|
-
check(`${pkg.path}/package.json`,
|
|
61
|
+
check(`${pkg.path}/package.json`, manifestVersion(join(pkg.dir, "package.json")));
|
|
88
62
|
const barrel = join(pkg.dir, "index.ts");
|
|
89
63
|
if (existsSync(barrel)) {
|
|
90
64
|
const actual = /export const PACKAGE_VERSION = "([^"]+)";/.exec(
|
|
91
65
|
readFileSync(barrel, "utf8"),
|
|
92
66
|
)?.[1];
|
|
93
|
-
check(`${pkg.path}/index.ts`,
|
|
67
|
+
check(`${pkg.path}/index.ts`, actual);
|
|
94
68
|
}
|
|
95
69
|
}
|
|
96
70
|
|
|
97
71
|
for (const path of find.findFiles("**/pyproject.toml", { cwd: root })) {
|
|
98
|
-
check(path,
|
|
99
|
-
}
|
|
100
|
-
for (const pkg of cargoVersions(root)) {
|
|
101
|
-
check(`Cargo package ${pkg.name}`, pkg.path, pkg.version);
|
|
72
|
+
check(path, pythonVersion(join(root, path)));
|
|
102
73
|
}
|
|
74
|
+
for (const pkg of cargoVersions(root)) check(`Cargo package ${pkg.name}`, pkg.version);
|
|
103
75
|
|
|
104
76
|
if (mismatches.length > 0) {
|
|
105
|
-
throw new Error(`
|
|
77
|
+
throw new Error(`Workspace version mismatch:\n${mismatches.join("\n")}`);
|
|
106
78
|
}
|
|
107
|
-
logger.success(
|
|
108
|
-
graph
|
|
109
|
-
? `all package versions match ${graph.units.length} release units`
|
|
110
|
-
: `all workspace versions match ${fixedVersion}`,
|
|
111
|
-
);
|
|
79
|
+
logger.success(`all workspace package versions match ${version}`);
|
|
112
80
|
}
|
|
113
81
|
|
|
114
82
|
main();
|