#!/usr/bin/env node const This = require('./this'); const util = require('util'); // Example of subcommands which are implemented as stand-alone executable files. // // When `.command()` is invoked with a description argument, // this tells Commander that you're going to use a stand-alone executable for the subcommand. // // Only `install` and `list` are implemented, see pm-install and pm-list.js class Pm extends This { constructor() { super(); this.version = '0.0.1'; this.description = 'Fake package manager'; super.init(); // initialize commander with overridden version and description } install() { /** * @command('install one or more packages') * @alias('i') */ // Calls stand-alone excutable `pm-install` because of @command() in docstring } search() { /** * @command('search with optional query') * @alias('s') */ // Calls stand-alone excutable `pm-search` because of @command() in docstring } update() { /** * @command('update installed packages') * @executable('myUpdateSubCommand') */ // Calls stand-alone excutable `myUpdateSubCommand` because of @command() in docstring } list() { /** * @command('list packages installed') */ // Calls stand-alone excutable `pm-list` because of @command() in docstring } // override This.discovery() discovery() { const methods = this.listMethods(); return methods; } // Basic test methods _testListMethod() { const pm = new Pm(); const pmMethods = pm.listMethods(); const testMethods = pmMethods.includes('install') && pmMethods.includes('search') && pmMethods.includes('update') && pmMethods.includes('list') && pmMethods.includes('discovery') && pmMethods.includes('start'); const testInternalMethods = !pmMethods.includes('_testListMethod'); console.assert(testMethods, 'Pm.listMethod() failed'); console.assert( testInternalMethods, 'Pm.listMethod() for internal methods failed. Classes with _ should be ignored' ); if (testMethods && testInternalMethods) { this.execCmd(`${this.workingDir}/log success 'testListMethod passed'`); } else { this.execCmd(`${this.workingDir}/log error 'testListMethod failed'`); } } _testListProperties() { const pm = new Pm(); const pmProperties = pm.listProperties(); const testProperties = pmProperties.includes('version') && pmProperties.includes('description') && pmProperties.includes('program'); console.assert(testProperties, 'Pm.listProperties() failed'); if (testProperties) { this.execCmd(`${this.workingDir}/log success 'testListProperties passed'`); } else { this.execCmd(`${this.workingDir}/log error 'testListProperties failed'`); } } _testGetClassName() { const pm = new Pm(); const pmClassName = pm.getClassName(); const testClassName = pmClassName === 'Pm'; console.assert(testClassName, 'Pm.getClassName() failed'); if (testClassName) { this.execCmd(`${this.workingDir}/log success 'testGetClassName passed'`); } else { this.execCmd(`${this.workingDir}/log error 'testGetClassName failed'`); } } selfTest() { // Run tests this._testListMethod(); this._testListProperties(); this._testGetClassName(); } start() { this.program.parse(); if (Object.keys(this.program.opts()).length || this.program.args.length) { // Debugging commander options and arguments const opts = util.inspect(this.program.opts(), { depth: null, colors: true, showHidden: true }); const args = util.inspect(this.program.args, { depth: null, colors: true, showHidden: true }); this.execCmd(`${this.workingDir}/log echo 'Options: ${opts}'`); this.execCmd(`${this.workingDir}/log echo 'Remaining arguments: ${args}'`); } else { this.program.outputHelp(); } // applies logDecorator to this.discovery() and binds it to 'this' to maintain the correct context //const logDecoratedDiscovery = this._logDecorator(this.discovery).bind(this); //logDecoratedDiscovery(); // Try the following on macOS or Linux: // ./examples/pm // // Try the following: // ./pm // ./pm help install // ./pm install -h // ./pm install foo bar baz // ./pm install foo bar baz --force } } // main const pm = new Pm(); // // applies logDecorator to this.discovery() and binds it to the instance to maintain the correct context // const logDecoratedDiscovery = pm._logDecorator(pm.discovery).bind(pm); // logDecoratedDiscovery(); pm.start(); //pm.selfTest();