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

required flags prevent subcommand --help; raise cryptic error #101

Closed
cspotcode opened this issue Aug 27, 2021 · 4 comments · Fixed by #128
Closed

required flags prevent subcommand --help; raise cryptic error #101

cspotcode opened this issue Aug 27, 2021 · 4 comments · Fixed by #128

Comments

@cspotcode
Copy link

cspotcode commented Aug 27, 2021

Reproduction: https://replit.com/@AndrewBradley/clipanion-repro (clicking "run" is not wired up, but the code is in "index.ts" and the shell can be used to run node ./dist/index.js)

When a subcommand foo has a required option --bar, and I try to run mycli foo --help I get a cryptic error:

~/clipanion-repro$ node ./dist/index.js foo --help
Unknown Syntax Error: Command not found; did you mean:

$ ... foo <--bar #0>
While running foo --help
~/clipanion-repro$ 

I get the same error when I try to run mycli foo. In the former case, with --help, I want to see help output about the command. In the latter, instead of the cryptic error, it would be ideal for the error to specifically mention that --bar is missing, but not to suggest that the foo command is unrecognized.


// index.ts
#!/usr/bin/env node

import { Command, Cli, Builtins, Usage, Option } from 'clipanion';
import { isEnum } from 'typanion';

const envs = ['qa', 'stage', 'prod'] as const;
const envOption = Option.String('--bar', {
    required: true,
    description: 'bar option',
    validator: isEnum(envs)
});

async function main() {
    const cli = new Cli();
    cli.register(Builtins.VersionCommand);
    cli.register(Builtins.HelpCommand);
    cli.register(FooCommand);
    await cli.runExit(process.argv.slice(2), Cli.defaultContext);
}

class FooCommand extends Command {
    static paths = [['foo']];
    static usage: Usage = {
        description: `
            foo stuff
        `
    }

    env = envOption;

    async execute() {}
}


main();
@seansfkelley
Copy link

This is actually stranger yet, and seems to have something to do with the name of the flags and not merely that they are required. I've triple-checked this because it's really so strange, so I don't think I'm crazy.

import { Option, Cli, Command } from "clipanion";

async function main() {
  const cli = new Cli();

  cli.register(FailingCommand);
  cli.register(SucceedingCommand);

  try {
    const command = cli.process(process.argv.slice(2));
    await cli.runExit(command, {
      stdin: process.stdin,
      stdout: process.stdout,
      stderr: process.stderr,
    });
  } catch (error) {
    process.stdout.write(cli.error(error));
    process.exitCode = 1;
  }
}

class FailingCommand extends Command {
  static paths = [["fail"]];

  flag = Option.String("-f", {
    required: true,
  });

  async execute() {}
}

class SucceedingCommand extends Command {
  static paths = [["succeed"]];

  flag = Option.String("-c", {
    required: true,
  });

  async execute() {}
}

main();

And if I run it...

> yarn ts-node cli.ts fail -h
Unknown Syntax Error: Command not found; did you mean:

$ ... fail <-f #0>
While running fail -h

> yarn ts-node cli.ts succeed -h
$ ... succeed <-c #0>

Notice that the only difference in the commands, aside from their paths, is the specific character chosen for the flag.

If I change the flag in SucceedingCommand to something else like -d or -e, it also fails. Why would -c be significant?

@cptpackrat
Copy link
Contributor

If I change the flag in SucceedingCommand to something else like -d or -e, it also fails. Why would -c be significant?

Might be related to this?

for (const opt of state.options) {
switch (opt.name) {
case `-c`: {
command.commands.push(Number(opt.value));
} break;
case `-i`: {
command.index = Number(opt.value);
} break;
}
}

I haven't really looked into how the help built-in works, but it looks like -c and -i are important to it.

@magicdawn
Copy link

and if you add Command.Default to static paths.
then run cli -h, this prints help message instead of Unknown Syntax Error: Command not found; did you mean:

@jakub-g
Copy link
Contributor

jakub-g commented Oct 19, 2022

Note: This is now fixed via https://github.com/arcanis/clipanion/pull/128/files for --help explicit case, but when just running the command without any params and you have a required param like name = Option.String('--name', { required: true }); it still shows the cryptic error.

yarn cli foo       
Unknown Syntax Error: Command not found; did you mean:

$ yarn cli foo <--name #0>
While running foo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants