@dbx-tools/projen 0.9.40 → 0.9.46
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 +58 -67
- package/index.ts +6 -8
- package/package.json +9 -10
- package/shims/python-node/bootstrap.ts +129 -0
- package/shims/python-node/child-process.ts +96 -0
- package/shims/python-node/crypto.ts +60 -0
- package/shims/python-node/fs-promises.ts +179 -0
- package/shims/python-node/fs.ts +173 -0
- package/shims/python-node/headers.ts +75 -0
- package/shims/python-node/host.ts +341 -0
- package/shims/python-node/os.ts +20 -0
- package/shims/python-node/process.ts +13 -0
- package/shims/python-node/readline.ts +37 -0
- package/shims/python-node/tsconfig.json +24 -0
- package/src/_lazy-require.ts +7 -25
- package/src/bun-app.ts +2 -2
- package/src/bun-workflow.ts +2 -170
- package/src/codegen.ts +23 -20
- package/src/dbx-tools-config.ts +52 -9
- package/src/generated.ts +4 -17
- package/src/mixin.ts +1 -5
- package/src/packages.ts +18 -15
- package/src/pnpm-workspace.ts +1 -4
- package/src/project-js.ts +65 -196
- package/src/project-predicate.ts +7 -3
- package/src/project-py.ts +127 -37
- package/src/publish.ts +13 -10
- package/src/python-node-bindings.ts +2 -0
- package/src/python-node-bundle.ts +6 -0
- package/src/release-options.ts +17 -17
- package/src/release.ts +31 -14
- package/src/scaffold.ts +4 -7
- package/src/tags.ts +6 -16
- package/src/vscode.ts +1 -1
- package/src/watch.ts +5 -5
- package/src/workspace-lock.ts +1 -0
- package/src/workspace-version.ts +4 -4
- package/tasks/barrels.ts +3 -5
- package/tasks/clean.ts +1 -0
- package/tasks/lib/compile-workspace.ts +41 -19
- package/tasks/lib/local-publish.ts +0 -28
- package/tasks/lib/publish-npm.ts +8 -0
- package/tasks/lib/publish-python.ts +4 -0
- package/tasks/lib/python-node-bindings.ts +107 -26
- package/tasks/lib/python-registry.ts +4 -0
- package/tasks/lib/python-release.ts +2 -0
- package/tasks/lib/release.ts +2 -2
- package/tasks/projenrc.ts +1 -0
- package/tasks/sync.ts +4 -4
- package/src/openapi.ts +0 -293
- package/tasks/local-publish.ts +0 -6
- package/tasks/openapi.ts +0 -35
package/src/project-js.ts
CHANGED
|
@@ -12,13 +12,13 @@ import * as projectUtils from "@dbx-tools/core/project-utils";
|
|
|
12
12
|
import { ignore, match } from "@dbx-tools/path";
|
|
13
13
|
import { object, stringUtils, type OneOrMany } from "@dbx-tools/shared-core";
|
|
14
14
|
import { type IConstruct } from "constructs";
|
|
15
|
-
import { Component,
|
|
15
|
+
import { Component, LogLevel, Project, javascript, typescript } from "projen";
|
|
16
16
|
import { JobPermission, type JobStep } from "projen/lib/github/workflows-model";
|
|
17
17
|
import type { ReleaseProjectOptions } from "projen/lib/release";
|
|
18
18
|
import { generateBarrels } from "./barrels.ts";
|
|
19
19
|
|
|
20
20
|
import { BUN_APP_OVERRIDES, RootBunfigFile } from "./bun-app.ts";
|
|
21
|
-
import { BUN_VERSION
|
|
21
|
+
import { BUN_VERSION } from "./bun-workflow.ts";
|
|
22
22
|
import { codegenModulePaths, generateCodegen } from "./codegen.ts";
|
|
23
23
|
import { DBXToolsConfig, type DBXToolsConfigOptions } from "./dbx-tools-config.ts";
|
|
24
24
|
import { resolvePkgRoot } from "./engine-root.ts";
|
|
@@ -52,6 +52,8 @@ export interface DBXToolsJavaScriptProject extends DBXToolsProject, javascript.N
|
|
|
52
52
|
readonly dbxToolsConfig: DBXToolsConfig;
|
|
53
53
|
/** npm scope (the `@scope` in `@scope/pkg`), without the leading `@`. */
|
|
54
54
|
readonly scope: string;
|
|
55
|
+
/** Branch that the repository's tag release must match. */
|
|
56
|
+
readonly releaseBranch: string;
|
|
55
57
|
|
|
56
58
|
/**
|
|
57
59
|
* The `pnpm-workspace.yaml` catalog / member / build-allowance state - only a
|
|
@@ -61,8 +63,6 @@ export interface DBXToolsJavaScriptProject extends DBXToolsProject, javascript.N
|
|
|
61
63
|
pnpmWorkspace?: PnpmWorkspaceState;
|
|
62
64
|
/** Root projenrc tsconfigs - only a tree ROOT has one. */
|
|
63
65
|
rootTsconfig?: DBXToolsRootTsconfig;
|
|
64
|
-
/** Repository outputs excluded from generated workflow dependency-cache hashing. */
|
|
65
|
-
readonly workflowCacheIgnorePaths: readonly string[];
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
/** Parsed npm package identifier: optional scope plus the unscoped package name. */
|
|
@@ -253,11 +253,8 @@ export function projectRepositoryUrl(project: javascript.NodeProject): string |
|
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
/** Resolve the branch release workflows use for a generated project. */
|
|
256
|
-
export function projectReleaseBranch(project:
|
|
257
|
-
return
|
|
258
|
-
(project as javascript.NodeProject & { readonly releaseBranch?: string }).releaseBranch ??
|
|
259
|
-
"main"
|
|
260
|
-
);
|
|
256
|
+
export function projectReleaseBranch(project: DBXToolsJavaScriptProject): string {
|
|
257
|
+
return project.releaseBranch;
|
|
261
258
|
}
|
|
262
259
|
|
|
263
260
|
/**
|
|
@@ -369,19 +366,21 @@ const PRETTIER_SETTINGS: javascript.PrettierSettings = {
|
|
|
369
366
|
export { PROJEN_VERSION } from "./projen-version.ts";
|
|
370
367
|
|
|
371
368
|
/** SPDX license shared by generated JavaScript and Python packages. */
|
|
372
|
-
export const
|
|
369
|
+
export const LICENSE = "Apache-2.0";
|
|
373
370
|
|
|
374
371
|
/**
|
|
375
372
|
* The engine's opinionated `NodeProject` defaults. A caller's own options override
|
|
376
373
|
* these (they are spread AFTER this). Root-only concerns key off `options.parent`,
|
|
377
374
|
* NOT the class: only the tree ROOT (no parent) turns on projen's built-in Prettier
|
|
378
375
|
* (the `prettier` devDep + `.prettierrc.json` + `.prettierignore`), so a child package
|
|
379
|
-
* inherits the root's config rather than emitting its own.
|
|
380
|
-
* are
|
|
376
|
+
* inherits the root's config rather than emitting its own. Projen's informational
|
|
377
|
+
* status messages are hidden by default while task output, warnings, and errors
|
|
378
|
+
* remain visible. `name`/`defaultReleaseBranch` are resolved/applied by the caller.
|
|
381
379
|
*/
|
|
382
380
|
function defaultProjectOptions(options: DBXToolsJavaScriptProjectOptions) {
|
|
383
381
|
const isRoot = options.parent === undefined;
|
|
384
382
|
return {
|
|
383
|
+
logging: { level: LogLevel.WARN },
|
|
385
384
|
// Bun owns install/run/build/test locally and in CI. projen renders
|
|
386
385
|
// `bun install`/`bunx` and a native `trustedDependencies` field from this.
|
|
387
386
|
// The engine still emits `pnpm-workspace.yaml` itself (see
|
|
@@ -410,7 +409,7 @@ function defaultProjectOptions(options: DBXToolsJavaScriptProjectOptions) {
|
|
|
410
409
|
// workflow opts in per run through `npm_config_provenance`, so local publishes
|
|
411
410
|
// to Verdaccio still work without a CI OIDC provider. See
|
|
412
411
|
// {@link DBXToolsRelease}.
|
|
413
|
-
...(isRoot ? {} : { npmAccess: javascript.NpmAccess.PUBLIC }),
|
|
412
|
+
...(isRoot || options.publishable === false ? {} : { npmAccess: javascript.NpmAccess.PUBLIC }),
|
|
414
413
|
workflowPackageCache: false,
|
|
415
414
|
// The root build validates the whole workspace and must not also pack every
|
|
416
415
|
// member into unused `dist/js` tarballs. Child projects keep projen's package
|
|
@@ -457,9 +456,8 @@ function defaultProjectOptions(options: DBXToolsJavaScriptProjectOptions) {
|
|
|
457
456
|
/**
|
|
458
457
|
* `gitIgnoreOptions` with its `ignorePatterns` array CLONED, for handing to a
|
|
459
458
|
* projen `Project` constructor: projen's IgnoreFile ALIASES the array it is given
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
* pristine array to seed a child's fresh one. Spread AFTER `...options`.
|
|
459
|
+
* and every later `addPatterns` call mutates it. The caller's typed options must
|
|
460
|
+
* remain unchanged while Projen owns and extends the generated ignore file.
|
|
463
461
|
*/
|
|
464
462
|
function copiedGitIgnoreOptions(
|
|
465
463
|
options: DBXToolsJavaScriptProjectOptions,
|
|
@@ -516,11 +514,20 @@ function validateReleaseOptions(options: DBXToolsJavaScriptProjectOptions): void
|
|
|
516
514
|
/** Options for {@link DBXToolsNodeProject} (the monorepo root). */
|
|
517
515
|
export type DBXToolsReleaseMode = "dbx-tools" | "disabled";
|
|
518
516
|
|
|
517
|
+
/** Native constructor fields resolved for one filesystem-discovered package. */
|
|
518
|
+
export interface DiscoveredTypeScriptPackageOptions {
|
|
519
|
+
readonly name: string;
|
|
520
|
+
readonly description?: string;
|
|
521
|
+
readonly entrypoint?: string;
|
|
522
|
+
readonly publishable?: boolean;
|
|
523
|
+
}
|
|
524
|
+
|
|
519
525
|
type SupportedWorkflowOptions = Pick<
|
|
520
526
|
ReleaseProjectOptions,
|
|
521
527
|
"postBuildSteps" | "workflowContainerImage" | "workflowRunsOn" | "workflowRunsOnGroup"
|
|
522
528
|
>;
|
|
523
529
|
|
|
530
|
+
/** Options shared by discovered package roots and standalone JavaScript projects. */
|
|
524
531
|
export type DBXToolsJavaScriptProjectOptions = CommonProjectOptions &
|
|
525
532
|
Partial<
|
|
526
533
|
Omit<javascript.NodeProjectOptions, keyof ReleaseProjectOptions | "release" | "releaseToNpm">
|
|
@@ -548,8 +555,11 @@ export type DBXToolsJavaScriptProjectOptions = CommonProjectOptions &
|
|
|
548
555
|
* disable. Defaults to `"node"`.
|
|
549
556
|
*/
|
|
550
557
|
readonly omitRelativePrefix?: OneOrMany<string>;
|
|
551
|
-
/** Resolve
|
|
552
|
-
readonly
|
|
558
|
+
/** Resolve native constructor fields before a discovered package is constructed. */
|
|
559
|
+
readonly resolvePackageOptions?: (
|
|
560
|
+
pkg: DiscoveredPackage,
|
|
561
|
+
defaults: DiscoveredTypeScriptPackageOptions,
|
|
562
|
+
) => DiscoveredTypeScriptPackageOptions;
|
|
553
563
|
/**
|
|
554
564
|
* Maps a path token / relPath / glob to tag(s), unioned into a package's
|
|
555
565
|
* path-derived tags. Defaults to an identity map over the known tag names; a
|
|
@@ -575,14 +585,14 @@ export type DBXToolsJavaScriptProjectOptions = CommonProjectOptions &
|
|
|
575
585
|
readonly releaseValidationTasks?: readonly string[];
|
|
576
586
|
/** Release build prerequisites installed before repository validation tasks. */
|
|
577
587
|
readonly releaseSetupSteps?: readonly JobStep[];
|
|
588
|
+
/** Repository-specific synthesis commands run before release source verification. */
|
|
589
|
+
readonly releaseSynthesisCommands?: readonly string[];
|
|
578
590
|
/** Set to `false` to omit normal npm workspace publication. */
|
|
579
591
|
readonly nodeRelease?: boolean;
|
|
580
592
|
/** Unified dbx-tools release workflow, or no release surface. Defaults to `dbx-tools`. */
|
|
581
593
|
readonly releaseMode?: DBXToolsReleaseMode;
|
|
582
594
|
/** Prefix for generated release tags. Defaults to `v`. */
|
|
583
595
|
readonly releaseTagPrefix?: string;
|
|
584
|
-
/** Repository output paths excluded from generated workflow dependency-cache hashing. */
|
|
585
|
-
readonly workflowCacheIgnorePaths?: readonly string[];
|
|
586
596
|
/**
|
|
587
597
|
* Extra workspace member paths (repo-relative, POSIX) to list in the workspace
|
|
588
598
|
* config ALONGSIDE the discovered `packageRoots` members - for a package that
|
|
@@ -609,16 +619,6 @@ export type DBXToolsTypeScriptProjectOptions = Partial<
|
|
|
609
619
|
> &
|
|
610
620
|
DBXToolsJavaScriptProjectOptions;
|
|
611
621
|
|
|
612
|
-
const initializingWorkflowCachePaths = new Map<string, readonly string[]>();
|
|
613
|
-
|
|
614
|
-
function configuredOutdir(
|
|
615
|
-
options: Pick<DBXToolsJavaScriptProjectOptions, "parent" | "outdir">,
|
|
616
|
-
): string {
|
|
617
|
-
return options.parent
|
|
618
|
-
? resolve(options.parent.outdir, options.outdir ?? ".")
|
|
619
|
-
: resolve(options.outdir ?? process.cwd());
|
|
620
|
-
}
|
|
621
|
-
|
|
622
622
|
/**
|
|
623
623
|
* A monorepo root. Scans `packageRoots` and appends a
|
|
624
624
|
* {@link DBXToolsTypeScriptProject} per `src`-bearing folder, then emits the
|
|
@@ -635,7 +635,6 @@ export class DBXToolsNodeProject
|
|
|
635
635
|
rootTsconfig?: DBXToolsRootTsconfig;
|
|
636
636
|
readonly extraWorkspaceMembers: readonly string[];
|
|
637
637
|
readonly releaseBranch: string;
|
|
638
|
-
readonly workflowCacheIgnorePaths: readonly string[];
|
|
639
638
|
private readonly rootInstallOnly: boolean;
|
|
640
639
|
|
|
641
640
|
constructor(options: DBXToolsJavaScriptProjectOptions = {}) {
|
|
@@ -648,8 +647,6 @@ export class DBXToolsNodeProject
|
|
|
648
647
|
// into `package.json` (`workspaces`/`catalog`) for bun to read. The
|
|
649
648
|
// `pnpm-workspace.yaml` is still emitted for the Databricks Apps pnpm install.
|
|
650
649
|
const pnpmWorkspace = new PnpmWorkspaceState(options);
|
|
651
|
-
const outdir = configuredOutdir(options);
|
|
652
|
-
initializingWorkflowCachePaths.set(outdir, options.workflowCacheIgnorePaths ?? []);
|
|
653
650
|
super({
|
|
654
651
|
...defaultProjectOptions(options),
|
|
655
652
|
pnpmOptions: {
|
|
@@ -668,40 +665,11 @@ export class DBXToolsNodeProject
|
|
|
668
665
|
this.scope = scope;
|
|
669
666
|
this.extraWorkspaceMembers = options.extraWorkspaceMembers ?? [];
|
|
670
667
|
this.releaseBranch = options.defaultReleaseBranch ?? "main";
|
|
671
|
-
this.workflowCacheIgnorePaths = options.workflowCacheIgnorePaths ?? [];
|
|
672
|
-
initializingWorkflowCachePaths.delete(outdir);
|
|
673
668
|
this.rootInstallOnly = options.rootInstallOnly !== false;
|
|
674
669
|
this.dbxToolsConfig = new DBXToolsConfig(this, options);
|
|
675
670
|
initProject(this, options);
|
|
676
671
|
}
|
|
677
672
|
|
|
678
|
-
public override renderWorkflowSetup(options?: javascript.RenderWorkflowSetupOptions): JobStep[] {
|
|
679
|
-
const steps = super.renderWorkflowSetup(options);
|
|
680
|
-
if (this.parent) return steps;
|
|
681
|
-
return steps.flatMap((step) => {
|
|
682
|
-
if (step.uses?.startsWith("oven-sh/setup-bun@")) {
|
|
683
|
-
return [
|
|
684
|
-
...bunCacheRestoreSteps(this, {
|
|
685
|
-
ignorePaths:
|
|
686
|
-
this.workflowCacheIgnorePaths ??
|
|
687
|
-
initializingWorkflowCachePaths.get(resolve(this.outdir)) ??
|
|
688
|
-
[],
|
|
689
|
-
}),
|
|
690
|
-
];
|
|
691
|
-
}
|
|
692
|
-
if (step.run?.startsWith("bun install")) {
|
|
693
|
-
return [
|
|
694
|
-
step,
|
|
695
|
-
bunCacheSaveStep({
|
|
696
|
-
condition:
|
|
697
|
-
"github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository",
|
|
698
|
-
}),
|
|
699
|
-
];
|
|
700
|
-
}
|
|
701
|
-
return [step];
|
|
702
|
-
}) as JobStep[];
|
|
703
|
-
}
|
|
704
|
-
|
|
705
673
|
public override preSynthesize(): void {
|
|
706
674
|
prepareRootSynthesis(this, this.rootInstallOnly);
|
|
707
675
|
super.preSynthesize();
|
|
@@ -714,11 +682,11 @@ export class DBXToolsNodeProject
|
|
|
714
682
|
* Root-owned workspace install policy.
|
|
715
683
|
*
|
|
716
684
|
* Every projen child has its own `NodePackage` post-synth hook, which otherwise
|
|
717
|
-
* runs
|
|
718
|
-
* child install tasks
|
|
719
|
-
*
|
|
720
|
-
*
|
|
721
|
-
*
|
|
685
|
+
* runs the install task against the same root workspace once per package. Clear
|
|
686
|
+
* the public child install tasks while leaving dependency resolution and the
|
|
687
|
+
* root's real install/install:ci tasks intact. Applied in root `preSynthesize`
|
|
688
|
+
* so manually attached late children are included and repeated synths remain
|
|
689
|
+
* idempotent.
|
|
722
690
|
*/
|
|
723
691
|
export const ROOT_INSTALL_ONLY_MIXIN = mixin.create(
|
|
724
692
|
(construct: IConstruct): construct is DBXToolsNodeProject | DBXToolsTypeScriptProject =>
|
|
@@ -727,12 +695,6 @@ export const ROOT_INSTALL_ONLY_MIXIN = mixin.create(
|
|
|
727
695
|
(child) => {
|
|
728
696
|
child.package.installTask.reset();
|
|
729
697
|
child.package.installCiTask.reset();
|
|
730
|
-
const nodePackage = child.package as unknown as {
|
|
731
|
-
installDependencies(trigger: unknown): void;
|
|
732
|
-
logInstallTrigger(trigger: unknown): void;
|
|
733
|
-
};
|
|
734
|
-
nodePackage.installDependencies = () => {};
|
|
735
|
-
nodePackage.logInstallTrigger = () => {};
|
|
736
698
|
},
|
|
737
699
|
);
|
|
738
700
|
|
|
@@ -754,7 +716,6 @@ export class DBXToolsTypeScriptProject
|
|
|
754
716
|
rootTsconfig?: DBXToolsRootTsconfig;
|
|
755
717
|
readonly extraWorkspaceMembers: readonly string[];
|
|
756
718
|
readonly releaseBranch: string;
|
|
757
|
-
readonly workflowCacheIgnorePaths: readonly string[];
|
|
758
719
|
private readonly rootInstallOnly: boolean;
|
|
759
720
|
|
|
760
721
|
constructor(options: DBXToolsTypeScriptProjectOptions) {
|
|
@@ -795,7 +756,6 @@ export class DBXToolsTypeScriptProject
|
|
|
795
756
|
this.scope = scope;
|
|
796
757
|
this.extraWorkspaceMembers = options.extraWorkspaceMembers ?? [];
|
|
797
758
|
this.releaseBranch = options.defaultReleaseBranch ?? "main";
|
|
798
|
-
this.workflowCacheIgnorePaths = options.workflowCacheIgnorePaths ?? [];
|
|
799
759
|
this.rootInstallOnly = options.rootInstallOnly !== false;
|
|
800
760
|
// Pairs with `jsx` in SHARED_COMPILER_OPTIONS: projen's default `include` is
|
|
801
761
|
// `src/**/*.ts` only, which silently omits a `.tsx` file from the program
|
|
@@ -862,10 +822,9 @@ class GeneratedSource extends Component {
|
|
|
862
822
|
public override preSynthesize(): void {
|
|
863
823
|
const root = resolve(this.project.outdir);
|
|
864
824
|
for (const subproject of this.project.subprojects) {
|
|
865
|
-
if (!(subproject instanceof
|
|
866
|
-
const codegen = subproject.package.manifest.codegen as { inputs?: string[] } | undefined;
|
|
825
|
+
if (!(subproject instanceof DBXToolsTypeScriptProject)) continue;
|
|
867
826
|
const packagePath = toPosix(relative(root, subproject.outdir));
|
|
868
|
-
const modules = codegenModulePaths(
|
|
827
|
+
const modules = codegenModulePaths(subproject.dbxToolsConfig.codegenInputs);
|
|
869
828
|
for (const module of modules) {
|
|
870
829
|
this.project.annotateGenerated(`/${packagePath}/${module}`);
|
|
871
830
|
}
|
|
@@ -898,10 +857,10 @@ class GeneratedSource extends Component {
|
|
|
898
857
|
*
|
|
899
858
|
* projen gives a monorepo root empty `compile`/`test` tasks - a child's tasks
|
|
900
859
|
* are the child's business - so `bun run build` at the root type-checked nothing
|
|
901
|
-
* and ran no package tests. Compilation groups ordinary
|
|
902
|
-
*
|
|
903
|
-
* still use Bun's filtered workspace fan-out. Both read the current
|
|
904
|
-
* list from `package.json`, so a newly added member needs no re-synth.
|
|
860
|
+
* and ran no package tests. Compilation groups ordinary package tsconfigs into
|
|
861
|
+
* a few TypeScript processes and runs custom package lifecycles alongside them.
|
|
862
|
+
* Tests still use Bun's filtered workspace fan-out. Both read the current
|
|
863
|
+
* workspace list from `package.json`, so a newly added member needs no re-synth.
|
|
905
864
|
*
|
|
906
865
|
* `*` matches every workspace MEMBER and never the root itself, so the test
|
|
907
866
|
* task delegating to it cannot recurse. Members declared outside the scanned
|
|
@@ -923,35 +882,9 @@ class WorkspaceValidationTasks extends Component {
|
|
|
923
882
|
}
|
|
924
883
|
|
|
925
884
|
/**
|
|
926
|
-
*
|
|
927
|
-
*
|
|
928
|
-
* Projen otherwise leaves jobs at GitHub's six-hour ceiling. Missing workflows
|
|
929
|
-
* are a no-op, so roots that keep the engine defaults (`github`/build workflow
|
|
930
|
-
* off) do not gain new files.
|
|
931
|
-
*/
|
|
932
|
-
class WorkflowDefaults extends Component {
|
|
933
|
-
public override preSynthesize(): void {
|
|
934
|
-
const build = this.project.tryFindObjectFile(".github/workflows/build.yml");
|
|
935
|
-
build?.addOverride("on.pull_request.types", ["opened", "synchronize", "reopened", "closed"]);
|
|
936
|
-
build?.addOverride(
|
|
937
|
-
"jobs.build.if",
|
|
938
|
-
"${{ github.event_name != 'pull_request' || github.event.action != 'closed' }}",
|
|
939
|
-
);
|
|
940
|
-
for (const job of ["build", "self-mutation"]) {
|
|
941
|
-
build?.addOverride(`jobs.${job}.timeout-minutes`, 30);
|
|
942
|
-
}
|
|
943
|
-
build?.addOverride("permissions", { contents: "read" });
|
|
944
|
-
build?.addOverride("concurrency", {
|
|
945
|
-
group: "${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}",
|
|
946
|
-
"cancel-in-progress": true,
|
|
947
|
-
});
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
/**
|
|
952
|
-
* Ignore each `codegen`-declaring package's `src/` from the root ESLint config.
|
|
885
|
+
* Ignore each codegen-declaring package's generated modules from root ESLint.
|
|
953
886
|
* Those modules are read-only (ts-to-zod); lint `--fix` otherwise EACCES-crashes
|
|
954
|
-
* on them. Runs in `preSynthesize` so mixin-added
|
|
887
|
+
* on them. Runs in `preSynthesize` so mixin-added typed config is visible.
|
|
955
888
|
*/
|
|
956
889
|
class EslintIgnoreCodegen extends Component {
|
|
957
890
|
public override preSynthesize(): void {
|
|
@@ -959,16 +892,15 @@ class EslintIgnoreCodegen extends Component {
|
|
|
959
892
|
if (!eslint) return;
|
|
960
893
|
const rootAbs = resolve(this.project.outdir);
|
|
961
894
|
for (const sub of this.project.subprojects) {
|
|
962
|
-
if (!(sub instanceof
|
|
963
|
-
|
|
964
|
-
if (!codegen?.inputs?.length) continue;
|
|
895
|
+
if (!(sub instanceof DBXToolsTypeScriptProject)) continue;
|
|
896
|
+
if (sub.dbxToolsConfig.codegenInputs.length === 0) continue;
|
|
965
897
|
const rel = toPosix(relative(rootAbs, sub.outdir));
|
|
966
898
|
// Ignore the generated MODULES, not the package's whole `src/`. A codegen
|
|
967
899
|
// package may hold hand-written modules next to its generated ones
|
|
968
900
|
// (shared-genie generates `dashboards.ts` beside a hand-written
|
|
969
901
|
// `genie-model.ts`), and a blanket `src/**` would silently stop linting
|
|
970
902
|
// them - the failure mode being invisible, since ESLint just reports less.
|
|
971
|
-
for (const module of codegenModulePaths(
|
|
903
|
+
for (const module of codegenModulePaths(sub.dbxToolsConfig.codegenInputs)) {
|
|
972
904
|
eslint.addIgnorePattern(`${rel}/${module}`);
|
|
973
905
|
}
|
|
974
906
|
}
|
|
@@ -989,11 +921,10 @@ class PrettierIgnoreGenerated extends Component {
|
|
|
989
921
|
prettier.addIgnorePattern("**/src/generated/**");
|
|
990
922
|
const rootAbs = resolve(this.project.outdir);
|
|
991
923
|
for (const sub of this.project.subprojects) {
|
|
992
|
-
if (!(sub instanceof
|
|
924
|
+
if (!(sub instanceof DBXToolsTypeScriptProject)) continue;
|
|
993
925
|
const rel = toPosix(relative(rootAbs, sub.outdir));
|
|
994
926
|
prettier.addIgnorePattern(`${rel}/index.ts`);
|
|
995
|
-
const
|
|
996
|
-
for (const module of codegenModulePaths(codegen?.inputs ?? [])) {
|
|
927
|
+
for (const module of codegenModulePaths(sub.dbxToolsConfig.codegenInputs)) {
|
|
997
928
|
prettier.addIgnorePattern(`${rel}/${module}`);
|
|
998
929
|
}
|
|
999
930
|
}
|
|
@@ -1109,7 +1040,6 @@ function resolveTags(p: DiscoveredPackage, tagPaths: Record<string, string[]>):
|
|
|
1109
1040
|
/** Register the native projen tasks on the monorepo root. */
|
|
1110
1041
|
function registerRootTasks(project: javascript.NodeProject): void {
|
|
1111
1042
|
project.addTask("barrels", { execArgs: taskCommand("barrels.ts") });
|
|
1112
|
-
project.addTask("openapi", { execArgs: taskCommand("openapi.ts") });
|
|
1113
1043
|
project.addTask("clean", { execArgs: taskCommand("clean.ts"), receiveArgs: true });
|
|
1114
1044
|
project.addTask("sync", {
|
|
1115
1045
|
execArgs: taskCommand("sync.ts"),
|
|
@@ -1156,12 +1086,8 @@ function initProject(
|
|
|
1156
1086
|
execArgs: [...packageStep.execArgs, "--ignore-scripts"],
|
|
1157
1087
|
});
|
|
1158
1088
|
}
|
|
1159
|
-
// Only a ROOT configures the workspace; a child just swaps its default-laden
|
|
1160
|
-
// `.gitignore` for a fresh one that carries package-specific patterns only.
|
|
1161
|
-
swapChildGitignore(project, options);
|
|
1162
1089
|
return;
|
|
1163
1090
|
}
|
|
1164
|
-
project.package.file.readonly = false;
|
|
1165
1091
|
|
|
1166
1092
|
if (project instanceof DBXToolsNodeProject) {
|
|
1167
1093
|
project.rootTsconfig = new DBXToolsRootTsconfig(project);
|
|
@@ -1177,7 +1103,6 @@ function initProject(
|
|
|
1177
1103
|
// a plain `bun` exec rather than any wrapper: the default task is spawned by
|
|
1178
1104
|
// nested installs/synths, and a wrapper that exported `npm_config_*` broke them.
|
|
1179
1105
|
project.defaultTask?.reset("bun .projenrc.ts");
|
|
1180
|
-
project.buildWorkflow?.workflow.file?.addOverride("jobs.build.env.BUN_VERSION", BUN_VERSION);
|
|
1181
1106
|
|
|
1182
1107
|
// Pin bun's hoisted linker workspace-wide (see RootBunfigFile) so a peer dep
|
|
1183
1108
|
// resolves to one copy and singletons/types stay coherent.
|
|
@@ -1189,6 +1114,9 @@ function initProject(
|
|
|
1189
1114
|
if (selfDep) project.addDevDeps(selfDep);
|
|
1190
1115
|
project.addDevDeps(...DEV_DEPS_ROOT);
|
|
1191
1116
|
configureRootPackage(project);
|
|
1117
|
+
// Workspaces generated by this engine intentionally do not track local-registry
|
|
1118
|
+
// lockfiles, so the CI-named install task must resolve from manifests as well.
|
|
1119
|
+
project.package.installCiTask.reset("bun install");
|
|
1192
1120
|
const roots = options.packageRoots ?? DEFAULT_PACKAGE_ROOTS;
|
|
1193
1121
|
project.dbxToolsConfig.packageRoots = [...roots];
|
|
1194
1122
|
if (options.syncResynthPaths?.length) {
|
|
@@ -1220,7 +1148,6 @@ function initProject(
|
|
|
1220
1148
|
project.gitignore.addPatterns(".env", ".env.*", "!.env.example", "!.env.sample", ".idea/*");
|
|
1221
1149
|
for (const root of roots) {
|
|
1222
1150
|
project.annotateGenerated(`/${root}/**/index.ts`);
|
|
1223
|
-
project.annotateGenerated(`/${root}/openapi/**`);
|
|
1224
1151
|
project.annotateGenerated(`/${root}/**/src/generated/**`);
|
|
1225
1152
|
}
|
|
1226
1153
|
for (const member of project.extraWorkspaceMembers) {
|
|
@@ -1250,11 +1177,9 @@ function initProject(
|
|
|
1250
1177
|
description: "Fix ESLint issues across the codebase",
|
|
1251
1178
|
exec: "bun run eslint -- --fix",
|
|
1252
1179
|
});
|
|
1253
|
-
// Generated read-only outputs (barrels,
|
|
1254
|
-
//
|
|
1255
|
-
// openapi / codegen / projen.
|
|
1180
|
+
// Generated read-only outputs (barrels, app scripts, and codegen). ESLint
|
|
1181
|
+
// --fix cannot rewrite files owned by the barrel generator, codegen, or projen.
|
|
1256
1182
|
for (const root of roots) {
|
|
1257
|
-
eslint.addIgnorePattern(`${root}/openapi/**`);
|
|
1258
1183
|
eslint.addIgnorePattern(`${root}/**/index.ts`);
|
|
1259
1184
|
}
|
|
1260
1185
|
eslint.addIgnorePattern("**/src/generated/**");
|
|
@@ -1266,14 +1191,11 @@ function initProject(
|
|
|
1266
1191
|
// them to a project. ESLint still cannot parse them.
|
|
1267
1192
|
eslint.addIgnorePattern("**/dev.ts");
|
|
1268
1193
|
eslint.addIgnorePattern("**/build.ts");
|
|
1269
|
-
// A deploy-staging helper that lives at a package root (outside any `src/**`
|
|
1270
|
-
// tsconfig), same parse-resolution problem as the bun app scripts above.
|
|
1271
|
-
eslint.addIgnorePattern("**/stage-deploy.ts");
|
|
1272
1194
|
for (const override of BUN_APP_OVERRIDES) {
|
|
1273
1195
|
eslint.addIgnorePattern(`**/${override}`);
|
|
1274
1196
|
}
|
|
1275
|
-
// Codegen
|
|
1276
|
-
//
|
|
1197
|
+
// Codegen inputs may be added by mixins after construction; ignore their
|
|
1198
|
+
// generated modules once typed package configuration is final.
|
|
1277
1199
|
new EslintIgnoreCodegen(project);
|
|
1278
1200
|
eslint.addRules({
|
|
1279
1201
|
"import/no-relative-packages": "error",
|
|
@@ -1300,7 +1222,11 @@ function initProject(
|
|
|
1300
1222
|
// cross-package imports.
|
|
1301
1223
|
const tsResolver = eslint.config?.settings?.["import/resolver"]?.typescript;
|
|
1302
1224
|
if (tsResolver) {
|
|
1303
|
-
tsResolver.project = [
|
|
1225
|
+
tsResolver.project = [
|
|
1226
|
+
"tsconfig.json",
|
|
1227
|
+
...roots.map((r) => `${r}/**/tsconfig.json`),
|
|
1228
|
+
...project.extraWorkspaceMembers.map((member) => `${member}/tsconfig.json`),
|
|
1229
|
+
];
|
|
1304
1230
|
}
|
|
1305
1231
|
|
|
1306
1232
|
const enabledTagMixins = resolveEnabledTagMixins(options.defaultTagMixins);
|
|
@@ -1334,10 +1260,13 @@ function initProject(
|
|
|
1334
1260
|
continue;
|
|
1335
1261
|
}
|
|
1336
1262
|
const defaultPackageName = packageNameFor(project.scope, p.relPath, omitPrefixes);
|
|
1263
|
+
const packageOptions =
|
|
1264
|
+
options.resolvePackageOptions?.(p, { name: defaultPackageName }) ??
|
|
1265
|
+
({ name: defaultPackageName } satisfies DiscoveredTypeScriptPackageOptions);
|
|
1337
1266
|
new DBXToolsTypeScriptProject({
|
|
1338
1267
|
parent: project,
|
|
1339
1268
|
outdir: p.memberPath,
|
|
1340
|
-
|
|
1269
|
+
...packageOptions,
|
|
1341
1270
|
tags,
|
|
1342
1271
|
});
|
|
1343
1272
|
}
|
|
@@ -1354,7 +1283,6 @@ function initProject(
|
|
|
1354
1283
|
}
|
|
1355
1284
|
|
|
1356
1285
|
new WorkspaceValidationTasks(project);
|
|
1357
|
-
new WorkflowDefaults(project);
|
|
1358
1286
|
new PrettierIgnoreGenerated(project);
|
|
1359
1287
|
new GeneratedSource(project);
|
|
1360
1288
|
|
|
@@ -1368,56 +1296,11 @@ function initProject(
|
|
|
1368
1296
|
pythonRoot: options.releasePythonRoot,
|
|
1369
1297
|
validationTasks: options.releaseValidationTasks,
|
|
1370
1298
|
setupSteps: options.releaseSetupSteps,
|
|
1299
|
+
synthesisCommands: options.releaseSynthesisCommands,
|
|
1371
1300
|
});
|
|
1372
1301
|
}
|
|
1373
1302
|
}
|
|
1374
1303
|
|
|
1375
|
-
/**
|
|
1376
|
-
* A child's `.gitignore`, tracking whether any pattern was ever added so an
|
|
1377
|
-
* untouched (empty) file can be dropped at presynth. `exclude`/`include` and
|
|
1378
|
-
* constructor `ignorePatterns` all funnel through {@link addPatterns}, so the flag
|
|
1379
|
-
* sees every route - but seed patterns must be added AFTER construction (see
|
|
1380
|
-
* {@link swapChildGitignore}) because class fields initialize after `super()`.
|
|
1381
|
-
*/
|
|
1382
|
-
class ChildGitignore extends IgnoreFile {
|
|
1383
|
-
/** True once any pattern landed (custom patterns => the file is emitted). */
|
|
1384
|
-
public hasPatterns = false;
|
|
1385
|
-
|
|
1386
|
-
public override addPatterns(...patterns: string[]): void {
|
|
1387
|
-
if (patterns.length) this.hasPatterns = true;
|
|
1388
|
-
super.addPatterns(...patterns);
|
|
1389
|
-
}
|
|
1390
|
-
}
|
|
1391
|
-
|
|
1392
|
-
/**
|
|
1393
|
-
* Swap a CHILD's default `.gitignore` - pre-populated by `NodeProject` with the
|
|
1394
|
-
* same defaults the root already carries (git applies the root's file to the whole
|
|
1395
|
-
* tree) - for a FRESH {@link ChildGitignore}. Caller-supplied patterns
|
|
1396
|
-
* (`gitignore` / `gitIgnoreOptions.ignorePatterns`) are re-seeded, and later
|
|
1397
|
-
* `project.gitignore.addPatterns(...)` calls (tag/user mixins) land here too, so a
|
|
1398
|
-
* package CAN carry package-specific ignores without inheriting the root noise.
|
|
1399
|
-
* Left empty, the file is dropped by {@link preSynthesizeProject}. Safe because
|
|
1400
|
-
* projen only writes gitignore defaults at construction time (`addDefaultGitIgnore`,
|
|
1401
|
-
* yarn-berry config), never during synth.
|
|
1402
|
-
*/
|
|
1403
|
-
function swapChildGitignore(
|
|
1404
|
-
project: javascript.NodeProject,
|
|
1405
|
-
options: DBXToolsJavaScriptProjectOptions,
|
|
1406
|
-
): void {
|
|
1407
|
-
project.tryRemoveFile(".gitignore");
|
|
1408
|
-
const fresh = new ChildGitignore(project, ".gitignore", {
|
|
1409
|
-
...options.gitIgnoreOptions,
|
|
1410
|
-
// Re-added below so the custom-pattern flag sees them (not clobbered by the
|
|
1411
|
-
// subclass field initializer running after super()).
|
|
1412
|
-
ignorePatterns: undefined,
|
|
1413
|
-
});
|
|
1414
|
-
const seeds = [...(options.gitignore ?? []), ...(options.gitIgnoreOptions?.ignorePatterns ?? [])];
|
|
1415
|
-
if (seeds.length) fresh.addPatterns(...seeds);
|
|
1416
|
-
// `Project.gitignore` is readonly only at compile time; rebind it so every
|
|
1417
|
-
// subsequent `project.gitignore.*` call reaches the fresh file.
|
|
1418
|
-
(project as { gitignore: IgnoreFile }).gitignore = fresh;
|
|
1419
|
-
}
|
|
1420
|
-
|
|
1421
1304
|
function preSynthesizeProject(project: javascript.NodeProject): void {
|
|
1422
1305
|
// `Project.files` is OWN-project only (its `components` getter filters on the
|
|
1423
1306
|
// project's own node path), so reaching a child's files means walking the tree.
|
|
@@ -1439,19 +1322,5 @@ function preSynthesizeProject(project: javascript.NodeProject): void {
|
|
|
1439
1322
|
// only. Runs here rather than in the constructor so the tags have already
|
|
1440
1323
|
// installed their `exports` layouts for it to mirror.
|
|
1441
1324
|
if (p instanceof javascript.NodeProject) applyCompiledPublish(p);
|
|
1442
|
-
// A child's `.gitignore` survives ONLY when it carries custom patterns (see
|
|
1443
|
-
// swapChildGitignore). `.gitattributes` is always dropped - the root's
|
|
1444
|
-
// annotateGenerated globs cover the children. Runs once from the root's
|
|
1445
|
-
// preSynthesize and again from each child's own; both passes agree, so the
|
|
1446
|
-
// second is a no-op.
|
|
1447
|
-
const keepGitignore = p.gitignore instanceof ChildGitignore && p.gitignore.hasPatterns;
|
|
1448
|
-
for (const path of keepGitignore ? [".gitattributes"] : [".gitignore", ".gitattributes"]) {
|
|
1449
|
-
if (p.tryRemoveFile(path)) {
|
|
1450
|
-
const rootPath = resolve(p.outdir, path);
|
|
1451
|
-
if (existsSync(rootPath)) {
|
|
1452
|
-
p.logger.info(`Removed ${rootPath} from ${p.name}`);
|
|
1453
|
-
}
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
1325
|
}
|
|
1457
1326
|
}
|
package/src/project-predicate.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composable, runtime-safe predicates for selecting Projen projects by type,
|
|
3
|
+
* package identity, tags, and repository path.
|
|
4
|
+
*/
|
|
1
5
|
import { relative } from "node:path";
|
|
2
6
|
import { match, PathMatchInput, PathMatchPredicate } from "@dbx-tools/path";
|
|
3
7
|
import {
|
|
@@ -19,9 +23,9 @@ import type { DBXToolsProject } from "./project.ts";
|
|
|
19
23
|
*
|
|
20
24
|
* Uses projen's own `Project.isProject` rather than `instanceof`. It tests for
|
|
21
25
|
* `Symbol.for("projen.Project")`, which every `Project` constructor stamps on
|
|
22
|
-
* itself, so it still matches
|
|
23
|
-
*
|
|
24
|
-
*
|
|
26
|
+
* itself, so it still matches if an invalid consumer install resolves a second
|
|
27
|
+
* Projen copy despite the engine's peer dependency. An `instanceof` guard would
|
|
28
|
+
* silently reject that construct before the install problem can be diagnosed.
|
|
25
29
|
*/
|
|
26
30
|
export function isProject(): Predicate<IConstruct, Project> {
|
|
27
31
|
return predicate.create((c: IConstruct): c is Project => Project.isProject(c));
|