@omer-x/buttler
Version:
automates CI/CD workflows using Docker and GitHub webhooks
77 lines (75 loc) • 2.39 kB
JavaScript
// src/cli.ts
import { spawn } from "node:child_process";
import fs from "node:fs/promises";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { Command } from "commander";
async function checkFile(filePath) {
try {
await fs.access(filePath);
return true;
} catch {
return false;
}
}
function spawnChildProcess(detached, debug) {
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const appPath = resolve(__dirname, "../ui/server.js");
const child = spawn("node", [appPath], {
detached,
stdio: detached ? "ignore" : "inherit",
env: {
...process.env,
PORT: "2083",
WEBHOOK_SECRET: "buttler",
CURRENT_WORKING_DIRECTORY: process.cwd(),
DRIZZLE_DIR: resolve(__dirname, "../drizzle"),
...debug ? { DEBUG_MODE: "yes" } : {}
}
});
if (detached) child.unref();
return child.pid;
}
async function start(development) {
if (development) {
await stop();
}
const pidFilePath = resolve(process.cwd(), "PID");
const exists = await checkFile(pidFilePath);
if (exists) {
return console.warn("the application is already running");
}
const pid = spawnChildProcess(!development, development);
await fs.writeFile(pidFilePath, `${pid}`, "utf8");
console.log("the application has started");
}
async function stop() {
const pidFilePath = resolve(process.cwd(), "PID");
const exists = await checkFile(pidFilePath);
if (!exists) {
return console.warn("the application was not running");
}
const content = await fs.readFile(pidFilePath, "utf-8");
const pid = parseInt(content);
try {
if (isNaN(pid)) throw new Error("Invalid PID");
process.kill(pid);
console.log("the application is stopped");
} catch {
console.warn("the application was crashed");
} finally {
await fs.unlink(pidFilePath);
}
}
async function restart() {
await stop();
await start(false);
}
var program = new Command();
program.command("dev").description("starts the application").action(() => start(true));
program.command("start").description("starts the application").action(() => start(false));
program.command("stop").description("stops the application").action(stop);
program.command("restart").description("restarts the application").action(restart);
program.parse(process.argv);