@dbx-tools/projen 0.9.19 → 0.9.28

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.
Files changed (56) hide show
  1. package/README.md +83 -229
  2. package/index.ts +11 -18
  3. package/package.json +9 -5
  4. package/src/_task-command.ts +75 -0
  5. package/src/barrels.ts +1 -74
  6. package/src/module-exports.ts +175 -1
  7. package/src/openapi.ts +5 -72
  8. package/src/packages.ts +45 -0
  9. package/src/project-js.ts +5 -48
  10. package/src/project-predicate.ts +1 -2
  11. package/src/project-py.ts +87 -199
  12. package/src/project.ts +2 -2
  13. package/src/python-node-bindings.ts +138 -0
  14. package/src/python-node-bundle.ts +92 -0
  15. package/src/release-catalog.ts +40 -208
  16. package/src/{release-dispatch.ts → release-context.ts} +0 -11
  17. package/src/release.ts +74 -778
  18. package/src/scaffold.ts +2 -6
  19. package/src/workspace-version.ts +9 -121
  20. package/tasks/bump.ts +17 -34
  21. package/tasks/databricks-cli-assets.ts +129 -0
  22. package/tasks/local-publish.ts +61 -138
  23. package/tasks/publish-npm.ts +71 -30
  24. package/tasks/publish-python.ts +61 -148
  25. package/tasks/publish.ts +32 -182
  26. package/tasks/python-node-bindings-watch.ts +47 -0
  27. package/tasks/python-node-bindings.ts +1017 -0
  28. package/tasks/python-registry.ts +2 -9
  29. package/tasks/python-release.ts +74 -0
  30. package/tasks/release-version.ts +23 -2
  31. package/tasks/release.ts +99 -0
  32. package/tasks/sync.ts +13 -18
  33. package/tasks/version-check.ts +13 -72
  34. package/src/_rust-project.ts +0 -429
  35. package/src/_rust-release-workflow.ts +0 -698
  36. package/src/project-rs.ts +0 -1127
  37. package/src/release-plan.ts +0 -269
  38. package/src/release-please.ts +0 -242
  39. package/src/uniffi.ts +0 -65
  40. package/tasks/publish-uniffi-local.ts +0 -314
  41. package/tasks/release-assets.ts +0 -476
  42. package/tasks/release-bootstrap.ts +0 -59
  43. package/tasks/release-candidate.ts +0 -383
  44. package/tasks/release-manifest.ts +0 -273
  45. package/tasks/release-plan.ts +0 -89
  46. package/tasks/release-please.ts +0 -162
  47. package/tasks/release-pr.ts +0 -563
  48. package/tasks/release-request.ts +0 -166
  49. package/tasks/release-summary-units.ts +0 -75
  50. package/tasks/release-summary.ts +0 -381
  51. package/tasks/rust.ts +0 -178
  52. package/tasks/stamp-python.ts +0 -13
  53. package/tasks/uniffi-python.d.ts +0 -61
  54. package/tasks/uniffi-python.js +0 -191
  55. package/tasks/uniffi-release.mjs +0 -573
  56. package/tasks/uniffi.ts +0 -271
package/README.md CHANGED
@@ -19,7 +19,7 @@ Key features:
19
19
  files based on package predicates.
20
20
  - OpenAPI client generation from tsoa controllers and zod schema generation from
21
21
  `.d.ts` inputs.
22
- - Read-only generated-file stamping, cleanup, and watch-loop helpers.
22
+ - Read-only generated-file ownership, cleanup, and watch-loop helpers.
23
23
 
24
24
  ## Define A Workspace Root
25
25
 
@@ -45,8 +45,12 @@ instead of creating a second owner. An explicit `outdir` is the workspace root
45
45
  for naming, Git metadata, package discovery, codegen, and barrels even when the
46
46
  calling process has a different current directory.
47
47
 
48
- The unified dbx-tools release surface is enabled by default. Set
49
- `releaseMode: "disabled"` to omit its workflow and bump/version/release tasks.
48
+ The unified dbx-tools release surface is enabled by default. `bump` increments
49
+ the local `VERSION` and synchronizes generated version surfaces. `release`
50
+ commits that bump on the configured release branch, pushes it, and pushes an
51
+ annotated version tag. The generated GitHub workflow runs only for matching tag
52
+ pushes and publishes directly from that immutable commit. Set
53
+ `releaseMode: "disabled"` to omit the workflow and bump/version/release tasks.
50
54
  The inherited Projen `release` and `releaseTrigger` options are intentionally
51
55
  not part of this engine's public options because they create a competing release
52
56
  workflow.
@@ -58,13 +62,8 @@ Repository policy stays in the consuming `.projenrc.ts`:
58
62
  artifact upload, and deployment without naming a docs script or output tree.
59
63
  - `releasePythonRoot` passes the actual Python package root to local release
60
64
  preparation. Omit it when the workspace has no standard Python packages.
