@bensandee/tooling 0.53.1 → 0.54.0

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 (2) hide show
  1. package/dist/bin.mjs +43 -17
  2. package/package.json +1 -1
package/dist/bin.mjs CHANGED
@@ -715,8 +715,8 @@ function mergeWithSavedConfig(detected, saved) {
715
715
  //#endregion
716
716
  //#region src/release/docker.ts
717
717
  const ToolingDockerMapSchema = z.record(z.string(), z.object({
718
- dockerfile: z.string(),
719
- context: z.string().default("."),
718
+ dockerfile: z.string().optional(),
719
+ context: z.string().optional(),
720
720
  buildArgs: z.record(z.string(), z.string()).optional()
721
721
  }));
722
722
  const ToolingConfigDockerSchema = z.object({ docker: ToolingDockerMapSchema.optional() });
@@ -737,6 +737,21 @@ function loadDockerMap(executor, cwd) {
737
737
  return {};
738
738
  }
739
739
  }
740
+ /**
741
+ * Merge a convention-discovered config with a user override. Missing override fields
742
+ * fall back to convention. Returns undefined if no dockerfile can be resolved from
743
+ * either source.
744
+ */
745
+ function mergeDockerConfig(convention, override) {
746
+ if (!override) return convention;
747
+ const dockerfile = override.dockerfile ?? convention?.dockerfile;
748
+ if (!dockerfile) return void 0;
749
+ return {
750
+ dockerfile,
751
+ context: override.context ?? convention?.context ?? ".",
752
+ buildArgs: override.buildArgs ?? convention?.buildArgs
753
+ };
754
+ }
740
755
  /** Read name and version from a package's package.json. */
