iffy / nim-argparse

Argument parsing for Nim
MIT License
120 stars 8 forks source link

Detect stdin in non-interactive environment. #40

Closed danielecook closed 3 years ago

danielecook commented 4 years ago

I am trying to write a a CLI that can take stdin or read from a file.

Most tools allow this syntax:

# stdin
cat tests/fastq/dup.fq | sc --debug fq-dedup

# alternative stdin with explicit "-" to indicate stdin
cat tests/fastq/dup.fq | sc --debug fq-dedup - 

# specify file directly
sc --debug fq-dedup  tests/fastq/dup.fq

I was able to come up with a workaround to get this to work locally. I use terminal.isatty(stdin) to detect whether input is coming from stdin, but it would be more convenient if argparse could make this distinction.

In other words, is there a way to specify whether stdin is allowed for an argument, and have nim-argparse handle parsing of this or detect stdin?

On a related note, terminal.isatty() does not appear to work in non-interactive environments. Any idea what is going on there?

iffy commented 4 years ago

Thanks for posting this!

I was going to suggest that you could do it as follows, but you're right that - is not allowed as an explicit option.

import argparse

let p = newParser("example"):
  arg("filetoread", default = "-")
  run:
    var fh = if opts.filetoread == "-": stdin else: open(opts.filetoread)
    echo "File size: ", fh.readAll().len

p.run()

You can run it like this:

$ ./example example.nim
File size: 213
$ cat example.nim | ./example
File size: 213
$ cat example.nim | ./example -
...
Error: unhandled exception: unknown option: - [UsageError]

When I get some time, I'll fix that last usage to allow - to be a valid argument value.

On a related note, terminal.isatty() does not appear to work in non-interactive environments. Any idea what is going on there?

I'm not sure about how terminal.isatty() works.

iffy commented 3 years ago

Fixed in v1.0.0