61
- - `releaseValidationTasks` names repository tasks that must pass in the release
62
- worktree before Cargo tests, compilation, local publication, or approval.
63
- Use it for repository-specific guards that also run in release CI.
64
- - `releaseSummary` controls versioned release notes. It defaults to Cursor,
65
- Codex, Claude fallback order and writes a deterministic Git summary when every
66
- configured provider is unavailable; pass `false` to disable or provide a
67
- `providers` array to choose the order/subset.
65
+ - `releaseValidationTasks` names repository tasks that must pass in tag CI
66
+ before release artifacts are built and published.
68
67
  - `pullRequestTitlePolicy` configures semantic title types and scope policy.
69
68
  Omit it or pass `false` to disable the title job.
70
69
  - `workflowCacheIgnorePaths` excludes generated output trees that may contain
@@ -90,8 +89,9 @@ without turning Python packages into JavaScript workspace projects. It generates
90
89
  the root and member `pyproject.toml` files, standard `py:*` tasks, the VS Code
91
90
  interpreter setting, and an optional manual PyPI trusted-publishing workflow.
92
91
  Projen's native `PyprojectTomlFile` owns generated TOML formatting. Temporary
93
- publication stamping uses parsed TOML, changes versions and sibling
94
- dependencies structurally, and restores the original files byte-for-byte.
92
+ release packaging copies each project to an isolated directory and projects
93
+ sibling registry requirements there with parsed TOML. Source manifests already
94
+ carry the root `VERSION` and are never rewritten for publication.
95
95
 
96
96
  ```ts
97
97
  import { project, projectPy } from "@dbx-tools/projen";
@@ -123,193 +123,70 @@ without repeating repository coordinates. Pass `repository`, `name`, or
123
123
  VS Code component; dbx-tools reuses it rather than constructing a second
124
124
  `.vscode/settings.json` owner.
125
125
 
126
- ## Add A Rust Workspace
127
-
128
- `DBXToolsRustWorkspace` discovers every source-bearing folder under its
129
- configurable `root` (default `packages/rs`), generates its Cargo manifest, and
130
- derives the crate name and repository from the parent project. A crate containing
131
- `uniffi::setup_scaffolding!()`
132
- automatically wires matching public Node and Python binding packages using the
133
- `<name>-rs` folder suffix. Node packages are named `@<scope>/<name>-rs`;
134
- Python distributions are named `<scope>-<name>-rs` and export generated values
135
- from `<scope>.<name>_rs`. Binding packages are always dedicated and
136
- never merge generated code into handwritten Node or Python packages.
137
- Repository-specific dependencies and features remain
138
- declarative options in `.projenrc.ts`; generated bindings are built separately
139
- from projen synthesis. Target-independent Node binding TypeScript is committed
140
- and remains generated/read-only, while native libraries stay ignored. Node
141
- facades compile to `lib/` and publish JavaScript entry points that plain Node
142
- can load from `node_modules`. A complete `bindings.ts` / `_bindings.ts` /
143
- `_bindings-ffi.ts` triplet is exported directly from the generated package
144
- barrel. Python keeps `bindings.py` as the generated implementation and leaves
145
- `__init__.py` as its generated package-root export. Node generation fails when
146
- direct binding names conflict.
147
- Do not create a `nodeExports` binding subpath or a handwritten type facade.
148
-
149
- Each discovered member is a native Projen `Project`, exposed as
150
- `DBXToolsRustProject`. The same class also owns standalone Cargo projects with
151
- the flat object-style options used by the Node and Python project classes:
126
+ ### Bundle Node Code For PythonMonkey
152
127
 
153
- ```ts
154
- import { project } from "@dbx-tools/projen";
128
+ Add `nodeBindings` to any `DBXToolsPythonWorkspace` package to generate a
129
+ committed CommonJS runtime and async Python wrappers from a public Node package.
130
+ The configuration is written to `pyproject.toml`, so the generation task also
131
+ works in consuming repositories after `@dbx-tools/projen` is installed.
155
132
 