741
756
  function readPackageInfo(executor, packageJsonPath) {
742
757
  const raw = executor.readFile(packageJsonPath);
@@ -821,16 +836,23 @@ function detectDockerPackages(executor, cwd, repoName) {
821
836
  if (packageDirs.length > 0) {
822
837
  for (const dir of packageDirs) {
823
838
  const convention = findConventionDockerfile(executor, cwd, dir);
824
- const docker = overrides[dir] ?? convention;
839
+ const override = overrides[dir];
840
+ const docker = mergeDockerConfig(convention, override);
825
841
  if (docker) {
826
842
  packages.push(createDockerPackage(executor, cwd, dir, repoName, docker));
827
843
  seen.add(dir);
828
844
  }
829
845
  }
830
- for (const [dir, docker] of Object.entries(overrides)) if (!seen.has(dir)) packages.push(createDockerPackage(executor, cwd, dir, repoName, docker));
846
+ for (const [dir, override] of Object.entries(overrides)) {
847
+ if (seen.has(dir)) continue;
848
+ const docker = mergeDockerConfig(void 0, override);
849
+ if (!docker) throw new FatalError(`Docker override for "${dir}" has no dockerfile and no convention Dockerfile was found`);
850
+ packages.push(createDockerPackage(executor, cwd, dir, repoName, docker));
851
+ }
831
852
  } else {
832
853
  const convention = findRootDockerfile(executor, cwd);
833
- const docker = overrides["."] ?? convention;
854
+ const override = overrides["."];
855
+ const docker = mergeDockerConfig(convention, override);
834
856
  if (docker) packages.push(createDockerPackage(executor, cwd, ".", repoName, docker));
835
857
  }
836
858
  return packages;
@@ -842,7 +864,8 @@ function detectDockerPackages(executor, cwd, repoName) {
842
864
  function readSinglePackageDocker(executor, cwd, packageDir, repoName) {
843
865
  const dir = path.basename(path.resolve(cwd, packageDir));
844
866
  const convention = findConventionDockerfile(executor, cwd, dir);
845
- const docker = loadDockerMap(executor, cwd)[dir] ?? convention;
867
+ const override = loadDockerMap(executor, cwd)[dir];
868
+ const docker = mergeDockerConfig(convention, override);
846
869
  if (!docker) throw new FatalError(`No Dockerfile found for package "${dir}" (checked convention paths and .tooling.json)`);
847
870
  return createDockerPackage(executor, cwd, dir, repoName, docker);
848
871
  }
@@ -896,36 +919,39 @@ function interpolate(value, env, onMissing) {
896
919
  });
897
920
  }
898
921
  /**
899
- * Translate a package's configured buildArgs map into `--build-arg K=V` flags,
900
- * expanding env-var references in values. Warns once per unset variable per build.
922
+ * Resolve a package's configured buildArgs map into `K=V` pairs, expanding
923
+ * env-var references in values. Warns once per unset variable per build.
901
924
  */
902
925
  function resolveBuildArgs(pkg, env) {
903
926
  const entries = Object.entries(pkg.docker.buildArgs ?? {});
904
927
  if (entries.length === 0) return [];
905
928
  const warned = /* @__PURE__ */ new Set();
906
- const flags = [];
929
+ const pairs = [];
907
930
  for (const [k, rawValue] of entries) {
908
931
  const resolved = interpolate(rawValue, env, (missing) => {
909
932
  if (warned.has(missing)) return;
910
933
  warned.add(missing);
911
934
  log.warn(`docker build arg "${k}" for ${pkg.dir}: env var ${missing} is not set; using empty string`);
912
935
  });
913
- flags.push("--build-arg", `${k}=${resolved}`);
936
+ pairs.push(`${k}=${resolved}`);
914
937
  }
915
- return flags;
938
+ return pairs;
916
939
  }
917
940
  /** Build a single docker image from its config. Paths are resolved relative to cwd. */
918
941
  function buildImage(executor, pkg, cwd, extraArgs) {
919
942
  const dockerfilePath = path.resolve(cwd, pkg.docker.dockerfile);
920
943
  const contextPath = path.resolve(cwd, pkg.docker.context);
921
- const configuredArgs = resolveBuildArgs(pkg, process.env);
944
+ const configuredPairs = resolveBuildArgs(pkg, process.env);
945
+ log.info(` build args: ${configuredPairs.length > 0 ? configuredPairs.join(" ") : "(none)"}`);
946
+ log.info(` extra args: ${extraArgs.length > 0 ? extraArgs.join(" ") : "(none)"}`);
947
+ const buildArgFlags = configuredPairs.flatMap((pair) => ["--build-arg", pair]);
922
948
  executor.execInherit("docker", [
923
949
  "build",
924
950
  "-f",
925
951
  dockerfilePath,
926
952
  "-t",
927
953
  `${pkg.imageName}:latest`,
928
- ...configuredArgs,
954
+ ...buildArgFlags,
929
955
  ...extraArgs,
930
956
  contextPath
931
957
  ]);
@@ -1674,7 +1700,7 @@ async function generatePackageJson(ctx) {
1674
1700
  const devDeps = { ...ROOT_DEV_DEPS };
1675
1701
  if (!isMonorepo) Object.assign(devDeps, PER_PACKAGE_DEV_DEPS);
1676
1702
  devDeps["@bensandee/config"] = isWorkspacePackage(ctx, "@bensandee/config") ? "workspace:*" : "0.10.2";
1677
- devDeps["@bensandee/tooling"] = isWorkspacePackage(ctx, "@bensandee/tooling") ? "workspace:*" : "0.53.1";
1703
+ devDeps["@bensandee/tooling"] = isWorkspacePackage(ctx, "@bensandee/tooling") ? "workspace:*" : "0.54.0";
1678
1704
  if (ctx.config.useEslintPlugin) devDeps["@bensandee/eslint-plugin"] = isWorkspacePackage(ctx, "@bensandee/eslint-plugin") ? "workspace:*" : "0.12.0";
1679
1705
  if (ctx.config.formatter === "oxfmt") devDeps["oxfmt"] = {
1680
1706
  "@changesets/cli": "2.30.0",
@@ -3450,7 +3476,7 @@ async function runGenerators(ctx) {
3450
3476
  function generateMigratePrompt(results, config, detected) {
3451
3477
  const sections = [];
3452
3478
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
3453
- sections.push(`# Migration Prompt\n\n_Generated by \`@bensandee/tooling@0.53.1 repo:sync\` on ${timestamp}_\n`);
3479
+ sections.push(`# Migration Prompt\n\n_Generated by \`@bensandee/tooling@0.54.0 repo:sync\` on ${timestamp}_\n`);
3454
3480
  const changed = results.filter((r) => r.action === "created" || r.action === "updated" || r.action === "archived");
3455
3481
  if (changed.length > 0) {
3456
3482
  const items = changed.map((r) => {
@@ -6753,7 +6779,7 @@ async function sendWebhookWithLogging(url, secret, payload) {
6753
6779
  const main = defineCommand({
6754
6780
  meta: {
6755
6781
  name: "bst",
6756
- version: "0.53.1",
6782
+ version: "0.54.0",
6757
6783
  description: "Bootstrap and maintain standardized TypeScript project tooling"
6758
6784
  },
6759
6785
  subCommands: {
@@ -6821,7 +6847,7 @@ const main = defineCommand({
6821
6847
  })
6822
6848
  }
6823
6849
  });
6824
- console.log(`@bensandee/tooling v0.53.1`);
6850
+ console.log(`@bensandee/tooling v0.54.0`);
6825
6851
  async function run() {
6826
6852
  await runMain(main);
6827
6853
  process.exit(process.exitCode ?? 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bensandee/tooling",
3
- "version": "0.53.1",
3
+ "version": "0.54.0",
4
4
  "description": "CLI tool to bootstrap and maintain standardized TypeScript project tooling",
5
5
  "license": "MIT",
6
6
  "repository": {