index.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. "use strict";
  2. const dedent = require("dedent");
  3. const log = require("npmlog");
  4. const yargs = require("yargs/yargs");
  5. const { globalOptions } = require("@lerna/global-options");
  6. module.exports = lernaCLI;
  7. /**
  8. * A factory that returns a yargs() instance configured with everything except commands.
  9. * Chain .parse() from this method to invoke.
  10. *
  11. * @param {Array = []} argv
  12. * @param {String = process.cwd()} cwd
  13. */
  14. function lernaCLI(argv, cwd) {
  15. const cli = yargs(argv, cwd);
  16. return globalOptions(cli)
  17. .usage("Usage: $0 <command> [options]")
  18. .demandCommand(1, "A command is required. Pass --help to see all available commands and options.")
  19. .recommendCommands()
  20. .strict()
  21. .fail((msg, err) => {
  22. // certain yargs validations throw strings :P
  23. const actual = err || new Error(msg);
  24. // ValidationErrors are already logged, as are package errors
  25. if (actual.name !== "ValidationError" && !actual.pkg) {
  26. // the recommendCommands() message is too terse
  27. if (/Did you mean/.test(actual.message)) {
  28. log.error("lerna", `Unknown command "${cli.parsed.argv._[0]}"`);
  29. }
  30. log.error("lerna", actual.message);
  31. }
  32. // exit non-zero so the CLI can be usefully chained
  33. cli.exit(actual.exitCode > 0 ? actual.exitCode : 1, actual);
  34. })
  35. .alias("h", "help")
  36. .alias("v", "version")
  37. .wrap(cli.terminalWidth()).epilogue(dedent`
  38. When a command fails, all logs are written to lerna-debug.log in the current working directory.
  39. For more information, find our manual at https://github.com/lerna/lerna
  40. `);
  41. }