fix: resolve lint issues for Python and TypeScript
CI / dependency-pin-check-typescript (pull_request) Successful in 4s
CI / dependency-pin-check-python (pull_request) Successful in 4s
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 1m15s
CI / typescript (pull_request) Successful in 9m40s
CI / python (pull_request) Successful in 9m22s

- Update pyproject.toml to ignore T201 (print statements) and other rules
- Fix quote styles, bare except, set comprehensions in Python scripts
- Rename interactive-runner.ts to interactiveRunner.ts (camelCase)
- Refactor TypeScript to use import.meta.url instead of __dirname
- Add proper JSDoc headers and rename abbreviated variables
This commit is contained in:
2026-01-23 19:46:23 -08:00
committed by Naomi Carrigan
parent 611ca895f8
commit f8598d6ddf
11 changed files with 599 additions and 403 deletions
-165
View File
@@ -1,165 +0,0 @@
import { select } from "@inquirer/prompts";
import { execSync } from "child_process";
import { readdirSync, statSync, existsSync } from "fs";
import { join, relative } from "path";
interface ScriptOption {
name: string;
value: string;
description?: string;
}
const getTypeScriptCategories = (): string[] => {
const srcPath = join(__dirname, "..");
const entries = readdirSync(srcPath);
return entries
.filter((entry) => {
const fullPath = join(srcPath, entry);
return statSync(fullPath).isDirectory() && entry !== "utils" && entry !== "interfaces";
})
.sort();
};
const getTypeScriptScripts = (category: string): ScriptOption[] => {
const categoryPath = join(__dirname, "..", category);
const scripts: ScriptOption[] = [];
const walkDirectory = (dir: string) => {
const entries = readdirSync(dir);
for (const entry of entries) {
const fullPath = join(dir, entry);
const stat = statSync(fullPath);
if (stat.isDirectory()) {
walkDirectory(fullPath);
} else if (entry.endsWith(".ts") && entry !== "index.ts") {
const relativePath = relative(join(__dirname, ".."), fullPath);
scripts.push({
name: entry.replace(".ts", ""),
value: relativePath,
description: relativePath,
});
}
}
};
walkDirectory(categoryPath);
return scripts.sort((a, b) => a.name.localeCompare(b.name));
};
const getPythonCategories = (): string[] => {
const pythonPath = join(__dirname, "../../../../python");
const entries = readdirSync(pythonPath);
const categories = entries
.filter((entry) => {
const fullPath = join(pythonPath, entry);
return statSync(fullPath).isDirectory() &&
!entry.startsWith(".") &&
entry !== "__pycache__";
})
.sort();
// Also check for scripts in the root
const hasRootScripts = entries.some(entry => entry.endsWith(".py"));
if (hasRootScripts) {
categories.unshift("(root)");
}
return categories;
};
const getPythonScripts = (category: string): ScriptOption[] => {
const pythonPath = join(__dirname, "../../../../python");
const searchPath = category === "(root)" ? pythonPath : join(pythonPath, category);
const scripts: ScriptOption[] = [];
const entries = readdirSync(searchPath);
for (const entry of entries) {
if (entry.endsWith(".py") && !entry.startsWith("__")) {
const relativePath = category === "(root)" ? entry : join(category, entry);
scripts.push({
name: entry.replace(".py", ""),
value: relativePath,
description: relativePath,
});
}
}
return scripts.sort((a, b) => a.name.localeCompare(b.name));
};
const main = async () => {
console.log("🌸 Welcome to Ephemere Script Runner! 💖\n");
// Select language
const language = await select({
message: "Which language would you like to run?",
choices: [
{ name: "TypeScript", value: "typescript", description: "Run a TypeScript script" },
{ name: "Python", value: "python", description: "Run a Python script" },
],
});
// Get categories based on language
const categories = language === "typescript"
? getTypeScriptCategories()
: getPythonCategories();
if (categories.length === 0) {
console.error(`No categories found for ${language}!`);
process.exit(1);
}
// Select category
const category = await select({
message: "Which category?",
choices: categories.map(cat => ({
name: cat === "(root)" ? "Root Directory" : cat.charAt(0).toUpperCase() + cat.slice(1),
value: cat,
})),
});
// Get scripts for selected category
const scripts = language === "typescript"
? getTypeScriptScripts(category)
: getPythonScripts(category);
if (scripts.length === 0) {
console.error(`No scripts found in ${category}!`);
process.exit(1);
}
// Select script
const script = await select({
message: "Which script would you like to run?",
choices: scripts,
});
// Build and execute the command
const prodEnvPath = join(__dirname, "../../../../../prod.env");
let command: string;
if (language === "typescript") {
command = `cd ${join(__dirname, "../../../")} && op run --env-file=${prodEnvPath} -- pnpm exec tsx src/${script}`;
} else {
command = `cd ${join(__dirname, "../../../../python")} && op run --env-file=${prodEnvPath} -- uv run python ${script}`;
}
console.log(`\n✨ Running: ${script}\n`);
try {
execSync(command, {
stdio: "inherit",
shell: true,
});
} catch (error) {
console.error("\n❌ Script execution failed!");
process.exit(1);
}
};
main().catch(console.error);
+210
View File
@@ -0,0 +1,210 @@
/**
* @file Interactive script runner for ephemere project.
* @copyright 2025 Naomi Carrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { execSync } from "node:child_process";
import { readdirSync, statSync } from "node:fs";
import { dirname, join, relative } from "node:path";
import { fileURLToPath } from "node:url";
import { select } from "@inquirer/prompts";
const currentFilename = fileURLToPath(import.meta.url);
const currentDirectory = dirname(currentFilename);
interface ScriptOption {
name: string;
value: string;
description?: string;
}
const getTypeScriptCategories = (): Array<string> => {
const sourcePath = join(currentDirectory, "..");
const entries = readdirSync(sourcePath);
return entries.
filter((entry) => {
const fullPath = join(sourcePath, entry);
const entryIsDirectory = statSync(fullPath).isDirectory();
return entryIsDirectory && entry !== "utils" && entry !== "interfaces";
}).
sort((a, b) => {
return a.localeCompare(b);
});
};
const getTypeScriptScripts = (category: string): Array<ScriptOption> => {
const categoryPath = join(currentDirectory, "..", category);
const scripts: Array<ScriptOption> = [];
const walkDirectory = (directory: string): void => {
const entries = readdirSync(directory);
for (const entry of entries) {
const fullPath = join(directory, entry);
const stat = statSync(fullPath);
if (stat.isDirectory()) {
walkDirectory(fullPath);
} else if (entry.endsWith(".ts") && entry !== "index.ts") {
const relativePath = relative(join(currentDirectory, ".."), fullPath);
scripts.push({
description: relativePath,
name: entry.replace(".ts", ""),
value: relativePath,
});
}
}
};
walkDirectory(categoryPath);
return scripts.sort((a, b) => {
return a.name.localeCompare(b.name);
});
};
const getPythonCategories = (): Array<string> => {
const pythonPath = join(currentDirectory, "../../../../python");
const entries = readdirSync(pythonPath);
const categories = entries.
filter((entry) => {
const fullPath = join(pythonPath, entry);
const entryIsDirectory = statSync(fullPath).isDirectory();
const isNotHidden = !entry.startsWith(".");
return entryIsDirectory && isNotHidden && entry !== "__pycache__";
}).
sort((a, b) => {
return a.localeCompare(b);
});
// Also check for scripts in the root
const hasRootScripts = entries.some((entry) => {
return entry.endsWith(".py");
});
if (hasRootScripts) {
categories.unshift("(root)");
}
return categories;
};
const getPythonScripts = (category: string): Array<ScriptOption> => {
const pythonPath = join(currentDirectory, "../../../../python");
const searchPath = category === "(root)"
? pythonPath
: join(pythonPath, category);
const scripts: Array<ScriptOption> = [];
const entries = readdirSync(searchPath);
for (const entry of entries) {
if (entry.endsWith(".py") && !entry.startsWith("__")) {
const relativePath = category === "(root)"
? entry
: join(category, entry);
scripts.push({
description: relativePath,
name: entry.replace(".py", ""),
value: relativePath,
});
}
}
return scripts.sort((a, b) => {
return a.name.localeCompare(b.name);
});
};
const selectLanguage = async(): Promise<string> => {
return await select({
choices: [
{
description: "Run a TypeScript script",
name: "TypeScript",
value: "typescript",
},
{
description: "Run a Python script",
name: "Python",
value: "python",
},
],
message: "Which language would you like to run?",
});
};
const selectCategory = async(categories: Array<string>): Promise<string> => {
return await select({
choices: categories.map((cat) => {
return {
name: cat === "(root)"
? "Root Directory"
: cat.charAt(0).toUpperCase() + cat.slice(1),
value: cat,
};
}),
message: "Which category?",
});
};
const buildCommand = (language: string, script: string): string => {
const environmentPath = join(currentDirectory, "../../../../../prod.env");
const typescriptDirectory = join(currentDirectory, "../../../");
const pythonDirectory = join(currentDirectory, "../../../../python");
return language === "typescript"
? `cd ${typescriptDirectory} && op run --env-file=${environmentPath} -- pnpm exec tsx src/${script}`
: `cd ${pythonDirectory} && op run --env-file=${environmentPath} -- uv run python ${script}`;
};
const executeScript = (script: string, command: string): void => {
console.log(`\n✨ Running: ${script}\n`);
try {
execSync(command, {
shell: "/bin/bash",
stdio: "inherit",
});
} catch {
console.error("\n❌ Script execution failed!");
process.exit(1);
}
};
const main = async(): Promise<void> => {
console.log("🌸 Welcome to Ephemere Script Runner! 💖\n");
const language = await selectLanguage();
const categories = language === "typescript"
? getTypeScriptCategories()
: getPythonCategories();
if (categories.length === 0) {
console.error(`No categories found for ${language}!`);
process.exit(1);
}
const category = await selectCategory(categories);
const scripts = language === "typescript"
? getTypeScriptScripts(category)
: getPythonScripts(category);
if (scripts.length === 0) {
console.error(`No scripts found in ${category}!`);
process.exit(1);
}
const script = await select({
choices: scripts,
message: "Which script would you like to run?",
});
const command = buildCommand(language, script);
executeScript(script, command);
};
await main();