Giter Club home page Giter Club logo

Comments (10)

alecthomas avatar alecthomas commented on May 18, 2024 1

I think I'll close this without implementing the other features, as it keeps things simple.

from kong.

alecthomas avatar alecthomas commented on May 18, 2024

Seems reasonable, how would you expect this to map to a Go struct? Maybe the following?

type CLI struct {
  Input io.Reader `name:"-" arg:""`
}

from kong.

alecthomas avatar alecthomas commented on May 18, 2024

Actually I think a better approach is to add first class support for mapping - to an arg, AND add support for io.Reader, independently. Then if you have:

type CLI struct {
  Input string `arg:""`
}

if the command line encounters - it will read stdin into that field value.

But if you have

type CLI struct {
  Input io.Reader `arg:""`
}

If you do app - It will set the field to os.Stdin. But if you do app "foo bar waz" it will wrap that string in a strings.Reader.

That seems fairly elegant?

from kong.

mkmik avatar mkmik commented on May 18, 2024

I was thinking about something simpler:

"-" would just be as any other string value, i.e. the application will just get "-".

When using type:"path" (and "existingfile") "-" would be recognized and turned into "/dev/stdin"

from kong.

alecthomas avatar alecthomas commented on May 18, 2024

"/dev/stdin" doesn't work on Windows though.

from kong.

mkmik avatar mkmik commented on May 18, 2024

Would "conIN$" work on windows? (I don't have a Windows machine handy to try it out)

from kong.

mkmik avatar mkmik commented on May 18, 2024

If you do app - It will set the field to os.Stdin. But if you do app "foo bar waz" it will wrap that string in a strings.Reader.

That seems fairly elegant?

Sorry, this doesn't resonate with me. If when I invoke app - I expect app to read from stdin, then when I run app "foo bar waz" I expect app to read from a file named foo bar waz.


Let's split this in multiple subproblems:

1: plain string arguments

string with no special filename type mapping should let a lone - pass as an argument value, as other flag parsing libraries do. I think kong should not impose unnecessary restrictions here and thus "get in the way" in whatever the author of the CLI tool wants to do.

I.e. given:

type CLI struct {
  Foo string `arg:"" type:""`
  Bar string
}

and a commandline a b --bar bar c - d,
Foo: []string{"a", "b", "c", "-", "d"} and Bar: "bar"

2: path and existingfile type mappers

Type mappers like path, existingfile try to turn a string into a filename. Those type mappers understand that the arguments are paths and already do things like home directory expansion (~). Those mappers could turn - into a filename that when opened will clone the stdin file descriptor. This feature might not be straightforward (or even possible) to implement on non-unix OSs (e.g. Windows).

3: *os.File

If the user wants to offload to kong not only pathname resolution but also reading the contents of the input files themselves, we could consider accepting a flag with type os.File:

type CLI struct {
  Foo *os.File `arg:""`
}

and

type CLI struct {
  Bar []*os.File `arg:""`
}

One advantage of os.File vs io.Reader, among other things, is that it preserves the filename which might be used by the CLI utility to report meaningful error messages.

In this case an arg value of "-" will just mean os.Stdin (which is an *os.File too).

We could also support io.Reader if the user doesn't want to specify a *os.File. But in this case, I think the user will have to specify something in the type:"..." tag, in order to explicitly ask that the arguments are filenames to be opened. We'd still pass an *os.File (and the user can later do Foo.(*os.File) dynamically).

4: io.Reader

Your suggestion about turning a string literal into a io.Reader reminds me of a common pattern in some utilities (like curl):

type CLI {
  Data io.Reader `type:"dataorfile"`
}
$ app -d foo
got: "foo"
$ echo -n bar >/tmp/file.txt
$ app -d @/tmp/file.txt
got: "bar"

We could support string, []byte or io.Reader, the latter being preferred since it wouldn't load the whole file at once.

from kong.

alecthomas avatar alecthomas commented on May 18, 2024

I think I agree re. strings becoming a strings.Reader, it's a bit confusing.

I can't find any reliable information about whether CONIN$ works or not. If it does, I think the string file types should be okay.

So I think the changes are:

  1. Don't treat - as an error, just pass it through as a value to a flag or arg.
  2. If a "file" type (eg. type:"existingfile") encounters a - map it to the system's /dev/stdin.
  3. (optional) Add support for *os.File, which would implicitly have the same semantics as the file string types, except that it would also open the file.

from kong.

alecthomas avatar alecthomas commented on May 18, 2024

Okay give that a whirl. I did the bare minimum for now; flags and arguments will accept "-" without erroring, and "existingfile" has special case for "-" to just pass it through. The user will have to do consumer useful with it.

from kong.

mkmik avatar mkmik commented on May 18, 2024

Thanks!

from kong.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.