nadesiko3
Version:
Japanese Programming Language
167 lines (163 loc) • 3.99 kB
text/typescript
// commander_ja.mts
const CommanderJa: {[key: string]: any} = {
args: /** @type {string[]} */([]),
_alias: /** @type {Record<string, string>} */({}),
_hasarg: /** @type {Record<string, boolean>} */({}),
_help: /** @type {[string, string][]} */([]),
_usage: '',
_version: '1.0.0',
_title: '',
reset: function () {
this.args = []
this._alias = {}
this._hasarg = {}
this._help = []
this._usage = ''
this._version = '1.0.0'
this._title = ''
this.option('-h, --help', '使い方を表示する')
},
/**
* set version info
* @param {*} ver version info
* @param {*} cmd -v, --version
*/
version (ver: string, cmd: string) {
this.option(cmd, 'バージョン情報を表示')
this._version = ver
return this
},
/**
* @param {string} title
*/
title (title: string) {
this._title = title
return this
},
/**
* @param {string} usage
*/
usage (usage: string) {
this._usage = usage
return this
},
/**
* @param {string} cmd
* @param {string} desc
*/
option (cmd: string, desc: string) {
this._help.push([cmd, desc])
let name1 = ''
const name2: any = /** @type {string[]} */([])
const cmdList = cmd.split(',')
cmdList.forEach((t) => {
const c = t.replace(/\s+/, '')
const m = c.match(/^(-+)([a-zA-Z0-9_]+)/)
if (!m) {
throw Error('[Invalid option]: should be -(shortname) --(longname): ' + cmd)
}
if (m[1] === '--') {
name1 = m[2]
return
}
if (m[1] === '-') {
name2.push(m[2])
}
})
if (name1 === '') {
throw Error('Invalid option(no longname): ' + cmd)
}
if (name1 === 'version') { name1 = 'version_' }
this[name1] = false
name2.forEach((t: any) => {
this._alias[t] = name1
})
this._hasarg[name1] = (cmd.indexOf('[') >= 0)
return this
},
/**
* parse and return str
* @param {string[]} argv
* @return {string}
*/
parseStr (argv: string[]): string {
this.args = []
const paramStack: string[] = []
let lastOpt = ''
for (let i = 2; i < argv.length; i++) {
const arg = argv[i]
// Not Options
if (arg.charAt(0) !== '-') {
if (paramStack.length > 0) {
const argParam: string = paramStack.pop() || ''
this[argParam] = arg
continue
}
this.args.push(arg)
continue
}
// Options
if (arg.substring(0, 2) === '--') {
lastOpt = arg.substring(2)
if (lastOpt === 'version') { lastOpt = 'version_' }
} else {
// Short Option
const shortName = arg.substring(1)
if (this._alias[shortName]) {
lastOpt = this._alias[shortName]
} else {
// Not exists
continue
}
}
// set option true
this[lastOpt] = true
if (this._hasarg[lastOpt]) { // has argument?
// init parameter
this[lastOpt] = ''
paramStack.push(lastOpt)
}
}
// show version?
if (this.version_) {
return this._version
}
// show help?
if (this.help) {
return this.getHelp()
}
return ''
},
/**
* parse
* @param {*} argv
*/
parse (argv: any) {
const s = this.parseStr(argv)
if (s === '') {
return this
}
console.log(s)
if (typeof process !== 'undefined') {
process.exit(0)
}
if (typeof (globalThis as any).Deno !== 'undefined') {
(globalThis as any).Deno.exit(0)
}
},
getHelp () {
let ss = ''
if (this._title) {
ss += this._title + '\n'
}
ss += '使い方: ' + this._usage + '\n'
ss += 'オプション:\n'
const spc = ' '
this._help.forEach((c: any) => {
const opt = c[0] + spc
ss += ' ' + opt.substring(0, 20) + ' ' + c[1] + '\n'
})
return ss
}
}
export default CommanderJa