feat(): Optimize docstring parser for commander and make depending changes
This commit is contained in:
parent
64815d15f6
commit
e29f085961
|
@ -15,3 +15,12 @@ https://unix.stackexchange.com/questions/65235/universal-node-js-shebang
|
|||
## Set location for npm packages with repl sessions
|
||||
|
||||
https://sabljakovich.medium.com/how-to-use-npm-packages-with-node-js-repl-sessions-cd77300ebfe2
|
||||
|
||||
## Dependencies versionn
|
||||
|
||||
The iSH-App on iOS has the following latest versions available
|
||||
|
||||
- nodejs v16.11.1
|
||||
- npm v7.17.0
|
||||
|
||||
These versions are deprecated, but if we want to use these scripts on iSH, we have to make sure they run on that outdated versions.
|
||||
|
|
18
log
18
log
|
@ -13,7 +13,8 @@ class Log extends This {
|
|||
|
||||
echo(message) {
|
||||
/**
|
||||
* @command
|
||||
* @program()
|
||||
* @command()
|
||||
* @argument('<message>')
|
||||
*/
|
||||
console.log(message);
|
||||
|
@ -21,7 +22,8 @@ class Log extends This {
|
|||
|
||||
success(message) {
|
||||
/**
|
||||
* @command
|
||||
* @program()
|
||||
* @command()
|
||||
* @argument('<message>')
|
||||
*/
|
||||
console.log(this._echoInGreen(message));
|
||||
|
@ -29,7 +31,8 @@ class Log extends This {
|
|||
|
||||
info(message) {
|
||||
/**
|
||||
* @command
|
||||
* @program()
|
||||
* @command()
|
||||
* @argument('<message>')
|
||||
*/
|
||||
console.log(`[INFO] ${message}`);
|
||||
|
@ -37,7 +40,8 @@ class Log extends This {
|
|||
|
||||
warn(message) {
|
||||
/**
|
||||
* @command
|
||||
* @program()
|
||||
* @command()
|
||||
* @argument('<message>')
|
||||
*/
|
||||
console.warn(`[WARN] ${this._echoInYellow(message)}`);
|
||||
|
@ -45,13 +49,17 @@ class Log extends This {
|
|||
|
||||
error(message) {
|
||||
/**
|
||||
* @command
|
||||
* @program()
|
||||
* @command()
|
||||
* @argument('<message>')
|
||||
*/
|
||||
console.error(`[ERR] ${this._echoInRed(message)}`);
|
||||
}
|
||||
|
||||
start() {
|
||||
/**
|
||||
* @program()
|
||||
*/
|
||||
this.program.parse();
|
||||
|
||||
if (Object.keys(this.program.opts()).length || this.program.args.length) {
|
||||
|
|
230
package-lock.json
generated
Normal file
230
package-lock.json
generated
Normal file
|
@ -0,0 +1,230 @@
|
|||
{
|
||||
"name": "once-nodejs",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"commander": "^12.1.0",
|
||||
"shelljs": "^0.8.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^3.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "12.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
|
||||
"integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"deprecated": "Glob versions prior to v9 are no longer supported",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/interpret": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
|
||||
"integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/is-core-module": {
|
||||
"version": "2.14.0",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz",
|
||||
"integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==",
|
||||
"dependencies": {
|
||||
"hasown": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
|
||||
"integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/rechoir": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
|
||||
"integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
|
||||
"dependencies": {
|
||||
"resolve": "^1.1.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.8",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
|
||||
"integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
|
||||
"dependencies": {
|
||||
"is-core-module": "^2.13.0",
|
||||
"path-parse": "^1.0.7",
|
||||
"supports-preserve-symlinks-flag": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"resolve": "bin/resolve"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/shelljs": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz",
|
||||
"integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==",
|
||||
"dependencies": {
|
||||
"glob": "^7.0.0",
|
||||
"interpret": "^1.0.0",
|
||||
"rechoir": "^0.6.2"
|
||||
},
|
||||
"bin": {
|
||||
"shjs": "bin/shjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"commander": "^12.1.0",
|
||||
"omelette": "^0.4.17",
|
||||
"shelljs": "^0.8.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
31
pm
31
pm
|
@ -1,7 +1,6 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
const This = require('./this');
|
||||
const util = require('util');
|
||||
|
||||
// Example of subcommands which are implemented as stand-alone executable files.
|
||||
//
|
||||
|
@ -19,6 +18,7 @@ class Pm extends This {
|
|||
|
||||
install() {
|
||||
/**
|
||||
* @program()
|
||||
* @command('install one or more packages')
|
||||
* @alias('i')
|
||||
*/
|
||||
|
@ -27,6 +27,7 @@ class Pm extends This {
|
|||
|
||||
search() {
|
||||
/**
|
||||
* @program()
|
||||
* @command('search with optional query')
|
||||
* @alias('s')
|
||||
*/
|
||||
|
@ -35,6 +36,7 @@ class Pm extends This {
|
|||
|
||||
update() {
|
||||
/**
|
||||
* @program()
|
||||
* @command('update installed packages')
|
||||
* @executable('myUpdateSubCommand')
|
||||
*/
|
||||
|
@ -43,6 +45,7 @@ class Pm extends This {
|
|||
|
||||
list() {
|
||||
/**
|
||||
* @program()
|
||||
* @command('list packages installed')
|
||||
*/
|
||||
// Calls stand-alone excutable `pm-list` because of @command(<description>) in docstring
|
||||
|
@ -118,31 +121,7 @@ class Pm extends This {
|
|||
}
|
||||
|
||||
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
|
||||
super.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
32
pm-install
32
pm-install
|
@ -1,39 +1,23 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
const This = require('./this');
|
||||
const util = require('util');
|
||||
|
||||
class PmInstall extends This {
|
||||
constructor() {
|
||||
super();
|
||||
this.version = '0.0.1';
|
||||
this.description = 'Install package with fake package manager'
|
||||
this.description = 'Install package with fake package manager';
|
||||
super.init(); // initialize commander with overridden version and description
|
||||
}
|
||||
|
||||
start() {
|
||||
// Usage
|
||||
const pmInstall = new PmInstall();
|
||||
// Output: Methods of ExampleClass: [ 'methodOne', 'methodTwo' ]
|
||||
// Properties of ExampleClass: [ 'propertyOne', 'propertyTwo', 'version' ] and Version: 1.1.0
|
||||
// pmInstall.discovery();
|
||||
|
||||
this.program
|
||||
.usage('-n 3 32 -l x y z -- op')
|
||||
.option('-n, --number <numbers...>', 'specify numbers')
|
||||
.option('-l, --letter [letters...]', 'specify letters')
|
||||
|
||||
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();
|
||||
}
|
||||
/**
|
||||
* @program()
|
||||
* @usage('-n 3 32 -l x y z -- op')
|
||||
* @option('-n, --number <numbers...>', 'specify numbers')
|
||||
* @option('-l, --letter [letters...]', 'specify letters')
|
||||
*/
|
||||
super.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
12
pm-list
12
pm-list
|
@ -1,23 +1,17 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
const This = require('./this');
|
||||
const { Command } = require('commander');
|
||||
const program = new Command();
|
||||
|
||||
class PmList extends This {
|
||||
constructor() {
|
||||
super();
|
||||
this.version = '0.0.1';
|
||||
this.description = 'List packages of fake package manager';
|
||||
super.init(); // initialize commander with overridden version and description
|
||||
}
|
||||
|
||||
start() {
|
||||
// Usage
|
||||
const pmList = new PmList();
|
||||
// Output: Methods of ExampleClass: [ 'methodOne', 'methodTwo' ]
|
||||
// Properties of ExampleClass: [ 'propertyOne', 'propertyTwo', 'version' ] and Version: 1.1.0
|
||||
// pmList.discovery();
|
||||
|
||||
program.name(this.scriptName).version('0.0.1').description('List packages of fake package manager').outputHelp();
|
||||
super.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
183
pnpm-lock.yaml
183
pnpm-lock.yaml
|
@ -1,183 +0,0 @@
|
|||
lockfileVersion: '6.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
commander:
|
||||
specifier: ^12.1.0
|
||||
version: 12.1.0
|
||||
omelette:
|
||||
specifier: ^0.4.17
|
||||
version: 0.4.17
|
||||
shelljs:
|
||||
specifier: ^0.8.5
|
||||
version: 0.8.5
|
||||
|
||||
devDependencies:
|
||||
prettier:
|
||||
specifier: ^3.3.2
|
||||
version: 3.3.2
|
||||
|
||||
packages:
|
||||
/balanced-match@1.0.2:
|
||||
resolution:
|
||||
{ integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== }
|
||||
dev: false
|
||||
|
||||
/brace-expansion@1.1.11:
|
||||
resolution:
|
||||
{ integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== }
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
concat-map: 0.0.1
|
||||
dev: false
|
||||
|
||||
/commander@12.1.0:
|
||||
resolution:
|
||||
{ integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA== }
|
||||
engines: { node: '>=18' }
|
||||
dev: false
|
||||
|
||||
/concat-map@0.0.1:
|
||||
resolution:
|
||||
{ integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== }
|
||||
dev: false
|
||||
|
||||
/fs.realpath@1.0.0:
|
||||
resolution:
|
||||
{ integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== }
|
||||
dev: false
|
||||
|
||||
/function-bind@1.1.2:
|
||||
resolution:
|
||||
{ integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== }
|
||||
dev: false
|
||||
|
||||
/glob@7.2.3:
|
||||
resolution:
|
||||
{ integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== }
|
||||
deprecated: Glob versions prior to v9 are no longer supported
|
||||
dependencies:
|
||||
fs.realpath: 1.0.0
|
||||
inflight: 1.0.6
|
||||
inherits: 2.0.4
|
||||
minimatch: 3.1.2
|
||||
once: 1.4.0
|
||||
path-is-absolute: 1.0.1
|
||||
dev: false
|
||||
|
||||
/hasown@2.0.2:
|
||||
resolution:
|
||||
{ integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== }
|
||||
engines: { node: '>= 0.4' }
|
||||
dependencies:
|
||||
function-bind: 1.1.2
|
||||
dev: false
|
||||
|
||||
/inflight@1.0.6:
|
||||
resolution:
|
||||
{ integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== }
|
||||
deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
|
||||
dependencies:
|
||||
once: 1.4.0
|
||||
wrappy: 1.0.2
|
||||
dev: false
|
||||
|
||||
/inherits@2.0.4:
|
||||
resolution:
|
||||
{ integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== }
|
||||
dev: false
|
||||
|
||||
/interpret@1.4.0:
|
||||
resolution:
|
||||
{ integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== }
|
||||
engines: { node: '>= 0.10' }
|
||||
dev: false
|
||||
|
||||
/is-core-module@2.14.0:
|
||||
resolution:
|
||||
{ integrity: sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A== }
|
||||
engines: { node: '>= 0.4' }
|
||||
dependencies:
|
||||
hasown: 2.0.2
|
||||
dev: false
|
||||
|
||||
/minimatch@3.1.2:
|
||||
resolution:
|
||||
{ integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== }
|
||||
dependencies:
|
||||
brace-expansion: 1.1.11
|
||||
dev: false
|
||||
|
||||
/omelette@0.4.17:
|
||||
resolution:
|
||||
{ integrity: sha512-UlU69G6Bhu0XFjw3tjFZ0qyiMUjAOR+rdzblA1nLQ8xiqFtxOVlkhM39BlgTpLFx9fxkm6rnxNNRsS5GxE/yww== }
|
||||
engines: { node: '>=0.8.0' }
|
||||
dev: false
|
||||
|
||||
/once@1.4.0:
|
||||
resolution:
|
||||
{ integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== }
|
||||
dependencies:
|
||||
wrappy: 1.0.2
|
||||
dev: false
|
||||
|
||||
/path-is-absolute@1.0.1:
|
||||
resolution:
|
||||
{ integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== }
|
||||
engines: { node: '>=0.10.0' }
|
||||
dev: false
|
||||
|
||||
/path-parse@1.0.7:
|
||||
resolution:
|
||||
{ integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== }
|
||||
dev: false
|
||||
|
||||
/prettier@3.3.2:
|
||||
resolution:
|
||||
{ integrity: sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA== }
|
||||
engines: { node: '>=14' }
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/rechoir@0.6.2:
|
||||
resolution:
|
||||
{ integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== }
|
||||
engines: { node: '>= 0.10' }
|
||||
dependencies:
|
||||
resolve: 1.22.8
|
||||
dev: false
|
||||
|
||||
/resolve@1.22.8:
|
||||
resolution:
|
||||
{ integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== }
|
||||
hasBin: true
|
||||
dependencies:
|
||||
is-core-module: 2.14.0
|
||||
path-parse: 1.0.7
|
||||
supports-preserve-symlinks-flag: 1.0.0
|
||||
dev: false
|
||||
|
||||
/shelljs@0.8.5:
|
||||
resolution:
|
||||
{ integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== }
|
||||
engines: { node: '>=4' }
|
||||
hasBin: true
|
||||
dependencies:
|
||||
glob: 7.2.3
|
||||
interpret: 1.4.0
|
||||
rechoir: 0.6.2
|
||||
dev: false
|
||||
|
||||
/supports-preserve-symlinks-flag@1.0.0:
|
||||
resolution:
|
||||
{ integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== }
|
||||
engines: { node: '>= 0.4' }
|
||||
dev: false
|
||||
|
||||
/wrappy@1.0.2:
|
||||
resolution:
|
||||
{ integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== }
|
||||
dev: false
|
155
this
155
this
|
@ -3,6 +3,7 @@
|
|||
const path = require('path');
|
||||
const { Command } = require('commander');
|
||||
const shell = require('shelljs');
|
||||
const util = require('util');
|
||||
|
||||
class This {
|
||||
constructor() {
|
||||
|
@ -60,8 +61,20 @@ class This {
|
|||
}
|
||||
|
||||
start() {
|
||||
// Not implemented, so it needs to be overridden!
|
||||
console.warn(this._echoInYellow(`Method ${this._getCurrentFunctionName()} not implemented!`));
|
||||
/**
|
||||
* @program()
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
execCmd(cmd) {
|
||||
|
@ -102,11 +115,22 @@ class This {
|
|||
|
||||
// Utility function to extract docstring from a function, e.g.
|
||||
//
|
||||
// start() {
|
||||
// /**
|
||||
// * @program()
|
||||
// * @usage([options] [command])
|
||||
// * @option('-d, --debug', 'Enable debug mode')
|
||||
// ..
|
||||
// }
|
||||
//
|
||||
//
|
||||
// echo(str) {
|
||||
// /**
|
||||
// @command
|
||||
// @argument('<message>')
|
||||
// */
|
||||
// * @program()
|
||||
// * @command()
|
||||
// * @argument('<message>')
|
||||
// * @option('-c, --color <name>', 'Prints in color mode')
|
||||
// */
|
||||
// console.log(str);
|
||||
// }
|
||||
//
|
||||
|
@ -128,66 +152,87 @@ class This {
|
|||
}
|
||||
|
||||
// Extract command and arguments
|
||||
const commandMatch = docString.match(/@command(?:\('([^']*)'\))?/);
|
||||
const aliasMatch = docString.match(/@alias\('(.+?)'\)/);
|
||||
const argumentsMatch = /@argument\('(.+?)'\)/g;
|
||||
const optionsMatch = /@option\('(.+?)'\)/g;
|
||||
const defaultMatch = docString.match(/@default/);
|
||||
const executableMatch = docString.match(/@executable\('(.+?)'\)/);
|
||||
const programRegex = /@program\(\)/;
|
||||
const usageRegex = /@usage\('(.+?)'\)/;
|
||||
const commandRegex = /@command(?:\('(.+?)'\))?/;
|
||||
const aliasRegex = /@alias\('(.+?)'\)/;
|
||||
const argumentsRegex = /@argument\('(.+?)'\)/g;
|
||||
const optionsRegex = /@option\('(?<flag>.+?)',\s*'(?<description>.+?)'(?:,\s*'(?<defaultValue>.+?)')?\)/g;
|
||||
const defaultRegex = /@default/;
|
||||
const executableRegex = /@executable\('(.+?)'\)/;
|
||||
|
||||
if (!commandMatch) {
|
||||
// No @command tag found
|
||||
// get regex matches with capture groups
|
||||
const programMatch = docString.match(programRegex);
|
||||
const usageMatch = docString.match(usageRegex);
|
||||
const commandMatch = docString.match(commandRegex);
|
||||
const aliasMatch = docString.match(aliasRegex);
|
||||
const defaultMatch = docString.match(defaultRegex);
|
||||
const executableMatch = docString.match(executableRegex);
|
||||
|
||||
if (!programMatch) {
|
||||
// No @program() tag found
|
||||
return;
|
||||
}
|
||||
|
||||
const commandName = fn.name;
|
||||
const commandDescription = commandMatch ? commandMatch[1] : '';
|
||||
const alias = aliasMatch ? aliasMatch[1] : '';
|
||||
const defaultCommand = defaultMatch ? true : false;
|
||||
const executable = executableMatch ? executableMatch[1] : '';
|
||||
if (commandMatch) {
|
||||
// Generate the commander statement
|
||||
const commandName = fn.name;
|
||||
const commandDescription = commandMatch ? commandMatch[1] : '';
|
||||
const alias = aliasMatch ? aliasMatch[1] : '';
|
||||
const defaultCommand = defaultMatch ? true : false;
|
||||
const executable = executableMatch ? executableMatch[1] : '';
|
||||
|
||||
// Generate the commander statement
|
||||
// Get the function reference
|
||||
const func = this[commandName].bind(this);
|
||||
// Get the function reference
|
||||
const func = this[commandName].bind(this);
|
||||
|
||||
// Create a command
|
||||
// When `.command()` is invoked with a description argument,
|
||||
// this tells Commander that you're going to use a stand-alone executable for the subcommand.
|
||||
let command;
|
||||
if (commandDescription) {
|
||||
command = this.program.command(commandName, commandDescription, {
|
||||
isDefault: defaultCommand,
|
||||
executableFile: executable,
|
||||
});
|
||||
// Create a command
|
||||
// See https://github.com/tj/commander.js?tab=readme-ov-file#quick-start
|
||||
// When `.command()` is invoked with a description argument,
|
||||
// this tells Commander that you're going to use a stand-alone executable for the subcommand.
|
||||
let command;
|
||||
if (commandDescription) {
|
||||
// build stand-alone command
|
||||
command = this.program.command(commandName, commandDescription, {
|
||||
isDefault: defaultCommand,
|
||||
executableFile: executable,
|
||||
});
|
||||
|
||||
if (alias) {
|
||||
command.alias(alias);
|
||||
if (alias) {
|
||||
command.alias(alias);
|
||||
}
|
||||
} else {
|
||||
// build command with function name as action
|
||||
command = this.program.command(commandName, { isDefault: defaultCommand });
|
||||
|
||||
// Set the action for the command
|
||||
command.action((arg) => {
|
||||
func(arg);
|
||||
});
|
||||
}
|
||||
|
||||
// If the commandName expects arguments, we add them here
|
||||
(docString.match(argumentsRegex) || [])
|
||||
.map((e) => e.replace(argumentsRegex, '$1'))
|
||||
.forEach((arg) => {
|
||||
command.argument(arg);
|
||||
});
|
||||
|
||||
// If the commandName expects options, we add them here
|
||||
// See https://github.com/tj/commander.js?tab=readme-ov-file#options
|
||||
for (const match of docString.matchAll(optionsRegex)) {
|
||||
command.option(match.groups['flag'], match.groups['description'], match.groups['defaultValue']);
|
||||
}
|
||||
} else {
|
||||
command = this.program.command(commandName, { isDefault: defaultCommand });
|
||||
// Add usage
|
||||
if (usageMatch) {
|
||||
this.program.usage(usageMatch[1]);
|
||||
}
|
||||
|
||||
// Set the action for the command
|
||||
command.action((arg) => {
|
||||
func(arg);
|
||||
});
|
||||
}
|
||||
|
||||
// If the commandName expects arguments, we add them here
|
||||
let argMatch;
|
||||
while ((argMatch = argumentsMatch.exec(docString)) !== null) {
|
||||
command.argument(argMatch[1]);
|
||||
}
|
||||
|
||||
// If the commandName expects options, we add them here
|
||||
let optMatch;
|
||||
while ((optMatch = optionsMatch.exec(docString)) !== null) {
|
||||
command.option(optMatch[1]);
|
||||
}
|
||||
}
|
||||
|
||||
_addMethodsToClass(cls, metadata) {
|
||||
if (cls) {
|
||||
cls.commands.push(metadata);
|
||||
// If the program expects options, we add them here
|
||||
// See https://github.com/tj/commander.js?tab=readme-ov-file#options
|
||||
for (const match of docString.matchAll(optionsRegex)) {
|
||||
this.program.option(match.groups['flag'], match.groups['description'], match.groups['defaultValue']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user