@dbx-tools/projen 0.9.12 → 0.9.17

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 CHANGED
@@ -184,8 +184,10 @@ Foreign callback adapters must first be wrapped in an object created by their
184
184
  own native library (`createStorageHandle` for auth), because callback registries
185
185
  are library-local. Release wheels replace sibling Git requirements with matching
186
186
  native-wheel versions, and dependent publishers wait for their dependencies.
187
- Each crate builds its own `<crate>-uniffi-bindgen` executable so a workspace
188
- build has no colliding binary outputs. Packaging runs that prebuilt executable.
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.
189
191
  Cargo manifests, target config, and UniFFI config are generated from structured
190
192
  Projen `TomlFile` objects. Local and release Python generation share one
191
193
  dependency-free helper for generator arguments, target-specific executable
@@ -231,13 +233,16 @@ branch that already contains released `main`, and merges `main` into a diverged
231
233
  branch when the merge is conflict-free. Missing branches and conflicted merges
232
234
  are left untouched.
233
235
 
234
- The Rust matrix has one row per target. Each row installs native dependencies,
235
- builds the Cargo workspace once, then packages every discovered output from
236
- that shared build. Set a source-only crate's or
236
+ Rust release generation creates separate UniFFI and binary matrices with one row
237
+ per target. A UniFFI row builds all discovered binding packages together. A
238
+ binary row builds all selected release binaries in one Cargo invocation with
239
+ the union of their required features, so a feature-gated companion does not
240
+ trigger a second compile graph. Each matrix has its own source-scoped
241
+ fingerprint, raw bundle, and Cargo cache namespace. Set a source-only crate's or
237
242
  release-enabled binary's `releaseExcludeOs` package option to omit it from
238
- incompatible rows through Cargo `--exclude`. Release binary packaging and
239
- artifact upload are skipped in those rows. UniFFI crates cannot use this option
240
- because every configured target must produce their artifacts.
243
+ incompatible binary rows. Release binary packaging and artifact upload are
244
+ skipped in those rows. UniFFI crates cannot use this option because every
245
+ configured target must produce their artifacts.
241
246
  Set a release binary's `cli` package option and the workspace
242
247
  `cliRegistryPath` to generate a typed `dbx` command registry from the same
243
248
  selected targets. The generated entries carry only the archives that the
@@ -250,17 +255,17 @@ Node facades. A binary-only row therefore installs no language package tool.
250
255
  `rustVersion` remains the MSRV recorded in package manifests, while
251
256
  `releaseRustVersion` independently defaults release compilation to `stable`.
252
257
  Stable Windows rows verify and use the hosted runner's installed Rust toolchain
253
- and select `rust-lld` for the workspace build. Rust release rows restore and
254
- update dependency-only Cargo caches in the release branch's cache scope. The
255
- cache key excludes workspace version changes, and manual tag recovery restores
256
- without saving a tag-scoped copy. There is no separate cache workflow or
257
- sccache layer. After publishing the current raw Rust bundles and build manifests,
258
+ and select `rust-lld` for compilation. Rust release rows restore and update
259
+ dependency-only Cargo caches in the release branch's category-and-target cache
260
+ scope. The cache key excludes workspace version changes, and manual tag recovery
261
+ restores without saving a tag-scoped copy. There is no separate cache workflow
262
+ or sccache layer. After publishing the current raw Rust bundles and build manifests,
258
263
  the GitHub release job deletes those internal assets from published
259
264
  `vMAJOR.MINOR.PATCH` releases strictly lower than the current version while
260
265
  leaving versioned consumer binaries in place. Phase timings are written to each
261
266
  build log. Python generation executes the already-built
262
- `target/<triple>/release/<crate>-uniffi-bindgen` directly. Artifact packaging therefore
263
- does no Rust compilation after the main workspace build.
267
+ `target/<triple>/release/<crate>-uniffi-bindgen` directly. Artifact packaging
268
+ therefore does no Rust compilation after the UniFFI build.
264
269
 
265
270
  Artifacts identify their crate, target, and type. Rust jobs publish non-private
