0

Before people start crying "duplicate", I've already examined

The first of these is basically the same question in a different use case and as a result the answers do not address my use case.

So... how do you encode a command line like the following with named parameters separated from their values by a space?

arduino-cli compile --fqbn arduino:avr:nano

Should it look like this (1)?

let cp = child.process(
  "/path/to/arduino-cli.exe", 
  [
    "compile", 
    "--fqbn arduino:avr:nano"
  ]
);

or this (2)?

let cp = child.process(
  "/path/to/arduino-cli.exe", 
  [
    "compile", 
    "--fqbn", 
    "arduino:avr:nano"
  ]
);

or this (3)?

let cp = child.process(
  "/path/to/arduino-cli.exe", 
  [
    "compile", 
    "fqbn", 
    "arduino:avr:nano"
  ]
);

or this (4)?

let cp = child.process(
  "/path/to/arduino-cli.exe", 
  {
    _: ["compile"],
    fqbn: "arduino:avr:nano"
  }
);

TypeScript won't allow the last option even though I suspect it is the right answer, so I submit the problem for wider consideration.

Peter Wone
  • 17,965
  • 12
  • 82
  • 134
  • The second one looks right to me. The arguments are supposed to be an array of strings, one argument per array element so the third one is the wrong format (which is why TypeScript won't allow it). The first one has more than one argument in one array element. – jfriend00 Oct 08 '20 at 00:52
  • The thing is, it's a named argument. Also, none of them work. I'm just now redoing the tests in case I screwed up. – Peter Wone Oct 08 '20 at 01:05
  • Make a little test app that just logs what arguments it is passed and then experiment with different ways to pass the arguments when spawning that test app. – jfriend00 Oct 08 '20 at 01:10
  • Also, what OS are you running this on? – jfriend00 Oct 08 '20 at 01:23
  • @jfriend00 What OS? During dev, Win10. However, it is intended to be cross platform. Your question is ominous. Tell me the bad news. – Peter Wone Oct 08 '20 at 04:06
  • I asked because Windows argument handling is different in some ways. See the `windowsVerbatimArguments` option for `spawn()` for evidence of this. Anyway, it looks like you got it figured out. – jfriend00 Oct 08 '20 at 04:30

1 Answers1

2

After setting up for repeatable testing

    let args: any[] = [];
    args.push(["compile", `--fqbn ${selectedBoard.board.fqbn}`]);
    args.push(["compile", "--fqbn", selectedBoard.board.fqbn]);
    args.push(["compile", "fqbn", selectedBoard.board.fqbn]);
    args.push({ _: ["compile"], fqbn: selectedBoard.board.fqbn });
    let cp = child_process.spawn(cliPath, args[1], { cwd: getInoPath() });
    cp.stdout.on("data", (data: any) => outputChannel.append(data.toString()));
    cp.stderr.on("data", (data: any) => outputChannel.append(data.toString()));
    cp.on("error", (err: any) => {
      outputChannel.append(err);
    });

I found that @jfriend00 was right, it is indeed the second arguments version

["compile", "--fqbn", selectedBoard.board.fqbn]

but there was another problem causing it to fail – the CWD needed to be set in the options.

let cp = child_process.spawn(cliPath, args[1], { cwd: getInoPath() });

The key insight here is to capture both error events and stderr. The failure was reported on stderr and no error event was raised. After exposing stderr the problem was quickly resolved.

Peter Wone
  • 17,965
  • 12
  • 82
  • 134