Skip to content

Commit

Permalink
Dynamic help text from command options
Browse files Browse the repository at this point in the history
  • Loading branch information
ianthomas23 committed May 21, 2024
1 parent 3310a41 commit 720c7d1
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 18 deletions.
6 changes: 3 additions & 3 deletions src/commands/ls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { BooleanOption } from "../option"
import { Options } from "../options"

class LsOptions extends Options {
commaSeparated = new BooleanOption("m")
long = new BooleanOption("l")
reverse = new BooleanOption("r")
commaSeparated = new BooleanOption("m", "", "List files across the page, separated by commas.")
long = new BooleanOption("l", "", "List files in long format.")
reverse = new BooleanOption("r", "", "Reverse the order of the sort.")
}

export class LsCommand extends Command<LsOptions> {
Expand Down
10 changes: 7 additions & 3 deletions src/option.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
export abstract class Option {
constructor(readonly shortName: string) {}
constructor(
readonly shortName: string,
readonly longName: string,
readonly description: string,
) {}

get isSet(): boolean {
return this._isSet
Expand All @@ -13,7 +17,7 @@ export abstract class Option {
}

export class BooleanOption extends Option {
constructor(shortName: string) {
super(shortName)
constructor(shortName: string, longName: string, description: string) {
super(shortName, longName, description)
}
}
32 changes: 20 additions & 12 deletions src/options.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import { Option } from "./option"

export abstract class Options {
private static _findByShortName<T extends Options>(options: T, shortName: string): Option {
static fromArgs<T extends Options>(args: string[], optionsType: (new () => T)): T {
const options = new optionsType
for (const arg of args) {
if (arg[0] == "-") {
const shortName = arg[1]
options._findByShortName(shortName).set()
}
}
return options
}

private _findByShortName<T extends Options>(shortName: string): Option {
let v: Option
for (v of Object.values(options)) {
for (v of Object.values(this)) {
if (v.shortName == shortName) {
return v
}
Expand All @@ -12,15 +23,12 @@ export abstract class Options {
throw new Error(`No such shortName option "${shortName}"`)
}

static fromArgs<T extends Options>(args: string[], optionsType: (new () => T)): T {
const options = new optionsType
for (const arg of args) {
if (arg[0] == "-") {
const shortName = arg[1]
this._findByShortName(options, shortName).set()
}
}

return options
_help(): string[] {
// Dynamically create help text from options.
// Could have short form for usage, and longer form for man page.
const sorted = [...Object.values(this)].sort(
(a, b) => (a.shortName ?? a.longName) > (b.shortName ?? b.longName) ? 1 : -1
)
return sorted.map((option) => `-${option.shortName} ${option.description}`)
}
}

0 comments on commit 720c7d1

Please sign in to comment.