266
271
  Cargo crates with `cargo publish --no-verify` and upload requested binary assets
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.12";
6
+ export const PACKAGE_VERSION = "0.9.17";
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";
@@ -57,7 +57,7 @@ export type { DBXToolsJavaScriptProject, DBXToolsReleaseMode, PullRequestTitlePo
57
57
  export { DBXToolsPythonProject, DBXToolsPythonWorkspace } from "./src/project-py.ts";
58
58
  export type { PythonRepositoryOptions, PythonPackageOptions, PythonTrustedPublisherOptions, DBXToolsPythonProjectOptions, PythonReleaseOptions, DBXToolsPythonWorkspaceOptions } from "./src/project-py.ts";
59
59
  export { DBXToolsRustProject, RustReleaseOs, RustReleaseCpu, UNIFFI_RELEASE_TARGETS, DBXToolsRustWorkspace } from "./src/project-rs.ts";
60
- export type { CargoDependency, CargoDependencyOptions, CargoExampleOptions, DBXToolsRustProjectOptions, RustCrateOptions, RustCliOptions, DBXToolsRustWorkspaceOptions, RustReleasePlatform, UniFFIReleaseTarget, RustBindingMapping, RustWorkspaceMapping, RustReleaseBinaryAssetMapping, RustReleaseBinaryMapping } 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
61
  export { PROJEN_VERSION } from "./src/projen-version.ts";
62
62
  export { COMPILED_DIR, COMPILED_COMPILER_OPTIONS } from "./src/publish.ts";
63
63
  export { DBXToolsRelease } from "./src/release.ts";
@@ -76,6 +76,7 @@ export { DBXToolsRootTsconfig } from "./src/tsconfig.ts";
76
76
  export { makeDefaultedInterfaceParametersOptional, removeObsoleteInterfaceAliases, addTypeScriptExtensionsToBindingImports, addExplicitInterfaceReexports } from "./src/uniffi.ts";
77
77
  export type { TypeScriptBindingModule } from "./src/uniffi.ts";
78
78
  export { DBXToolsVsCode } from "./src/vscode.ts";
79
- export type { IgnoreGroupOptions } from "./src/watch.ts";
79
+ export type { IgnoreGroupOptions, WatchLoopOptions } from "./src/watch.ts";
80
+ export type { WorkspaceMutationLockOptions } from "./src/workspace-lock.ts";
80
81
  export { VERSION_FILE, DEFAULT_VERSION } from "./src/workspace-version.ts";
81
82
  export type { Semver, VersionLevel } from "./src/workspace-version.ts";
package/package.json CHANGED
@@ -30,9 +30,9 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@clack/prompts": "^1.7.0",
33
- "@dbx-tools/core": "^0.9.12",
34
- "@dbx-tools/path": "^0.9.12",
35
- "@dbx-tools/shared-core": "^0.9.12",
33
+ "@dbx-tools/core": "^0.9.17",
34
+ "@dbx-tools/path": "^0.9.17",
35
+ "@dbx-tools/shared-core": "^0.9.17",
36
36
  "commander": "^15.0.0",
37
37
  "concurrently": "^10.0.3",
38
38
  "constructs": "^10.6.0",
@@ -53,7 +53,7 @@
53
53
  },
54
54
  "main": "index.ts",
55
55
  "license": "Apache-2.0",
56
- "version": "0.9.12",
56
+ "version": "0.9.17",
57
57
  "types": "index.ts",
58
58
  "type": "module",
