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

fix #271 - give feedback for unrecognized commands #308

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"chalk": "^2.3.0",
"cli-table": "^0.3.1",
"commander": "^2.17.1",
"fuzzaldrin": "^2.1.0",
"date-fns": "^1.29.0",
"glob": "^7.1.2",
"inquirer": "^6.2.0",
Expand Down
21 changes: 21 additions & 0 deletions packages/cli/src/api/__snapshots__/utils.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`fuzzValidateCommand should return command is invalid if no commands are configured 1`] = `lingui: command compile is not a lingui command. See 'lingui --help' for the list of available commands.`;

exports[`fuzzValidateCommand should return empty string if user passes no command 1`] = `undefined`;

exports[`fuzzValidateCommand should return suggestions for mispelled 1`] = `
lingui: command compilesss is not a lingui command. See 'lingui --help' for the list of available commands.

Did you mean: compile?
`;

exports[`helpMisspelledCommand - show help for misspelled commands should return command is invalid if no commands are configured 1`] = `lingui: command compile is not a lingui command. See 'lingui --help' for the list of available commands.`;

exports[`helpMisspelledCommand - show help for misspelled commands should return suggestions for mispelled 1`] = `
lingui: command compilesss is not a lingui command. See 'lingui --help' for the list of available commands.

Did you mean: compile?
`;

exports[`helpMisspelledCommand - show help for misspelled commands shouldn't output anything if user passes no command 1`] = `undefined`;
38 changes: 38 additions & 0 deletions packages/cli/src/api/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import fs from "fs"
import path from "path"
import chalk from "chalk"
import { score } from "fuzzaldrin"

export function removeDirectory(dir, keep = false) {
if (!fs.existsSync(dir)) return
Expand Down Expand Up @@ -33,6 +34,43 @@ export function prettyOrigin(origins) {
}
}

/**
* .. js:function:: helpMisspelledCommand(command [, availableCommands = []])
* :param: command - command passed to CLI
* :param: availableCommands - all commands defined in commander.js
*
* If unknown commands is passed to CLI, check it agains all available commands
* for possible misspelled letter. Output help with suggestions to console.
*/
export function helpMisspelledCommand(command, availableCommands = []) {
const commandNames = availableCommands.map(command => command.name())

// if no command is supplied, then commander.js shows help automatically
if (!command || commandNames.includes(command)) {
return
}

const suggestions = commandNames
.map(name => ({
name,
score: score(name, command.slice(0, name.length))
}))
.filter(nameScore => nameScore.score > 0)
.slice(0, 3)
.map(commandScore => chalk.inverse(commandScore.name))
.join(", ")

console.log(
`lingui: command ${command} is not a lingui command. ` +
`See 'lingui --help' for the list of available commands.`
)

if (suggestions) {
console.log()
console.log(`Did you mean: ${suggestions}?`)
}
}

export const splitOrigin = origin => origin.split(":")

export const joinOrigin = origin => origin.join(":")
44 changes: 44 additions & 0 deletions packages/cli/src/api/utils.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { helpMisspelledCommand } from "./utils"
import { mockConsole } from "../mocks"

function getConsoleMockCalls({ mock }) {
if (!mock.calls.length) return
return mock.calls.map(call => call[0]).join("\n")
}

describe("helpMisspelledCommand - show help for misspelled commands", function() {
function mockCommands(command, commandNames) {
return helpMisspelledCommand(
command,
commandNames.map(commandName => ({ name: () => commandName }))
)
}

it("shouldn't output anything if command is valid", function() {
mockConsole(console => {
mockCommands("compile", ["compile"])
expect(getConsoleMockCalls(console.log)).toBeUndefined()
})
})

it("shouldn't output anything if user passes no command", function() {
mockConsole(console => {
mockCommands("", ["compile"])
expect(getConsoleMockCalls(console.log)).toMatchSnapshot()
})
})

it("should return command is invalid if no commands are configured", function() {
mockConsole(console => {
mockCommands("compile", [])
expect(getConsoleMockCalls(console.log)).toMatchSnapshot()
})
})

it("should return suggestions for mispelled", function() {
mockConsole(console => {
mockCommands("compilesss", ["compile"])
expect(getConsoleMockCalls(console.log)).toMatchSnapshot()
})
})
})
4 changes: 4 additions & 0 deletions packages/cli/src/lingui.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/usr/bin/env node

import { helpMisspelledCommand } from "./api/utils"

const program = require("commander")

let version
Expand All @@ -19,3 +21,5 @@ program
.command("extract [files...]", "Extracts messages from source files")
.command("compile", "Compile message catalogs")
.parse(process.argv)

helpMisspelledCommand(process.argv[2], program.commands)
4 changes: 4 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2717,6 +2717,10 @@ functional-red-black-tree@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"

fuzzaldrin@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fuzzaldrin/-/fuzzaldrin-2.1.0.tgz#90204c3e2fdaa6941bb28d16645d418063a90e9b"

gauge@~2.7.3:
version "2.7.4"
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
Expand Down