@dbx-tools/projen 0.9.154 → 0.9.158

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 (49) hide show
  1. package/README.md +36 -47
  2. package/index.ts +42 -20
  3. package/package.json +8 -8
  4. package/src/_task-command.ts +7 -7
  5. package/src/appkit-workspace.ts +278 -104
  6. package/src/barrels.ts +147 -259
  7. package/src/bun-app.ts +54 -10
  8. package/src/clean.ts +6 -6
  9. package/src/engine-root.ts +4 -4
  10. package/src/mixin.ts +0 -2
  11. package/src/module-exports.ts +4 -5
  12. package/src/npm-packaging.ts +128 -0
  13. package/src/npm-release.ts +200 -0
  14. package/src/packages.ts +11 -11
  15. package/src/project-js.ts +209 -103
  16. package/src/project-predicate.ts +5 -12
  17. package/src/project-py.ts +6 -6
  18. package/src/project.ts +7 -14
  19. package/src/publish.ts +3 -3
  20. package/src/python-node-bindings.ts +16 -12
  21. package/src/python-packaging.ts +177 -0
  22. package/src/release-options.ts +2 -2
  23. package/src/release.ts +3 -3
  24. package/src/shared-core-usage.ts +17 -4
  25. package/src/tags.ts +10 -9
  26. package/src/watch.ts +7 -9
  27. package/src/workspace-lock.ts +2 -2
  28. package/src/workspace-manifest.ts +2 -2
  29. package/tasks/appkit-deploy.ts +35 -15
  30. package/tasks/barrels.ts +6 -9
  31. package/tasks/bump.ts +1 -1
  32. package/tasks/clean.ts +3 -3
  33. package/tasks/cli.ts +3 -3
  34. package/tasks/compile-workspace.ts +8 -8
  35. package/tasks/dev-watch.ts +11 -11
  36. package/tasks/local-publish.ts +6 -6
  37. package/tasks/publish-npm.ts +11 -319
  38. package/tasks/publish-python.ts +2 -180
  39. package/tasks/publish.ts +6 -11
  40. package/tasks/python-node-bindings.ts +2 -2
  41. package/tasks/python-registry.ts +6 -6
  42. package/tasks/python-sync.ts +2 -3
  43. package/tasks/release-version.ts +1 -1
  44. package/tasks/release.ts +11 -11
  45. package/tasks/sync.ts +2 -2
  46. package/tasks/test-workspace.ts +9 -9
  47. package/tasks/verify-publications.ts +9 -5
  48. package/tasks/version-check.ts +5 -5
  49. /package/{tasks → src}/python-release.ts +0 -0
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env -S bun
2
2
  /** Validate one stable release version against the canonical workspace policy. */
3
3
  import { resolve } from "node:path";
4
- import * as projectUtils from "@dbx-tools/core/project-utils";
4
+ import { projectUtils } from "@dbx-tools/core";
5
5
  import { z } from "zod";
6
6
  import { runTaskMain, taskCommand, taskOptions } from "./cli.ts";
7
7
  import { TaskRootOptionSchema } from "./options.ts";
package/tasks/release.ts CHANGED
@@ -2,8 +2,8 @@
2
2
  /** Run the configured release transaction. */
3
3
  import { readFileSync } from "node:fs";
4
4
  import { join } from "node:path";
5
- import * as projectUtils from "@dbx-tools/core/project-utils";
6
- import { errorUtils, json, log } from "@dbx-tools/shared-core";
5
+ import { projectUtils, type ProjectGhAccount, resolveProjectGhAccount } from "@dbx-tools/core";
6
+ import { log, toError, parse } from "@dbx-tools/shared-core";
7
7
  import type { Command } from "commander";
8
8
  import { z } from "zod";
9
9
  import { parsedTaskOptions, runTaskMain, taskCommand } from "./cli.ts";
@@ -67,7 +67,7 @@ const GithubReleaseRunViewSchema = z
67
67
 
68
68
  /** Inputs required to locate and watch one tag-triggered release workflow. */