59
59
  "exports": {
@@ -2,13 +2,15 @@
2
2
  import { existsSync, readFileSync, readdirSync } from "node:fs";
3
3
  import { basename, join, resolve } from "node:path";
4
4
  import * as projectUtils from "@dbx-tools/core/project-utils";
5
- import { stringUtils } from "@dbx-tools/shared-core";
5
+ import { object, stringUtils } from "@dbx-tools/shared-core";
6
6
  import { License, Project, TextFile, TomlFile, javascript, type Task } from "projen";
7
7
  import { DBX_TOOLS_LICENSE, projectRepositoryUrl } from "./project-js.ts";
8
8
  import type { RustReleaseOs } from "./project-rs.ts";
9
9
  import type { DBXToolsProject, DBXToolsProjectOptions } from "./project.ts";
10
10
  import { readWorkspaceVersion } from "./workspace-version.ts";
11
11
 
12
+ export const UNIFFI_BINDGEN_FEATURE = "uniffi-bindgen";
13
+
12
14
  export interface CargoDependencyOptions {
13
15
  readonly version?: string;
14
16
  readonly workspace?: boolean;
@@ -50,6 +52,16 @@ export interface CargoExampleOptions {
50
52
  readonly requiredFeatures?: readonly string[];
51
53
  }
52
54
 
55
+ /** Rust code-first OpenAPI producer consumed by the shared generator. */
56
+ export interface RustOpenApiOptions {
57
+ /** Cargo binary that handles `--generate-spec` when the package has multiple binaries. */
58
+ readonly binary?: string;
59
+ /** Features enabled while running the OpenAPI export command. */
60
+ readonly features?: readonly string[];
61
+ /** Disable the crate's default features while running the export command. */
62
+ readonly noDefaultFeatures?: boolean;
63
+ }
64
+
53
65
  /** Cargo package, target, binding, and release behavior shared by every Rust project. */
54
66
  export interface RustCrateOptions {
55
67
  readonly description?: string;
@@ -67,6 +79,8 @@ export interface RustCrateOptions {
67
79
  readonly defaultFeatures?: readonly string[];
68
80
  /** Explicit example targets, including optional Cargo feature gates. */
69
81
  readonly examples?: readonly CargoExampleOptions[];
82
+ /** Generate an OpenAPI client package from this crate's aide document. */
83
+ readonly openapi?: boolean | RustOpenApiOptions;
70
84
  /** Cargo and release executable name. Defaults to the generated package name. */
71
85
  readonly binaryName?: string;
72
86
  /** Additional Cargo binary targets owned by this crate. */
@@ -106,29 +120,31 @@ export interface DBXToolsRustProjectOptions extends DBXToolsProjectOptions, Rust
106
120
  readonly repository?: string;
107
121
  }
108
122
 
109
- function rustSources(directory: string): string[] {
110
- if (!existsSync(directory)) return [];
111
- const files: string[] = [];
123
+ function* rustSources(directory: string): Generator<string> {
124
+ if (!existsSync(directory)) return;
112
125
  for (const entry of readdirSync(directory, { withFileTypes: true })) {
113
126
  const path = join(directory, entry.name);
114
- if (entry.isDirectory()) files.push(...rustSources(path));
115
- else if (entry.isFile() && entry.name.endsWith(".rs")) files.push(path);
127
+ if (entry.isDirectory()) yield* rustSources(path);
128
+ else if (entry.isFile() && entry.name.endsWith(".rs")) yield path;
116
129
  }
117
- return files;
118
130
  }
119
131
 
120
132
  /** Whether a Rust crate embeds the UniFFI proc-macro scaffolding marker. */
121
133
  export function hasUniFFIBindings(directory: string): boolean {
122
- return rustSources(join(directory, "src")).some((path) =>
123
- /\buniffi\s*::\s*setup_scaffolding\s*!\s*\(/.test(readFileSync(path, "utf8")),
124
- );
134
+ return object
135
+ .sequence(rustSources(join(directory, "src")))
136
+ .some((path) => /\buniffi\s*::\s*setup_scaffolding\s*!\s*\(/.test(readFileSync(path, "utf8")));
137
+ }
138
+
139
+ function hasRustSources(directory: string): boolean {
140
+ return object.sequence(rustSources(directory)).some(() => true);
125
141
  }
126
142
 
127
143
  export function discoverRustCrates(root: string): string[] {
128
144
  if (!existsSync(root)) return [];
129
145
  return readdirSync(root, { withFileTypes: true })
130
146
  .filter((entry) => entry.isDirectory())
131
- .filter((entry) => rustSources(join(root, entry.name, "src")).length > 0)
147
+ .filter((entry) => hasRustSources(join(root, entry.name, "src")))
132
148
  .map((entry) => entry.name)
133
149
  .sort();
134
150
  }
@@ -210,6 +226,7 @@ function packageOptions(
210
226
  ...(options.devDependencies ? { devDependencies: options.devDependencies } : {}),
211
227
  ...(options.features ? { features: options.features } : {}),
212
228
  ...(options.defaultFeatures ? { defaultFeatures: options.defaultFeatures } : {}),
229
+ ...(options.openapi !== undefined ? { openapi: options.openapi } : {}),
213
230
  ...(options.binaryName ? { binaryName: options.binaryName } : {}),
214
231
  ...(options.binaries ? { binaries: options.binaries } : {}),
215
232
  ...(options.cli !== undefined ? { cli: options.cli } : {}),
@@ -291,7 +308,13 @@ export class RustProject extends Project implements DBXToolsProject {
291
308
  ? {
292
309
  bin: [
293
310
  ...(this.uniffi
294
- ? [{ name: `${this.crateName}-uniffi-bindgen`, path: "uniffi-bindgen.rs" }]
311
+ ? [
312
+ {
313
+ name: `${this.crateName}-uniffi-bindgen`,
314
+ path: "uniffi-bindgen.rs",
315
+ "required-features": [UNIFFI_BINDGEN_FEATURE],
316
+ },
317
+ ]
295
318
  : []),
296
319
  ...(binary ? [{ name: binaryName, path: "src/main.rs" }] : []),
297
320
  ...(options.binaries ?? []).map((target) => ({
@@ -304,11 +327,12 @@ export class RustProject extends Project implements DBXToolsProject {
304
327
  ],
305
328
  }
306
329
  : {}),
307
- ...(options.features || options.defaultFeatures
330
+ ...(this.uniffi || options.features || options.defaultFeatures
308
331
  ? {
309
332
  features: {
310
333
  ...(options.defaultFeatures ? { default: [...options.defaultFeatures] } : {}),
311
334
  ...options.features,
335
+ ...(this.uniffi ? { [UNIFFI_BINDGEN_FEATURE]: ["uniffi/cli"] } : {}),
312
336
  },
313
337
  }
314
338
  : {}),