nodejs-bash-completion/this

104 lines
2.9 KiB
JavaScript

#!/usr/bin/env node
const path = require('path');
const { Command } = require('commander');
const shell = require('shelljs');
class This {
constructor() {
this.version = '0.0.1'; // Default version, can be overridden in subclasses
this.description = 'This is the parent class all other scripts should extend.'
this.scriptName = path.parse(process.argv[1]).base;
}
init() {
// implement commander abilities
this.program = new Command()
.name(this.scriptName)
.version(this.version)
.description(this.description)
.configureOutput({
// Visibly override write routines as example!
//writeOut: (str) => process.stdout.write(`[OUT] ${str}`),
//writeErr: (str) => process.stdout.write(`[ERR] ${str}`),
// Highlight errors in color.
outputError: (str, write) => write(this._echoInRed(str)),
});
}
getClassName() {
return this.constructor.name;
}
listMethods() {
const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(this)).filter(
(prop) => typeof this[prop] === 'function' && prop !== 'constructor' && !prop.startsWith('_')
);
return methods;
}
listProperties() {
const properties = Object.keys(this).filter((prop) => typeof this[prop] !== 'function');
return properties;
}
discovery() {
console.log(`My name is '${this.getClassName()}' and I have the version: ${this.version}`);
console.log(`My methods are:`, this.listMethods());
console.log(`My properties are:`, this.listProperties());
}
// Method to create a context manager for this instance
withContext(callback) {
callback(this);
}
start() {
// Not implemented, so it needs to be overridden!
console.warn(this._echoInYellow(`Method ${this._getCurrentFunctionName()} not implemented!`));
}
execCmd(cmd) {
// Run external tool synchronously
if (shell.exec(cmd).code !== 0) {
shell.echo('[ERR] ' + this._echoInRed(`Command '${cmd}' failed`));
shell.exit(1);
}
}
_echoInRed(str) {
// Add ANSI escape codes to display text in red.
return `\x1b[31m${str}\x1b[0m`;
}
_echoInYellow(str) {
// Add ANSI escape codes to display text in yellow.
return `\x1b[33m${str}\x1b[0m`;
}
_getCurrentFunctionName() {
// Create an Error object (but don't throw it)
const err = new Error();
// Extract the current stack trace
Error.captureStackTrace(err, this._getCurrentFunctionName);
// Extract the function name from the stack trace
const callerName = err.stack.split("\n")[1].trim().split(" ")[1];
return callerName;
}
// Higher-order function to decorate other functions and provide logging
_logDecorator(fn) {
return function (...args) {
console.log(`Calling ${fn.name} with arguments:`, args);
const result = fn.apply(this, args); // Use apply to maintain context
console.log(`Result of ${fn.name}:`, result);
return result;
};
}
}
module.exports = This;