diff --git a/packages/core/cli.js b/packages/core/cli.js index 67d51425fe7..04ef1a791e1 100755 --- a/packages/core/cli.js +++ b/packages/core/cli.js @@ -42,22 +42,40 @@ listeners.forEach(listener => process.removeListener("warning", listener)); const inputStrings = process.argv.slice(2); -const userWantsGeneralHelp = - inputStrings.length === 0 || - (inputStrings.length === 1 && ["help", "--help"].includes(inputStrings[0])); - -if (userWantsGeneralHelp) { - const { displayGeneralHelp } = require("./lib/command-utils"); - displayGeneralHelp(); - process.exit(0); -} - const { getCommand, prepareOptions, - runCommand + runCommand, + displayGeneralHelp } = require("./lib/command-utils"); +//User only enter truffle with no commands, let's show them what's available. +if (inputStrings.length === 0) { + displayGeneralHelp(); + process.exit(); +} + +//if `help` or `--help` is in the command, validate and transform the input argument for help +if ( + inputStrings.some(inputString => ["help", "--help"].includes(inputString)) +) { + //when user wants general help + if (inputStrings.length === 1) { + displayGeneralHelp(); + process.exit(); + } + + //check where is --help used, mutate argument into a proper help command + const helpIndex = inputStrings.indexOf("--help"); + + if (helpIndex !== -1) { + //remove `--help` from array + inputStrings.splice(helpIndex, 1); + //insert `help` in first position + inputStrings.unshift("help"); + } +} + const command = getCommand({ inputStrings, options: {}, @@ -67,7 +85,9 @@ const command = getCommand({ //getCommand() will return null if a command not recognized by truffle is used. if (command === null) { console.log( - `\`truffle ${inputStrings}\` is not a valid truffle command. Please see \`truffle help\` for available commands.` + `\`truffle ${inputStrings.join( + " " + )}\` is not a valid truffle command. Please see \`truffle help\` for available commands.` ); process.exit(1); } diff --git a/packages/core/lib/command-utils.js b/packages/core/lib/command-utils.js index 30cc45ae7a3..2941dd74046 100644 --- a/packages/core/lib/command-utils.js +++ b/packages/core/lib/command-utils.js @@ -93,8 +93,10 @@ const prepareOptions = ({ command, inputStrings, options }) => { const yargs = require("yargs/yargs")(); yargs .command(require(`./commands/${command.name}/meta`)) - //Turn off yargs' default behavior when handling "truffle --version" - .version(false); + //Turn off yargs' default behavior when handling `truffle --version` & `truffle --help` + .version(false) + .help(false); + const commandOptions = yargs.parse(inputStrings); // remove the task name itself put there by yargs diff --git a/packages/core/lib/commands/db/run.js b/packages/core/lib/commands/db/run.js index 9f4880e6948..74dca2135f3 100644 --- a/packages/core/lib/commands/db/run.js +++ b/packages/core/lib/commands/db/run.js @@ -13,6 +13,6 @@ module.exports = async function (args) { break; default: - console.log(`Unknown command: ${subCommand}`); + console.log(`Unknown truffle db command: ${subCommand}`); } }; diff --git a/packages/core/lib/commands/help/displayCommandHelp.js b/packages/core/lib/commands/help/displayCommandHelp.js index 0d3abeb00ff..e0ab4837cae 100644 --- a/packages/core/lib/commands/help/displayCommandHelp.js +++ b/packages/core/lib/commands/help/displayCommandHelp.js @@ -1,12 +1,20 @@ module.exports = async function (selectedCommand, subCommand, options) { const commands = require("../index"); const globalCommandOptions = require("../../global-command-options"); + const TruffleError = require("@truffle/error"); let commandHelp, commandDescription; + const inputStrings = process.argv.slice(2); + const chosenCommand = commands[selectedCommand].meta; - if (subCommand && chosenCommand.subCommands[subCommand]) { + if (subCommand) { + if (!chosenCommand.subCommands || !chosenCommand.subCommands[subCommand]) { + throw new TruffleError( + `"truffle ${inputStrings.join(" ")}" is an invalid command` + ); + } commandHelp = chosenCommand.subCommands[subCommand].help; commandDescription = chosenCommand.subCommands[subCommand].description; } else { diff --git a/packages/core/lib/commands/help/meta.js b/packages/core/lib/commands/help/meta.js index 9f3d51dc979..af10cf33f9a 100644 --- a/packages/core/lib/commands/help/meta.js +++ b/packages/core/lib/commands/help/meta.js @@ -3,7 +3,7 @@ module.exports = { description: "List all commands or provide information about a specific command", help: { - usage: "truffle help []", + usage: "truffle help [ []]", options: [ { option: "", diff --git a/packages/core/package.json b/packages/core/package.json index ce33f58ce33..cc243105ff7 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -35,6 +35,7 @@ "@truffle/debugger": "^11.0.22", "@truffle/decoder": "^5.3.5", "@truffle/deployer": "^3.3.2", + "@truffle/db-loader": "^0.2.10", "@truffle/environment": "^0.2.135", "@truffle/error": "^0.2.0", "@truffle/expect": "^0.1.4", @@ -69,6 +70,7 @@ "get-random-values": "^1.2.2", "glob": "^7.1.6", "inquirer": "8.2.2", + "iter-tools": "^7.5.0", "js-interpreter": "2.2.0", "lodash": "^4.17.21", "mocha": "10.1.0", @@ -82,6 +84,7 @@ "universal-analytics": "^0.4.17", "web3": "1.8.1", "web3-utils": "1.8.1", + "uuid": "^9.0.0", "xregexp": "^4.2.4", "yargs": "^13.3.0" }, @@ -103,4 +106,4 @@ } ], "namespace": "consensys" -} +} \ No newline at end of file diff --git a/packages/truffle/test/scenarios/commands/help.js b/packages/truffle/test/scenarios/commands/help.js index 6063d1714bb..813c59f97f0 100644 --- a/packages/truffle/test/scenarios/commands/help.js +++ b/packages/truffle/test/scenarios/commands/help.js @@ -42,5 +42,37 @@ describe("truffle help [ @standalone ]", function () { ); assert(output.includes("--environment")); }); + + it("displays help for the `help` command", async function () { + await CommandRunner.run("help help", config); + const output = logger.contents(); + assert( + output.includes( + " Description: List all commands or provide information about a specific command" + ) + ); + }).timeout(20000); + + it("displays help for given command when `--help` is at final position of the command line", async function () { + await CommandRunner.run("compile --help", config); + const output = logger.contents(); + assert(output.includes("Description: Compile contract source files")); + }).timeout(20000); + + it("displays help for given command when `--help` is at first position of the command line", async function () { + await CommandRunner.run("--help db serve", config); + const output = logger.contents(); + assert( + output.includes("Description: Start Truffle's GraphQL UI playground") + ); + }).timeout(20000); + + it("displays help for given command when `--help` is in the middle of the command line", async function () { + await CommandRunner.run("db --help serve", config); + const output = logger.contents(); + assert( + output.includes("Description: Start Truffle's GraphQL UI playground") + ); + }).timeout(20000); }); }); diff --git a/yarn.lock b/yarn.lock index c2611d55bdb..6b5cfec389c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16659,6 +16659,13 @@ iter-tools@^7.0.2: dependencies: "@babel/runtime" "^7.12.1" +iter-tools@^7.5.0: + version "7.5.0" + resolved "https://registry.yarnpkg.com/iter-tools/-/iter-tools-7.5.0.tgz#061240dcac13668e66bb787b0fcd407a58ea39ab" + integrity sha512-L0p/RG3Hwk1urilryDKqU8pQ1t5AaaMc7CHmiwJD/uh63Lv7VyjNng/esstf+Tct1587IpetpcDFdufz8sG+sQ== + dependencies: + "@babel/runtime" "^7.12.1" + iterate-iterator@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.1.tgz#1693a768c1ddd79c969051459453f082fe82e9f6"