@geekmidas/cli 10.0.0-alpha.49 → 10.0.0-alpha.50

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.
@@ -10,7 +10,7 @@ import { existsSync } from "node:fs";
10
10
  import { mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
11
11
  import { networkInterfaces } from "node:os";
12
12
  import { dirname, join, resolve } from "node:path";
13
- import { execFile } from "node:child_process";
13
+ import { execFile, spawn } from "node:child_process";
14
14
  import { DEFAULT_POSTGRES_VERSION, cacheTable, cookieDomain, dependenciesOf, dependentsOf, externalApiUrl, kebabCase, mobileOrigins, provideKey, providedKeyFor, provisionOrder, publicEnvFor, schemeBase } from "@geekmidas/manifest";
15
15
  import { createServer } from "node:net";
16
16
  import { config } from "dotenv";
@@ -213,6 +213,20 @@ async function prepareEntryCredentials(options) {
213
213
  workspace = await loadWorkspaceConfig(cwd).then((loaded) => loaded.workspace).catch(() => void 0);
214
214
  secretsRoot = workspace?.root ?? findSecretsRoot(cwd);
215
215
  }
216
+ if (appName && workspace && options.explicitPort === void 0) {
217
+ const { assignAppPorts, describeHolder, holderOf, withAppPorts } = await import("./index.mjs").then((n) => n.a);
218
+ const assigned = await assignAppPorts(workspace, [appName], {
219
+ free: isPortAvailable,
220
+ holder: holderOf
221
+ });
222
+ for (const { app, from, to, holder } of assigned.moved) logger.log(`↪️ ${app}: ${from} is held by ${describeHolder(holder)}, which is not this workspace's — using ${to}`);
223
+ workspace = withAppPorts(workspace, assigned.ports);
224
+ workspaceAppPort = assigned.ports[appName] ?? workspaceAppPort;
225
+ }
226
+ if (appName) {
227
+ const { APP_TAG_ENV, appTag } = await import("./index.mjs").then((n) => n.a);
228
+ process.env[APP_TAG_ENV] = appTag(secretsRoot, appName);
229
+ }
216
230
  const resolvedPort = options.explicitPort ?? workspaceAppPort ?? 3e3;
217
231
  const stage = options.stage ?? workspace?.stages.local;
218
232
  const store = stage ? workspace ? await secretsStoreFor(workspace, stage) : new FileSecretsStore(secretsRoot) : void 0;
@@ -1970,6 +1984,29 @@ function composeFiles(composePath) {
1970
1984
  }
1971
1985
  /** How long to wait for containers to pass their health checks. */
1972
1986
  const HEALTH_TIMEOUT_MS = 12e4;
1987
+ /** `docker compose up` exited unsuccessfully; its own output said why. */
1988
+ var ComposeUpFailed = class extends Error {
1989
+ services;
1990
+ code;
1991
+ constructor(services, code) {
1992
+ super(`docker compose could not start ${services.join(", ")} (exit ${code ?? "signal"}). Its output above names the container; \`docker compose logs <service>\` shows why it stopped.`);
1993
+ this.services = services;
1994
+ this.code = code;
1995
+ this.name = "ComposeUpFailed";
1996
+ }
1997
+ };
1998
+ /** Run compose with its output on this terminal rather than captured. */
1999
+ function shown(args, services) {
2000
+ return new Promise((resolve, reject) => {
2001
+ const child = spawn("docker", args, { stdio: [
2002
+ "ignore",
2003
+ "inherit",
2004
+ "inherit"
2005
+ ] });
2006
+ child.on("error", reject);
2007
+ child.on("close", (code) => code === 0 ? resolve() : reject(new ComposeUpFailed(services, code)));
2008
+ });
2009
+ }
1973
2010
  const dockerCli = {
1974
2011
  async publishedPort(composePath, service, inside) {
1975
2012
  try {
@@ -1986,8 +2023,8 @@ const dockerCli = {
1986
2023
  return;
1987
2024
  }
1988
2025
  },
1989
- async up(composePath, services) {
1990
- await run("docker", [
2026
+ async up(composePath, services, options = {}) {
2027
+ const args = [
1991
2028
  "compose",
1992
2029
  ...composeFiles(composePath),
1993
2030
  "up",
@@ -1996,7 +2033,9 @@ const dockerCli = {
1996
2033
  "--wait",
1997
2034
  `--wait-timeout=${Math.floor(HEALTH_TIMEOUT_MS / 1e3)}`,
1998
2035
  ...services
1999
- ]);
2036
+ ];
2037
+ if (options.show) return shown(args, services);
2038
+ await run("docker", args);
2000
2039
  },
2001
2040
  async copyOut(composePath, service, from, to) {
2002
2041
  await mkdir(dirname(to), { recursive: true });
@@ -2744,9 +2783,13 @@ async function reconcile(options) {
2744
2783
  TEST_STAGE
2745
2784
  ]);
2746
2785
  }
2747
- if (start && plan.containers.length > 0) await docker.up(composePath, plan.containers);
2786
+ if (start && plan.containers.length > 0) {
2787
+ options.progress?.(`🐳 Starting ${plan.containers.join(", ")} — the first start pulls each image, which can take a few minutes`);
2788
+ await docker.up(composePath, plan.containers, options.progress ? { show: true } : {});
2789
+ }
2748
2790
  if (start && plan.containers.includes("caddy")) await docker.reload(composePath, "caddy").catch(() => {});
2749
2791
  if (start && plan.containers.includes("caddy")) await docker.copyOut(composePath, "caddy", CADDY_ROOT_IN_CONTAINER, join(root, LOCAL_CA_PATH)).catch(() => {});
2792
+ if (start && provision) options.progress?.("🗄️ Creating what the constructs declare — databases, roles, buckets, topics");
2750
2793
  const provisioned = start && provision ? await create(plan, ports, sql, buckets, carriers, project) : [];
2751
2794
  await saveState(root, {
2752
2795
  hash,
@@ -2918,7 +2961,8 @@ async function reconcileWorkspace(workspace, options) {
2918
2961
  metroPorts: metroPorts(workspace, manifest),
2919
2962
  fakes,
2920
2963
  apps: (containers) => appServices(workspace, manifest, containers, runnables, fakes),
2921
- ...options.start === void 0 ? {} : { start: options.start }
2964
+ ...options.start === void 0 ? {} : { start: options.start },
2965
+ ...options.progress ? { progress: options.progress } : {}
2922
2966
  });
2923
2967
  await savePortState(workspace.root, { ...result.ports });
2924
2968
  return result;
@@ -2970,4 +3014,4 @@ function localAddress(port) {
2970
3014
  //#endregion
2971
3015
  export { loadEnvFiles as C, isPortAvailable as S, prepareEntryCredentials as T, fakeKey as _, reconcileWorkspace as a, createEntryWrapper as b, LOCAL_CA_PATH as c, postgresDatabaseNames as d, quoteIdentifier as f, describeServices as g, rootSite as h, derivedContainers as i, forgetState as l, resourceName as m, backendsOf as n, workspace_exports as o, pgClient as p, constructGlobs as r, COMPOSE_PATH as s, FAKE_ENV as t, applyPostgres as u, primaryPortKey as v, loadSecretsForApp as w, findAvailablePort as x, createCredentialsPreload as y };
2972
3016
 
2973
- //# sourceMappingURL=workspace-cb6U29EL.mjs.map
3017
+ //# sourceMappingURL=workspace-BsbxbqV-.mjs.map