Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add sub-command version #125 #146

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 24 additions & 0 deletions examples/versions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
require('ts-node/register')
const cli = require('../src/index').cac()

cli
.command('build [...files]', 'build files')
.option('--type [type]', 'build type', { default: 'node' })
.option('--target [target]', 'build target')
.action((files, options, type) => {
console.log(files, options)
})
.version('1.0.0')

cli
.command('set [...files]', 'build files')
.option('--type [type]', 'build type', { default: 'node' })
.option('--target [target]', 'build target')
.action((files, options, type) => {
console.log(files, options)
})
.version('1.0.1')

cli.version('1.0.2')
cli.help()
cli.parse()
13 changes: 11 additions & 2 deletions src/CAC.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ class CAC extends EventEmitter {
*/
help(callback?: HelpCallback) {
this.globalCommand.option('-h, --help', 'Display this message')

for (const command of this.commands) {
command.option('-h, --help', 'Display this message')
}

this.globalCommand.helpCallback = callback
this.showHelpOnExit = true
return this
Expand Down Expand Up @@ -140,7 +145,11 @@ class CAC extends EventEmitter {
*
*/
outputVersion() {
this.globalCommand.outputVersion()
if (this.matchedCommand) {
this.matchedCommand.outputVersion()
} else {
this.globalCommand.outputVersion()
}
}

private setParsedInfo(
Expand Down Expand Up @@ -220,7 +229,7 @@ class CAC extends EventEmitter {
this.unsetMatchedCommand()
}

if (this.options.version && this.showVersionOnExit && this.matchedCommandName == null) {
if (this.options.version && this.showVersionOnExit) {
this.outputVersion()
run = false
this.unsetMatchedCommand()
Expand Down
40 changes: 23 additions & 17 deletions src/Command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ class Command {
return this instanceof GlobalCommand
}

get isGlobalOrDefaultCommand(): boolean {
return this.isDefaultCommand || this.isGlobalCommand
}

/**
* Check if an option is registered in this command
* @param name Option name
Expand All @@ -132,15 +136,11 @@ class Command {

outputHelp() {
const { name, commands } = this.cli
const {
versionNumber,
options: globalOptions,
helpCallback,
} = this.cli.globalCommand
const { options: globalOptions, helpCallback } = this.cli.globalCommand

let sections: HelpSection[] = [
{
body: `${name}${versionNumber ? `/${versionNumber}` : ''}`,
body: this.getVersionOutput(),
},
]

Expand All @@ -149,8 +149,7 @@ class Command {
body: ` $ ${name} ${this.usageText || this.rawName}`,
})

const showCommands =
(this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0
const showCommands = this.isGlobalOrDefaultCommand && commands.length > 0

if (showCommands) {
const longestCommandName = findLongest(
Expand Down Expand Up @@ -180,12 +179,9 @@ class Command {
})
}

let options = this.isGlobalCommand
let options = this.isGlobalOrDefaultCommand
? globalOptions
: [...this.options, ...(globalOptions || [])]
if (!this.isGlobalCommand && !this.isDefaultCommand) {
options = options.filter((option) => option.name !== 'version')
}
: [...this.options]
if (options.length > 0) {
const longestOptionName = findLongest(
options.map((option) => option.rawName)
Expand Down Expand Up @@ -235,11 +231,21 @@ class Command {
)
}

outputVersion() {
private getVersionOutput(): string {
const { name } = this.cli
const { versionNumber } = this.cli.globalCommand
if (versionNumber) {
console.log(`${name}/${versionNumber} ${platformInfo}`)
const commandVersion = this.versionNumber
const globalVersion = this.cli.globalCommand.versionNumber

if (!this.isGlobalOrDefaultCommand && commandVersion) {
return `${name} ${this.name}/${commandVersion} ${platformInfo}`
} else {
return `${name}/${globalVersion} ${platformInfo}`
}
}
outputVersion() {
const versionText = this.getVersionOutput()
if (versionText) {
console.log(versionText)
}
}

Expand Down
31 changes: 31 additions & 0 deletions src/__test__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,34 @@ describe('--version in help message', () => {
expect(output).toContain(`--version`)
})
})

describe('cli version and sub-command version', () => {
test('global command version', async () => {
const output = await getOutput('versions.js', ['-v'])
expect(output).toContain('1.0.2')
})

test('sub command version', async () => {
const output1 = await getOutput('versions.js', ['build', '-v'])
expect(output1).toContain('1.0.0')

const output2 = await getOutput('versions.js', ['set', '-v'])
expect(output2).toContain('1.0.1')

//help message
const output_help = await getOutput('versions.js', ['set', '--help'])
expect(output_help).toContain('--version')
})

test('without sub-command version', async () => {
const default_command_output = await getOutput('help.js', ['-v'])
expect(default_command_output).toContain('0.0.0')

const sub_command_output = await getOutput('help.js', ['lint', '-v'])
expect(sub_command_output).toEqual(default_command_output) // fall back to default

//help message
const sub_command_help = await getOutput('help.js', ['lint', '-h'])
expect(sub_command_help).not.toContain('--version')
})
})