taylo
Version:
Make changes to a branch a plugin. A command-line tool to manage and apply plugins '.taylored'. Supports applying, removing, verifying plugins, and generating them from branch (GIT).
325 lines (324 loc) • 16.7 kB
JavaScript
;
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 });
const fs = __importStar(require("fs/promises"));
const path = __importStar(require("path"));
const constants_1 = require("./lib/constants");
const apply_logic_1 = require("./lib/apply-logic");
const save_handler_1 = require("./lib/handlers/save-handler");
const list_handler_1 = require("./lib/handlers/list-handler");
const offset_handler_1 = require("./lib/handlers/offset-handler");
const automatic_handler_1 = require("./lib/handlers/automatic-handler");
const utils_1 = require("./lib/utils");
const PatchAnalyzer_1 = require("./lib/PatchAnalyzer");
async function main() {
const rawArgs = process.argv.slice(2);
const CWD = process.cwd();
if (rawArgs.length === 0) {
(0, utils_1.printUsageAndExit)(undefined, true);
return;
}
const mode = rawArgs[0];
let argument;
let branchName;
const relevantModesForGitCheck = [
'--add',
'--remove',
'--verify-add',
'--verify-remove',
'--save',
'--list',
'--offset',
'--automatic',
'--upgrade',
];
if (relevantModesForGitCheck.includes(mode)) {
const gitDirPath = path.join(CWD, '.git');
try {
const gitDirStats = await fs.stat(gitDirPath);
if (!gitDirStats.isDirectory()) {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: A '.git' entity exists at '${gitDirPath}', but it is not a directory. This script must be run from the root of a Git repository for the command '${mode}'.`);
}
}
catch (error) {
if (error.code === 'ENOENT') {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: No '.git' directory found in '${CWD}'. The command '${mode}' must be run from the root of a Git repository.`);
}
else {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: Could not verify '.git' directory presence for '${mode}' in '${CWD}'. Details: ${error.message}`);
}
}
}
try {
if (mode === '--save') {
if (rawArgs.length !== 2) {
(0, utils_1.printUsageAndExit)('CRITICAL ERROR: --save option requires exactly one <branch_name> argument.');
}
argument = rawArgs[1];
if (argument.startsWith('--')) {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: Invalid branch name '${argument}' after --save. It cannot start with '--'.`);
}
await (0, save_handler_1.handleSaveOperation)(argument, CWD);
}
else if (mode === '--list') {
if (rawArgs.length !== 1) {
(0, utils_1.printUsageAndExit)('CRITICAL ERROR: --list option does not take any arguments.');
}
await (0, list_handler_1.handleListOperation)(CWD);
}
else if (mode === '--offset') {
if (rawArgs.length < 2) {
(0, utils_1.printUsageAndExit)('CRITICAL ERROR: --offset option requires at least one <taylored_file_name> argument.');
}
argument = rawArgs[1];
if (argument.startsWith('--')) {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: Invalid taylored file name '${argument}' after --offset. It cannot start with '--'.`);
}
if (argument.includes(path.sep) ||
argument.includes('/') ||
argument.includes('\\')) {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: <taylored_file_name> ('${argument}') must be a simple filename without path separators. It is assumed to be in the '${constants_1.TAYLORED_DIR_NAME}/' directory.`);
}
branchName = undefined;
let currentArgIndex = 2;
if (rawArgs.length > currentArgIndex &&
!rawArgs[currentArgIndex].startsWith('--')) {
branchName = rawArgs[currentArgIndex];
if (branchName.startsWith('--')) {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: Invalid branch name '${branchName}' provided for --offset. It cannot start with '--'.`);
}
currentArgIndex++;
}
if (rawArgs.length > currentArgIndex) {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: Unknown or unexpected argument '${rawArgs[currentArgIndex]}' for --offset. Expected optional [BRANCH_NAME] only.`);
}
await (0, offset_handler_1.handleOffsetCommand)(argument, CWD, branchName);
}
else if (mode === '--automatic') {
let extensionsInput;
let branchNameArgument;
let excludeDirs;
if (rawArgs.length === 3) {
extensionsInput = rawArgs[1];
branchNameArgument = rawArgs[2];
}
else if (rawArgs.length === 5) {
extensionsInput = rawArgs[1];
branchNameArgument = rawArgs[2];
if (rawArgs[3] !== '--exclude') {
(0, utils_1.printUsageAndExit)("CRITICAL ERROR: Expected '--exclude' as the fourth argument for --automatic with 5 arguments.");
}
const excludeArgument = rawArgs[4];
if (excludeArgument.startsWith('--')) {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: Invalid exclude argument '${excludeArgument}'. It cannot start with '--'.`);
}
excludeDirs = excludeArgument
.split(',')
.map((dir) => dir.trim())
.filter((dir) => dir.length > 0);
if (excludeDirs.length === 0 && excludeArgument.length > 0) {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: Exclude argument '${excludeArgument}' resulted in an empty list of directories.`);
}
else if (excludeDirs.length === 0 && excludeArgument.length === 0) {
excludeDirs = undefined;
}
}
else {
(0, utils_1.printUsageAndExit)('CRITICAL ERROR: --automatic option requires either 2 arguments (<EXTENSIONS> <branch_name>) or 4 arguments (<EXTENSIONS> <branch_name> --exclude <DIR_LIST>).');
return;
}
if (extensionsInput.startsWith('--')) {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: Invalid extensions input '${extensionsInput}' after --automatic. It cannot start with '--'.`);
}
if (extensionsInput.includes(path.sep) ||
extensionsInput.includes('/') ||
extensionsInput.includes('\\')) {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: <EXTENSIONS> ('${extensionsInput}') must be a simple extension string (e.g., 'ts,js,py') without path separators.`);
}
if (branchNameArgument.startsWith('--')) {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: Invalid branch name '${branchNameArgument}' after --automatic <EXTENSIONS>. It cannot start with '--'.`);
}
await (0, automatic_handler_1.handleAutomaticOperation)(extensionsInput, branchNameArgument, CWD, excludeDirs);
}
else if (mode === '--upgrade') {
if (rawArgs.length < 2 || rawArgs.length > 3) {
(0, utils_1.printUsageAndExit)('CRITICAL ERROR: --upgrade option requires a <patch_file> argument and optionally a [target_file_path].');
}
const patchFile = rawArgs[1];
if (patchFile.startsWith('--')) {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: Invalid patch file argument '${patchFile}'. It cannot start with '--'.`);
}
const resolvedPatchFileName = (0, utils_1.resolveTayloredFileName)(patchFile);
const fullPatchPath = path.join(CWD, constants_1.TAYLORED_DIR_NAME, resolvedPatchFileName);
let targetFilePath;
if (rawArgs.length === 3) {
targetFilePath = path.resolve(CWD, rawArgs[2]);
}
try {
const analyzer = new PatchAnalyzer_1.PatchAnalyzer();
const results = await analyzer.verifyIntegrityAndUpgrade(fullPatchPath, targetFilePath);
console.log(`\n=== Report for --upgrade command ===`);
results.forEach((result) => {
console.log(`File: ${result.file}`);
console.log(`Status: ${result.status.toUpperCase()}`);
console.log(`Message: ${result.message}`);
if (result.updated) {
console.log(`Patch updated: YES`);
}
else {
console.log(`Patch updated: NO`);
}
if (result.blocks && result.blocks.length > 0) {
console.log(` Modification blocks checked: ${result.blocks.length}`);
result.blocks.forEach((blockCheck, index) => {
console.log(` Block ${index + 1} (${blockCheck.blockType}):`);
console.log(` Top Frame: ${blockCheck.topFrame.intact ? 'INTACT' : 'MODIFIED/MISSING'}`);
if (!blockCheck.topFrame.intact) {
console.log(` Expected: "${blockCheck.topFrame.expected}"`);
console.log(` Actual: "${blockCheck.topFrame.actual}"`);
}
console.log(` Bottom Frame: ${blockCheck.bottomFrame.intact ? 'INTACT' : 'MODIFIED/MISSING'}`);
if (!blockCheck.bottomFrame.intact) {
console.log(` Expected: "${blockCheck.bottomFrame.expected}"`);
console.log(` Actual: "${blockCheck.bottomFrame.actual}"`);
}
});
}
console.log('-----------------------------------');
});
console.log(`\n--upgrade command completed.`);
}
catch (error) {
console.error(`CRITICAL ERROR: Failed to execute --upgrade command. Details: ${error.message}`);
throw error;
}
}
else {
const applyModes = [
'--add',
'--remove',
'--verify-add',
'--verify-remove',
];
if (applyModes.includes(mode)) {
if (rawArgs.length !== 2) {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: ${mode} requires a <taylored_file_name_or_path> argument.`);
}
const userInputFileName = rawArgs[1];
if (userInputFileName.startsWith('--')) {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: Invalid taylored file name '${userInputFileName}' after ${mode}. It cannot start with '--'.`);
}
const userInputAbsolutePath = path.join(CWD, constants_1.TAYLORED_DIR_NAME, userInputFileName);
let stats;
try {
stats = await fs.stat(userInputAbsolutePath);
}
catch (e) {
if (e.code !== 'ENOENT') {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: Could not access '${userInputAbsolutePath}'. Details: ${e.message}`);
return;
}
}
let isVerify = false;
let isReverse = false;
switch (mode) {
case '--add':
break;
case '--remove':
isReverse = true;
break;
case '--verify-add':
isVerify = true;
break;
case '--verify-remove':
isVerify = true;
isReverse = true;
break;
}
if (stats && stats.isDirectory()) {
console.log(`INFO: Processing patch group in directory: ${userInputFileName}`);
const patches = await (0, utils_1.findPatchesInDirectory)(userInputAbsolutePath);
if (patches.length === 0) {
console.log(`INFO: No .taylored files found in directory '${userInputAbsolutePath}'. Nothing to do.`);
return;
}
let patchesToProcess = (0, utils_1.sortPatchesNumerically)(patches);
if (isReverse) {
patchesToProcess = patchesToProcess.reverse();
console.log(`INFO: Found ${patchesToProcess.length} patch(es) to process in REVERSE order (for removal):`);
}
else {
console.log(`INFO: Found ${patchesToProcess.length} patch(es) to process in order:`);
}
patchesToProcess.forEach((p) => console.log(` - ${path.relative(path.join(CWD, constants_1.TAYLORED_DIR_NAME), p)}`));
for (const patchPath of patchesToProcess) {
const patchFileNameForApply = path.relative(path.join(CWD, constants_1.TAYLORED_DIR_NAME), patchPath);
console.log(`\nINFO: ==> ${mode} patch: ${patchFileNameForApply}`);
try {
await (0, apply_logic_1.handleApplyOperation)(patchFileNameForApply, isVerify, isReverse, mode, CWD);
console.log(`INFO: <== Successfully processed: ${patchFileNameForApply}`);
}
catch (error) {
console.error(`CRITICAL ERROR: Failed to process patch ${patchFileNameForApply} in group ${userInputFileName}. Halting group operation.`);
process.exit(1);
}
}
console.log(`\nINFO: Finished processing patch group: ${userInputFileName}`);
}
else {
const resolvedTayloredFileName = (0, utils_1.resolveTayloredFileName)(userInputFileName);
await (0, apply_logic_1.handleApplyOperation)(resolvedTayloredFileName, isVerify, isReverse, mode, CWD);
}
}
else {
(0, utils_1.printUsageAndExit)(`CRITICAL ERROR: Unknown option or command '${mode}'.`, true);
}
}
}
catch (error) {
if (!error.message.includes('CRITICAL ERROR')) {
console.error(`An unexpected error occurred: ${error.message}`);
}
process.exit(1);
}
}
main().catch((err) => {
const errorMessage = err && err.message ? err.message : 'Unknown error in main().catch';
if (!errorMessage.includes('CRITICAL ERROR')) {
console.error(`Error in main().catch: ${errorMessage}`);
}
process.exit(1);
});