@dbx-tools/projen 0.6.59 → 0.6.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -41
- package/index.ts +21 -6
- package/package.json +4 -4
- package/src/project.ts +0 -14
- package/tasks/sync.ts +0 -5
- package/src/rs-packages.ts +0 -237
- package/tasks/rs-packages.ts +0 -26
package/README.md
CHANGED
|
@@ -124,35 +124,6 @@ package is attempted even if one fails; the failures are re-thrown together as a
|
|
|
124
124
|
`AggregateError` naming each package, rather than the first one abandoning the
|
|
125
125
|
rest of the sweep.
|
|
126
126
|
|
|
127
|
-
### Generate Node And Python From Rosetta Sources
|
|
128
|
-
|
|
129
|
-
The experimental `rs-packages` convention keeps TypeScript as the canonical
|
|
130
|
-
Node implementation while colocating an explicit Python implementation in the
|
|
131
|
-
same file:
|
|
132
|
-
|
|
133
|
-
```ts
|
|
134
|
-
export function capitalize(value: string): string {
|
|
135
|
-
return value ? value[0]!.toUpperCase() + value.slice(1) : value;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/* @rs-python
|
|
139
|
-
def capitalize(value: str) -> str:
|
|
140
|
-
return value[:1].upper() + value[1:] if value else value
|
|
141
|
-
@rs-end */
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
By default, `rs-packages/shared/core/src/string.ts` generates:
|
|
145
|
-
|
|
146
|
-
- `packages/shared/core/src/string.ts`
|
|
147
|
-
- `python-packages/shared-core/src/shared_core/string.py`
|
|
148
|
-
|
|
149
|
-
Use `// @rs-node <path>` or `// @rs-python-path <path>` only when the inferred
|
|
150
|
-
paths are unsuitable. Every Rosetta source must live below a package's `src/`
|
|
151
|
-
folder and include at least one Python block; generation fails rather than
|
|
152
|
-
silently emitting an empty Python module. `DBXToolsNodeProject` enables the
|
|
153
|
-
`rs-packages` root by default, accepts `rsPackageRoots` for custom roots, and
|
|
154
|
-
accepts `rsPackageRoots: false` to disable the experiment.
|
|
155
|
-
|
|
156
127
|
## Generate OpenAPI Clients
|
|
157
128
|
|
|
158
129
|
```ts
|
|
@@ -217,7 +188,6 @@ file contract as the CLI.
|
|
|
217
188
|
- `pnpmWorkspace` - generated pnpm workspace file and catalog model.
|
|
218
189
|
- `barrels` / `moduleExports` - public entrypoint generation.
|
|
219
190
|
- `codegen` - `.d.ts` to zod schema generation.
|
|
220
|
-
- `rsPackages` - annotated TypeScript source to Node/Python generation.
|
|
221
191
|
- `openapi` - tsoa/OpenAPI package generation.
|
|
222
192
|
- `bunApp` / `tsconfig` / `vscode` - generated support files/components.
|
|
223
193
|
- `generated` / `clean` / `watch` / `scaffold` - read-only file stamping,
|
|
@@ -226,8 +196,8 @@ file contract as the CLI.
|
|
|
226
196
|
- `engineRoot` - engine package root resolution for bootstrapped repos.
|
|
227
197
|
|
|
228
198
|
The engine registers its commands as projen tasks on the workspace root, so run
|
|
229
|
-
them with `bun run <task>` - `sync` (add `--watch`), `barrels`, `openapi`,
|
|
230
|
-
`
|
|
199
|
+
them with `bun run <task>` - `sync` (add `--watch`), `barrels`, `openapi`, and
|
|
200
|
+
`clean`.
|
|
231
201
|
[`@dbx-tools/cli`](../packages/cli/dbx-tools) is only needed to
|
|
232
202
|
bootstrap a folder that has no `.projenrc.ts` or toolchain yet.
|
|
233
203
|
|
|
@@ -237,15 +207,14 @@ Every repo-wide task lives on the root, and the root's `compile` / `test`
|
|
|
237
207
|
delegate with `bun run --filter '*'` rather than emitting a step per member - so
|
|
238
208
|
a new package is covered without a re-synth. Work from the root:
|
|
239
209
|
|
|
240
|
-
| Task
|
|
241
|
-
|
|
|
242
|
-
| `bun run build`
|
|
243
|
-
| `bun run compile`
|
|
244
|
-
| `bun run test`
|
|
245
|
-
| `bun run sync`
|
|
246
|
-
| `bun run barrels`
|
|
247
|
-
| `bun run
|
|
248
|
-
| `bun run bump` | version, tag, and publish |
|
|
210
|
+
| Task | What it does |
|
|
211
|
+
| ----------------- | -------------------------------------------------- |
|
|
212
|
+
| `bun run build` | `compile` + `test` + `package` across every member |
|
|
213
|
+
| `bun run compile` | `tsc --build` in each member, in parallel |
|
|
214
|
+
| `bun run test` | `eslint` once, then each member's tests |
|
|
215
|
+
| `bun run sync` | re-synth (`--watch` to keep synthing) |
|
|
216
|
+
| `bun run barrels` | regenerate the read-only `index.ts` barrels |
|
|
217
|
+
| `bun run bump` | version, tag, and publish |
|
|
249
218
|
|
|
250
219
|
Members intentionally keep only the tasks that something OTHER than a human
|
|
251
220
|
invokes, so there is no second place to run the same thing:
|
package/index.ts
CHANGED
|
@@ -18,13 +18,20 @@ export * as project from "./src/project.ts";
|
|
|
18
18
|
export * as projectPredicate from "./src/project-predicate.ts";
|
|
19
19
|
export * as publish from "./src/publish.ts";
|
|
20
20
|
export * as release from "./src/release.ts";
|
|
21
|
-
export * as rsPackages from "./src/rs-packages.ts";
|
|
22
21
|
export * as scaffold from "./src/scaffold.ts";
|
|
23
22
|
export * as tags from "./src/tags.ts";
|
|
24
23
|
export * as tsconfig from "./src/tsconfig.ts";
|
|
25
24
|
export * as vscode from "./src/vscode.ts";
|
|
26
25
|
export * as watch from "./src/watch.ts";
|
|
27
|
-
export {
|
|
26
|
+
export {
|
|
27
|
+
BUN_DEV_OVERRIDE,
|
|
28
|
+
BUN_BUILD_OVERRIDE,
|
|
29
|
+
BUN_APP_OVERRIDES,
|
|
30
|
+
RootBunfigFile,
|
|
31
|
+
BunfigFile,
|
|
32
|
+
BunDevServerFile,
|
|
33
|
+
BunBuildFile,
|
|
34
|
+
} from "./src/bun-app.ts";
|
|
28
35
|
export { DBXToolsConfig } from "./src/dbx-tools-config.ts";
|
|
29
36
|
export type { DBXToolsConfigOptions } from "./src/dbx-tools-config.ts";
|
|
30
37
|
export { resolvePkgRoot } from "./src/engine-root.ts";
|
|
@@ -35,13 +42,21 @@ export { repoRoot, DEFAULT_PACKAGE_ROOTS, DiscoveredPackage } from "./src/packag
|
|
|
35
42
|
export type { RecordedPackage } from "./src/packages.ts";
|
|
36
43
|
export { PnpmWorkspaceState } from "./src/pnpm-workspace.ts";
|
|
37
44
|
export type { Catalog, AllowBuilds, DBXToolsPNPMWorkspaceOptions } from "./src/pnpm-workspace.ts";
|
|
38
|
-
export {
|
|
39
|
-
|
|
45
|
+
export {
|
|
46
|
+
PackageIdentifier,
|
|
47
|
+
PROJEN_VERSION,
|
|
48
|
+
DBXToolsNodeProject,
|
|
49
|
+
DBXToolsTypeScriptProject,
|
|
50
|
+
} from "./src/project.ts";
|
|
51
|
+
export type {
|
|
52
|
+
DBXToolsProject,
|
|
53
|
+
DBXToolsProjectOptions,
|
|
54
|
+
DBXToolsTypeScriptProjectOptions,
|
|
55
|
+
ApplyToProjectsOptions,
|
|
56
|
+
} from "./src/project.ts";
|
|
40
57
|
export { COMPILED_DIR, COMPILED_COMPILER_OPTIONS } from "./src/publish.ts";
|
|
41
58
|
export { DBXToolsRelease } from "./src/release.ts";
|
|
42
59
|
export type { StandaloneRelease, DBXToolsReleaseOptions } from "./src/release.ts";
|
|
43
|
-
export { DEFAULT_RS_PACKAGE_ROOTS, RsPackages } from "./src/rs-packages.ts";
|
|
44
|
-
export type { RsPackageOutput, GenerateRsPackagesOptions } from "./src/rs-packages.ts";
|
|
45
60
|
export { AGNOSTIC_COMPILER_OPTIONS, PACKAGE_TAG_MIXINS } from "./src/tags.ts";
|
|
46
61
|
export type { PackageTag } from "./src/tags.ts";
|
|
47
62
|
export { DBXToolsRootTsconfig } from "./src/tsconfig.ts";
|
package/package.json
CHANGED
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@clack/prompts": "^1.7.0",
|
|
29
|
-
"@dbx-tools/core": "0.6.
|
|
30
|
-
"@dbx-tools/path": "0.6.
|
|
31
|
-
"@dbx-tools/shared-core": "0.6.
|
|
29
|
+
"@dbx-tools/core": "0.6.61",
|
|
30
|
+
"@dbx-tools/path": "0.6.61",
|
|
31
|
+
"@dbx-tools/shared-core": "0.6.61",
|
|
32
32
|
"commander": "^15.0.0",
|
|
33
33
|
"concurrently": "^10.0.3",
|
|
34
34
|
"constructs": "^10.6.0",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
},
|
|
48
48
|
"main": "index.ts",
|
|
49
49
|
"license": "Apache-2.0",
|
|
50
|
-
"version": "0.6.
|
|
50
|
+
"version": "0.6.61",
|
|
51
51
|
"types": "index.ts",
|
|
52
52
|
"type": "module",
|
|
53
53
|
"exports": {
|
package/src/project.ts
CHANGED
|
@@ -30,7 +30,6 @@ import {
|
|
|
30
30
|
RootBunfigFile,
|
|
31
31
|
} from "./bun-app.ts";
|
|
32
32
|
import { DBXToolsVsCode } from "./vscode.ts";
|
|
33
|
-
import { DEFAULT_RS_PACKAGE_ROOTS, RsPackages } from "./rs-packages.ts";
|
|
34
33
|
import {
|
|
35
34
|
DEFAULT_PACKAGE_ROOTS,
|
|
36
35
|
type DiscoveredPackage,
|
|
@@ -520,11 +519,6 @@ export interface DBXToolsProjectOptions
|
|
|
520
519
|
* is a member of the single bun workspace, so the root links it from source.
|
|
521
520
|
*/
|
|
522
521
|
readonly extraWorkspaceMembers?: readonly string[];
|
|
523
|
-
/**
|
|
524
|
-
* Experimental TypeScript-to-Node/Python source roots. Defaults to
|
|
525
|
-
* `["rs-packages"]`; set `false` to disable the generator.
|
|
526
|
-
*/
|
|
527
|
-
readonly rsPackageRoots?: readonly string[] | false;
|
|
528
522
|
}
|
|
529
523
|
|
|
530
524
|
/** Options for {@link DBXToolsTypeScriptProject} (a package, or a compiling root). */
|
|
@@ -847,7 +841,6 @@ function registerRootTasks(project: javascript.NodeProject): void {
|
|
|
847
841
|
applyTasks(project, {
|
|
848
842
|
barrels: { exec: taskScript(project, "barrels.ts") },
|
|
849
843
|
openapi: { exec: taskScript(project, "openapi.ts") },
|
|
850
|
-
"rs-packages": { exec: taskScript(project, "rs-packages.ts"), receiveArgs: true },
|
|
851
844
|
clean: { exec: taskScript(project, "clean.ts"), receiveArgs: true },
|
|
852
845
|
// `receiveArgs` forwards `--watch`, so `bun run sync -- --watch` syncs once
|
|
853
846
|
// then starts the single node-path watcher loop.
|
|
@@ -932,13 +925,6 @@ function initProject(
|
|
|
932
925
|
project.vsCode = new DBXToolsVsCode(project);
|
|
933
926
|
|
|
934
927
|
registerRootTasks(project);
|
|
935
|
-
project.dbxToolsConfig.rsPackageRoots =
|
|
936
|
-
options.rsPackageRoots === false
|
|
937
|
-
? false
|
|
938
|
-
: [...(options.rsPackageRoots ?? DEFAULT_RS_PACKAGE_ROOTS)];
|
|
939
|
-
if (options.rsPackageRoots !== false) {
|
|
940
|
-
new RsPackages(project, options.rsPackageRoots ?? DEFAULT_RS_PACKAGE_ROOTS);
|
|
941
|
-
}
|
|
942
928
|
if (options.prettier || project.prettier) {
|
|
943
929
|
const formatTask = project.tasks.tryFind("format") ?? project.addTask("format");
|
|
944
930
|
formatTask.prependExec("prettier . --write", { receiveArgs: true });
|
package/tasks/sync.ts
CHANGED
|
@@ -57,11 +57,6 @@ if (!process.argv.includes("--watch")) {
|
|
|
57
57
|
{ command: `bun "${taskPath("projenrc.ts")}"`, name: "projenrc", prefixColor: "magenta" },
|
|
58
58
|
{ command: `bun "${taskPath("barrels.ts")}" --watch`, name: "barrels", prefixColor: "cyan" },
|
|
59
59
|
{ command: `bun "${taskPath("openapi.ts")}" --watch`, name: "openapi", prefixColor: "green" },
|
|
60
|
-
{
|
|
61
|
-
command: `bun "${taskPath("rs-packages.ts")}" --watch`,
|
|
62
|
-
name: "rs-packages",
|
|
63
|
-
prefixColor: "yellow",
|
|
64
|
-
},
|
|
65
60
|
],
|
|
66
61
|
{
|
|
67
62
|
prefix: "name",
|
package/src/rs-packages.ts
DELETED
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Experimental Rosetta-source generation.
|
|
3
|
-
*
|
|
4
|
-
* A TypeScript file under `rs-packages/<package>/src/` is the canonical Node
|
|
5
|
-
* implementation. Projen copies its TypeScript surface to the matching
|
|
6
|
-
* `packages/<package>/src/` path and extracts one or more `@rs-python` blocks
|
|
7
|
-
* into a conventional Python package path.
|
|
8
|
-
*/
|
|
9
|
-
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
10
|
-
import { dirname, extname, join, relative, resolve } from "node:path";
|
|
11
|
-
import { json, object } from "@dbx-tools/shared-core";
|
|
12
|
-
import { Component, javascript } from "projen";
|
|
13
|
-
import { header, makeReadonly, makeWritable } from "./generated.ts";
|
|
14
|
-
import { toPosix } from "./packages.ts";
|
|
15
|
-
|
|
16
|
-
export const DEFAULT_RS_PACKAGE_ROOTS = ["rs-packages"] as const;
|
|
17
|
-
|
|
18
|
-
const SOURCE_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
19
|
-
const PYTHON_BLOCK = /\/\*\s*@rs-python\s*\n([\s\S]*?)\n\s*@rs-end\s*\*\//g;
|
|
20
|
-
const NODE_OVERRIDE = /^\s*\/\/\s*@rs-node\s+(.+?)\s*$/m;
|
|
21
|
-
const PYTHON_OVERRIDE = /^\s*\/\/\s*@rs-python-path\s+(.+?)\s*$/m;
|
|
22
|
-
const RS_METADATA = /^\s*\/\/\s*@rs-(?:node|python-path)\s+.+?\s*$\n?/gm;
|
|
23
|
-
const NODE_MARKER = "// GENERATED by projen synth (rs-packages)";
|
|
24
|
-
const PYTHON_MARKER = "# GENERATED by projen synth (rs-packages)";
|
|
25
|
-
|
|
26
|
-
export interface RsPackageOutput {
|
|
27
|
-
readonly source: string;
|
|
28
|
-
readonly node: string;
|
|
29
|
-
readonly python: string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface GenerateRsPackagesOptions {
|
|
33
|
-
readonly projectRoot?: string;
|
|
34
|
-
readonly roots?: readonly string[];
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function sourceFiles(root: string): string[] {
|
|
38
|
-
if (!existsSync(root)) return [];
|
|
39
|
-
const files: string[] = [];
|
|
40
|
-
const visit = (dir: string): void => {
|
|
41
|
-
for (const entry of readdirSync(dir)) {
|
|
42
|
-
const path = join(dir, entry);
|
|
43
|
-
if (statSync(path).isDirectory()) visit(path);
|
|
44
|
-
else if (SOURCE_EXTENSIONS.has(extname(entry))) files.push(path);
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
visit(root);
|
|
48
|
-
return files.sort();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function dedent(value: string): string {
|
|
52
|
-
const lines = value.replace(/^\n+|\n+$/g, "").split("\n");
|
|
53
|
-
const indents = lines
|
|
54
|
-
.filter((line) => line.trim())
|
|
55
|
-
.map((line) => line.match(/^\s*/)?.[0].length ?? 0);
|
|
56
|
-
const width = indents.length ? Math.min(...indents) : 0;
|
|
57
|
-
return lines.map((line) => line.slice(width)).join("\n");
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function defaultOutputPaths(
|
|
61
|
-
projectRoot: string,
|
|
62
|
-
root: string,
|
|
63
|
-
source: string,
|
|
64
|
-
): Pick<RsPackageOutput, "node" | "python"> {
|
|
65
|
-
const sourceRelative = toPosix(relative(resolve(projectRoot, root), source));
|
|
66
|
-
const segments = sourceRelative.split("/");
|
|
67
|
-
const srcIndex = segments.indexOf("src");
|
|
68
|
-
if (srcIndex < 1) {
|
|
69
|
-
throw new Error(
|
|
70
|
-
`Rosetta source must live under <package>/src/: ${toPosix(relative(projectRoot, source))}`,
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const packageSegments = segments.slice(0, srcIndex);
|
|
75
|
-
const moduleSegments = segments.slice(srcIndex + 1);
|
|
76
|
-
const moduleFile = moduleSegments.pop();
|
|
77
|
-
if (!moduleFile) throw new Error(`Rosetta source has no module name: ${source}`);
|
|
78
|
-
|
|
79
|
-
const pythonDistribution = packageSegments.join("-");
|
|
80
|
-
const pythonImport = packageSegments.join("_").replace(/-/g, "_");
|
|
81
|
-
const pythonModule = `${moduleFile.slice(0, -extname(moduleFile).length).replace(/-/g, "_")}.py`;
|
|
82
|
-
|
|
83
|
-
return {
|
|
84
|
-
node: resolve(
|
|
85
|
-
projectRoot,
|
|
86
|
-
"packages",
|
|
87
|
-
...packageSegments,
|
|
88
|
-
"src",
|
|
89
|
-
...moduleSegments,
|
|
90
|
-
moduleFile,
|
|
91
|
-
),
|
|
92
|
-
python: resolve(
|
|
93
|
-
projectRoot,
|
|
94
|
-
"python-packages",
|
|
95
|
-
pythonDistribution,
|
|
96
|
-
"src",
|
|
97
|
-
pythonImport,
|
|
98
|
-
...moduleSegments,
|
|
99
|
-
pythonModule,
|
|
100
|
-
),
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function resolveOutput(
|
|
105
|
-
projectRoot: string,
|
|
106
|
-
override: RegExpMatchArray | null,
|
|
107
|
-
fallback: string,
|
|
108
|
-
): string {
|
|
109
|
-
const value = override?.[1]?.trim();
|
|
110
|
-
return value ? resolve(projectRoot, value) : fallback;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function assertWritableOutput(projectRoot: string, path: string, marker: string): void {
|
|
114
|
-
if (!existsSync(path)) return;
|
|
115
|
-
if (readFileSync(path, "utf8").startsWith(marker)) return;
|
|
116
|
-
throw new Error(
|
|
117
|
-
`Refusing to overwrite hand-authored Rosetta output: ${toPosix(relative(projectRoot, path))}`,
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function renderSource(projectRoot: string, root: string, source: string): RsPackageOutput {
|
|
122
|
-
const input = readFileSync(source, "utf8");
|
|
123
|
-
const defaults = defaultOutputPaths(projectRoot, root, source);
|
|
124
|
-
const node = resolveOutput(projectRoot, input.match(NODE_OVERRIDE), defaults.node);
|
|
125
|
-
const python = resolveOutput(projectRoot, input.match(PYTHON_OVERRIDE), defaults.python);
|
|
126
|
-
const pythonBlocks = [...input.matchAll(PYTHON_BLOCK)].map((match) => dedent(match[1] ?? ""));
|
|
127
|
-
|
|
128
|
-
if (!pythonBlocks.length) {
|
|
129
|
-
throw new Error(
|
|
130
|
-
`Rosetta source needs at least one /* @rs-python ... @rs-end */ block: ${toPosix(relative(projectRoot, source))}`,
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const nodeBody = input.replace(PYTHON_BLOCK, "").replace(RS_METADATA, "").trim();
|
|
135
|
-
const nodeContent = `${header({
|
|
136
|
-
tool: "projen synth (rs-packages)",
|
|
137
|
-
source: toPosix(relative(projectRoot, source)),
|
|
138
|
-
})}\n${nodeBody}\n`;
|
|
139
|
-
const pythonContent = [
|
|
140
|
-
"# GENERATED by projen synth (rs-packages) - DO NOT EDIT.",
|
|
141
|
-
`# Regenerated from ${toPosix(relative(projectRoot, source))}.`,
|
|
142
|
-
"# Hand edits are overwritten; edit the Rosetta source instead.",
|
|
143
|
-
"",
|
|
144
|
-
pythonBlocks.join("\n\n"),
|
|
145
|
-
"",
|
|
146
|
-
].join("\n");
|
|
147
|
-
|
|
148
|
-
for (const [path, content] of [
|
|
149
|
-
[node, nodeContent],
|
|
150
|
-
[python, pythonContent],
|
|
151
|
-
] as const) {
|
|
152
|
-
assertWritableOutput(projectRoot, path, path === node ? NODE_MARKER : PYTHON_MARKER);
|
|
153
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
154
|
-
makeWritable(path);
|
|
155
|
-
writeFileSync(path, content);
|
|
156
|
-
makeReadonly(path);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return { source, node, python };
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/** Read the roots recorded by synth for standalone tasks and watchers. */
|
|
163
|
-
export function configuredRsPackageRoots(projectRoot: string): readonly string[] | false {
|
|
164
|
-
const manifest = json.parseRecord(readFileSync(resolve(projectRoot, "package.json"), "utf8"));
|
|
165
|
-
const config = object.isRecord(manifest?.dbxToolsConfig) ? manifest.dbxToolsConfig : undefined;
|
|
166
|
-
const configured = config?.rsPackageRoots;
|
|
167
|
-
if (configured === false) return false;
|
|
168
|
-
if (Array.isArray(configured)) {
|
|
169
|
-
const roots = configured.filter(
|
|
170
|
-
(value): value is string => typeof value === "string" && !!value,
|
|
171
|
-
);
|
|
172
|
-
if (roots.length) return roots;
|
|
173
|
-
}
|
|
174
|
-
return DEFAULT_RS_PACKAGE_ROOTS;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
export function discoverRsPackageOutputs(
|
|
178
|
-
options: GenerateRsPackagesOptions = {},
|
|
179
|
-
): RsPackageOutput[] {
|
|
180
|
-
const projectRoot = resolve(options.projectRoot ?? process.cwd());
|
|
181
|
-
const roots = options.roots ?? DEFAULT_RS_PACKAGE_ROOTS;
|
|
182
|
-
return roots.flatMap((root) =>
|
|
183
|
-
sourceFiles(resolve(projectRoot, root)).map((source) => {
|
|
184
|
-
const defaults = defaultOutputPaths(projectRoot, root, source);
|
|
185
|
-
const input = readFileSync(source, "utf8");
|
|
186
|
-
return {
|
|
187
|
-
source,
|
|
188
|
-
node: resolveOutput(projectRoot, input.match(NODE_OVERRIDE), defaults.node),
|
|
189
|
-
python: resolveOutput(projectRoot, input.match(PYTHON_OVERRIDE), defaults.python),
|
|
190
|
-
};
|
|
191
|
-
}),
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
export function generateRsPackages(options: GenerateRsPackagesOptions = {}): RsPackageOutput[] {
|
|
196
|
-
const projectRoot = resolve(options.projectRoot ?? process.cwd());
|
|
197
|
-
const roots = options.roots ?? DEFAULT_RS_PACKAGE_ROOTS;
|
|
198
|
-
return roots.flatMap((root) =>
|
|
199
|
-
sourceFiles(resolve(projectRoot, root)).map((source) =>
|
|
200
|
-
renderSource(projectRoot, root, source),
|
|
201
|
-
),
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/** Projen lifecycle component that regenerates Rosetta outputs after synth. */
|
|
206
|
-
export class RsPackages extends Component {
|
|
207
|
-
private readonly outputs: RsPackageOutput[];
|
|
208
|
-
|
|
209
|
-
constructor(
|
|
210
|
-
project: javascript.NodeProject,
|
|
211
|
-
private readonly roots: readonly string[] = DEFAULT_RS_PACKAGE_ROOTS,
|
|
212
|
-
) {
|
|
213
|
-
super(project);
|
|
214
|
-
// Generate during construction so a brand-new Node package exists before the
|
|
215
|
-
// root's package scan later in the same synth. postSynthesize repeats this to
|
|
216
|
-
// restore outputs after projen has written the rest of the tree.
|
|
217
|
-
this.outputs = generateRsPackages({ projectRoot: project.outdir, roots });
|
|
218
|
-
for (const output of this.outputs) {
|
|
219
|
-
const node = `/${toPosix(relative(project.outdir, output.node))}`;
|
|
220
|
-
const python = `/${toPosix(relative(project.outdir, output.python))}`;
|
|
221
|
-
project.annotateGenerated(node);
|
|
222
|
-
project.annotateGenerated(python);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
public override preSynthesize(): void {
|
|
227
|
-
const eslint = javascript.Eslint.of(this.project);
|
|
228
|
-
if (!eslint) return;
|
|
229
|
-
for (const output of this.outputs) {
|
|
230
|
-
eslint.addIgnorePattern(toPosix(relative(this.project.outdir, output.node)));
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
public override postSynthesize(): void {
|
|
235
|
-
generateRsPackages({ projectRoot: this.project.outdir, roots: this.roots });
|
|
236
|
-
}
|
|
237
|
-
}
|
package/tasks/rs-packages.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
2
|
-
import { resolve } from "node:path";
|
|
3
|
-
import { log } from "@dbx-tools/shared-core";
|
|
4
|
-
import { configuredRsPackageRoots, generateRsPackages } from "../src/rs-packages.ts";
|
|
5
|
-
import { repoRoot } from "../src/packages.ts";
|
|
6
|
-
import { watchLoop } from "../src/watch.ts";
|
|
7
|
-
|
|
8
|
-
const logger = log.logger("projen:rs-packages");
|
|
9
|
-
const configuredRoots = configuredRsPackageRoots(repoRoot);
|
|
10
|
-
const roots = configuredRoots === false ? [] : configuredRoots;
|
|
11
|
-
const watchRoots = roots.map((root) => resolve(repoRoot, root)).filter(existsSync);
|
|
12
|
-
|
|
13
|
-
function generate(): void {
|
|
14
|
-
const outputs = generateRsPackages({ projectRoot: repoRoot, roots });
|
|
15
|
-
logger.success(`generated ${outputs.length} Rosetta module${outputs.length === 1 ? "" : "s"}`);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
generate();
|
|
19
|
-
|
|
20
|
-
if (process.argv.includes("--watch")) {
|
|
21
|
-
if (watchRoots.length) watchLoop("rs-packages", watchRoots, generate);
|
|
22
|
-
else {
|
|
23
|
-
logger.info("no Rosetta roots configured; watcher is idle");
|
|
24
|
-
setInterval(() => {}, 2_147_483_647);
|
|
25
|
-
}
|
|
26
|
-
}
|