@mesh-tech/mesh-cli
Version:
CLI for Mesh platform development utilities
70 lines (69 loc) • 3.3 kB
JavaScript
import { execFileSync } from "child_process";
import * as fs from "fs";
import * as path from "path";
import { logShipperPath } from "./dev-local.js";
import { meshCacheDir } from "../../utils/cache-home.js";
const DEV_RUNNER_IMAGE = "node:22-bookworm@sha256:5647be709086c696ff32edaaf1c70cd26d1da6ab2b39c32f3c7b4c4a31957e37";
function sessionDir(sessionName) {
return meshCacheDir("mesh-local", "dev", sessionName);
}
function renderDockerEnvFile(env) {
const lines = [];
for (const [key, entry] of Object.entries(env)) {
if (entry.value.includes("\n"))
continue;
lines.push(`${key}=${entry.value}`);
}
return lines.join("\n") + "\n";
}
export function writeDevCompose(sessionName, appRoot, services) {
const dir = sessionDir(sessionName);
const shipper = logShipperPath();
const blocks = [
`# Generated by \`mesh dev --local --runner docker\` — do not edit.`,
`name: ${sessionName}`,
`services:`,
];
for (const [name, service] of Object.entries(services)) {
const env = service.env ?? {};
fs.writeFileSync(path.join(dir, `${name}.env`), renderDockerEnvFile(env), { mode: 0o600 });
const workdir = path.posix.join("/workspace", service.src === "." ? "" : service.src);
const ship = env.OTEL_RESOURCE_ATTRIBUTES
? ` 2>&1 | NODE_OPTIONS= node /mesh-assets/log-shipper.mjs`
: "";
blocks.push(` ${name}:`, ` image: ${DEV_RUNNER_IMAGE}`, ` network_mode: host`, ` working_dir: ${workdir}`, ` volumes:`, ` - '${appRoot}:/workspace'`, ` - '${path.dirname(shipper)}:/mesh-assets:ro'`, ` environment:`, ` CI: 'true'`, ` npm_config_verify_deps_before_run: 'false'`, ` env_file:`, ` - './${name}.env'`, ` command: ["bash", "-lc", "set -o pipefail; corepack enable >/dev/null 2>&1; { ${service.command.join(" ")}; }${ship}"]`, ` restart: unless-stopped`);
}
const composePath = path.join(dir, "compose.yml");
fs.writeFileSync(composePath, blocks.join("\n") + "\n");
return composePath;
}
function composeArgs(sessionName, args) {
return ["compose", "-p", sessionName, "-f", path.join(sessionDir(sessionName), "compose.yml"), ...args];
}
export function dockerDevUp(sessionName) {
execFileSync("docker", composeArgs(sessionName, ["up", "-d"]), {
stdio: ["ignore", "inherit", "inherit"],
});
}
export function dockerDevDown(sessionName) {
execFileSync("docker", composeArgs(sessionName, ["down", "--remove-orphans"]), {
stdio: ["ignore", "inherit", "inherit"],
});
}
export function dockerDevPs(sessionName) {
return execFileSync("docker", composeArgs(sessionName, ["ps", "--format", "table {{.Service}}\t{{.State}}\t{{.Status}}"]), {
encoding: "utf-8",
stdio: ["ignore", "pipe", "pipe"],
});
}
export function dockerDevLogs(sessionName, service, tail) {
return execFileSync("docker", composeArgs(sessionName, ["logs", "--tail", String(tail), service]), {
encoding: "utf-8",
stdio: ["ignore", "pipe", "pipe"],
});
}
export function dockerDevRestart(sessionName, service) {
execFileSync("docker", composeArgs(sessionName, ["restart", service]), {
stdio: ["ignore", "inherit", "inherit"],
});
}