104 lines
2.9 KiB
JavaScript
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;
|