Compare commits

..

No commits in common. "main" and "0.1.1" have entirely different histories.
main ... 0.1.1

2 changed files with 39 additions and 54 deletions

View file

@ -2,7 +2,7 @@
"name": "@endeavorance/rundir", "name": "@endeavorance/rundir",
"type": "module", "type": "module",
"module": "src/cli.ts", "module": "src/cli.ts",
"version": "0.2.0", "version": "0.1.1",
"bin": { "bin": {
"rundir": "build/cli.js" "rundir": "build/cli.js"
}, },

View file

@ -1,4 +1,5 @@
import { existsSync } from "node:fs"; import { existsSync } from "node:fs";
import { homedir } from "node:os";
import path from "node:path"; import path from "node:path";
import { parseArgs } from "node:util"; import { parseArgs } from "node:util";
import { $, Glob } from "bun"; import { $, Glob } from "bun";
@ -19,20 +20,13 @@ class CLIError extends Error {
} }
} }
class NoRundirError extends CLIError {
name = "NoRundirError";
constructor() {
super("No rundir found in current directory tree");
}
}
const TEMPLATE_FILE_PATH = process.env["RUNDIR_TEMPLATE"] ?? null; const TEMPLATE_FILE_PATH = process.env["RUNDIR_TEMPLATE"] ?? null;
const DEFAULT_TEMPLATE = ` const DEFAULT_TEMPLATE = `
#!/usr/bin/env bash #!/usr/bin/env bash
# Description... # Description...
`.trim(); `.trim();
const VERSION = pkg.version; const VERSION = pkg.version;
const RUNDIR_PATH = path.join(process.cwd(), ".run");
const COMMENT_STARTERS = ["#", "//", "--"]; const COMMENT_STARTERS = ["#", "//", "--"];
const COMMANDS = ["ls", "help", "new", "create", "which", "x", "run"] as const; const COMMANDS = ["ls", "help", "new", "create", "which", "x", "run"] as const;
type Command = (typeof COMMANDS)[number]; type Command = (typeof COMMANDS)[number];
@ -58,19 +52,19 @@ function parseCommand(command: string): Command {
* @param fromPath The path to start searching from * @param fromPath The path to start searching from
* @returns The path to the rundir, or null if not found * @returns The path to the rundir, or null if not found
*/ */
function getRundirPath(fromPath?: string): string { function findNearestRundir(fromPath?: string): string | null {
const currentDir = fromPath ?? process.cwd(); const currentDir = fromPath ?? process.cwd();
const potentialPath = path.resolve(currentDir, ".run"); const potentialPath = path.join(currentDir, ".run");
if (currentDir === path.dirname(currentDir)) { if (currentDir === path.dirname(currentDir)) {
throw new NoRundirError(); return null;
} }
if (existsSync(potentialPath)) { if (existsSync(potentialPath)) {
return potentialPath; return potentialPath;
} }
return getRundirPath(path.dirname(currentDir)); return findNearestRundir(path.dirname(currentDir));
} }
/** /**
@ -79,12 +73,14 @@ function getRundirPath(fromPath?: string): string {
* @param name The name of the script * @param name The name of the script
* @returns The absolute path to the script * @returns The absolute path to the script
*/ */
function getScriptPath(name: string): string { function makeScriptPath(name: string): string {
return path.resolve(getRundirPath(), name); const rundir = findNearestRundir();
if (!rundir) {
throw new CLIError("No rundir found in the current directory tree.");
} }
async function scriptExists(name: string): Promise<boolean> { return path.join(rundir, name);
return Bun.file(getScriptPath(name)).exists();
} }
/** /**
@ -98,25 +94,24 @@ async function scriptExists(name: string): Promise<boolean> {
* @param name The name of the script to find the path of * @param name The name of the script to find the path of
*/ */
async function findScriptPath(name: string): Promise<string | null> { async function findScriptPath(name: string): Promise<string | null> {
const currentRundir = getRundirPath(); let currentDir = process.cwd();
if (!currentRundir) { while (currentDir !== path.dirname(currentDir)) {
throw new NoRundirError(); const potentialPath = path.join(currentDir, ".run", name);
if (await Bun.file(potentialPath).exists()) {
return potentialPath;
}
currentDir = path.dirname(currentDir);
} }
const expectedPath = path.resolve(currentRundir, name); const homeDirPath = path.join(homedir(), ".run", name);
if (await Bun.file(homeDirPath).exists()) {
return homeDirPath;
}
const checkFile = Bun.file(expectedPath);
const exists = await checkFile.exists();
if (!exists) {
return null; return null;
} }
return expectedPath;
}
/** /**
* Parses a line of text and returns the comment line or null * Parses a line of text and returns the comment line or null
* if the line does not start with a comment starter * if the line does not start with a comment starter
@ -182,9 +177,8 @@ async function readScriptData(scriptName: string): Promise<ScriptData> {
*/ */
async function ls(scriptName?: string) { async function ls(scriptName?: string) {
if (scriptName) { if (scriptName) {
const pathname = getScriptPath(scriptName); const pathname = await findScriptPath(scriptName);
const exists = await scriptExists(pathname); if (pathname === null) {
if (!exists) {
throw new CLIError(`Script "${scriptName}" not found.`); throw new CLIError(`Script "${scriptName}" not found.`);
} }
@ -192,7 +186,7 @@ async function ls(scriptName?: string) {
return; return;
} }
const currentRundir = getRundirPath(); const currentRundir = findNearestRundir();
const filesInDir = new Glob(`${currentRundir}/*`).scan(); const filesInDir = new Glob(`${currentRundir}/*`).scan();
const scriptLines: string[] = []; const scriptLines: string[] = [];
@ -215,7 +209,14 @@ async function ls(scriptName?: string) {
* @command * @command
*/ */
async function which() { async function which() {
console.log(getRundirPath()); const nearest = findNearestRundir();
if (!nearest) {
console.error("No rundir found in the current directory tree.");
process.exit(1);
}
console.log(path.resolve(nearest));
} }
/** /**
@ -223,7 +224,7 @@ async function which() {
* @command * @command
*/ */
async function newScript(name: string) { async function newScript(name: string) {
const scriptPath = getScriptPath(name); const scriptPath = makeScriptPath(name);
const scriptFile = Bun.file(scriptPath); const scriptFile = Bun.file(scriptPath);
let template = DEFAULT_TEMPLATE; let template = DEFAULT_TEMPLATE;
@ -244,7 +245,7 @@ async function newScript(name: string) {
await Bun.write(scriptFile, template); await Bun.write(scriptFile, template);
await $`chmod +x ${scriptPath}`; await $`chmod +x ${scriptPath}`;
console.log(scriptFile); console.log(name);
} }
/** /**
@ -259,23 +260,7 @@ async function runScript(name: string) {
process.exit(1); process.exit(1);
} }
const rundir = path.dirname(scriptPath); await $`${scriptPath}`;
const cwd = path.resolve(rundir, "..");
const proc = Bun.spawn([scriptPath], {
cwd,
env: {
...process.env,
RUNDIR_PATH: rundir,
RUNDIR_CWD: cwd,
RUNDIR_SCRIPT_PATH: scriptPath,
},
stdout: Bun.stdout,
stderr: Bun.stderr,
stdin: Bun.stdin,
});
await proc.exited;
} }
/** /**