UNPKG

tolkfmt-test-dev

Version:

Code formatter for the Tolk programming language

203 lines 7.18 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.main = main; const cac_1 = require("cac"); const fs = __importStar(require("node:fs")); const path = __importStar(require("node:path")); const glob_1 = require("glob"); const index_1 = require("./index"); const version = "0.0.13"; async function formatFile(filepath, options) { const content = readFileOrFail(filepath); if (content === undefined) return undefined; const { mode, range, sortImports } = options; try { const [formattedCode, time] = await measureTime(async () => { return (0, index_1.format)(content, { maxWidth: 100, range, sortImports }); }); const alreadyFormatted = content === formattedCode; if (mode === "check") { if (alreadyFormatted) { return true; } console.log(`[warn]`, path.basename(filepath)); return false; } if (mode === "format-and-write") { console.log(path.basename(filepath), `${time.toFixed(0)}ms`, status(content, formattedCode)); fs.writeFileSync(filepath, formattedCode); return alreadyFormatted; } else { process.stdout.write(formattedCode); return alreadyFormatted; } } catch (error) { if (error instanceof Error) { console.error(`Cannot format file ${path.relative(process.cwd(), filepath)}:`, error.message); } return undefined; } } function status(before, after) { if (before !== after) { return "(reformatted)"; } return "(unchanged)"; } async function measureTime(fn) { const startTime = performance.now(); const result = await fn(); const endTime = performance.now(); const time = endTime - startTime; return [result, time]; } function readFileOrFail(filePath) { try { return fs.readFileSync(filePath, "utf8"); } catch (error) { if (error instanceof Error) { console.error(`Cannot read file: ${error.message}`); } return undefined; } } function collectFilesToFormat(paths) { return paths.flatMap(inputPath => { if (!fs.existsSync(inputPath)) { console.error(`Path does not exist: ${inputPath}`); return []; } if (fs.statSync(inputPath).isFile()) { return inputPath; } // for directory, find all .tolk files return glob_1.glob.sync("**/*.tolk", { cwd: inputPath }).map(file => path.join(inputPath, file)); }); } function parseRange(rangeStr) { const regex = /^(\d+):(\d+)-(\d+):(\d+)$/; const match = regex.exec(rangeStr); if (!match) { throw new Error("Invalid range format. Expected: startLine:startChar-endLine:endChar (e.g., 1:5-3:10)"); } const [, startLine, startChar, endLine, endChar] = match; return { start: { line: Number.parseInt(startLine, 10), character: Number.parseInt(startChar, 10), }, end: { line: Number.parseInt(endLine, 10), character: Number.parseInt(endChar, 10), }, }; } async function main() { const cli = (0, cac_1.cac)("tolkfmt"); cli.version(version) .usage("[options] <files or directories>") .option("-w, --write", "Write result to same file") .option("-c, --check", "Check if the given files are formatted") .option("-r, --range <range>", "Format only the specified range (format: startLine:startChar-endLine:endChar)") .option("-s, --sort-imports", "Sort imports in the formatted file") .help(); const parsed = cli.parse(); // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const { write, check, range, sortImports = false } = parsed.options; const filePaths = parsed.args; if (write !== undefined && check !== undefined) { console.error("Error: Cannot use both --write and --check options together"); process.exit(1); } let parsedRange = undefined; if (range !== undefined) { try { parsedRange = parseRange(range); } catch (error) { console.error("Error:", error instanceof Error ? error.message : "Invalid range format"); process.exit(1); } } if (filePaths.length === 0) { return; } const mode = check === undefined ? (write === undefined ? "format" : "format-and-write") : "check"; if (mode === "check") { console.log("Checking formatting..."); } const filesToFormat = collectFilesToFormat([...filePaths]); if (filesToFormat.length === 0) { console.error("No .tolk files found"); process.exit(1); } let someFileCannotBeFormatted = false; let allFormatted = true; for (const file of filesToFormat) { const res = await formatFile(file, { mode, range: parsedRange, sortImports }); if (res === undefined) { someFileCannotBeFormatted = true; } else { allFormatted &&= res; } } if (check !== undefined) { if (allFormatted) { console.log("All Tolk files are properly formatted!"); } else { console.log("Code style issues found in the above files. Run tolkfmt with --write to fix."); process.exit(1); } } if (someFileCannotBeFormatted) { process.exit(1); } } process.on("uncaughtException", error => { console.error("Unexpected error:", error.message); process.exit(1); }); process.on("unhandledRejection", reason => { console.error("Unhandled promise rejection:", reason); process.exit(1); }); //# sourceMappingURL=cli.js.map