Comments (10)
I think I'll close this without implementing the other features, as it keeps things simple.
from kong.
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.
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.
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.
"/dev/stdin"
doesn't work on Windows though.
from kong.
Would "conIN$" work on windows? (I don't have a Windows machine handy to try it out)
from kong.
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.
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:
- Don't treat
-
as an error, just pass it through as a value to a flag or arg. - If a "file" type (eg.
type:"existingfile"
) encounters a-
map it to the system's /dev/stdin. - (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.
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.
Thanks!
from kong.
Related Issues (20)
- type `filecontent` not read file HOT 1
- print version info with usage
- Ambiguity in understanding whether Value.Set is set from default or explicit
- Counter incorrectly renders value in help HOT 2
- Switching command based on os.Args[0] HOT 2
- Is there any way to achieve this: --version is not inherited to subcommands? HOT 2
- NamedMapper doesn't take precedence over KindMapper HOT 2
- description newline stripping HOT 2
- Flag hook executed multiple times HOT 4
- Improving slice and map support
- BoolMapper is not triggered for custom type with IsBool() func HOT 1
- Drop automatic prefix in error messages returned by `Run()`? HOT 2
- Env Var Default value for flag sourced from a Plugin HOT 3
- Support For Stdin Flags HOT 1
- Not possible to pass an empty value to a flag with environment variable HOT 1
- Custom validators do not run for envars
- Custom validator does not run for nested structs HOT 1
- shell/help example panics HOT 2
- Dependency Dashboard
- Multiple commands sharing the same positional arguments HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from kong.