156
- new project.DBXToolsRustProject({
157
- name: "my-apps-core",
158
- outdir: "native/core",
159
- version: "0.1.0",
160
- description: "Shared native runtime",
161
- repository: "https://github.com/example/my-apps",
133
+ ```ts
134
+ new project.DBXToolsPythonWorkspace(root, {
135
+ root: "packages/py",
136
+ packages: [
137
+ {
138
+ directory: "auth",
139
+ description: "Python bindings for example auth",
140
+ nodeBindings: {
141
+ package: "@example/auth",
142
+ layout: "package",
143
+ private: false,
144
+ shimRoot: "projen/shims/python-node",
145
+ functionOverrides: [
146
+ {
147
+ module: "@example/core/file-lock",
148
+ export: "acquireFileLock",
149
+ handler: "projen/shims/python-node/file-lock.ts",
150
+ },
151
+ ],
152
+ },
153
+ },
154
+ ],
162
155
  });
163
156
  ```
164
157
 
165
- The project emits concrete standalone Cargo metadata plus `compile`, `test`,
166
- `package`, `lint`, `format`, and `format:check` tasks. A nested standalone
167
- project declares its own empty Cargo workspace so a surrounding repository
168
- workspace does not absorb it accidentally. The `examples` option emits explicit
169
- Cargo example targets and `required-features`, so an optional code generator is
170
- excluded from ordinary workspace tests until its feature is enabled.
171
- `DBXToolsRustWorkspace` constructs the same class with workspace-owned metadata
172
- and keeps aggregate binding and release coordination.
173
- `DBXToolsRustWorkspaceOptions.private` supplies the default Cargo publication
174
- policy for every discovered crate; a package-level `private` value overrides it.
175
- Cargo projects use the flat object-style constructor exclusively.
176
-
177
- Rust dependencies between binding-enabled workspace crates become Node
178
- `workspace:*` and Python `internalDependencies` automatically. Python generation
179
- selects the owning crate and supplies `external_packages` imports. UBRN currently
180
- emits every linked component; the generation task discards dependency outputs
181
- and rewrites their imports to the owning package root, including its generated
182
- `uniffiModule` converter table. It never copies a dependency's records or enums.
183
- Foreign callback adapters must first be wrapped in an object created by their
184
- own native library (`createStorageHandle` for auth), because callback registries
185
- are library-local. Release wheels replace sibling Git requirements with matching
186
- native-wheel versions, and dependent publishers wait for their dependencies.
187
- Each crate builds its own `<crate>-uniffi-bindgen` executable so one target row
188
- has no colliding binary outputs. The executable requires the generated
189
- `uniffi-bindgen` feature, which enables `uniffi/cli` only in the UniFFI matrix.
190
- Packaging runs that prebuilt executable.
191
- Cargo manifests, target config, and UniFFI config are generated from structured
192
- Projen `TomlFile` objects. Local and release Python generation share one
193
- dependency-free helper for generator arguments, target-specific executable
194
- names, generated headers, generated package-root exports, and native-library
195
- placement.
196
-
197
- `sync --watch` runs a focused Rust watcher beside the OpenAPI watcher. Changes
198
- inside an existing UniFFI crate regenerate that crate and its dependent bindings
199
- in dependency order; adding or
200
- removing a crate or `setup_scaffolding!()` marker triggers a full synth. Repos
201
- without Rust crates start no Rust watcher. When Rust projects are detected,
202
- Cargo is required and the focused task fails immediately if it is unavailable.
203
- `rs:bindings` is explicit rather than part of root `pre-compile`, so ordinary
204
- JavaScript PR builds type-check committed generated bindings without performing
205
- a host Rust build. Regenerate bindings through the focused watcher or explicit
206
- task while changing a UniFFI API. Release preparation runs Cargo workspace tests
207
- without invoking UBRN.
208
-
209
- Rust fingerprinting and binary version stamping use the dependency-free Node
210
- helper generated at `.projen/rust-release.mjs`. The implementation ships with
211
- `@dbx-tools/projen`, so consumers do not need a repository-specific helper
212
- crate, a crates.io publication, or an extra Cargo build before release
213
- orchestration can start.
214
-
215
- The workspace generates one `release.yml` workflow for every ecosystem. One
216
- root `VERSION` drives every Node, Python, Cargo, native, and GitHub artifact.
217
- `bun run release` prepares one reviewed PR into `main`; it enables automatic
218
- merge by default and accepts `--no-approve` for a human-controlled merge. One
219
- non-cancelling `release` concurrency group serializes publication.
220
-
221
- Release generation writes `release.yml` without scanning for or removing other
222
- workflow files. Consumers explicitly delete exact workflow files they no longer
223
- want.
224
-
225
- The release workflow accepts stage-specific manual recovery only for the exact
226
- annotated tag and expected SHA. npm retries compare archive content and
227
- repository identity, PyPI uses hash-aware existing-file behavior, Cargo checks
228
- existing versions, and GitHub assets upload to the single repository release.
229
-
230
- Set `releaseSyncBranch` when a repository retains a long-lived source branch.
231
- After publication the workflow fast-forwards a branch that is behind, skips a
232
- branch that already contains released `main`, and merges `main` into a diverged
233
- branch when the merge is conflict-free. Missing branches and conflicted merges
234
- are left untouched.
235
-
236
- Rust release generation creates one uncached matrix with one row per target.
237
- Each row builds all discovered bindings and selected release binaries together
238
- with the union of their required features, then packages every native artifact
239
- from that one Cargo output. Set a source-only crate's or release-enabled
240
- binary's `releaseExcludeOs` package option to omit it from incompatible rows.
241
- Release binary packaging and artifact upload are skipped in those rows. UniFFI
242
- crates cannot use this option because every configured target must produce
243
- their artifacts.
244
- Set a release binary's `cli` package option and the workspace
245
- `cliRegistryPath` to generate a typed `dbx` command registry from the same
246
- selected targets. The generated entries carry only the archives that the
247
- release matrix publishes, so an excluded operating system fails locally before
248
- any download is attempted. The runtime command uses `@dbx-tools/core`
249
- `bin.ensure`; the core installer itself contains no product registry.
250
- Rust rows prepare native npm
251
- archives and Python wheels; they do not install Bun or UBRN and do not build
252
- Node facades. A binary-only row therefore installs no language package tool.
253
- `rustVersion` remains the MSRV recorded in package manifests, while
254
- `releaseRustVersion` independently defaults release compilation to `stable`.
255
- Rows use the target runner's standard Rust toolchain without sccache, Cargo
256
- cache actions, source fingerprints, or reusable raw bundles. Phase timings are
257
- written to each build log. GitHub-hosted Python generation executes the
258
- already-built `target/<triple>/release/<crate>-uniffi-bindgen` directly. A local
259
- macOS build compiles one host generator and reuses it while packaging the
260
- Darwin, Linux, and Windows libraries.
261
-
262
- Artifacts identify their crate, target, and type. Rust jobs publish non-private
263
- Cargo crates with `cargo publish --no-verify` and upload requested binary assets
264
- to the GitHub release. Rust jobs never publish npm or PyPI packages.
265
-
266
- Set `LOCAL_CARGO_REGISTRY` to a named Cargo registry such as a loopback
267
- [Kellnr](https://kellnr.io/) instance and provide `LOCAL_CARGO_TOKEN`. Public
268
- Cargo crates also publish directly to crates.io
269
- with `CARGO_REGISTRY_TOKEN`. Override `releaseTargets` only when a consumer has
270
- additional native runners; ordinary projects inherit the maintained matrix
271
- automatically. `bun run release` also accepts repeatable `--os` and `--arch`
272
- selectors; every selected operating system is crossed with every selected
273
- architecture. Omit both filters to regenerate the complete maintained matrix.
274
- `DBX_TOOLS_RELEASE_PLATFORMS` can select the generated matrix without repeating
275
- environment parsing in a consumer.
276
-
277
- `bun run release` always prepares the production candidate locally. After the
278
- reviewed release pull request merges, the local process checks out the exact
279
- merge commit, builds the complete npm, Python, native binding, and Rust binary
280
- artifact set, then creates an annotated tag and draft GitHub Release. The draft
281
- contains `release-manifest.json`, `SHA256SUMS`, and every registry or binary
282
- artifact bound to that commit. A manager can rebuild an interrupted draft from
283
- the exact source with
284
- `bun run release:assets --version <version> --tag <tag> --sha <commit> --upload`.
285
- Publishing the draft is the production promotion event; `release.yml` verifies
286
- the tag, commit, version, manifest, checksums, and asset set before publishing
287
- the approved npm archives, Python distributions, and Cargo crates. GitHub-hosted
288
- runners never rebuild native release artifacts for singular-version releases.
289
-
290
- Public UniFFI facades are marked with `dbxToolsConfig.uniffi = true` in Node
291
- manifests and `[tool.dbx_tools.config] uniffi = true` in Python manifests. The
292
- approved npm archives are dependency-ordered and published through npm OIDC
293
- Trusted Publishing with provenance. Local Verdaccio publication does not enable
294
- provenance. Python publishes the exact approved wheels and source distributions
295
- through package-specific PyPI trusted-publisher environments; binding publishers
296
- wait for their dependencies. Trusted-publisher instructions name `release.yml`
297
- and the `v*` deployment tag policy. Cargo publication checks the approved source
298
- commit and skips an already-published version during recovery.
299
- The docs jobs generate README and TypeScript API content and deploy GitHub Pages
300
- from the same workflow. When a conventional Node binding path already belongs
301
- to a root subproject, Rust mapping reuses that project and adds binding
302
- dependencies and metadata to its existing manifest.
303
-
304
- The workspace npm publisher owns compilation for normal release publication. It
305
- selects every publishable package with compiled entry points, invokes one
306
- root-level filtered compile, then packs each package exactly once with lifecycle
307
- scripts disabled. It validates the archive identity, configured access,
308
- integrity, and repository metadata before publishing those same bytes. Local
309
- release preparation passes `--skip-compile` only after its immediately preceding
310
- validation compile and verifies every expected output exists before reuse.
311
- Package `prepack` tasks remain available for standalone publishes without
312
- multiplying `tsc --build` across the monorepo release flow.
158
+ `layout: "package"` owns the complete Python package under `generated-src`.
159
+ Use the default `layout: "submodule"` to place generated bindings under
160
+ `<module>._generated` beside handwritten source. Generated wrappers convert
161
+ public function names to `snake_case`, await promises, recursively convert plain
162
+ records and arrays, and proxy returned JavaScript class instances with
163
+ `snake_case` async methods.
164
+
165
+ Set `private: true` to keep every generated symbol out of the generated
166
+ `__init__.py`. The runtime and `node_bindings.py` remain available for a
167
+ handwritten consuming package to import selectively. The default is `false`.
168
+
169
+ Every function parameter is resolved through the TypeScript compiler API and
170
+ rendered with its Python-equivalent name and type. Supported record types become
171
+ keyword-only Python dataclasses, nested records become nested dataclasses, and a
172
+ same-named exported companion's `defaults()` method supplies field defaults. A
173
+ trailing optional record can be passed as the dataclass, a dictionary, or direct
174
+ snake-case keyword fields. Generation fails with the property path when a type
175
+ cannot be represented safely in Python.
176
+
177
+ Return types use the same compiler model. Plain records become generated
178
+ `TypedDict` responses, returned clients and class instances become `Protocol`
179
+ types with typed async methods, and primitives, arrays, maps, promises, and
180
+ optional values retain their corresponding Python annotations.
181
+
182
+ The workspace creates `<name>:python-runtime`,
183
+ `<name>:python-runtime:check`, and, for workspace Node dependencies,
184
+ `<name>:python-runtime:watch`. The root sync watcher includes the watch task.
185
+ Built-in shims can make ordinary Node imports work under PythonMonkey.
186
+ `functionOverrides` replaces named exports only in the generated runtime, so the
187
+ Node package does not gain Python callbacks or alternate source files. A
188
+ replacement may use a different export name through `handlerExport`; every
189
+ other export continues to come from the original module.
313
190
 
314
191
  ## Customize Packages With Mixins
315
192
 
@@ -469,10 +346,9 @@ file contract as the CLI.
469
346
  - `barrels` / `moduleExports` - public entrypoint generation.
470
347
  - `codegen` - `.d.ts` to zod schema generation.
471
348
  - `openapi` - tsoa/OpenAPI package generation.
472
- - `releaseCatalog` / `releasePlan` / `releasePlease` - cross-language ownership,
473
- affected planning, and Release Please graph propagation.
349
+ - `releaseCatalog` - cross-language package ownership and publication order.
474
350
  - `bunApp` / `tsconfig` / `vscode` - generated support files/components.
475
- - `generated` / `clean` / `watch` / `scaffold` - read-only file stamping,
351
+ - `generated` / `clean` / `watch` / `scaffold` - read-only file ownership,
476
352
  cleanup, watchers, and synth orchestration.
477
353
  - `publish` - packaging and tag-based release helpers.
478
354
  - `engineRoot` - engine package root resolution for bootstrapped repos.
@@ -499,36 +375,15 @@ list, so a new package is covered without a re-synth. Work from the root:
499
375
  | `bun run barrels` | regenerate the read-only `index.ts` barrels |
500
376
  | `bun run bump` | increment `VERSION` and regenerate version surfaces |
501
377
  | `bun run version:check` | verify every generated version against `VERSION` |
502
- | `bun run release` | validate, open, and automatically merge a release PR |
503
- | `bun run release --no-approve` | open the release PR without automatic merge |
504
-
505
- `release` commits and pushes pending source work, creates a release worktree,
506
- increments `VERSION`, synthesizes manifests and registries, runs validation and
507
- local publication, writes the release summary, and opens one PR. It enables
508
- automatic merge unless `--no-approve` is supplied. The merged `VERSION` change
509
- starts publication from the exact `main` SHA and creates one `v<version>` tag;
510
- the command waits for that workflow by default. Use `--no-wait` to return after
511
- requesting auto-merge, `--no-validate` to skip repository tests/compile, or
512
- `--no-local-publish` to skip local registry preflight.
513
- Version resolution considers both repository tags and historical
514
- `<component>-v<version>` tags, ensuring a singular release starts above every
515
- component version left by an independent-version migration.
516
- The repository host and owner are derived from the Git remote. If the GitHub CLI
517
- has multiple accounts for that host, release preparation selects the first
518
- authenticated account with write access to the detected repository. Classic
519
- tokens must include the `workflow` scope so the release PR can update the
520
- generated workflow.
521
-
522
- The GitHub PR workflow runs the explicit `pr:validate` task through Projen's
523
- public `BuildWorkflow` `buildTask` option. That task runs synth plus the
524
- workspace TypeScript compile rather than the complete root build. Release
525
- preparation has already run Rust tests, workspace type-checking, and local
526
- package preflight before opening the PR. JavaScript behavior tests remain an
527
- explicit developer task.
528
-
529
- The generated workflow publishes the complete public workspace at the singular
530
- version. Rust, Python, Node, GitHub asset, and docs stages share the verified tag
531
- and SHA. Documentation generation runs only on this version-triggered workflow.
378
+ | `bun run release` | run the configured release transaction |
379
+
380
+ Run exactly `bun run release` from a clean `main`. It calls the existing `bump`
381
+ task, commits the generated version changes, pushes `main`, and pushes the
382
+ matching annotated `vX.Y.Z` tag. Pass `--no-bump` only to release an existing
383
+ synchronized local bump. The tag workflow verifies that the tag points at the
384
+ exact `origin/main` commit, publishes npm and PyPI directly from that checkout,
385
+ then builds and deploys documentation. Local npm and Python registry publication
386
+ remains available through the direct local publication tooling.
532
387
 
533
388
  Members intentionally keep only the tasks that something OTHER than a human
534
389
  invokes, so there is no second place to run the same thing:
@@ -557,7 +412,6 @@ from the root instead.
557
412
  ## Versioning
558
413
 
559
414
  `VERSION` is the language-neutral version seam. Real package manifests remain
560
- Projen-owned and reproduce it exactly across JavaScript, Python, Rust, UniFFI
561
- bindings, native package metadata, and runtime binary registries. Package and
415
+ Projen-owned and reproduce it exactly across JavaScript and Python packages. Package and
562
416
  artifact discovery still supplies publication order and target inventory; it
563
417
  does not create independent version ownership.
package/index.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  // Hand edits are overwritten on the next watch; this file is read-only.
4
4
 
5
5
  export const PACKAGE_IDENTIFIER = "@dbx-tools/projen";
6
- export const PACKAGE_VERSION = "0.9.19";
6
+ export const PACKAGE_VERSION = "0.9.28";
7
7
  export * as barrels from "./src/barrels.ts";
8
8
  export * as bunApp from "./src/bun-app.ts";
9
9
  export * as bunWorkflow from "./src/bun-workflow.ts";
@@ -21,19 +21,17 @@ export * as project from "./src/project.ts";
21
21
  export * as projectJs from "./src/project-js.ts";
22
22
  export * as projectPredicate from "./src/project-predicate.ts";
23
23
  export * as projectPy from "./src/project-py.ts";
24
- export * as projectRs from "./src/project-rs.ts";
25
24
  export * as projenVersion from "./src/projen-version.ts";
26
25
  export * as publish from "./src/publish.ts";
26
+ export * as pythonNodeBindings from "./src/python-node-bindings.ts";
27
+ export * as pythonNodeBundle from "./src/python-node-bundle.ts";
27
28
  export * as release from "./src/release.ts";
28
29
  export * as releaseCatalog from "./src/release-catalog.ts";
29
- export * as releaseDispatch from "./src/release-dispatch.ts";
30
+ export * as releaseContext from "./src/release-context.ts";
30
31
  export * as releaseGithub from "./src/release-github.ts";
31
- export * as releasePlan from "./src/release-plan.ts";
32
- export * as releasePlease from "./src/release-please.ts";
33
32
  export * as scaffold from "./src/scaffold.ts";
34
33
  export * as tags from "./src/tags.ts";
35
34
  export * as tsconfig from "./src/tsconfig.ts";
36
- export * as uniffi from "./src/uniffi.ts";
37
35
  export * as vscode from "./src/vscode.ts";
38
36
  export * as watch from "./src/watch.ts";
39
37
  export * as workspaceLock from "./src/workspace-lock.ts";
@@ -46,7 +44,7 @@ export type { DBXToolsConfigOptions } from "./src/dbx-tools-config.ts";
46
44
  export { resolvePkgRoot } from "./src/engine-root.ts";
47
45
  export type { HeaderOpts } from "./src/generated.ts";
48
46
  export type { ConstructsMixin } from "./src/mixin.ts";
49
- export type { ModuleStatement, ModuleExport } from "./src/module-exports.ts";
47
+ export type { ModuleStatement, ModuleExport, PublicFunctionExport } from "./src/module-exports.ts";
50
48
  export { repoRoot, DEFAULT_PACKAGE_ROOTS, DiscoveredPackage } from "./src/packages.ts";
51
49
  export type { RecordedPackage } from "./src/packages.ts";
52
50
  export { PnpmWorkspaceState } from "./src/pnpm-workspace.ts";
@@ -56,25 +54,20 @@ export { PackageIdentifier, DBX_TOOLS_LICENSE, DBXToolsNodeProject, ROOT_INSTALL
56
54
  export type { DBXToolsJavaScriptProject, DBXToolsReleaseMode, PullRequestTitlePolicyOptions, DBXToolsJavaScriptProjectOptions, DBXToolsTypeScriptProjectOptions } from "./src/project-js.ts";
57
55
  export { DBXToolsPythonProject, DBXToolsPythonWorkspace } from "./src/project-py.ts";
58
56
  export type { PythonRepositoryOptions, PythonPackageOptions, PythonTrustedPublisherOptions, DBXToolsPythonProjectOptions, PythonReleaseOptions, DBXToolsPythonWorkspaceOptions } from "./src/project-py.ts";
59
- export { DBXToolsRustProject, RustReleaseOs, RustReleaseCpu, UNIFFI_RELEASE_TARGETS, DBXToolsRustWorkspace } from "./src/project-rs.ts";
60
- export type { CargoDependency, CargoDependencyOptions, CargoExampleOptions, DBXToolsRustProjectOptions, RustCrateOptions, RustCliOptions, RustOpenApiOptions, DBXToolsRustWorkspaceOptions, RustReleasePlatform, UniFFIReleaseTarget, RustBindingMapping, RustOpenApiMapping, RustWorkspaceMapping, RustReleaseBinaryAssetMapping, RustReleaseBinaryMapping } from "./src/project-rs.ts";
61
57
  export { PROJEN_VERSION } from "./src/projen-version.ts";
62
58
  export { COMPILED_DIR, COMPILED_COMPILER_OPTIONS } from "./src/publish.ts";
59
+ export type { ResolvedPythonNodeFunctionOverride, ResolvedPythonNodeBindings } from "./src/python-node-bindings.ts";
60
+ export { PythonNodeBundle } from "./src/python-node-bundle.ts";
61
+ export type { PythonNodeFunctionOverride, PythonNodeBindingsOptions, PythonNodeBundleOptions } from "./src/python-node-bundle.ts";
63
62
  export { DBXToolsRelease } from "./src/release.ts";
64
- export type { ReleaseStage, ReleaseDocsOptions, ReleaseSummaryOptions, DBXToolsReleaseOptions } from "./src/release.ts";
63
+ export type { ReleaseStage, ReleaseDocsOptions, DBXToolsReleaseOptions } from "./src/release.ts";
65
64
  export { DBXToolsReleaseCatalog } from "./src/release-catalog.ts";
66
- export type { DBXToolsVersioningMode, ReleaseProjectLanguage, ReleaseArtifactKind, ReleaseEdgeKind, ReleasePropagation, ReleaseUnitRule, DBXToolsReleaseCatalogOptions, ReleaseDependencyInput, ReleaseProjectRegistration, ExternalReleaseProjectRegistration, ReleaseArtifactRegistration, ReleaseProjectNode, ReleaseArtifact, ReleaseDependencyEdge, ReleaseUnit, ReleaseUnitGraph } from "./src/release-catalog.ts";
67
- export { RELEASE_TAG, RELEASE_SHA, RELEASE_VERSION, RELEASE_SUMMARY_DIRECTORY, RELEASE_SUMMARY_PROVIDER_NAMES, RELEASE_SUMMARY_FILE } from "./src/release-dispatch.ts";
68
- export type { ReleaseSummaryProviderName } from "./src/release-dispatch.ts";
65
+ export type { ReleaseProjectLanguage, ReleaseArtifactKind, ReleaseEdgeKind, ReleasePropagation, ReleaseUnitRule, DBXToolsReleaseCatalogOptions, ReleaseDependencyInput, ReleaseProjectRegistration, ExternalReleaseProjectRegistration, ReleaseArtifactRegistration, ReleaseProjectNode, ReleaseArtifact, ReleaseDependencyEdge, ReleaseUnit, ReleaseUnitGraph } from "./src/release-catalog.ts";
66
+ export { RELEASE_TAG, RELEASE_SHA, RELEASE_VERSION } from "./src/release-context.ts";
69
67
  export type { GithubRepositoryIdentity, GithubAuthenticatedAccount, GithubRepositoryPermissions } from "./src/release-github.ts";
70
- export type { ReleaseReason, PlannedReleaseUnit, PlannedPackage, PlannedArtifact, PlannedRustTarget, ReleasePlan } from "./src/release-plan.ts";
71
- export { ReleaseUnitWorkspacePlugin } from "./src/release-please.ts";
72
- export type { ReleaseUnitWorkspacePluginOptions } from "./src/release-please.ts";
73
68
  export { AGNOSTIC_COMPILER_OPTIONS, PACKAGE_TAG_MIXINS } from "./src/tags.ts";
74
69
  export type { PackageTag } from "./src/tags.ts";
75
70
  export { DBXToolsRootTsconfig } from "./src/tsconfig.ts";
76
- export { makeDefaultedInterfaceParametersOptional, removeObsoleteInterfaceAliases, addTypeScriptExtensionsToBindingImports, addExplicitInterfaceReexports } from "./src/uniffi.ts";
77
- export type { TypeScriptBindingModule } from "./src/uniffi.ts";
78
71
  export { DBXToolsVsCode } from "./src/vscode.ts";
79
72
  export type { IgnoreGroupOptions, WatchLoopOptions } from "./src/watch.ts";
80
73
  export type { WorkspaceMutationLockOptions } from "./src/workspace-lock.ts";
package/package.json CHANGED
@@ -1,5 +1,10 @@
1
1
  {
2
2
  "name": "@dbx-tools/projen",
3
+ "repository": {
4
+ "type": "git",
5
+ "url": "git+https://github.com/reggie-db/dbx-tools.git",
6
+ "directory": "projen"
7
+ },
3
8
  "scripts": {
4
9
  "build": "projen build",
5
10
  "clobber": "projen clobber",
@@ -29,16 +34,15 @@
29
34
  },
30
35
  "dependencies": {
31
36
  "@clack/prompts": "^1.7.0",
32
- "@dbx-tools/core": "^0.9.19",
33
- "@dbx-tools/path": "^0.9.19",
34
- "@dbx-tools/shared-core": "^0.9.19",
37
+ "@dbx-tools/core": "^0.9.28",
38
+ "@dbx-tools/path": "^0.9.28",
39
+ "@dbx-tools/shared-core": "^0.9.28",
35
40
  "commander": "^15.0.0",
36
41
  "concurrently": "^10.0.3",
37
42
  "constructs": "^10.6.0",
38
43
  "is-identifier": "^1",
39
44
  "openapi-typescript": "^7.13.0",
40
45
  "oxc-parser": "^0.90.0",
41
- "release-please": "17.11.2",
42
46
  "semver": "^7.7.3",
43
47
  "smol-toml": "1.8.0",
44
48
  "ts-to-zod": "^5.1.0",
@@ -52,7 +56,7 @@
52
56
  },
53
57
  "main": "index.ts",
54
58
  "license": "Apache-2.0",
55
- "version": "0.9.19",
59
+ "version": "0.9.28",
56
60
  "types": "index.ts",
57
61
  "type": "module",
58
62
  "exports": {
@@ -12,6 +12,13 @@ export interface CaptureTaskCommandOptions extends TaskCommandOptions {
12
12
  readonly check?: boolean;
13
13
  }
14
14
 
15
+ export type ProbeTaskCommandOptions = TaskCommandOptions;
16
+
17
+ export interface LoggedTaskCommandOptions extends TaskCommandOptions {
18
+ /** Receive normalized stdout and stderr lines after the command exits. */
19
+ readonly onLine: (line: string) => void;
20
+ }
21
+
15
22
  function executable(command: string): string {
16
23
  return command === "bun" && process.versions.bun ? process.execPath : command;
17
24
  }
@@ -69,6 +76,47 @@ export function captureTaskCommand(
69
76
  return result.exitCode === 0 ? (result.stdout?.trim() ?? "") : "";
70
77
  }
71
78
 
79
+ /** Capture trimmed stdout while preserving command failure as `undefined`. */
80
+ export function probeTaskCommand(
81
+ cwd: string,
82
+ command: string,
83
+ args: readonly string[],
84
+ options: ProbeTaskCommandOptions = {},
85
+ ): string | undefined {
86
+ const result = exec.spawnSync(executable(command), [...args], {
87
+ cwd,
88
+ env: options.env,
89
+ stdout: "capture",
90
+ stderr: options.stderr ?? "ignore",
91
+ stdin: "ignore",
92
+ check: false,
93
+ });
94
+ return result.exitCode === 0 ? (result.stdout?.trim() ?? "") : undefined;
95
+ }
96
+
97
+ /** Run a checked command while routing captured output through one line policy. */
98
+ export function runLoggedTaskCommand(
99
+ cwd: string,
100
+ command: string,
101
+ args: readonly string[],
102
+ options: LoggedTaskCommandOptions,
103
+ ): void {
104
+ const result = exec.spawnSync(executable(command), [...args], {
105
+ cwd,
106
+ env: options.env,
107
+ stdout: "capture",
108
+ stderr: "capture",
109
+ stdin: "ignore",
110
+ check: false,
111
+ });
112
+ for (const line of [...result.stdoutLines, ...result.stderrLines]) {
113
+ if (line) options.onLine(line);
114
+ }
115
+ if (result.exitCode !== 0) {
116
+ throw new Error(`${command} exited with ${result.exitCode}`);
117
+ }
118
+ }
119
+
72
120
  /** Whether a quiet, non-interactive command exits successfully. */
73
121
  export function taskCommandSucceeds(
74
122
  cwd: string,
@@ -87,3 +135,30 @@ export function taskCommandSucceeds(
87
135
  }).exitCode === 0
88
136
  );
89
137
  }
138
+
139
+ /** Run Git with the shared non-interactive checked command policy. */
140
+ export function runGitTaskCommand(
141
+ cwd: string,
142
+ args: readonly string[],
143
+ options: TaskCommandOptions = {},
144
+ ): void {
145
+ runTaskCommand(cwd, "git", args, options);
146
+ }
147
+
148
+ /** Capture Git output, returning an empty string for optional offline probes. */
149
+ export function captureGitTaskCommand(
150
+ cwd: string,
151
+ args: readonly string[],
152
+ options: CaptureTaskCommandOptions = {},
153
+ ): string {
154
+ return captureTaskCommand(cwd, "git", args, options);
155
+ }
156
+
157
+ /** Whether a quiet Git command succeeds. */
158
+ export function gitTaskCommandSucceeds(
159
+ cwd: string,
160
+ args: readonly string[],
161
+ options: Pick<TaskCommandOptions, "env"> = {},
162
+ ): boolean {
163
+ return taskCommandSucceeds(cwd, "git", args, options);
164
+ }