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

A clean way to get pass through arguments? #1293

Closed
teststaybaka opened this issue Jul 4, 2020 · 7 comments
Closed

A clean way to get pass through arguments? #1293

teststaybaka opened this issue Jul 4, 2020 · 7 comments

Comments

@teststaybaka
Copy link

Hi, I'm writing a simple CLI tool that triggers the execution of another JS file which also takes command line arguments, but I couldn't figure out a clean way to get pass-through arguments. A short snipet written in TypeScript is shown below.

import { Command } from "commander";
let program = new Command();
program
  .command("run <file>")
  .action(
    (file, options): void => {
      new Builder().build();
      console.log(file);
      console.log(options);
      spawnSync("node", [file, ...options.args], {
        stdio: "inherit",
      });
    });
program.parse();

Then when I execute the CLI as cli run executable.js -- --test-flag, it doesnt' work because options.args contains [ 'executable.js', '--test-flag' ], which seems to match the document though:

leaving any args not consumed by the program options in the program.args array.

Is there a better way to get an array of pass-through arguments, which excludes <file> and other potential positional arguments? Thanks!

@shadowspawn
Copy link
Collaborator

shadowspawn commented Jul 4, 2020

1/3: I think what you have might work if you just remove file from the spawn arguments since it is also included in args like:

spawnSync("node", options.args, {
        stdio: "inherit",
      });

@shadowspawn
Copy link
Collaborator

shadowspawn commented Jul 4, 2020

2/3: The extra arguments actually get passed to the action handler too. (Currently undocumented, as I am not sure it is useful enough!)

const { Command } = require("commander");
let program = new Command();
program
  .command("run <file>")
  .action(
    (file, options, extraArgs) => {
      console.log(file);
      console.log(extraArgs);
    });
program.parse();

@shadowspawn
Copy link
Collaborator

shadowspawn commented Jul 4, 2020

3/3: But my preferred approach is to make it explicit as part of the command so it appears in the help too, like:

const { Command } = require("commander");
let program = new Command();
program
  .command("run <file> [args...]")
  .action(
    (file, args, options) => {
      console.log(file);
      console.log(args);
    });
program.parse();

@teststaybaka
Copy link
Author

Thanks for the quick response.

  1. I actually want to do some processing to the file name and I guess people could define more positional arguments.
  2. I feel this is the best solution.
  3. [args...] doesn't work if I need to pass through undefined options. I.e., cli run executable.js --test-flag complains "error: unknown option '--test-flag'". I want to pass through any unknown options, so I couldn't define them ahead of time. I guess we could configure somehow to ignore unknown options but I'm not sure it'd be better than 2).

@shadowspawn
Copy link
Collaborator

cli run executable.js --test-flag complains "error: unknown option '--test-flag'"

This is the same behaviour with all three approaches. You still need the -- to stop the option processing. (Or turn on .allowUnknownOptions().)

Like you had in your original post:

cli run executable.js -- --test-flag

@teststaybaka
Copy link
Author

teststaybaka commented Jul 4, 2020

I see. I'm actually really surprised that [args...] would capture arguments even after --. Thansks for the help!

@shadowspawn
Copy link
Collaborator

Pull Request opened to add .enablePositionalOptions() and .passThroughOptions(): #1427

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

No branches or pull requests

2 participants