@dbx-tools/projen 0.6.182 → 0.6.185

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
@@ -153,7 +153,11 @@ skips matching files and fails when an existing filename has different content.
153
153
 
154
154
  The Rust matrix has one row per target. Each row installs native dependencies,
155
155
  restores Cargo and sccache once, builds the Cargo workspace once, then packages
156
- every discovered output from that shared build. Rust rows prepare native npm
156
+ every discovered output from that shared build. Set a source-only crate's
157
+ `releaseExcludeOs` package option to omit it from incompatible rows through
158
+ Cargo `--exclude`; crates that produce UniFFI or release-binary artifacts cannot
159
+ use this option because every configured target must produce their artifacts.
160
+ Rust rows prepare native npm
157
161
  archives and Python wheels; they do not install Bun or UBRN and do not build
158
162
  Node facades. A binary-only row therefore installs no language package tool.
159
163
  `rustVersion` remains the MSRV recorded in package manifests, while
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.6.181";
6
+ export const PACKAGE_VERSION = "0.6.184";
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";
package/package.json CHANGED
@@ -25,9 +25,9 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "@clack/prompts": "^1.7.0",
28
- "@dbx-tools/core": "0.6.182",
29
- "@dbx-tools/path": "0.6.182",
30
- "@dbx-tools/shared-core": "0.6.182",
28
+ "@dbx-tools/core": "0.6.185",
29
+ "@dbx-tools/path": "0.6.185",
30
+ "@dbx-tools/shared-core": "0.6.185",
31
31
  "commander": "^15.0.0",
32
32
  "concurrently": "^10.0.3",
33
33
  "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.182",
50
+ "version": "0.6.185",
51
51
  "types": "index.ts",
52
52
  "type": "module",
53
53
  "exports": {
package/src/project-rs.ts CHANGED
@@ -46,6 +46,8 @@ export interface RustPackageOptions {
46
46
  readonly private?: boolean;
47
47
  /** Build this crate's binary for each target and attach it to the GitHub release. */
48
48
  readonly release?: boolean;
49
+ /** Omit this source-only crate from release workspace builds on these operating systems. */
50
+ readonly releaseExcludeOs?: readonly RustReleaseOs[];
49
51
  readonly dependencies?: Readonly<Record<string, CargoDependency>>;
50
52
  readonly devDependencies?: Readonly<Record<string, CargoDependency>>;
51
53
  readonly features?: Readonly<Record<string, readonly string[]>>;
@@ -444,6 +446,34 @@ export class DBXToolsRustProject extends Project implements DBXToolsProject {
444
446
  }
445
447
  }
446
448
 
449
+ function rustPackageDependencies(
450
+ packages: readonly DBXToolsRustProject[],
451
+ pkg: DBXToolsRustProject,
452
+ root: string,
453
+ workspaceDependencies: Readonly<Record<string, CargoDependency>> | undefined,
454
+ ): DBXToolsRustProject[] {
455
+ return packages.filter(
456
+ (dependency) =>
457
+ dependency !== pkg &&
458
+ Object.entries(pkg.packageOptions.dependencies ?? {}).some(([name, value]) => {
459
+ const resolved =
460
+ typeof value === "object" && value.workspace
461
+ ? (workspaceDependencies?.[name] ?? value)
462
+ : value;
463
+ return (
464
+ name === dependency.crateName ||
465
+ (typeof resolved === "object" &&
466
+ (resolved.package === dependency.crateName ||
467
+ (resolved.path !== undefined &&
468
+ resolve(
469
+ typeof value === "object" && value.workspace ? root : pkg.outdir,
470
+ resolved.path,
471
+ ) === dependency.outdir)))
472
+ );
473
+ }),
474
+ );
475
+ }
476
+
447
477
  /** Generated Rust workspace plus convention-derived UniFFI facade packages. */
448
478
  export class DBXToolsRustWorkspace {
449
479
  readonly packages: readonly DBXToolsRustProject[];
@@ -473,27 +503,30 @@ export class DBXToolsRustWorkspace {
473
503
  );
474
504
 
475
505
  const bindings = this.packages.filter((pkg) => pkg.uniffi);
506
+ const packageDependencies = (pkg: DBXToolsRustProject) =>
507
+ rustPackageDependencies(this.packages, pkg, project.outdir, options.workspaceDependencies);
508
+ for (const pkg of this.packages) {
509
+ const excludedOs = new Set(pkg.packageOptions.releaseExcludeOs ?? []);
510
+ if (excludedOs.size && (pkg.uniffi || pkg.packageOptions.release)) {
511
+ throw new Error(
512
+ `${pkg.crateName} cannot set releaseExcludeOs because it produces target-specific release artifacts`,
513
+ );
514
+ }
515
+ for (const dependency of packageDependencies(pkg)) {
516
+ for (const os of dependency.packageOptions.releaseExcludeOs ?? []) {
517
+ if (!excludedOs.has(os)) {
518
+ throw new Error(
519
+ `${pkg.crateName} must exclude ${os} release builds because it depends on ${dependency.crateName}`,
520
+ );
521
+ }
522
+ }
523
+ }
524
+ }
476
525
  const bindingDependencies = (pkg: DBXToolsRustProject, language: "node" | "python") =>
477
526
  bindings.filter(
478
527
  (dependency) =>
479
- dependency !== pkg &&
480
528
  (dependency.packageOptions.bindings ?? ["node", "python"]).includes(language) &&
481
- Object.entries(pkg.packageOptions.dependencies ?? {}).some(([name, value]) => {
482
- const resolved =
483
- typeof value === "object" && value.workspace
484
- ? (options.workspaceDependencies?.[name] ?? value)
485
- : value;
486
- return (
487
- name === dependency.crateName ||
488
- (typeof resolved === "object" &&
489
- (resolved.package === dependency.crateName ||
490
- (resolved.path !== undefined &&
491
- resolve(
492
- typeof value === "object" && value.workspace ? project.outdir : pkg.outdir,
493
- resolved.path,
494
- ) === dependency.outdir)))
495
- );
496
- }),
529
+ packageDependencies(pkg).includes(dependency),
497
530
  );
498
531
  this.bindingMappings = orderRustBindings(
499
532
  bindings.map((pkg) => {
@@ -732,19 +765,30 @@ export class DBXToolsRustWorkspace {
732
765
  crate: pkg.crateName,
733
766
  binary: pkg.packageOptions.binaryName ?? pkg.crateName,
734
767
  }));
735
- const orderedBindingCrates = this.bindingMappings.map((binding) => binding.crate);
736
- const publicCrates = this.packages
737
- .filter((pkg) => !pkg.packageOptions.private)
738
- .sort((first, second) => {
739
- // Binding crates publish in topological order before release-only crates that may consume them.
740
- const firstIndex = orderedBindingCrates.indexOf(first.crateName);
741
- const secondIndex = orderedBindingCrates.indexOf(second.crateName);
742
- if (firstIndex < 0) return secondIndex < 0 ? 0 : 1;
743
- if (secondIndex < 0) return -1;
744
- return firstIndex - secondIndex;
745
- })
746
- .map((pkg) => pkg.crateName);
747
- const targetMatrix = targets.map((target) => ({ ...target }));
768
+ const publicCrates = orderRustBindings(
769
+ this.packages
770
+ .filter((pkg) => !pkg.packageOptions.private)
771
+ .map((pkg) => ({
772
+ crate: pkg.crateName,
773
+ rust: pkg.outdir,
774
+ dependencies: rustPackageDependencies(
775
+ this.packages,
776
+ pkg,
777
+ project.outdir,
778
+ options.workspaceDependencies,
779
+ ).map((dependency) => dependency.crateName),
780
+ })),
781
+ ).map((pkg) => pkg.crate);
782
+ const hasReleaseExclusions = this.packages.some(
783
+ (pkg) => pkg.packageOptions.releaseExcludeOs?.length,
784
+ );
785
+ const targetMatrix = targets.map((target) => {
786
+ const cargoExcludes = this.packages
787
+ .filter((pkg) => pkg.packageOptions.releaseExcludeOs?.includes(target.os))
788
+ .map((pkg) => `--exclude ${pkg.crateName}`)
789
+ .join(" ");
790
+ return { ...target, ...(hasReleaseExclusions ? { cargoExcludes } : {}) };
791
+ });
748
792
  const hasPythonBindings = bindings.some((binding) => binding.python);
749
793
  const usePreinstalledWindowsRust = releaseRustVersion === "stable";
750
794
  const hasTargetOutputs =
@@ -893,7 +937,9 @@ export class DBXToolsRustWorkspace {
893
937
  },
894
938
  run: timedBash(
895
939
  "rust_workspace",
896
- 'cargo build --release --workspace --target "${{ matrix.cargo }}"',
940
+ `cargo build --release --workspace --target "\${{ matrix.cargo }}"${
941
+ hasReleaseExclusions ? " ${{ matrix.cargoExcludes }}" : ""
942
+ }`,
897
943
  ),
898
944
  },
899
945
  ...(bindingCommands.length