69
69
  export interface WatchReleaseGithubActionsOptions {
70
- readonly account: projectUtils.ProjectGhAccount;
70
+ readonly account: ProjectGhAccount;
71
71
  readonly head: string;
72
72
  readonly root: string;
73
73
  readonly tag: string;
@@ -80,7 +80,7 @@ export type ReleaseGithubActionsWatcher = (
80
80
  options: WatchReleaseGithubActionsOptions,
81
81
  ) => Promise<void>;
82
82
 
83
- function githubRepository(account: projectUtils.ProjectGhAccount): string {
83
+ function githubRepository(account: ProjectGhAccount): string {
84
84
  return account.host === "github.com"
85
85
  ? account.remote.repository
86
86
  : `${account.host}/${account.remote.repository}`;
@@ -194,7 +194,7 @@ export async function watchReleaseGithubActions(
194
194
  ],
195
195
  { check: true, env: account.env, stderr: "inherit" },
196
196
  );
197
- const parsed = z.array(GithubReleaseRunSchema).safeParse(json.parse(output, []));
197
+ const parsed = z.array(GithubReleaseRunSchema).safeParse(parse(output, []));
198
198
  if (!parsed.success) throw new Error("GitHub returned invalid release workflow metadata");
199
199
  run = parsed.data.find(
200
200
  (candidate) => candidate.headSha === head && candidate.headBranch === tag,
@@ -234,7 +234,7 @@ export async function watchReleaseGithubActions(
234
234
  ],
235
235
  { check: true, env: account.env, stderr: "inherit" },
236
236
  );
237
- const parsed = GithubReleaseRunViewSchema.safeParse(json.parse(output));
237
+ const parsed = GithubReleaseRunViewSchema.safeParse(parse(output));
238
238
  if (!parsed.success) throw new Error("GitHub returned invalid release progress metadata");
239
239
  reportGithubProgress(parsed.data, progress);
240
240
  completed = parsed.data.status === "completed";
@@ -251,7 +251,7 @@ export async function watchReleaseGithubActions(
251
251
  }
252
252
  } catch (error) {
253
253
  logger.warn("GitHub Actions release watch stopped; the remote run was not cancelled", {
254
- error: errorUtils.toError(error),
254
+ error: toError(error),
255
255
  runId: run.databaseId,
256
256
  url: run.url,
257
257
  });
@@ -305,7 +305,7 @@ function pushAnnotatedReleaseTag(options: {
305
305
  }): void {
306
306
  const { annotation, branch, head, remote, root, tag } = options;
307
307
  runTaskCommand(root, "git", ["tag", "--annotate", tag, "--message", annotation]);
308
- const githubAccount = projectUtils.resolveProjectGhAccount(root, { remote });
308
+ const githubAccount = resolveProjectGhAccount(root, { remote });
309
309
  if (!githubAccount) {
310
310
  logger.warn(
311
311
  "no authenticated GitHub account can access the release repository; using git push",
@@ -382,7 +382,7 @@ function pushAnnotatedReleaseTag(options: {
382
382
  } catch (error) {
383
383
  if (remoteRefCreated) throw error;
384
384
  logger.warn("GitHub API tag creation failed; using git push", {
385
- error: errorUtils.toError(error),
385
+ error: toError(error),
386
386
  repository: githubAccount.remote.repository,
387
387
  });
388
388
  runTaskCommand(root, "git", ["push", remote, `refs/tags/${tag}`]);
@@ -480,7 +480,7 @@ export async function runRelease(
480
480
  /** After local release actions, wait for and stream the matching GitHub Actions run. */
481
481
  readonly watchGithubActions?: boolean;
482
482
  readonly githubActionsWatcher?: ReleaseGithubActionsWatcher;
483
- readonly resolveGithubAccount?: typeof projectUtils.resolveProjectGhAccount;
483
+ readonly resolveGithubAccount?: typeof resolveProjectGhAccount;
484
484
  },
485
485
  ): Promise<string> {
486
486
  const { branch, prefix, remote, root } = options;
@@ -606,7 +606,7 @@ export async function runRelease(
606
606
  }
607
607
 
608
608
  if (shouldWatchReleaseGithubActions(options, selection)) {
609
- const account = (options.resolveGithubAccount ?? projectUtils.resolveProjectGhAccount)(root, {
609
+ const account = (options.resolveGithubAccount ?? resolveProjectGhAccount)(root, {
610
610
  remote,
611
611
  });
612
612
  if (account) {
package/tasks/sync.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env -S bun
2
2
  /** Synthesize once or supervise Projen, barrels, and registered focused watchers. */
3
3
  import { fileURLToPath } from "node:url";
4
- import { errorUtils, log } from "@dbx-tools/shared-core";
4
+ import { log, toError } from "@dbx-tools/shared-core";
5
5
  import concurrently from "concurrently";
6
6
  import { z } from "zod";
7
7
  import { runTaskMain, taskCommand, taskOptions } from "./cli.ts";
@@ -84,7 +84,7 @@ export async function main(args: string[] = process.argv.slice(2)): Promise<void
84
84
  } catch (err) {
85
85
  // A tree that doesn't synth is precisely when the watcher is most useful: the edit
86
86
  // that repairs it is the one the projenrc watcher is sitting there waiting for.
87
- logger.error("initial sync failed - watching anyway", { error: errorUtils.toError(err) });
87
+ logger.error("initial sync failed - watching anyway", { error: toError(err) });
88
88
  }
89
89
 
90
90
  const watchers = [
@@ -1,8 +1,8 @@
1
1
  import { readFileSync, writeFileSync } from "node:fs";
2
2
  import { basename, join, relative, resolve, sep } from "node:path";
3
- import * as exec from "@dbx-tools/core/exec";
4
- import { findFilesSync } from "@dbx-tools/path/find";
5
- import { log, object } from "@dbx-tools/shared-core";
3
+ import { spawnSync, spawn } from "@dbx-tools/core";
4
+ import { findFilesSync } from "@dbx-tools/path";
5
+ import { log, sequence } from "@dbx-tools/shared-core";
6
6
  import { z } from "zod";
7
7
  import { runTaskMain, taskCommand, taskOptions, taskPositionals, taskRoot } from "./cli.ts";
8
8
  import { TaskRootOptionSchema } from "./options.ts";
@@ -137,7 +137,7 @@ function changedFiles(root: string, base?: string): string[] {
137
137
  const candidates = base ? [base] : ["origin/main", "main", "HEAD~1"];
138
138
  let committed: string[] = [];
139
139
  for (const candidate of candidates) {
140
- const result = exec.spawnSync("git", ["diff", "--name-only", `${candidate}...HEAD`], {
140
+ const result = spawnSync("git", ["diff", "--name-only", `${candidate}...HEAD`], {
141
141
  cwd: root,
142
142
  stdin: "ignore",
143
143
  stdout: "capture",
@@ -148,14 +148,14 @@ function changedFiles(root: string, base?: string): string[] {
148
148
  break;
149
149
  }
150
150
  }
151
- const working = exec.spawnSync("git", ["diff", "--name-only", "HEAD"], {
151
+ const working = spawnSync("git", ["diff", "--name-only", "HEAD"], {
152
152
  cwd: root,
153
153
  stdin: "ignore",
154
154
  stdout: "capture",
155
155
  stderr: "ignore",
156
156
  check: true,
157
157
  }).stdoutLines;
158
- return [...object.sequence(committed, working).filter(Boolean).distinct()].sort();
158
+ return [...sequence(committed, working).filter(Boolean).distinct()].sort();
159
159
  }
160
160
 
161
161
  function selectedTests(
@@ -203,13 +203,13 @@ function runnerGroup(root: string, path: string): string {
203
203
  if (relativePath.startsWith("packages/js/shared/")) return "browser-shared";
204
204
  if (
205
205
  relativePath.startsWith("packages/js/ui/") ||
206
- relativePath.startsWith("packages/example/app/")
206
+ relativePath.startsWith("packages/demo/client/")
207
207
  ) {
208
208
  return "react-ui";
209
209
  }
210
210
  if (relativePath.startsWith("projen/")) return "projen";
211
211
  if (relativePath.startsWith("docs/scripts/")) return "docs";
212
- if (relativePath.startsWith("packages/example/")) return "examples";
212
+ if (relativePath.startsWith("packages/demo/")) return "demo";
213
213
  return "node";
214
214
  }
215
215
 
@@ -228,7 +228,7 @@ async function runTests(root: string, files: readonly string[]): Promise<void> {
228
228
  const started = performance.now();
229
229
  const jobs = [...groups].map(async ([name, paths]) => {
230
230
  const groupStarted = performance.now();
231
- const result = await exec.spawn("bun", ["test", ...paths], {
231
+ const result = await spawn("bun", ["test", ...paths], {
232
232
  cwd: root,
233
233
  stdin: "ignore",
234
234
  stdout: "inherit",
@@ -3,10 +3,14 @@
3
3
  import { createHash } from "node:crypto";
4
4
  import { readFileSync, readdirSync } from "node:fs";
5
5
  import { basename, join, resolve } from "node:path";
6
- import { asyncUtils, errorUtils, log } from "@dbx-tools/shared-core";
6
+ import { log, poll, mapConcurrent, toError } from "@dbx-tools/shared-core";
7
7
  import { z } from "zod";
8
8
  import { runTaskMain, taskCommand, taskOptions } from "./cli.ts";
9
- import { npmReleaseMatches, publishedNpmRelease, readNpmArchiveIdentity } from "./publish-npm.ts";
9
+ import {
10
+ npmReleaseMatches,
11
+ publishedNpmRelease,
12
+ readNpmArchiveIdentity,
13
+ } from "../src/npm-release.ts";
10
14
  import { PUBLIC_NPM_REGISTRY_URL, PUBLIC_PYPI_REGISTRY_URL } from "../src/release-context.ts";
11
15
 
12
16
  const DEFAULT_CONCURRENCY = 8;
@@ -65,9 +69,9 @@ export async function waitForPublications(
65
69
  let pending = [...probes];
66
70
  let previousCount: number | undefined;
67
71
  try {
68
- for await (const unavailable of asyncUtils.poll<PublicationProbe[]>(
72
+ for await (const unavailable of poll<PublicationProbe[]>(
69
73
  async ({ signal }) => {
70
- const results = await asyncUtils.mapConcurrent(
74
+ const results = await mapConcurrent(
71
75
  pending,
72
76
  async (probe) => {
73
77
  try {
@@ -75,7 +79,7 @@ export async function waitForPublications(
75
79
  if (available) errors.delete(probe.label);
76
80
  return { available, probe };
77
81
  } catch (error) {
78
- errors.set(probe.label, errorUtils.toError(error));
82
+ errors.set(probe.label, toError(error));
79
83
  return { available: false, probe };
80
84
  }
81
85
  },
@@ -2,9 +2,9 @@
2
2
  /** Verify that every committed package version matches the root VERSION file. */
3
3
  import { readFileSync } from "node:fs";
4
4
  import { join } from "node:path";
5
- import * as projectUtils from "@dbx-tools/core/project-utils";
6
- import { find } from "@dbx-tools/path";
7
- import { json, log } from "@dbx-tools/shared-core";
5
+ import { projectUtils } from "@dbx-tools/core";
6
+ import { findFiles } from "@dbx-tools/path";
7
+ import { log, parseRecord } from "@dbx-tools/shared-core";
8
8
  import { parse } from "smol-toml";
9
9
  import { runTaskMain } from "./cli.ts";
10
10
  import { recordedPackages } from "../src/packages.ts";
@@ -13,7 +13,7 @@ import { readWorkspaceVersion } from "../src/workspace-version.ts";
13
13
  const logger = log.logger("projen:version-check");
14
14
 
15
15
  function manifestVersion(path: string): string | undefined {
16
- const manifest = json.parseRecord(readFileSync(path, "utf8"));
16
+ const manifest = parseRecord(readFileSync(path, "utf8"));
17
17
  return typeof manifest?.version === "string" ? manifest.version : undefined;
18
18
  }
19
19
 
@@ -37,7 +37,7 @@ export async function main(): Promise<void> {
37
37
  check(`${pkg.path}/package.json`, manifestVersion(join(pkg.dir, "package.json")));
38
38
  }
39
39
 
40
- for await (const path of find.findFiles("**/pyproject.toml", { cwd: root })) {
40
+ for await (const path of findFiles("**/pyproject.toml", { cwd: root })) {
41
41
  check(path, pythonVersion(join(root, path)));
42
42
  }
43
43
  if (mismatches.length > 0) {
File without changes