@dbx-tools/cli 0.3.43 → 0.4.0
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/index.ts +1 -1
- package/lib/bin/dbx-tools.d.ts +2 -0
- package/lib/bin/dbx-tools.js +10 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.js +12 -0
- package/lib/src/bootstrap.d.ts +45 -0
- package/lib/src/bootstrap.js +186 -0
- package/lib/src/cli.d.ts +2 -0
- package/lib/src/cli.js +52 -0
- package/lib/src/pnpm.d.ts +8 -0
- package/lib/src/pnpm.js +81 -0
- package/lib/src/root.d.ts +27 -0
- package/lib/src/root.js +77 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/package.json +27 -11
- package/src/bootstrap.ts +47 -4
- package/src/cli.ts +9 -2
package/index.ts
CHANGED
|
@@ -6,7 +6,7 @@ export * as bootstrap from "./src/bootstrap";
|
|
|
6
6
|
export * as cli from "./src/cli";
|
|
7
7
|
export * as pnpm from "./src/pnpm";
|
|
8
8
|
export * as root from "./src/root";
|
|
9
|
-
export { bootstrapWorkspace, seedToolchain, runInitialSynth } from "./src/bootstrap";
|
|
9
|
+
export { ensureEngineCurrent, bootstrapWorkspace, seedToolchain, runInitialSynth } from "./src/bootstrap";
|
|
10
10
|
export { runCli } from "./src/cli";
|
|
11
11
|
export { resolvePnpmArgv, runPnpm, ensureWorkspaceReady, runProjen } from "./src/pnpm";
|
|
12
12
|
export { findWorkspaceRoot, needsBootstrap, needsInstall, needsToolchain, workspaceRoot, rootLabel } from "./src/root";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env -S npx tsx
|
|
2
|
+
/**
|
|
3
|
+
* `dbx-tools` bootstraps uninitialized workspaces, then forwards to projen.
|
|
4
|
+
*/
|
|
5
|
+
import { runCli } from "../src/cli.js";
|
|
6
|
+
runCli(process.argv).catch((err) => {
|
|
7
|
+
console.error(err);
|
|
8
|
+
process.exit(1);
|
|
9
|
+
});
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGJ4LXRvb2xzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vYmluL2RieC10b29scy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0E7O0dBRUc7QUFDSCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRXBDLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBWSxFQUFFLEVBQUU7SUFDMUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNuQixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiIyEvdXNyL2Jpbi9lbnYgLVMgbnB4IHRzeFxuLyoqXG4gKiBgZGJ4LXRvb2xzYCBib290c3RyYXBzIHVuaW5pdGlhbGl6ZWQgd29ya3NwYWNlcywgdGhlbiBmb3J3YXJkcyB0byBwcm9qZW4uXG4gKi9cbmltcG9ydCB7IHJ1bkNsaSB9IGZyb20gXCIuLi9zcmMvY2xpXCI7XG5cbnJ1bkNsaShwcm9jZXNzLmFyZ3YpLmNhdGNoKChlcnI6IHVua25vd24pID0+IHtcbiAgY29uc29sZS5lcnJvcihlcnIpO1xuICBwcm9jZXNzLmV4aXQoMSk7XG59KTtcbiJdfQ==
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * as bootstrap from "./src/bootstrap.js";
|
|
2
|
+
export * as cli from "./src/cli.js";
|
|
3
|
+
export * as pnpm from "./src/pnpm.js";
|
|
4
|
+
export * as root from "./src/root.js";
|
|
5
|
+
export { ensureEngineCurrent, bootstrapWorkspace, seedToolchain, runInitialSynth } from "./src/bootstrap.js";
|
|
6
|
+
export { runCli } from "./src/cli.js";
|
|
7
|
+
export { resolvePnpmArgv, runPnpm, ensureWorkspaceReady, runProjen } from "./src/pnpm.js";
|
|
8
|
+
export { findWorkspaceRoot, needsBootstrap, needsInstall, needsToolchain, workspaceRoot, rootLabel } from "./src/root.js";
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// GENERATED by projen watch - DO NOT EDIT.
|
|
2
|
+
// Regenerated from the exporting modules in ./src.
|
|
3
|
+
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
|
+
export * as bootstrap from "./src/bootstrap.js";
|
|
5
|
+
export * as cli from "./src/cli.js";
|
|
6
|
+
export * as pnpm from "./src/pnpm.js";
|
|
7
|
+
export * as root from "./src/root.js";
|
|
8
|
+
export { ensureEngineCurrent, bootstrapWorkspace, seedToolchain, runInitialSynth } from "./src/bootstrap.js";
|
|
9
|
+
export { runCli } from "./src/cli.js";
|
|
10
|
+
export { resolvePnpmArgv, runPnpm, ensureWorkspaceReady, runProjen } from "./src/pnpm.js";
|
|
11
|
+
export { findWorkspaceRoot, needsBootstrap, needsInstall, needsToolchain, workspaceRoot, rootLabel } from "./src/root.js";
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxPQUFPLEtBQUssU0FBUyxNQUFNLGlCQUFpQixDQUFDO0FBQzdDLE9BQU8sS0FBSyxHQUFHLE1BQU0sV0FBVyxDQUFDO0FBQ2pDLE9BQU8sS0FBSyxJQUFJLE1BQU0sWUFBWSxDQUFDO0FBQ25DLE9BQU8sS0FBSyxJQUFJLE1BQU0sWUFBWSxDQUFDO0FBQ25DLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxrQkFBa0IsRUFBRSxhQUFhLEVBQUUsZUFBZSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDMUcsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNuQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxTQUFTLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDdkYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGNBQWMsRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsTUFBTSxZQUFZLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBHRU5FUkFURUQgYnkgcHJvamVuIHdhdGNoIC0gRE8gTk9UIEVESVQuXG4vLyBSZWdlbmVyYXRlZCBmcm9tIHRoZSBleHBvcnRpbmcgbW9kdWxlcyBpbiAuL3NyYy5cbi8vIEhhbmQgZWRpdHMgYXJlIG92ZXJ3cml0dGVuIG9uIHRoZSBuZXh0IHdhdGNoOyB0aGlzIGZpbGUgaXMgcmVhZC1vbmx5LlxuXG5leHBvcnQgKiBhcyBib290c3RyYXAgZnJvbSBcIi4vc3JjL2Jvb3RzdHJhcFwiO1xuZXhwb3J0ICogYXMgY2xpIGZyb20gXCIuL3NyYy9jbGlcIjtcbmV4cG9ydCAqIGFzIHBucG0gZnJvbSBcIi4vc3JjL3BucG1cIjtcbmV4cG9ydCAqIGFzIHJvb3QgZnJvbSBcIi4vc3JjL3Jvb3RcIjtcbmV4cG9ydCB7IGVuc3VyZUVuZ2luZUN1cnJlbnQsIGJvb3RzdHJhcFdvcmtzcGFjZSwgc2VlZFRvb2xjaGFpbiwgcnVuSW5pdGlhbFN5bnRoIH0gZnJvbSBcIi4vc3JjL2Jvb3RzdHJhcFwiO1xuZXhwb3J0IHsgcnVuQ2xpIH0gZnJvbSBcIi4vc3JjL2NsaVwiO1xuZXhwb3J0IHsgcmVzb2x2ZVBucG1Bcmd2LCBydW5QbnBtLCBlbnN1cmVXb3Jrc3BhY2VSZWFkeSwgcnVuUHJvamVuIH0gZnJvbSBcIi4vc3JjL3BucG1cIjtcbmV4cG9ydCB7IGZpbmRXb3Jrc3BhY2VSb290LCBuZWVkc0Jvb3RzdHJhcCwgbmVlZHNJbnN0YWxsLCBuZWVkc1Rvb2xjaGFpbiwgd29ya3NwYWNlUm9vdCwgcm9vdExhYmVsIH0gZnJvbSBcIi4vc3JjL3Jvb3RcIjtcbiJdfQ==
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upgrade an established workspace whose installed engine predates this CLI.
|
|
3
|
+
*
|
|
4
|
+
* Bootstrapping pins the engine once, and nothing afterwards revisits it - so a
|
|
5
|
+
* workspace created months ago kept resolving its original engine no matter how
|
|
6
|
+
* current the CLI invoking it was, and failed inside the OLD engine's code
|
|
7
|
+
* (`sync --watch` dying on a `concurrently` that engine never declared). The two
|
|
8
|
+
* are released in lockstep, so this CLI's version is exactly the engine it
|
|
9
|
+
* expects.
|
|
10
|
+
*
|
|
11
|
+
* Only ever moves FORWARD: an engine at or ahead of this CLI is left alone, so
|
|
12
|
+
* an older CLI cannot downgrade a workspace.
|
|
13
|
+
*/
|
|
14
|
+
export declare function ensureEngineCurrent(root: string): void;
|
|
15
|
+
/**
|
|
16
|
+
* Turn a folder into a functioning dbx-tools workspace: `pnpm init`, seed
|
|
17
|
+
* `pnpm-workspace.yaml`, add `projen`/`typescript`/`tsx` + the engine package,
|
|
18
|
+
* write a minimal `.projenrc.ts`, synth once (with `PROJEN_DISABLE_POST`), then
|
|
19
|
+
* install. Does not run barrels - run `pnpm run barrels` or a full projen synth
|
|
20
|
+
* post-install to generate package barrels.
|
|
21
|
+
*
|
|
22
|
+
* Every step is idempotent and self-guarded, so this is safe to run against a
|
|
23
|
+
* folder that ALREADY has a hand-authored `.projenrc.ts` (and even a committed
|
|
24
|
+
* `package.json`) but is missing the installed toolchain - e.g. a freshly copied
|
|
25
|
+
* project whose generated files (including manifests) are gitignored. In that
|
|
26
|
+
* case `pnpm init` and the `.projenrc.ts` scaffold are skipped, but the engine +
|
|
27
|
+
* projen + tsx are (re)installed so the subsequent synth can regenerate
|
|
28
|
+
* everything. See {@link seedToolchain}.
|
|
29
|
+
*/
|
|
30
|
+
export declare function bootstrapWorkspace(root: string, projenSpecifier?: string): void;
|
|
31
|
+
/**
|
|
32
|
+
* Install the toolchain a synth needs (`projen`, `typescript`, `tsx`, and the
|
|
33
|
+
* dbx-tools engine), seeding a `package.json` and `pnpm-workspace.yaml` first
|
|
34
|
+
* when absent. Idempotent: run it whenever the engine is missing, so a copied
|
|
35
|
+
* project with a `.projenrc.ts` but no `node_modules`/manifests can be brought
|
|
36
|
+
* up to a synth-ready state without full bootstrapping.
|
|
37
|
+
*/
|
|
38
|
+
export declare function seedToolchain(root: string, projenSpecifier?: string): void;
|
|
39
|
+
/**
|
|
40
|
+
* Run the initial synth by executing `.projenrc.ts` directly with tsx (with
|
|
41
|
+
* `PROJEN_DISABLE_POST` set), NOT `projen <task>`. Use right after seeding a
|
|
42
|
+
* fresh workspace: the projen TASKS (`sync`, `barrels`, ...) only exist once
|
|
43
|
+
* `.projenrc.ts` has run once, so `projen sync` can't be the bootstrapping step.
|
|
44
|
+
*/
|
|
45
|
+
export declare function runInitialSynth(root: string): void;
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bootstrap a brand-new folder into a working dbx-tools workspace before projen runs.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
import { intro, outro } from "@clack/prompts";
|
|
10
|
+
import { exec } from "@dbx-tools/core";
|
|
11
|
+
import { json } from "@dbx-tools/shared-core";
|
|
12
|
+
import { resolvePnpmArgv, runPnpm } from "./pnpm.js";
|
|
13
|
+
import { rootLabel } from "./root.js";
|
|
14
|
+
/** Fallback when this CLI's own version isn't a real release (an in-repo `0.0.0`). */
|
|
15
|
+
const FALLBACK_PROJEN_SPECIFIER = "@dbx-tools/projen@latest";
|
|
16
|
+
/**
|
|
17
|
+
* Install the engine at THIS CLI's own version. The two are released together by
|
|
18
|
+
* the root `bump`, so the matching engine always exists on the registry.
|
|
19
|
+
*
|
|
20
|
+
* Not `@latest`, and not a bare `@dbx-tools/projen`. A bare specifier can land on
|
|
21
|
+
* a stray `0.0.0`, whose `^0.0.0` caret then reaches no real release. `@latest`
|
|
22
|
+
* has a subtler failure: pnpm 11 applies a `minimumReleaseAge` delay, so for the
|
|
23
|
+
* first day after a release it deliberately resolves a dist-tag to the newest
|
|
24
|
+
* version OLDER than the threshold and merely notes the newer one
|
|
25
|
+
* (`+ @dbx-tools/projen 0.1.24 (0.3.42 is available)`). A bootstrap run right
|
|
26
|
+
* after a release therefore installed a months-old engine against a current CLI,
|
|
27
|
+
* which is how `sync --watch` died on an engine predating its `concurrently`
|
|
28
|
+
* dependency. An explicit range admits only the version we want, so the age
|
|
29
|
+
* heuristic has nothing older to fall back to.
|
|
30
|
+
*/
|
|
31
|
+
function defaultProjenSpecifier() {
|
|
32
|
+
const version = ownVersion();
|
|
33
|
+
return version ? `@dbx-tools/projen@^${version}` : FALLBACK_PROJEN_SPECIFIER;
|
|
34
|
+
}
|
|
35
|
+
/** This CLI's own released version, or `undefined` for an in-repo `0.0.0` build. */
|
|
36
|
+
function ownVersion() {
|
|
37
|
+
try {
|
|
38
|
+
const manifestPath = fileURLToPath(new URL("../package.json", import.meta.url));
|
|
39
|
+
const version = json.parseRecord(readFileSync(manifestPath, "utf8"))?.version;
|
|
40
|
+
return typeof version === "string" && version !== "0.0.0" ? version : undefined;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** Compare `x.y.z` triples; returns <0, 0, or >0. Missing parts count as 0. */
|
|
47
|
+
function compareVersions(a, b) {
|
|
48
|
+
const parts = (v) => v.split(".").map((p) => Number.parseInt(p, 10) || 0);
|
|
49
|
+
const [x, y] = [parts(a), parts(b)];
|
|
50
|
+
return x[0] - y[0] || x[1] - y[1] || x[2] - y[2];
|
|
51
|
+
}
|
|
52
|
+
/** Version of the engine currently installed at `root`, if any. */
|
|
53
|
+
function installedEngineVersion(root) {
|
|
54
|
+
try {
|
|
55
|
+
const manifest = join(root, "node_modules", "@dbx-tools", "projen", "package.json");
|
|
56
|
+
const version = json.parseRecord(readFileSync(manifest, "utf8"))?.version;
|
|
57
|
+
return typeof version === "string" ? version : undefined;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Upgrade an established workspace whose installed engine predates this CLI.
|
|
65
|
+
*
|
|
66
|
+
* Bootstrapping pins the engine once, and nothing afterwards revisits it - so a
|
|
67
|
+
* workspace created months ago kept resolving its original engine no matter how
|
|
68
|
+
* current the CLI invoking it was, and failed inside the OLD engine's code
|
|
69
|
+
* (`sync --watch` dying on a `concurrently` that engine never declared). The two
|
|
70
|
+
* are released in lockstep, so this CLI's version is exactly the engine it
|
|
71
|
+
* expects.
|
|
72
|
+
*
|
|
73
|
+
* Only ever moves FORWARD: an engine at or ahead of this CLI is left alone, so
|
|
74
|
+
* an older CLI cannot downgrade a workspace.
|
|
75
|
+
*/
|
|
76
|
+
export function ensureEngineCurrent(root) {
|
|
77
|
+
const expected = ownVersion();
|
|
78
|
+
if (!expected)
|
|
79
|
+
return;
|
|
80
|
+
const installed = installedEngineVersion(root);
|
|
81
|
+
if (installed && compareVersions(installed, expected) >= 0)
|
|
82
|
+
return;
|
|
83
|
+
runPnpm(["add", "-D", defaultProjenSpecifier()], root);
|
|
84
|
+
}
|
|
85
|
+
// Reach the class through its module NAMESPACE. Current engines also hoist it
|
|
86
|
+
// flat, but every engine ever published exports the namespace, and this template
|
|
87
|
+
// is resolved against `@latest` - a flat import dies on an older one with
|
|
88
|
+
// "does not provide an export named 'DBXToolsNodeProject'".
|
|
89
|
+
const PROJENRC_TEMPLATE = `import { project as projectApi } from "@dbx-tools/projen";
|
|
90
|
+
|
|
91
|
+
const project = new projectApi.DBXToolsNodeProject();
|
|
92
|
+
project.synth();
|
|
93
|
+
`;
|
|
94
|
+
/** Seed `pnpm-workspace.yaml` so the first \`pnpm add\` can allow esbuild non-interactively. */
|
|
95
|
+
const WORKSPACE_SEED = `packages: []
|
|
96
|
+
allowBuilds:
|
|
97
|
+
esbuild: true
|
|
98
|
+
`;
|
|
99
|
+
/**
|
|
100
|
+
* Turn a folder into a functioning dbx-tools workspace: `pnpm init`, seed
|
|
101
|
+
* `pnpm-workspace.yaml`, add `projen`/`typescript`/`tsx` + the engine package,
|
|
102
|
+
* write a minimal `.projenrc.ts`, synth once (with `PROJEN_DISABLE_POST`), then
|
|
103
|
+
* install. Does not run barrels - run `pnpm run barrels` or a full projen synth
|
|
104
|
+
* post-install to generate package barrels.
|
|
105
|
+
*
|
|
106
|
+
* Every step is idempotent and self-guarded, so this is safe to run against a
|
|
107
|
+
* folder that ALREADY has a hand-authored `.projenrc.ts` (and even a committed
|
|
108
|
+
* `package.json`) but is missing the installed toolchain - e.g. a freshly copied
|
|
109
|
+
* project whose generated files (including manifests) are gitignored. In that
|
|
110
|
+
* case `pnpm init` and the `.projenrc.ts` scaffold are skipped, but the engine +
|
|
111
|
+
* projen + tsx are (re)installed so the subsequent synth can regenerate
|
|
112
|
+
* everything. See {@link seedToolchain}.
|
|
113
|
+
*/
|
|
114
|
+
export function bootstrapWorkspace(root, projenSpecifier = defaultProjenSpecifier()) {
|
|
115
|
+
intro(`Bootstrapping dbx-tools workspace in ${rootLabel(root)}`);
|
|
116
|
+
seedToolchain(root, projenSpecifier);
|
|
117
|
+
const projenrc = join(root, ".projenrc.ts");
|
|
118
|
+
if (!existsSync(projenrc)) {
|
|
119
|
+
writeFileSync(projenrc, PROJENRC_TEMPLATE);
|
|
120
|
+
}
|
|
121
|
+
runInitialSynth(root);
|
|
122
|
+
runPnpm(["install", "--no-frozen-lockfile", "--force"], root);
|
|
123
|
+
outro("Workspace ready - re-run dbx-tools or add packages under packages/");
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Install the toolchain a synth needs (`projen`, `typescript`, `tsx`, and the
|
|
127
|
+
* dbx-tools engine), seeding a `package.json` and `pnpm-workspace.yaml` first
|
|
128
|
+
* when absent. Idempotent: run it whenever the engine is missing, so a copied
|
|
129
|
+
* project with a `.projenrc.ts` but no `node_modules`/manifests can be brought
|
|
130
|
+
* up to a synth-ready state without full bootstrapping.
|
|
131
|
+
*/
|
|
132
|
+
export function seedToolchain(root, projenSpecifier = defaultProjenSpecifier()) {
|
|
133
|
+
const manifestPath = join(root, "package.json");
|
|
134
|
+
if (!existsSync(manifestPath)) {
|
|
135
|
+
runPnpm(["init"], root);
|
|
136
|
+
normalizeSeedManifest(manifestPath);
|
|
137
|
+
}
|
|
138
|
+
const workspaceFile = join(root, "pnpm-workspace.yaml");
|
|
139
|
+
if (!existsSync(workspaceFile)) {
|
|
140
|
+
writeFileSync(workspaceFile, WORKSPACE_SEED);
|
|
141
|
+
}
|
|
142
|
+
runPnpm(["add", "-D", "projen", "typescript@^5.9.3", "tsx@^4.23.0", projenSpecifier], root);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Make what `pnpm init` produced safe to synth against. Two corrections, both
|
|
146
|
+
* because that output varies by pnpm version:
|
|
147
|
+
*
|
|
148
|
+
* - drop `devEngines`, which pnpm 11 seeds as `packageManager: { name: "pnpm",
|
|
149
|
+
* onFail: "download" }`. Any npm-based tool later in the chain (an
|
|
150
|
+
* `npx`/dlx fallback) then refuses with EBADDEVENGINES, its runner being npm;
|
|
151
|
+
* - force `type: "module"`, which pnpm 11 writes and pnpm 10 does not. tsx
|
|
152
|
+
* picks the entry's format from the nearest manifest, so without it
|
|
153
|
+
* `.projenrc.ts` loads as CJS and the first dependency using top-level await
|
|
154
|
+
* dies on "not supported with the cjs output format".
|
|
155
|
+
*
|
|
156
|
+
* projen regenerates the whole manifest at synth, so this only has to hold the
|
|
157
|
+
* seed together long enough to get there.
|
|
158
|
+
*/
|
|
159
|
+
function normalizeSeedManifest(manifestPath) {
|
|
160
|
+
try {
|
|
161
|
+
const manifest = json.parseRecord(readFileSync(manifestPath, "utf8"));
|
|
162
|
+
if (!manifest)
|
|
163
|
+
return;
|
|
164
|
+
delete manifest.devEngines;
|
|
165
|
+
manifest.type = "module";
|
|
166
|
+
writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
// A malformed/absent manifest here just means the later `pnpm add` recreates it.
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Run the initial synth by executing `.projenrc.ts` directly with tsx (with
|
|
174
|
+
* `PROJEN_DISABLE_POST` set), NOT `projen <task>`. Use right after seeding a
|
|
175
|
+
* fresh workspace: the projen TASKS (`sync`, `barrels`, ...) only exist once
|
|
176
|
+
* `.projenrc.ts` has run once, so `projen sync` can't be the bootstrapping step.
|
|
177
|
+
*/
|
|
178
|
+
export function runInitialSynth(root) {
|
|
179
|
+
const [command, ...prefix] = resolvePnpmArgv();
|
|
180
|
+
exec.spawnSync(command, [...prefix, "exec", "tsx", ".projenrc.ts"], {
|
|
181
|
+
cwd: root,
|
|
182
|
+
env: { ...process.env, PROJEN_DISABLE_POST: "true" },
|
|
183
|
+
check: true,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9vdHN0cmFwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Jvb3RzdHJhcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBQ0gsT0FBTyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDakMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN2QyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDOUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxPQUFPLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDbEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUVuQyxzRkFBc0Y7QUFDdEYsTUFBTSx5QkFBeUIsR0FBRywwQkFBMEIsQ0FBQztBQUU3RDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILFNBQVMsc0JBQXNCO0lBQzdCLE1BQU0sT0FBTyxHQUFHLFVBQVUsRUFBRSxDQUFDO0lBQzdCLE9BQU8sT0FBTyxDQUFDLENBQUMsQ0FBQyxzQkFBc0IsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLHlCQUF5QixDQUFDO0FBQy9FLENBQUM7QUFFRCxvRkFBb0Y7QUFDcEYsU0FBUyxVQUFVO0lBQ2pCLElBQUksQ0FBQztRQUNILE1BQU0sWUFBWSxHQUFHLGFBQWEsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxpQkFBaUIsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDaEYsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMs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O1FBQ3RFLElBQUksQ0FBQyxRQUFRO1lBQUUsT0FBTztRQUN0QixPQUFPLFFBQVEsQ0FBQyxVQUFVLENBQUM7UUFDM0IsUUFBUSxDQUFDLElBQUksR0FBRyxRQUFRLENBQUM7UUFDekIsYUFBYSxDQUFDLFlBQVksRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEUsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLGlGQUFpRjtJQUNuRixDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FBQyxJQUFZO0lBQzFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsR0FBRyxNQUFNLENBQUMsR0FBRyxlQUFlLEVBQUUsQ0FBQztJQUMvQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxDQUFDLEdBQUcsTUFBTSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsY0FBYyxDQUFDLEVBQUU7UUFDbEUsR0FBRyxFQUFFLElBQUk7UUFDVCxHQUFHLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxHQUFHLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxFQUFFO1FBQ3BELEtBQUssRUFBRSxJQUFJO0tBQ1osQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQm9vdHN0cmFwIGEgYnJhbmQtbmV3IGZvbGRlciBpbnRvIGEgd29ya2luZyBkYngtdG9vbHMgd29ya3NwYWNlIGJlZm9yZSBwcm9qZW4gcnVucy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cbmltcG9ydCB7IGV4aXN0c1N5bmMsIHJlYWRGaWxlU3luYywgd3JpdGVGaWxlU3luYyB9IGZyb20gXCJub2RlOmZzXCI7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgZmlsZVVSTFRvUGF0aCB9IGZyb20gXCJub2RlOnVybFwiO1xuaW1wb3J0IHsgaW50cm8sIG91dHJvIH0gZnJvbSBcIkBjbGFjay9wcm9tcHRzXCI7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSBcIkBkYngtdG9vbHMvY29yZVwiO1xuaW1wb3J0IHsganNvbiB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyByZXNvbHZlUG5wbUFyZ3YsIHJ1blBucG0gfSBmcm9tIFwiLi9wbnBtXCI7XG5pbXBvcnQgeyByb290TGFiZWwgfSBmcm9tIFwiLi9yb290XCI7XG5cbi8qKiBGYWxsYmFjayB3aGVuIHRoaXMgQ0xJJ3Mgb3duIHZlcnNpb24gaXNuJ3QgYSByZWFsIHJlbGVhc2UgKGFuIGluLXJlcG8gYDAuMC4wYCkuICovXG5jb25zdCBGQUxMQkFDS19QUk9KRU5fU1BFQ0lGSUVSID0gXCJAZGJ4LXRvb2xzL3Byb2plbkBsYXRlc3RcIjtcblxuLyoqXG4gKiBJbnN0YWxsIHRoZSBlbmdpbmUgYXQgVEhJUyBDTEkncyBvd24gdmVyc2lvbi4gVGhlIHR3byBhcmUgcmVsZWFzZWQgdG9nZXRoZXIgYnlcbiAqIHRoZSByb290IGBidW1wYCwgc28gdGhlIG1hdGNoaW5nIGVuZ2luZSBhbHdheXMgZXhpc3RzIG9uIHRoZSByZWdpc3RyeS5cbiAqXG4gKiBOb3QgYEBsYXRlc3RgLCBhbmQgbm90IGEgYmFyZSBgQGRieC10b29scy9wcm9qZW5gLiBBIGJhcmUgc3BlY2lmaWVyIGNhbiBsYW5kIG9uXG4gKiBhIHN0cmF5IGAwLjAuMGAsIHdob3NlIGBeMC4wLjBgIGNhcmV0IHRoZW4gcmVhY2hlcyBubyByZWFsIHJlbGVhc2UuIGBAbGF0ZXN0YFxuICogaGFzIGEgc3VidGxlciBmYWlsdXJlOiBwbnBtIDExIGFwcGxpZXMgYSBgbWluaW11bVJlbGVhc2VBZ2VgIGRlbGF5LCBzbyBmb3IgdGhlXG4gKiBmaXJzdCBkYXkgYWZ0ZXIgYSByZWxlYXNlIGl0IGRlbGliZXJhdGVseSByZXNvbHZlcyBhIGRpc3QtdGFnIHRvIHRoZSBuZXdlc3RcbiAqIHZlcnNpb24gT0xERVIgdGhhbiB0aGUgdGhyZXNob2xkIGFuZCBtZXJlbHkgbm90ZXMgdGhlIG5ld2VyIG9uZVxuICogKGArIEBkYngtdG9vbHMvcHJvamVuIDAuMS4yNCAoMC4zLjQyIGlzIGF2YWlsYWJsZSlgKS4gQSBib290c3RyYXAgcnVuIHJpZ2h0XG4gKiBhZnRlciBhIHJlbGVhc2UgdGhlcmVmb3JlIGluc3RhbGxlZCBhIG1vbnRocy1vbGQgZW5naW5lIGFnYWluc3QgYSBjdXJyZW50IENMSSxcbiAqIHdoaWNoIGlzIGhvdyBgc3luYyAtLXdhdGNoYCBkaWVkIG9uIGFuIGVuZ2luZSBwcmVkYXRpbmcgaXRzIGBjb25jdXJyZW50bHlgXG4gKiBkZXBlbmRlbmN5LiBBbiBleHBsaWNpdCByYW5nZSBhZG1pdHMgb25seSB0aGUgdmVyc2lvbiB3ZSB3YW50LCBzbyB0aGUgYWdlXG4gKiBoZXVyaXN0aWMgaGFzIG5vdGhpbmcgb2xkZXIgdG8gZmFsbCBiYWNrIHRvLlxuICovXG5mdW5jdGlvbiBkZWZhdWx0UHJvamVuU3BlY2lmaWVyKCk6IHN0cmluZyB7XG4gIGNvbnN0IHZlcnNpb24gPSBvd25WZXJzaW9uKCk7XG4gIHJldHVybiB2ZXJzaW9uID8gYEBkYngtdG9vbHMvcHJvamVuQF4ke3ZlcnNpb259YCA6IEZBTExCQUNLX1BST0pFTl9TUEVDSUZJRVI7XG59XG5cbi8qKiBUaGlzIENMSSdzIG93biByZWxlYXNlZCB2ZXJzaW9uLCBvciBgdW5kZWZpbmVkYCBmb3IgYW4gaW4tcmVwbyBgMC4wLjBgIGJ1aWxkLiAqL1xuZnVuY3Rpb24gb3duVmVyc2lvbigpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICB0cnkge1xuICAgIGNvbnN0IG1hbmlmZXN0UGF0aCA9IGZpbGVVUkxUb1BhdGgobmV3IFVSTChcIi4uL3BhY2thZ2UuanNvblwiLCBpbXBvcnQubWV0YS51cmwpKTtcbiAgICBjb25zdCB2ZXJzaW9uID0ganNvbi5wYXJzZVJlY29yZChyZWFkRmlsZVN5bmMobWFuaWZlc3RQYXRoLCBcInV0ZjhcIikpPy52ZXJzaW9uO1xuICAgIHJldHVybiB0eXBlb2YgdmVyc2lvbiA9PT0gXCJzdHJpbmdcIiAmJiB2ZXJzaW9uICE9PSBcIjAuMC4wXCIgPyB2ZXJzaW9uIDogdW5kZWZpbmVkO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbi8qKiBDb21wYXJlIGB4LnkuemAgdHJpcGxlczsgcmV0dXJucyA8MCwgMCwgb3IgPjAuIE1pc3NpbmcgcGFydHMgY291bnQgYXMgMC4gKi9cbmZ1bmN0aW9uIGNvbXBhcmVWZXJzaW9ucyhhOiBzdHJpbmcsIGI6IHN0cmluZyk6IG51bWJlciB7XG4gIGNvbnN0IHBhcnRzID0gKHY6IHN0cmluZykgPT4gdi5zcGxpdChcIi5cIikubWFwKChwKSA9PiBOdW1iZXIucGFyc2VJbnQocCwgMTApIHx8IDApO1xuICBjb25zdCBbeCwgeV0gPSBbcGFydHMoYSksIHBhcnRzKGIpXTtcbiAgcmV0dXJuIHhbMF0gLSB5WzBdIHx8IHhbMV0gLSB5WzFdIHx8IHhbMl0gLSB5WzJdO1xufVxuXG4vKiogVmVyc2lvbiBvZiB0aGUgZW5naW5lIGN1cnJlbnRseSBpbnN0YWxsZWQgYXQgYHJvb3RgLCBpZiBhbnkuICovXG5mdW5jdGlvbiBpbnN0YWxsZWRFbmdpbmVWZXJzaW9uKHJvb3Q6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHRyeSB7XG4gICAgY29uc3QgbWFuaWZlc3QgPSBqb2luKHJvb3QsIFwibm9kZV9tb2R1bGVzXCIsIFwiQGRieC10b29sc1wiLCBcInByb2plblwiLCBcInBhY2thZ2UuanNvblwiKTtcbiAgICBjb25zdCB2ZXJzaW9uID0ganNvbi5wYXJzZVJlY29yZChyZWFkRmlsZVN5bmMobWFuaWZlc3QsIFwidXRmOFwiKSk/LnZlcnNpb247XG4gICAgcmV0dXJuIHR5cGVvZiB2ZXJzaW9uID09PSBcInN0cmluZ1wiID8gdmVyc2lvbiA6IHVuZGVmaW5lZDtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG4vKipcbiAqIFVwZ3JhZGUgYW4gZXN0YWJsaXNoZWQgd29ya3NwYWNlIHdob3NlIGluc3RhbGxlZCBlbmdpbmUgcHJlZGF0ZXMgdGhpcyBDTEkuXG4gKlxuICogQm9vdHN0cmFwcGluZyBwaW5zIHRoZSBlbmdpbmUgb25jZSwgYW5kIG5vdGhpbmcgYWZ0ZXJ3YXJkcyByZXZpc2l0cyBpdCAtIHNvIGFcbiAqIHdvcmtzcGFjZSBjcmVhdGVkIG1vbnRocyBhZ28ga2VwdCByZXNvbHZpbmcgaXRzIG9yaWdpbmFsIGVuZ2luZSBubyBtYXR0ZXIgaG93XG4gKiBjdXJyZW50IHRoZSBDTEkgaW52b2tpbmcgaXQgd2FzLCBhbmQgZmFpbGVkIGluc2lkZSB0aGUgT0xEIGVuZ2luZSdzIGNvZGVcbiAqIChgc3luYyAtLXdhdGNoYCBkeWluZyBvbiBhIGBjb25jdXJyZW50bHlgIHRoYXQgZW5naW5lIG5ldmVyIGRlY2xhcmVkKS4gVGhlIHR3b1xuICogYXJlIHJlbGVhc2VkIGluIGxvY2tzdGVwLCBzbyB0aGlzIENMSSdzIHZlcnNpb24gaXMgZXhhY3RseSB0aGUgZW5naW5lIGl0XG4gKiBleHBlY3RzLlxuICpcbiAqIE9ubHkgZXZlciBtb3ZlcyBGT1JXQVJEOiBhbiBlbmdpbmUgYXQgb3IgYWhlYWQgb2YgdGhpcyBDTEkgaXMgbGVmdCBhbG9uZSwgc29cbiAqIGFuIG9sZGVyIENMSSBjYW5ub3QgZG93bmdyYWRlIGEgd29ya3NwYWNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZW5zdXJlRW5naW5lQ3VycmVudChyb290OiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3QgZXhwZWN0ZWQgPSBvd25WZXJzaW9uKCk7XG4gIGlmICghZXhwZWN0ZWQpIHJldHVybjtcbiAgY29uc3QgaW5zdGFsbGVkID0gaW5zdGFsbGVkRW5naW5lVmVyc2lvbihyb290KTtcbiAgaWYgKGluc3RhbGxlZCAmJiBjb21wYXJlVmVyc2lvbnMoaW5zdGFsbGVkLCBleHBlY3RlZCkgPj0gMCkgcmV0dXJuO1xuICBydW5QbnBtKFtcImFkZFwiLCBcIi1EXCIsIGRlZmF1bHRQcm9qZW5TcGVjaWZpZXIoKV0sIHJvb3QpO1xufVxuXG4vLyBSZWFjaCB0aGUgY2xhc3MgdGhyb3VnaCBpdHMgbW9kdWxlIE5BTUVTUEFDRS4gQ3VycmVudCBlbmdpbmVzIGFsc28gaG9pc3QgaXRcbi8vIGZsYXQsIGJ1dCBldmVyeSBlbmdpbmUgZXZlciBwdWJsaXNoZWQgZXhwb3J0cyB0aGUgbmFtZXNwYWNlLCBhbmQgdGhpcyB0ZW1wbGF0ZVxuLy8gaXMgcmVzb2x2ZWQgYWdhaW5zdCBgQGxhdGVzdGAgLSBhIGZsYXQgaW1wb3J0IGRpZXMgb24gYW4gb2xkZXIgb25lIHdpdGhcbi8vIFwiZG9lcyBub3QgcHJvdmlkZSBhbiBleHBvcnQgbmFtZWQgJ0RCWFRvb2xzTm9kZVByb2plY3QnXCIuXG5jb25zdCBQUk9KRU5SQ19URU1QTEFURSA9IGBpbXBvcnQgeyBwcm9qZWN0IGFzIHByb2plY3RBcGkgfSBmcm9tIFwiQGRieC10b29scy9wcm9qZW5cIjtcblxuY29uc3QgcHJvamVjdCA9IG5ldyBwcm9qZWN0QXBpLkRCWFRvb2xzTm9kZVByb2plY3QoKTtcbnByb2plY3Quc3ludGgoKTtcbmA7XG5cbi8qKiBTZWVkIGBwbnBtLXdvcmtzcGFjZS55YW1sYCBzbyB0aGUgZmlyc3QgXFxgcG5wbSBhZGRcXGAgY2FuIGFsbG93IGVzYnVpbGQgbm9uLWludGVyYWN0aXZlbHkuICovXG5jb25zdCBXT1JLU1BBQ0VfU0VFRCA9IGBwYWNrYWdlczogW11cbmFsbG93QnVpbGRzOlxuICBlc2J1aWxkOiB0cnVlXG5gO1xuXG4vKipcbiAqIFR1cm4gYSBmb2xkZXIgaW50byBhIGZ1bmN0aW9uaW5nIGRieC10b29scyB3b3Jrc3BhY2U6IGBwbnBtIGluaXRgLCBzZWVkXG4gKiBgcG5wbS13b3Jrc3BhY2UueWFtbGAsIGFkZCBgcHJvamVuYC9gdHlwZXNjcmlwdGAvYHRzeGAgKyB0aGUgZW5naW5lIHBhY2thZ2UsXG4gKiB3cml0ZSBhIG1pbmltYWwgYC5wcm9qZW5yYy50c2AsIHN5bnRoIG9uY2UgKHdpdGggYFBST0pFTl9ESVNBQkxFX1BPU1RgKSwgdGhlblxuICogaW5zdGFsbC4gRG9lcyBub3QgcnVuIGJhcnJlbHMgLSBydW4gYHBucG0gcnVuIGJhcnJlbHNgIG9yIGEgZnVsbCBwcm9qZW4gc3ludGhcbiAqIHBvc3QtaW5zdGFsbCB0byBnZW5lcmF0ZSBwYWNrYWdlIGJhcnJlbHMuXG4gKlxuICogRXZlcnkgc3RlcCBpcyBpZGVtcG90ZW50IGFuZCBzZWxmLWd1YXJkZWQsIHNvIHRoaXMgaXMgc2FmZSB0byBydW4gYWdhaW5zdCBhXG4gKiBmb2xkZXIgdGhhdCBBTFJFQURZIGhhcyBhIGhhbmQtYXV0aG9yZWQgYC5wcm9qZW5yYy50c2AgKGFuZCBldmVuIGEgY29tbWl0dGVkXG4gKiBgcGFja2FnZS5qc29uYCkgYnV0IGlzIG1pc3NpbmcgdGhlIGluc3RhbGxlZCB0b29sY2hhaW4gLSBlLmcuIGEgZnJlc2hseSBjb3BpZWRcbiAqIHByb2plY3Qgd2hvc2UgZ2VuZXJhdGVkIGZpbGVzIChpbmNsdWRpbmcgbWFuaWZlc3RzKSBhcmUgZ2l0aWdub3JlZC4gSW4gdGhhdFxuICogY2FzZSBgcG5wbSBpbml0YCBhbmQgdGhlIGAucHJvamVucmMudHNgIHNjYWZmb2xkIGFyZSBza2lwcGVkLCBidXQgdGhlIGVuZ2luZSArXG4gKiBwcm9qZW4gKyB0c3ggYXJlIChyZSlpbnN0YWxsZWQgc28gdGhlIHN1YnNlcXVlbnQgc3ludGggY2FuIHJlZ2VuZXJhdGVcbiAqIGV2ZXJ5dGhpbmcuIFNlZSB7QGxpbmsgc2VlZFRvb2xjaGFpbn0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBib290c3RyYXBXb3Jrc3BhY2UoXG4gIHJvb3Q6IHN0cmluZyxcbiAgcHJvamVuU3BlY2lmaWVyOiBzdHJpbmcgPSBkZWZhdWx0UHJvamVuU3BlY2lmaWVyKCksXG4pOiB2b2lkIHtcbiAgaW50cm8oYEJvb3RzdHJhcHBpbmcgZGJ4LXRvb2xzIHdvcmtzcGFjZSBpbiAke3Jvb3RMYWJlbChyb290KX1gKTtcblxuICBzZWVkVG9vbGNoYWluKHJvb3QsIHByb2plblNwZWNpZmllcik7XG5cbiAgY29uc3QgcHJvamVucmMgPSBqb2luKHJvb3QsIFwiLnByb2plbnJjLnRzXCIpO1xuICBpZiAoIWV4aXN0c1N5bmMocHJvamVucmMpKSB7XG4gICAgd3JpdGVGaWxlU3luYyhwcm9qZW5yYywgUFJPSkVOUkNfVEVNUExBVEUpO1xuICB9XG5cbiAgcnVuSW5pdGlhbFN5bnRoKHJvb3QpO1xuXG4gIHJ1blBucG0oW1wiaW5zdGFsbFwiLCBcIi0tbm8tZnJvemVuLWxvY2tmaWxlXCIsIFwiLS1mb3JjZVwiXSwgcm9vdCk7XG4gIG91dHJvKFwiV29ya3NwYWNlIHJlYWR5IC0gcmUtcnVuIGRieC10b29scyBvciBhZGQgcGFja2FnZXMgdW5kZXIgcGFja2FnZXMvXCIpO1xufVxuXG4vKipcbiAqIEluc3RhbGwgdGhlIHRvb2xjaGFpbiBhIHN5bnRoIG5lZWRzIChgcHJvamVuYCwgYHR5cGVzY3JpcHRgLCBgdHN4YCwgYW5kIHRoZVxuICogZGJ4LXRvb2xzIGVuZ2luZSksIHNlZWRpbmcgYSBgcGFja2FnZS5qc29uYCBhbmQgYHBucG0td29ya3NwYWNlLnlhbWxgIGZpcnN0XG4gKiB3aGVuIGFic2VudC4gSWRlbXBvdGVudDogcnVuIGl0IHdoZW5ldmVyIHRoZSBlbmdpbmUgaXMgbWlzc2luZywgc28gYSBjb3BpZWRcbiAqIHByb2plY3Qgd2l0aCBhIGAucHJvamVucmMudHNgIGJ1dCBubyBgbm9kZV9tb2R1bGVzYC9tYW5pZmVzdHMgY2FuIGJlIGJyb3VnaHRcbiAqIHVwIHRvIGEgc3ludGgtcmVhZHkgc3RhdGUgd2l0aG91dCBmdWxsIGJvb3RzdHJhcHBpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZWVkVG9vbGNoYWluKFxuICByb290OiBzdHJpbmcsXG4gIHByb2plblNwZWNpZmllcjogc3RyaW5nID0gZGVmYXVsdFByb2plblNwZWNpZmllcigpLFxuKTogdm9pZCB7XG4gIGNvbnN0IG1hbmlmZXN0UGF0aCA9IGpvaW4ocm9vdCwgXCJwYWNrYWdlLmpzb25cIik7XG4gIGlmICghZXhpc3RzU3luYyhtYW5pZmVzdFBhdGgpKSB7XG4gICAgcnVuUG5wbShbXCJpbml0XCJdLCByb290KTtcbiAgICBub3JtYWxpemVTZWVkTWFuaWZlc3QobWFuaWZlc3RQYXRoKTtcbiAgfVxuXG4gIGNvbnN0IHdvcmtzcGFjZUZpbGUgPSBqb2luKHJvb3QsIFwicG5wbS13b3Jrc3BhY2UueWFtbFwiKTtcbiAgaWYgKCFleGlzdHNTeW5jKHdvcmtzcGFjZUZpbGUpKSB7XG4gICAgd3JpdGVGaWxlU3luYyh3b3Jrc3BhY2VGaWxlLCBXT1JLU1BBQ0VfU0VFRCk7XG4gIH1cblxuICBydW5QbnBtKFtcImFkZFwiLCBcIi1EXCIsIFwicHJvamVuXCIsIFwidHlwZXNjcmlwdEBeNS45LjNcIiwgXCJ0c3hAXjQuMjMuMFwiLCBwcm9qZW5TcGVjaWZpZXJdLCByb290KTtcbn1cblxuLyoqXG4gKiBNYWtlIHdoYXQgYHBucG0gaW5pdGAgcHJvZHVjZWQgc2FmZSB0byBzeW50aCBhZ2FpbnN0LiBUd28gY29ycmVjdGlvbnMsIGJvdGhcbiAqIGJlY2F1c2UgdGhhdCBvdXRwdXQgdmFyaWVzIGJ5IHBucG0gdmVyc2lvbjpcbiAqXG4gKiAgIC0gZHJvcCBgZGV2RW5naW5lc2AsIHdoaWNoIHBucG0gMTEgc2VlZHMgYXMgYHBhY2thZ2VNYW5hZ2VyOiB7IG5hbWU6IFwicG5wbVwiLFxuICogICAgIG9uRmFpbDogXCJkb3dubG9hZFwiIH1gLiBBbnkgbnBtLWJhc2VkIHRvb2wgbGF0ZXIgaW4gdGhlIGNoYWluIChhblxuICogICAgIGBucHhgL2RseCBmYWxsYmFjaykgdGhlbiByZWZ1c2VzIHdpdGggRUJBRERFVkVOR0lORVMsIGl0cyBydW5uZXIgYmVpbmcgbnBtO1xuICogICAtIGZvcmNlIGB0eXBlOiBcIm1vZHVsZVwiYCwgd2hpY2ggcG5wbSAxMSB3cml0ZXMgYW5kIHBucG0gMTAgZG9lcyBub3QuIHRzeFxuICogICAgIHBpY2tzIHRoZSBlbnRyeSdzIGZvcm1hdCBmcm9tIHRoZSBuZWFyZXN0IG1hbmlmZXN0LCBzbyB3aXRob3V0IGl0XG4gKiAgICAgYC5wcm9qZW5yYy50c2AgbG9hZHMgYXMgQ0pTIGFuZCB0aGUgZmlyc3QgZGVwZW5kZW5jeSB1c2luZyB0b3AtbGV2ZWwgYXdhaXRcbiAqICAgICBkaWVzIG9uIFwibm90IHN1cHBvcnRlZCB3aXRoIHRoZSBjanMgb3V0cHV0IGZvcm1hdFwiLlxuICpcbiAqIHByb2plbiByZWdlbmVyYXRlcyB0aGUgd2hvbGUgbWFuaWZlc3QgYXQgc3ludGgsIHNvIHRoaXMgb25seSBoYXMgdG8gaG9sZCB0aGVcbiAqIHNlZWQgdG9nZXRoZXIgbG9uZyBlbm91Z2ggdG8gZ2V0IHRoZXJlLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVTZWVkTWFuaWZlc3QobWFuaWZlc3RQYXRoOiBzdHJpbmcpOiB2b2lkIHtcbiAgdHJ5IHtcbiAgICBjb25zdCBtYW5pZmVzdCA9IGpzb24ucGFyc2VSZWNvcmQocmVhZEZpbGVTeW5jKG1hbmlmZXN0UGF0aCwgXCJ1dGY4XCIpKTtcbiAgICBpZiAoIW1hbmlmZXN0KSByZXR1cm47XG4gICAgZGVsZXRlIG1hbmlmZXN0LmRldkVuZ2luZXM7XG4gICAgbWFuaWZlc3QudHlwZSA9IFwibW9kdWxlXCI7XG4gICAgd3JpdGVGaWxlU3luYyhtYW5pZmVzdFBhdGgsIGAke0pTT04uc3RyaW5naWZ5KG1hbmlmZXN0LCBudWxsLCAyKX1cXG5gKTtcbiAgfSBjYXRjaCB7XG4gICAgLy8gQSBtYWxmb3JtZWQvYWJzZW50IG1hbmlmZXN0IGhlcmUganVzdCBtZWFucyB0aGUgbGF0ZXIgYHBucG0gYWRkYCByZWNyZWF0ZXMgaXQuXG4gIH1cbn1cblxuLyoqXG4gKiBSdW4gdGhlIGluaXRpYWwgc3ludGggYnkgZXhlY3V0aW5nIGAucHJvamVucmMudHNgIGRpcmVjdGx5IHdpdGggdHN4ICh3aXRoXG4gKiBgUFJPSkVOX0RJU0FCTEVfUE9TVGAgc2V0KSwgTk9UIGBwcm9qZW4gPHRhc2s+YC4gVXNlIHJpZ2h0IGFmdGVyIHNlZWRpbmcgYVxuICogZnJlc2ggd29ya3NwYWNlOiB0aGUgcHJvamVuIFRBU0tTIChgc3luY2AsIGBiYXJyZWxzYCwgLi4uKSBvbmx5IGV4aXN0IG9uY2VcbiAqIGAucHJvamVucmMudHNgIGhhcyBydW4gb25jZSwgc28gYHByb2plbiBzeW5jYCBjYW4ndCBiZSB0aGUgYm9vdHN0cmFwcGluZyBzdGVwLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcnVuSW5pdGlhbFN5bnRoKHJvb3Q6IHN0cmluZyk6IHZvaWQge1xuICBjb25zdCBbY29tbWFuZCwgLi4ucHJlZml4XSA9IHJlc29sdmVQbnBtQXJndigpO1xuICBleGVjLnNwYXduU3luYyhjb21tYW5kLCBbLi4ucHJlZml4LCBcImV4ZWNcIiwgXCJ0c3hcIiwgXCIucHJvamVucmMudHNcIl0sIHtcbiAgICBjd2Q6IHJvb3QsXG4gICAgZW52OiB7IC4uLnByb2Nlc3MuZW52LCBQUk9KRU5fRElTQUJMRV9QT1NUOiBcInRydWVcIiB9LFxuICAgIGNoZWNrOiB0cnVlLFxuICB9KTtcbn1cbiJdfQ==
|
package/lib/src/cli.d.ts
ADDED
package/lib/src/cli.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `dbx-tools` commander entry: detect root, bootstrap or install, forward to projen.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import { bootstrapWorkspace, ensureEngineCurrent, runInitialSynth, seedToolchain, } from "./bootstrap.js";
|
|
8
|
+
import { ensureWorkspaceReady, runPnpm, runProjen } from "./pnpm.js";
|
|
9
|
+
import { findWorkspaceRoot, needsBootstrap, needsToolchain } from "./root.js";
|
|
10
|
+
/**
|
|
11
|
+
* Prepare the workspace at `root`, then run `pnpm exec projen` with `projenArgs`.
|
|
12
|
+
*
|
|
13
|
+
* Three cases, in order:
|
|
14
|
+
* - no `.projenrc.ts` at all -> full bootstrap (scaffold + install + synth),
|
|
15
|
+
* which already runs the initial synth; nothing more to forward.
|
|
16
|
+
* - a `.projenrc.ts` but the engine/toolchain isn't installed (e.g. a freshly
|
|
17
|
+
* copied project whose generated files + manifests are gitignored) -> seed
|
|
18
|
+
* the toolchain, then run the INITIAL synth directly (the projen tasks the
|
|
19
|
+
* args would name, like `sync`, don't exist until `.projenrc.ts` has run
|
|
20
|
+
* once), and install. Don't forward `projenArgs` - the synth is the work.
|
|
21
|
+
* - otherwise (established workspace) -> ensure deps, bring the engine up to
|
|
22
|
+
* this CLI's version, then forward to projen.
|
|
23
|
+
*/
|
|
24
|
+
async function prepareAndRunProjen(projenArgs, startDir) {
|
|
25
|
+
const root = await findWorkspaceRoot(startDir);
|
|
26
|
+
if (needsBootstrap(root)) {
|
|
27
|
+
bootstrapWorkspace(root);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (needsToolchain(root)) {
|
|
31
|
+
seedToolchain(root);
|
|
32
|
+
runInitialSynth(root);
|
|
33
|
+
runPnpm(["install", "--no-frozen-lockfile", "--force"], root);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
ensureWorkspaceReady(root);
|
|
37
|
+
ensureEngineCurrent(root);
|
|
38
|
+
runProjen(projenArgs, root);
|
|
39
|
+
}
|
|
40
|
+
/** Parse `argv` with commander and forward remaining args to projen. */
|
|
41
|
+
export async function runCli(argv) {
|
|
42
|
+
const program = new Command()
|
|
43
|
+
.name("dbx-tools")
|
|
44
|
+
.description("Bootstrap dbx-tools workspaces and forward to projen")
|
|
45
|
+
.allowUnknownOption()
|
|
46
|
+
.allowExcessArguments()
|
|
47
|
+
.showHelpAfterError()
|
|
48
|
+
.helpOption("-h, --help", "Show dbx-tools help");
|
|
49
|
+
program.parse(argv);
|
|
50
|
+
await prepareAndRunProjen(program.args);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBQ0gsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwQyxPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLG1CQUFtQixFQUNuQixlQUFlLEVBQ2YsYUFBYSxHQUNkLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxjQUFjLEVBQUUsY0FBYyxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBRTNFOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxLQUFLLFVBQVUsbUJBQW1CLENBQUMsVUFBb0IsRUFBRSxRQUFpQjtJQUN4RSxNQUFNLElBQUksR0FBRyxNQUFNLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQy9DLElBQUksY0FBYyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDekIsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDekIsT0FBTztJQUNULENBQUM7SUFDRCxJQUFJLGNBQWMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ3pCLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQixlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEIsT0FBTyxDQUFDLENBQUMsU0FBUyxFQUFFLHNCQUFzQixFQUFFLFNBQVMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzlELE9BQU87SUFDVCxDQUFDO0lBQ0Qsb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDM0IsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDMUIsU0FBUyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUM5QixDQUFDO0FBRUQsd0VBQXdFO0FBQ3hFLE1BQU0sQ0FBQyxLQUFLLFVBQVUsTUFBTSxDQUFDLElBQWM7SUFDekMsTUFBTSxPQUFPLEdBQUcsSUFBSSxPQUFPLEVBQUU7U0FDMUIsSUFBSSxDQUFDLFdBQVcsQ0FBQztTQUNqQixXQUFXLENBQUMsc0RBQXNELENBQUM7U0FDbkUsa0JBQWtCLEVBQUU7U0FDcEIsb0JBQW9CLEVBQUU7U0FDdEIsa0JBQWtCLEVBQUU7U0FDcEIsVUFBVSxDQUFDLFlBQVksRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO0lBRW5ELE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDcEIsTUFBTSxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDMUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogYGRieC10b29sc2AgY29tbWFuZGVyIGVudHJ5OiBkZXRlY3Qgcm9vdCwgYm9vdHN0cmFwIG9yIGluc3RhbGwsIGZvcndhcmQgdG8gcHJvamVuLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gXCJjb21tYW5kZXJcIjtcbmltcG9ydCB7XG4gIGJvb3RzdHJhcFdvcmtzcGFjZSxcbiAgZW5zdXJlRW5naW5lQ3VycmVudCxcbiAgcnVuSW5pdGlhbFN5bnRoLFxuICBzZWVkVG9vbGNoYWluLFxufSBmcm9tIFwiLi9ib290c3RyYXBcIjtcbmltcG9ydCB7IGVuc3VyZVdvcmtzcGFjZVJlYWR5LCBydW5QbnBtLCBydW5Qcm9qZW4gfSBmcm9tIFwiLi9wbnBtXCI7XG5pbXBvcnQgeyBmaW5kV29ya3NwYWNlUm9vdCwgbmVlZHNCb290c3RyYXAsIG5lZWRzVG9vbGNoYWluIH0gZnJvbSBcIi4vcm9vdFwiO1xuXG4vKipcbiAqIFByZXBhcmUgdGhlIHdvcmtzcGFjZSBhdCBgcm9vdGAsIHRoZW4gcnVuIGBwbnBtIGV4ZWMgcHJvamVuYCB3aXRoIGBwcm9qZW5BcmdzYC5cbiAqXG4gKiBUaHJlZSBjYXNlcywgaW4gb3JkZXI6XG4gKiAgIC0gbm8gYC5wcm9qZW5yYy50c2AgYXQgYWxsIC0+IGZ1bGwgYm9vdHN0cmFwIChzY2FmZm9sZCArIGluc3RhbGwgKyBzeW50aCksXG4gKiAgICAgd2hpY2ggYWxyZWFkeSBydW5zIHRoZSBpbml0aWFsIHN5bnRoOyBub3RoaW5nIG1vcmUgdG8gZm9yd2FyZC5cbiAqICAgLSBhIGAucHJvamVucmMudHNgIGJ1dCB0aGUgZW5naW5lL3Rvb2xjaGFpbiBpc24ndCBpbnN0YWxsZWQgKGUuZy4gYSBmcmVzaGx5XG4gKiAgICAgY29waWVkIHByb2plY3Qgd2hvc2UgZ2VuZXJhdGVkIGZpbGVzICsgbWFuaWZlc3RzIGFyZSBnaXRpZ25vcmVkKSAtPiBzZWVkXG4gKiAgICAgdGhlIHRvb2xjaGFpbiwgdGhlbiBydW4gdGhlIElOSVRJQUwgc3ludGggZGlyZWN0bHkgKHRoZSBwcm9qZW4gdGFza3MgdGhlXG4gKiAgICAgYXJncyB3b3VsZCBuYW1lLCBsaWtlIGBzeW5jYCwgZG9uJ3QgZXhpc3QgdW50aWwgYC5wcm9qZW5yYy50c2AgaGFzIHJ1blxuICogICAgIG9uY2UpLCBhbmQgaW5zdGFsbC4gRG9uJ3QgZm9yd2FyZCBgcHJvamVuQXJnc2AgLSB0aGUgc3ludGggaXMgdGhlIHdvcmsuXG4gKiAgIC0gb3RoZXJ3aXNlIChlc3RhYmxpc2hlZCB3b3Jrc3BhY2UpIC0+IGVuc3VyZSBkZXBzLCBicmluZyB0aGUgZW5naW5lIHVwIHRvXG4gKiAgICAgdGhpcyBDTEkncyB2ZXJzaW9uLCB0aGVuIGZvcndhcmQgdG8gcHJvamVuLlxuICovXG5hc3luYyBmdW5jdGlvbiBwcmVwYXJlQW5kUnVuUHJvamVuKHByb2plbkFyZ3M6IHN0cmluZ1tdLCBzdGFydERpcj86IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCByb290ID0gYXdhaXQgZmluZFdvcmtzcGFjZVJvb3Qoc3RhcnREaXIpO1xuICBpZiAobmVlZHNCb290c3RyYXAocm9vdCkpIHtcbiAgICBib290c3RyYXBXb3Jrc3BhY2Uocm9vdCk7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChuZWVkc1Rvb2xjaGFpbihyb290KSkge1xuICAgIHNlZWRUb29sY2hhaW4ocm9vdCk7XG4gICAgcnVuSW5pdGlhbFN5bnRoKHJvb3QpO1xuICAgIHJ1blBucG0oW1wiaW5zdGFsbFwiLCBcIi0tbm8tZnJvemVuLWxvY2tmaWxlXCIsIFwiLS1mb3JjZVwiXSwgcm9vdCk7XG4gICAgcmV0dXJuO1xuICB9XG4gIGVuc3VyZVdvcmtzcGFjZVJlYWR5KHJvb3QpO1xuICBlbnN1cmVFbmdpbmVDdXJyZW50KHJvb3QpO1xuICBydW5Qcm9qZW4ocHJvamVuQXJncywgcm9vdCk7XG59XG5cbi8qKiBQYXJzZSBgYXJndmAgd2l0aCBjb21tYW5kZXIgYW5kIGZvcndhcmQgcmVtYWluaW5nIGFyZ3MgdG8gcHJvamVuLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1bkNsaShhcmd2OiBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwcm9ncmFtID0gbmV3IENvbW1hbmQoKVxuICAgIC5uYW1lKFwiZGJ4LXRvb2xzXCIpXG4gICAgLmRlc2NyaXB0aW9uKFwiQm9vdHN0cmFwIGRieC10b29scyB3b3Jrc3BhY2VzIGFuZCBmb3J3YXJkIHRvIHByb2plblwiKVxuICAgIC5hbGxvd1Vua25vd25PcHRpb24oKVxuICAgIC5hbGxvd0V4Y2Vzc0FyZ3VtZW50cygpXG4gICAgLnNob3dIZWxwQWZ0ZXJFcnJvcigpXG4gICAgLmhlbHBPcHRpb24oXCItaCwgLS1oZWxwXCIsIFwiU2hvdyBkYngtdG9vbHMgaGVscFwiKTtcblxuICBwcm9ncmFtLnBhcnNlKGFyZ3YpO1xuICBhd2FpdCBwcmVwYXJlQW5kUnVuUHJvamVuKHByb2dyYW0uYXJncyk7XG59XG4iXX0=
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Memoized `[command, ...prefix]` argv prefix to run pnpm (resolved install, else corepack, else npx). */
|
|
2
|
+
export declare const resolvePnpmArgv: () => string[];
|
|
3
|
+
/** Run pnpm with inherited stdio from `cwd`. */
|
|
4
|
+
export declare function runPnpm(args: string[], cwd: string): void;
|
|
5
|
+
/** Install workspace dependencies when `node_modules` or projen is missing. */
|
|
6
|
+
export declare function ensureWorkspaceReady(root: string): void;
|
|
7
|
+
/** Run `pnpm exec projen` with the given args from `root`. */
|
|
8
|
+
export declare function runProjen(args: string[], root: string): void;
|
package/lib/src/pnpm.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pnpm discovery, workspace install, and projen forwarding for the `dbx-tools` CLI.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { createRequire } from "node:module";
|
|
7
|
+
import { dirname, join } from "node:path";
|
|
8
|
+
import { exec } from "@dbx-tools/core";
|
|
9
|
+
import { functionModule } from "@dbx-tools/shared-core";
|
|
10
|
+
import { needsInstall } from "./root.js";
|
|
11
|
+
/** True when `pnpm --version` runs, i.e. pnpm is already on PATH. */
|
|
12
|
+
function pnpmOnPath() {
|
|
13
|
+
try {
|
|
14
|
+
exec.spawnSync("pnpm", ["--version"], {
|
|
15
|
+
stderr: "ignore",
|
|
16
|
+
stdin: "ignore",
|
|
17
|
+
stdout: "ignore",
|
|
18
|
+
check: true,
|
|
19
|
+
});
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function resolvePnpmArgvImpl() {
|
|
27
|
+
// 1. A resolvable `pnpm` dependency (the normal in-workspace case): run its
|
|
28
|
+
// bin directly with the current node - no PATH or package-manager shim.
|
|
29
|
+
try {
|
|
30
|
+
const require = createRequire(import.meta.url);
|
|
31
|
+
const pkgJsonPath = require.resolve("pnpm/package.json");
|
|
32
|
+
const pkg = require(pkgJsonPath);
|
|
33
|
+
const bin = typeof pkg.bin === "string" ? pkg.bin : pkg.bin.pnpm;
|
|
34
|
+
return [process.execPath, join(dirname(pkgJsonPath), bin)];
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// fall through
|
|
38
|
+
}
|
|
39
|
+
// 2. A bare `pnpm` already on PATH (e.g. running under `pnpm dlx`). Prefer
|
|
40
|
+
// this over the corepack/npx fallbacks so we never shell through npm -
|
|
41
|
+
// `npx -y pnpm` runs under npm, which rejects a bootstrapped
|
|
42
|
+
// `devEngines.packageManager: pnpm` manifest with EBADDEVENGINES.
|
|
43
|
+
if (pnpmOnPath())
|
|
44
|
+
return ["pnpm"];
|
|
45
|
+
// 3. Try to enable pnpm via corepack, then use it.
|
|
46
|
+
try {
|
|
47
|
+
exec.spawnSync("corepack", ["enable", "pnpm"], {
|
|
48
|
+
stderr: "ignore",
|
|
49
|
+
stdin: "ignore",
|
|
50
|
+
stdout: "ignore",
|
|
51
|
+
check: true,
|
|
52
|
+
});
|
|
53
|
+
if (pnpmOnPath())
|
|
54
|
+
return ["pnpm"];
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// fall through
|
|
58
|
+
}
|
|
59
|
+
// 4. Last resort: fetch pnpm on demand via npx. Pass `--engine-strict=false`
|
|
60
|
+
// (and skip npm's devEngines gate) so npm doesn't refuse to run just
|
|
61
|
+
// because the target manifest declares `devEngines.packageManager: pnpm`.
|
|
62
|
+
return ["npx", "-y", "--engine-strict=false", "pnpm"];
|
|
63
|
+
}
|
|
64
|
+
/** Memoized `[command, ...prefix]` argv prefix to run pnpm (resolved install, else corepack, else npx). */
|
|
65
|
+
export const resolvePnpmArgv = functionModule.memoize(resolvePnpmArgvImpl);
|
|
66
|
+
/** Run pnpm with inherited stdio from `cwd`. */
|
|
67
|
+
export function runPnpm(args, cwd) {
|
|
68
|
+
const [command, ...prefix] = resolvePnpmArgv();
|
|
69
|
+
exec.spawnSync(command, [...prefix, ...args], { cwd, check: true });
|
|
70
|
+
}
|
|
71
|
+
/** Install workspace dependencies when `node_modules` or projen is missing. */
|
|
72
|
+
export function ensureWorkspaceReady(root) {
|
|
73
|
+
if (needsInstall(root)) {
|
|
74
|
+
runPnpm(["install", "--no-frozen-lockfile"], root);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** Run `pnpm exec projen` with the given args from `root`. */
|
|
78
|
+
export function runProjen(args, root) {
|
|
79
|
+
runPnpm(["exec", "projen", ...args], root);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG5wbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wbnBtLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFDSCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzVDLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQzFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN2QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDeEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUt0QyxxRUFBcUU7QUFDckUsU0FBUyxVQUFVO0lBQ2pCLElBQUksQ0FBQztRQUNILElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsV0FBVyxDQUFDLEVBQUU7WUFDcEMsTUFBTSxFQUFFLFFBQVE7WUFDaEIsS0FBSyxFQUFFLFFBQVE7WUFDZixNQUFNLEVBQUUsUUFBUTtZQUNoQixLQUFLLEVBQUUsSUFBSTtTQUNaLENBQUMsQ0FBQztRQUNILE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztBQUNILENBQUM7QUFFRCxTQUFTLG1CQUFtQjtJQUMxQiw0RUFBNEU7SUFDNUUsMkVBQTJFO0lBQzNFLElBQUksQ0FBQztRQUNILE1BQU0sT0FBTyxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQy9DLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUN6RCxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFzQixDQUFDO1FBQ3RELE1BQU0sR0FBRyxHQUFHLE9BQU8sR0FBRyxDQUFDLEdBQUcsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDO1FBQ2pFLE9BQU8sQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsZUFBZTtJQUNqQixDQUFDO0lBRUQsMkVBQTJFO0lBQzNFLDBFQUEwRTtJQUMxRSxnRUFBZ0U7SUFDaEUscUVBQXFFO0lBQ3JFLElBQUksVUFBVSxFQUFFO1FBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRWxDLG1EQUFtRDtJQUNuRCxJQUFJLENBQUM7UUFDSCxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsRUFBRTtZQUM3QyxNQUFNLEVBQUUsUUFBUTtZQUNoQixLQUFLLEVBQUUsUUFBUTtZQUNmLE1BQU0sRUFBRSxRQUFRO1lBQ2hCLEtBQUssRUFBRSxJQUFJO1NBQ1osQ0FBQyxDQUFDO1FBQ0gsSUFBSSxVQUFVLEVBQUU7WUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLGVBQWU7SUFDakIsQ0FBQztJQUVELDZFQUE2RTtJQUM3RSx3RUFBd0U7SUFDeEUsNkVBQTZFO0lBQzdFLE9BQU8sQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLHVCQUF1QixFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ3hELENBQUM7QUFFRCwyR0FBMkc7QUFDM0csTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLGNBQWMsQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsQ0FBQztBQUUzRSxnREFBZ0Q7QUFDaEQsTUFBTSxVQUFVLE9BQU8sQ0FBQyxJQUFjLEVBQUUsR0FBVztJQUNqRCxNQUFNLENBQUMsT0FBTyxFQUFFLEdBQUcsTUFBTSxDQUFDLEdBQUcsZUFBZSxFQUFFLENBQUM7SUFDL0MsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQ3RFLENBQUM7QUFFRCwrRUFBK0U7QUFDL0UsTUFBTSxVQUFVLG9CQUFvQixDQUFDLElBQVk7SUFDL0MsSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUN2QixPQUFPLENBQUMsQ0FBQyxTQUFTLEVBQUUsc0JBQXNCLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNyRCxDQUFDO0FBQ0gsQ0FBQztBQUVELDhEQUE4RDtBQUM5RCxNQUFNLFVBQVUsU0FBUyxDQUFDLElBQWMsRUFBRSxJQUFZO0lBQ3BELE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsR0FBRyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUM3QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBwbnBtIGRpc2NvdmVyeSwgd29ya3NwYWNlIGluc3RhbGwsIGFuZCBwcm9qZW4gZm9yd2FyZGluZyBmb3IgdGhlIGBkYngtdG9vbHNgIENMSS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tIFwibm9kZTptb2R1bGVcIjtcbmltcG9ydCB7IGRpcm5hbWUsIGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSBcIkBkYngtdG9vbHMvY29yZVwiO1xuaW1wb3J0IHsgZnVuY3Rpb25Nb2R1bGUgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgbmVlZHNJbnN0YWxsIH0gZnJvbSBcIi4vcm9vdFwiO1xuXG4vKiogQSBwYWNrYWdlLmpzb24gYGJpbmAgZmllbGQ6IGVpdGhlciBhIHNpbmdsZSBjb21tYW5kIHN0cmluZywgb3IgYSBuYW1lIC0+IHBhdGggbWFwLiAqL1xudHlwZSBCaW5GaWVsZCA9IHN0cmluZyB8IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG5cbi8qKiBUcnVlIHdoZW4gYHBucG0gLS12ZXJzaW9uYCBydW5zLCBpLmUuIHBucG0gaXMgYWxyZWFkeSBvbiBQQVRILiAqL1xuZnVuY3Rpb24gcG5wbU9uUGF0aCgpOiBib29sZWFuIHtcbiAgdHJ5IHtcbiAgICBleGVjLnNwYXduU3luYyhcInBucG1cIiwgW1wiLS12ZXJzaW9uXCJdLCB7XG4gICAgICBzdGRlcnI6IFwiaWdub3JlXCIsXG4gICAgICBzdGRpbjogXCJpZ25vcmVcIixcbiAgICAgIHN0ZG91dDogXCJpZ25vcmVcIixcbiAgICAgIGNoZWNrOiB0cnVlLFxuICAgIH0pO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzb2x2ZVBucG1Bcmd2SW1wbCgpOiBzdHJpbmdbXSB7XG4gIC8vIDEuIEEgcmVzb2x2YWJsZSBgcG5wbWAgZGVwZW5kZW5jeSAodGhlIG5vcm1hbCBpbi13b3Jrc3BhY2UgY2FzZSk6IHJ1biBpdHNcbiAgLy8gICAgYmluIGRpcmVjdGx5IHdpdGggdGhlIGN1cnJlbnQgbm9kZSAtIG5vIFBBVEggb3IgcGFja2FnZS1tYW5hZ2VyIHNoaW0uXG4gIHRyeSB7XG4gICAgY29uc3QgcmVxdWlyZSA9IGNyZWF0ZVJlcXVpcmUoaW1wb3J0Lm1ldGEudXJsKTtcbiAgICBjb25zdCBwa2dKc29uUGF0aCA9IHJlcXVpcmUucmVzb2x2ZShcInBucG0vcGFja2FnZS5qc29uXCIpO1xuICAgIGNvbnN0IHBrZyA9IHJlcXVpcmUocGtnSnNvblBhdGgpIGFzIHsgYmluOiBCaW5GaWVsZCB9O1xuICAgIGNvbnN0IGJpbiA9IHR5cGVvZiBwa2cuYmluID09PSBcInN0cmluZ1wiID8gcGtnLmJpbiA6IHBrZy5iaW4ucG5wbTtcbiAgICByZXR1cm4gW3Byb2Nlc3MuZXhlY1BhdGgsIGpvaW4oZGlybmFtZShwa2dKc29uUGF0aCksIGJpbildO1xuICB9IGNhdGNoIHtcbiAgICAvLyBmYWxsIHRocm91Z2hcbiAgfVxuXG4gIC8vIDIuIEEgYmFyZSBgcG5wbWAgYWxyZWFkeSBvbiBQQVRIIChlLmcuIHJ1bm5pbmcgdW5kZXIgYHBucG0gZGx4YCkuIFByZWZlclxuICAvLyAgICB0aGlzIG92ZXIgdGhlIGNvcmVwYWNrL25weCBmYWxsYmFja3Mgc28gd2UgbmV2ZXIgc2hlbGwgdGhyb3VnaCBucG0gLVxuICAvLyAgICBgbnB4IC15IHBucG1gIHJ1bnMgdW5kZXIgbnBtLCB3aGljaCByZWplY3RzIGEgYm9vdHN0cmFwcGVkXG4gIC8vICAgIGBkZXZFbmdpbmVzLnBhY2thZ2VNYW5hZ2VyOiBwbnBtYCBtYW5pZmVzdCB3aXRoIEVCQURERVZFTkdJTkVTLlxuICBpZiAocG5wbU9uUGF0aCgpKSByZXR1cm4gW1wicG5wbVwiXTtcblxuICAvLyAzLiBUcnkgdG8gZW5hYmxlIHBucG0gdmlhIGNvcmVwYWNrLCB0aGVuIHVzZSBpdC5cbiAgdHJ5IHtcbiAgICBleGVjLnNwYXduU3luYyhcImNvcmVwYWNrXCIsIFtcImVuYWJsZVwiLCBcInBucG1cIl0sIHtcbiAgICAgIHN0ZGVycjogXCJpZ25vcmVcIixcbiAgICAgIHN0ZGluOiBcImlnbm9yZVwiLFxuICAgICAgc3Rkb3V0OiBcImlnbm9yZVwiLFxuICAgICAgY2hlY2s6IHRydWUsXG4gICAgfSk7XG4gICAgaWYgKHBucG1PblBhdGgoKSkgcmV0dXJuIFtcInBucG1cIl07XG4gIH0gY2F0Y2gge1xuICAgIC8vIGZhbGwgdGhyb3VnaFxuICB9XG5cbiAgLy8gNC4gTGFzdCByZXNvcnQ6IGZldGNoIHBucG0gb24gZGVtYW5kIHZpYSBucHguIFBhc3MgYC0tZW5naW5lLXN0cmljdD1mYWxzZWBcbiAgLy8gICAgKGFuZCBza2lwIG5wbSdzIGRldkVuZ2luZXMgZ2F0ZSkgc28gbnBtIGRvZXNuJ3QgcmVmdXNlIHRvIHJ1biBqdXN0XG4gIC8vICAgIGJlY2F1c2UgdGhlIHRhcmdldCBtYW5pZmVzdCBkZWNsYXJlcyBgZGV2RW5naW5lcy5wYWNrYWdlTWFuYWdlcjogcG5wbWAuXG4gIHJldHVybiBbXCJucHhcIiwgXCIteVwiLCBcIi0tZW5naW5lLXN0cmljdD1mYWxzZVwiLCBcInBucG1cIl07XG59XG5cbi8qKiBNZW1vaXplZCBgW2NvbW1hbmQsIC4uLnByZWZpeF1gIGFyZ3YgcHJlZml4IHRvIHJ1biBwbnBtIChyZXNvbHZlZCBpbnN0YWxsLCBlbHNlIGNvcmVwYWNrLCBlbHNlIG5weCkuICovXG5leHBvcnQgY29uc3QgcmVzb2x2ZVBucG1Bcmd2ID0gZnVuY3Rpb25Nb2R1bGUubWVtb2l6ZShyZXNvbHZlUG5wbUFyZ3ZJbXBsKTtcblxuLyoqIFJ1biBwbnBtIHdpdGggaW5oZXJpdGVkIHN0ZGlvIGZyb20gYGN3ZGAuICovXG5leHBvcnQgZnVuY3Rpb24gcnVuUG5wbShhcmdzOiBzdHJpbmdbXSwgY3dkOiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3QgW2NvbW1hbmQsIC4uLnByZWZpeF0gPSByZXNvbHZlUG5wbUFyZ3YoKTtcbiAgZXhlYy5zcGF3blN5bmMoY29tbWFuZCwgWy4uLnByZWZpeCwgLi4uYXJnc10sIHsgY3dkLCBjaGVjazogdHJ1ZSB9KTtcbn1cblxuLyoqIEluc3RhbGwgd29ya3NwYWNlIGRlcGVuZGVuY2llcyB3aGVuIGBub2RlX21vZHVsZXNgIG9yIHByb2plbiBpcyBtaXNzaW5nLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuc3VyZVdvcmtzcGFjZVJlYWR5KHJvb3Q6IHN0cmluZyk6IHZvaWQge1xuICBpZiAobmVlZHNJbnN0YWxsKHJvb3QpKSB7XG4gICAgcnVuUG5wbShbXCJpbnN0YWxsXCIsIFwiLS1uby1mcm96ZW4tbG9ja2ZpbGVcIl0sIHJvb3QpO1xuICB9XG59XG5cbi8qKiBSdW4gYHBucG0gZXhlYyBwcm9qZW5gIHdpdGggdGhlIGdpdmVuIGFyZ3MgZnJvbSBgcm9vdGAuICovXG5leHBvcnQgZnVuY3Rpb24gcnVuUHJvamVuKGFyZ3M6IHN0cmluZ1tdLCByb290OiBzdHJpbmcpOiB2b2lkIHtcbiAgcnVuUG5wbShbXCJleGVjXCIsIFwicHJvamVuXCIsIC4uLmFyZ3NdLCByb290KTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walk upward from `startDir` for `.projenrc.ts`. If none is found, try git
|
|
3
|
+
* top-level only when that directory also contains `.projenrc.ts`; otherwise return
|
|
4
|
+
* `resolve(startDir)` (which may not be a workspace root).
|
|
5
|
+
*/
|
|
6
|
+
export declare function findWorkspaceRoot(startDir?: string): Promise<string>;
|
|
7
|
+
/**
|
|
8
|
+
* True when the folder has no `.projenrc.ts` yet and needs full bootstrapping.
|
|
9
|
+
* Keying off `.projenrc.ts` (not `package.json`) avoids clobbering a cleaned
|
|
10
|
+
* workspace that still has a hand-authored projenrc.
|
|
11
|
+
*/
|
|
12
|
+
export declare function needsBootstrap(root: string): boolean;
|
|
13
|
+
/** True when `node_modules` or projen itself is missing under `root`. */
|
|
14
|
+
export declare function needsInstall(root: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* True when the synth TOOLCHAIN isn't installed yet: no `node_modules`, or the
|
|
17
|
+
* dbx-tools engine / `projen` aren't resolvable under it. Distinct from a full
|
|
18
|
+
* bootstrap (which keys off a MISSING `.projenrc.ts`): here the projenrc exists
|
|
19
|
+
* but its dependencies don't - e.g. a copied project whose generated manifests
|
|
20
|
+
* and `node_modules` are gitignored. Seeding the toolchain (not scaffolding)
|
|
21
|
+
* makes it synth-ready without touching the hand-authored `.projenrc.ts`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function needsToolchain(root: string): boolean;
|
|
24
|
+
/** Async, memoized root lookup from the process cwd at first use. */
|
|
25
|
+
export declare const workspaceRoot: () => Promise<string>;
|
|
26
|
+
/** Short label for log output (`basename` of the resolved root). */
|
|
27
|
+
export declare function rootLabel(root: string): string;
|
package/lib/src/root.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace root detection for the `dbx-tools` CLI.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync } from "node:fs";
|
|
7
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
8
|
+
import { exec } from "@dbx-tools/core";
|
|
9
|
+
import { functionModule } from "@dbx-tools/shared-core";
|
|
10
|
+
async function gitToplevel() {
|
|
11
|
+
const { exitCode, stdout } = await exec.spawn("git", ["rev-parse", "--show-toplevel"], {
|
|
12
|
+
stdout: "capture",
|
|
13
|
+
stderr: "ignore",
|
|
14
|
+
stdin: "ignore",
|
|
15
|
+
});
|
|
16
|
+
if (exitCode !== 0)
|
|
17
|
+
return undefined;
|
|
18
|
+
return stdout || undefined;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Walk upward from `startDir` for `.projenrc.ts`. If none is found, try git
|
|
22
|
+
* top-level only when that directory also contains `.projenrc.ts`; otherwise return
|
|
23
|
+
* `resolve(startDir)` (which may not be a workspace root).
|
|
24
|
+
*/
|
|
25
|
+
export async function findWorkspaceRoot(startDir = process.cwd()) {
|
|
26
|
+
let dir = resolve(startDir);
|
|
27
|
+
while (true) {
|
|
28
|
+
if (existsSync(join(dir, ".projenrc.ts")))
|
|
29
|
+
return dir;
|
|
30
|
+
const parent = dirname(dir);
|
|
31
|
+
if (parent === dir)
|
|
32
|
+
break;
|
|
33
|
+
dir = parent;
|
|
34
|
+
}
|
|
35
|
+
const fromGit = await gitToplevel();
|
|
36
|
+
if (fromGit && existsSync(join(fromGit, ".projenrc.ts")))
|
|
37
|
+
return fromGit;
|
|
38
|
+
return resolve(startDir);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* True when the folder has no `.projenrc.ts` yet and needs full bootstrapping.
|
|
42
|
+
* Keying off `.projenrc.ts` (not `package.json`) avoids clobbering a cleaned
|
|
43
|
+
* workspace that still has a hand-authored projenrc.
|
|
44
|
+
*/
|
|
45
|
+
export function needsBootstrap(root) {
|
|
46
|
+
return !existsSync(join(root, ".projenrc.ts"));
|
|
47
|
+
}
|
|
48
|
+
/** True when `node_modules` or projen itself is missing under `root`. */
|
|
49
|
+
export function needsInstall(root) {
|
|
50
|
+
if (!existsSync(join(root, "node_modules")))
|
|
51
|
+
return true;
|
|
52
|
+
if (existsSync(join(root, ".projenrc.ts")) && !existsSync(join(root, "node_modules", "projen"))) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* True when the synth TOOLCHAIN isn't installed yet: no `node_modules`, or the
|
|
59
|
+
* dbx-tools engine / `projen` aren't resolvable under it. Distinct from a full
|
|
60
|
+
* bootstrap (which keys off a MISSING `.projenrc.ts`): here the projenrc exists
|
|
61
|
+
* but its dependencies don't - e.g. a copied project whose generated manifests
|
|
62
|
+
* and `node_modules` are gitignored. Seeding the toolchain (not scaffolding)
|
|
63
|
+
* makes it synth-ready without touching the hand-authored `.projenrc.ts`.
|
|
64
|
+
*/
|
|
65
|
+
export function needsToolchain(root) {
|
|
66
|
+
const modules = join(root, "node_modules");
|
|
67
|
+
if (!existsSync(modules))
|
|
68
|
+
return true;
|
|
69
|
+
return !existsSync(join(modules, "projen")) || !existsSync(join(modules, "@dbx-tools", "projen"));
|
|
70
|
+
}
|
|
71
|
+
/** Async, memoized root lookup from the process cwd at first use. */
|
|
72
|
+
export const workspaceRoot = functionModule.memoize(() => findWorkspaceRoot());
|
|
73
|
+
/** Short label for log output (`basename` of the resolved root). */
|
|
74
|
+
export function rootLabel(root) {
|
|
75
|
+
return basename(root) || root;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm9vdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yb290LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFDSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ3JDLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDN0QsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUV4RCxLQUFLLFVBQVUsV0FBVztJQUN4QixNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQyxXQUFXLEVBQUUsaUJBQWlCLENBQUMsRUFBRTtRQUNyRixNQUFNLEVBQUUsU0FBUztRQUNqQixNQUFNLEVBQUUsUUFBUTtRQUNoQixLQUFLLEVBQUUsUUFBUTtLQUNoQixDQUFDLENBQUM7SUFDSCxJQUFJLFFBQVEsS0FBSyxDQUFDO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDckMsT0FBTyxNQUFNLElBQUksU0FBUyxDQUFDO0FBQzdCLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxpQkFBaUIsQ0FBQyxXQUFtQixPQUFPLENBQUMsR0FBRyxFQUFFO0lBQ3RFLElBQUksR0FBRyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM1QixPQUFPLElBQUksRUFBRSxDQUFDO1FBQ1osSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxjQUFjLENBQUMsQ0FBQztZQUFFLE9BQU8sR0FBRyxDQUFDO1FBQ3RELE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM1QixJQUFJLE1BQU0sS0FBSyxHQUFHO1lBQUUsTUFBTTtRQUMxQixHQUFHLEdBQUcsTUFBTSxDQUFDO0lBQ2YsQ0FBQztJQUVELE1BQU0sT0FBTyxHQUFHLE1BQU0sV0FBVyxFQUFFLENBQUM7SUFDcEMsSUFBSSxPQUFPLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFBRSxPQUFPLE9BQU8sQ0FBQztJQUV6RSxPQUFPLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUMzQixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUMsSUFBWTtJQUN6QyxPQUFPLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQztBQUNqRCxDQUFDO0FBRUQseUVBQXlFO0FBQ3pFLE1BQU0sVUFBVSxZQUFZLENBQUMsSUFBWTtJQUN2QyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUN6RCxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxjQUFjLEVBQUUsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ2hHLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsY0FBYyxDQUFDLElBQVk7SUFDekMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxjQUFjLENBQUMsQ0FBQztJQUMzQyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ3RDLE9BQU8sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsWUFBWSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7QUFDcEcsQ0FBQztBQUVELHFFQUFxRTtBQUNyRSxNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsY0FBYyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUM7QUFFL0Usb0VBQW9FO0FBQ3BFLE1BQU0sVUFBVSxTQUFTLENBQUMsSUFBWTtJQUNwQyxPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUM7QUFDaEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogV29ya3NwYWNlIHJvb3QgZGV0ZWN0aW9uIGZvciB0aGUgYGRieC10b29sc2AgQ0xJLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuaW1wb3J0IHsgZXhpc3RzU3luYyB9IGZyb20gXCJub2RlOmZzXCI7XG5pbXBvcnQgeyBiYXNlbmFtZSwgZGlybmFtZSwgam9pbiwgcmVzb2x2ZSB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IGV4ZWMgfSBmcm9tIFwiQGRieC10b29scy9jb3JlXCI7XG5pbXBvcnQgeyBmdW5jdGlvbk1vZHVsZSB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5cbmFzeW5jIGZ1bmN0aW9uIGdpdFRvcGxldmVsKCk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IHsgZXhpdENvZGUsIHN0ZG91dCB9ID0gYXdhaXQgZXhlYy5zcGF3bihcImdpdFwiLCBbXCJyZXYtcGFyc2VcIiwgXCItLXNob3ctdG9wbGV2ZWxcIl0sIHtcbiAgICBzdGRvdXQ6IFwiY2FwdHVyZVwiLFxuICAgIHN0ZGVycjogXCJpZ25vcmVcIixcbiAgICBzdGRpbjogXCJpZ25vcmVcIixcbiAgfSk7XG4gIGlmIChleGl0Q29kZSAhPT0gMCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgcmV0dXJuIHN0ZG91dCB8fCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogV2FsayB1cHdhcmQgZnJvbSBgc3RhcnREaXJgIGZvciBgLnByb2plbnJjLnRzYC4gSWYgbm9uZSBpcyBmb3VuZCwgdHJ5IGdpdFxuICogdG9wLWxldmVsIG9ubHkgd2hlbiB0aGF0IGRpcmVjdG9yeSBhbHNvIGNvbnRhaW5zIGAucHJvamVucmMudHNgOyBvdGhlcndpc2UgcmV0dXJuXG4gKiBgcmVzb2x2ZShzdGFydERpcilgICh3aGljaCBtYXkgbm90IGJlIGEgd29ya3NwYWNlIHJvb3QpLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmluZFdvcmtzcGFjZVJvb3Qoc3RhcnREaXI6IHN0cmluZyA9IHByb2Nlc3MuY3dkKCkpOiBQcm9taXNlPHN0cmluZz4ge1xuICBsZXQgZGlyID0gcmVzb2x2ZShzdGFydERpcik7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgaWYgKGV4aXN0c1N5bmMoam9pbihkaXIsIFwiLnByb2plbnJjLnRzXCIpKSkgcmV0dXJuIGRpcjtcbiAgICBjb25zdCBwYXJlbnQgPSBkaXJuYW1lKGRpcik7XG4gICAgaWYgKHBhcmVudCA9PT0gZGlyKSBicmVhaztcbiAgICBkaXIgPSBwYXJlbnQ7XG4gIH1cblxuICBjb25zdCBmcm9tR2l0ID0gYXdhaXQgZ2l0VG9wbGV2ZWwoKTtcbiAgaWYgKGZyb21HaXQgJiYgZXhpc3RzU3luYyhqb2luKGZyb21HaXQsIFwiLnByb2plbnJjLnRzXCIpKSkgcmV0dXJuIGZyb21HaXQ7XG5cbiAgcmV0dXJuIHJlc29sdmUoc3RhcnREaXIpO1xufVxuXG4vKipcbiAqIFRydWUgd2hlbiB0aGUgZm9sZGVyIGhhcyBubyBgLnByb2plbnJjLnRzYCB5ZXQgYW5kIG5lZWRzIGZ1bGwgYm9vdHN0cmFwcGluZy5cbiAqIEtleWluZyBvZmYgYC5wcm9qZW5yYy50c2AgKG5vdCBgcGFja2FnZS5qc29uYCkgYXZvaWRzIGNsb2JiZXJpbmcgYSBjbGVhbmVkXG4gKiB3b3Jrc3BhY2UgdGhhdCBzdGlsbCBoYXMgYSBoYW5kLWF1dGhvcmVkIHByb2plbnJjLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbmVlZHNCb290c3RyYXAocm9vdDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiAhZXhpc3RzU3luYyhqb2luKHJvb3QsIFwiLnByb2plbnJjLnRzXCIpKTtcbn1cblxuLyoqIFRydWUgd2hlbiBgbm9kZV9tb2R1bGVzYCBvciBwcm9qZW4gaXRzZWxmIGlzIG1pc3NpbmcgdW5kZXIgYHJvb3RgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5lZWRzSW5zdGFsbChyb290OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgaWYgKCFleGlzdHNTeW5jKGpvaW4ocm9vdCwgXCJub2RlX21vZHVsZXNcIikpKSByZXR1cm4gdHJ1ZTtcbiAgaWYgKGV4aXN0c1N5bmMoam9pbihyb290LCBcIi5wcm9qZW5yYy50c1wiKSkgJiYgIWV4aXN0c1N5bmMoam9pbihyb290LCBcIm5vZGVfbW9kdWxlc1wiLCBcInByb2plblwiKSkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogVHJ1ZSB3aGVuIHRoZSBzeW50aCBUT09MQ0hBSU4gaXNuJ3QgaW5zdGFsbGVkIHlldDogbm8gYG5vZGVfbW9kdWxlc2AsIG9yIHRoZVxuICogZGJ4LXRvb2xzIGVuZ2luZSAvIGBwcm9qZW5gIGFyZW4ndCByZXNvbHZhYmxlIHVuZGVyIGl0LiBEaXN0aW5jdCBmcm9tIGEgZnVsbFxuICogYm9vdHN0cmFwICh3aGljaCBrZXlzIG9mZiBhIE1JU1NJTkcgYC5wcm9qZW5yYy50c2ApOiBoZXJlIHRoZSBwcm9qZW5yYyBleGlzdHNcbiAqIGJ1dCBpdHMgZGVwZW5kZW5jaWVzIGRvbid0IC0gZS5nLiBhIGNvcGllZCBwcm9qZWN0IHdob3NlIGdlbmVyYXRlZCBtYW5pZmVzdHNcbiAqIGFuZCBgbm9kZV9tb2R1bGVzYCBhcmUgZ2l0aWdub3JlZC4gU2VlZGluZyB0aGUgdG9vbGNoYWluIChub3Qgc2NhZmZvbGRpbmcpXG4gKiBtYWtlcyBpdCBzeW50aC1yZWFkeSB3aXRob3V0IHRvdWNoaW5nIHRoZSBoYW5kLWF1dGhvcmVkIGAucHJvamVucmMudHNgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbmVlZHNUb29sY2hhaW4ocm9vdDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IG1vZHVsZXMgPSBqb2luKHJvb3QsIFwibm9kZV9tb2R1bGVzXCIpO1xuICBpZiAoIWV4aXN0c1N5bmMobW9kdWxlcykpIHJldHVybiB0cnVlO1xuICByZXR1cm4gIWV4aXN0c1N5bmMoam9pbihtb2R1bGVzLCBcInByb2plblwiKSkgfHwgIWV4aXN0c1N5bmMoam9pbihtb2R1bGVzLCBcIkBkYngtdG9vbHNcIiwgXCJwcm9qZW5cIikpO1xufVxuXG4vKiogQXN5bmMsIG1lbW9pemVkIHJvb3QgbG9va3VwIGZyb20gdGhlIHByb2Nlc3MgY3dkIGF0IGZpcnN0IHVzZS4gKi9cbmV4cG9ydCBjb25zdCB3b3Jrc3BhY2VSb290ID0gZnVuY3Rpb25Nb2R1bGUubWVtb2l6ZSgoKSA9PiBmaW5kV29ya3NwYWNlUm9vdCgpKTtcblxuLyoqIFNob3J0IGxhYmVsIGZvciBsb2cgb3V0cHV0IChgYmFzZW5hbWVgIG9mIHRoZSByZXNvbHZlZCByb290KS4gKi9cbmV4cG9ydCBmdW5jdGlvbiByb290TGFiZWwocm9vdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGJhc2VuYW1lKHJvb3QpIHx8IHJvb3Q7XG59XG4iXX0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["../src/bootstrap.ts","../src/cli.ts","../src/pnpm.ts","../src/root.ts","../index.ts","../bin/dbx-tools.ts"],"version":"5.9.3"}
|
package/package.json
CHANGED
|
@@ -18,29 +18,45 @@
|
|
|
18
18
|
"commander": "^15.0.0",
|
|
19
19
|
"pnpm": "^11.0.6",
|
|
20
20
|
"tsx": "^4.23.0",
|
|
21
|
-
"@dbx-tools/
|
|
22
|
-
"@dbx-tools/core": "0.
|
|
21
|
+
"@dbx-tools/core": "0.4.0",
|
|
22
|
+
"@dbx-tools/shared-core": "0.4.0"
|
|
23
23
|
},
|
|
24
|
-
"main": "index.
|
|
24
|
+
"main": "./lib/index.js",
|
|
25
25
|
"license": "UNLICENSED",
|
|
26
26
|
"publishConfig": {
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
|
-
"version": "0.
|
|
30
|
-
"types": "index.ts",
|
|
29
|
+
"version": "0.4.0",
|
|
30
|
+
"types": "./lib/index.d.ts",
|
|
31
31
|
"type": "module",
|
|
32
32
|
"exports": {
|
|
33
|
-
".":
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"./
|
|
33
|
+
".": {
|
|
34
|
+
"types": "./lib/index.d.ts",
|
|
35
|
+
"default": "./lib/index.js"
|
|
36
|
+
},
|
|
37
|
+
"./bootstrap": {
|
|
38
|
+
"types": "./lib/src/bootstrap.d.ts",
|
|
39
|
+
"default": "./lib/src/bootstrap.js"
|
|
40
|
+
},
|
|
41
|
+
"./cli": {
|
|
42
|
+
"types": "./lib/src/cli.d.ts",
|
|
43
|
+
"default": "./lib/src/cli.js"
|
|
44
|
+
},
|
|
45
|
+
"./pnpm": {
|
|
46
|
+
"types": "./lib/src/pnpm.d.ts",
|
|
47
|
+
"default": "./lib/src/pnpm.js"
|
|
48
|
+
},
|
|
49
|
+
"./root": {
|
|
50
|
+
"types": "./lib/src/root.d.ts",
|
|
51
|
+
"default": "./lib/src/root.js"
|
|
52
|
+
},
|
|
38
53
|
"./package.json": "./package.json"
|
|
39
54
|
},
|
|
40
55
|
"files": [
|
|
41
56
|
"index.ts",
|
|
42
57
|
"src",
|
|
43
|
-
"bin"
|
|
58
|
+
"bin",
|
|
59
|
+
"lib"
|
|
44
60
|
],
|
|
45
61
|
"dbxToolsConfig": {
|
|
46
62
|
"tags": [
|
package/src/bootstrap.ts
CHANGED
|
@@ -31,17 +31,60 @@ const FALLBACK_PROJEN_SPECIFIER = "@dbx-tools/projen@latest";
|
|
|
31
31
|
* heuristic has nothing older to fall back to.
|
|
32
32
|
*/
|
|
33
33
|
function defaultProjenSpecifier(): string {
|
|
34
|
+
const version = ownVersion();
|
|
35
|
+
return version ? `@dbx-tools/projen@^${version}` : FALLBACK_PROJEN_SPECIFIER;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** This CLI's own released version, or `undefined` for an in-repo `0.0.0` build. */
|
|
39
|
+
function ownVersion(): string | undefined {
|
|
34
40
|
try {
|
|
35
41
|
const manifestPath = fileURLToPath(new URL("../package.json", import.meta.url));
|
|
36
42
|
const version = json.parseRecord(readFileSync(manifestPath, "utf8"))?.version;
|
|
37
|
-
return typeof version === "string" && version !== "0.0.0"
|
|
38
|
-
? `@dbx-tools/projen@^${version}`
|
|
39
|
-
: FALLBACK_PROJEN_SPECIFIER;
|
|
43
|
+
return typeof version === "string" && version !== "0.0.0" ? version : undefined;
|
|
40
44
|
} catch {
|
|
41
|
-
return
|
|
45
|
+
return undefined;
|
|
42
46
|
}
|
|
43
47
|
}
|
|
44
48
|
|
|
49
|
+
/** Compare `x.y.z` triples; returns <0, 0, or >0. Missing parts count as 0. */
|
|
50
|
+
function compareVersions(a: string, b: string): number {
|
|
51
|
+
const parts = (v: string) => v.split(".").map((p) => Number.parseInt(p, 10) || 0);
|
|
52
|
+
const [x, y] = [parts(a), parts(b)];
|
|
53
|
+
return x[0] - y[0] || x[1] - y[1] || x[2] - y[2];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Version of the engine currently installed at `root`, if any. */
|
|
57
|
+
function installedEngineVersion(root: string): string | undefined {
|
|
58
|
+
try {
|
|
59
|
+
const manifest = join(root, "node_modules", "@dbx-tools", "projen", "package.json");
|
|
60
|
+
const version = json.parseRecord(readFileSync(manifest, "utf8"))?.version;
|
|
61
|
+
return typeof version === "string" ? version : undefined;
|
|
62
|
+
} catch {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Upgrade an established workspace whose installed engine predates this CLI.
|
|
69
|
+
*
|
|
70
|
+
* Bootstrapping pins the engine once, and nothing afterwards revisits it - so a
|
|
71
|
+
* workspace created months ago kept resolving its original engine no matter how
|
|
72
|
+
* current the CLI invoking it was, and failed inside the OLD engine's code
|
|
73
|
+
* (`sync --watch` dying on a `concurrently` that engine never declared). The two
|
|
74
|
+
* are released in lockstep, so this CLI's version is exactly the engine it
|
|
75
|
+
* expects.
|
|
76
|
+
*
|
|
77
|
+
* Only ever moves FORWARD: an engine at or ahead of this CLI is left alone, so
|
|
78
|
+
* an older CLI cannot downgrade a workspace.
|
|
79
|
+
*/
|
|
80
|
+
export function ensureEngineCurrent(root: string): void {
|
|
81
|
+
const expected = ownVersion();
|
|
82
|
+
if (!expected) return;
|
|
83
|
+
const installed = installedEngineVersion(root);
|
|
84
|
+
if (installed && compareVersions(installed, expected) >= 0) return;
|
|
85
|
+
runPnpm(["add", "-D", defaultProjenSpecifier()], root);
|
|
86
|
+
}
|
|
87
|
+
|
|
45
88
|
// Reach the class through its module NAMESPACE. Current engines also hoist it
|
|
46
89
|
// flat, but every engine ever published exports the namespace, and this template
|
|
47
90
|
// is resolved against `@latest` - a flat import dies on an older one with
|
package/src/cli.ts
CHANGED
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import { Command } from "commander";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
bootstrapWorkspace,
|
|
9
|
+
ensureEngineCurrent,
|
|
10
|
+
runInitialSynth,
|
|
11
|
+
seedToolchain,
|
|
12
|
+
} from "./bootstrap";
|
|
8
13
|
import { ensureWorkspaceReady, runPnpm, runProjen } from "./pnpm";
|
|
9
14
|
import { findWorkspaceRoot, needsBootstrap, needsToolchain } from "./root";
|
|
10
15
|
|
|
@@ -19,7 +24,8 @@ import { findWorkspaceRoot, needsBootstrap, needsToolchain } from "./root";
|
|
|
19
24
|
* the toolchain, then run the INITIAL synth directly (the projen tasks the
|
|
20
25
|
* args would name, like `sync`, don't exist until `.projenrc.ts` has run
|
|
21
26
|
* once), and install. Don't forward `projenArgs` - the synth is the work.
|
|
22
|
-
* - otherwise (established workspace) -> ensure deps,
|
|
27
|
+
* - otherwise (established workspace) -> ensure deps, bring the engine up to
|
|
28
|
+
* this CLI's version, then forward to projen.
|
|
23
29
|
*/
|
|
24
30
|
async function prepareAndRunProjen(projenArgs: string[], startDir?: string): Promise<void> {
|
|
25
31
|
const root = await findWorkspaceRoot(startDir);
|
|
@@ -34,6 +40,7 @@ async function prepareAndRunProjen(projenArgs: string[], startDir?: string): Pro
|
|
|
34
40
|
return;
|
|
35
41
|
}
|
|
36
42
|
ensureWorkspaceReady(root);
|
|
43
|
+
ensureEngineCurrent(root);
|
|
37
44
|
runProjen(projenArgs, root);
|
|
38
45
|
}
|
|
39
46
|
|