Git Product home page Git Product logo

argparse's People

Contributors

abathargh avatar akamensky avatar alecbakholdin avatar densestvoid avatar drewwalters96 avatar goofinator avatar jaikrishnats avatar jhughes1153 avatar josegonzalez avatar look avatar peterlitszo avatar rsheasby avatar silversoldier avatar thegreyd avatar vsachs avatar zuoxiaofeng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

argparse's Issues

SelectorList flag

We should enable a SelectorList argument type which accepts a list of strings which match the Selector criteria

Question about returned parameters (not a bug report)

Congratulations on porting the ArgParse concept from Python. ArgParse is one of the Python packages that I have used heavily so this was quite welcome to find. If I find any bugs or suggestions for enhancements, I'll write up a separate issue.

  1. Since Parser.X is returning something, why return a pointer to the something? Why not simply return the something itself? Yes, argparse is consistent which is always a good thing.

  2. When will argparse be part of the standard package library? i.e. import argparse without the github references.

Add support for nargs functionality

  1. Take constant or variable number of arguments that follow
  2. Important for optional arguments
  3. Does not make much sense for positional arguments

Provide <META> fields and Author Information in usage string

First of all thanks for the awesome work. I noticed a few discrepancies and usage issues which can make this package better.

  1. Python's argparse provides a metavar field which adds a description, a META field for the argument which is missing from this package. So say if a field is a filename then it would show up as,
  -x  --export      <filename> Export all entries to <filename>

I could not find a way to do that with this package.

  1. Author information - I want to add a copyright plus author email field in my help string which is not possible with this package as it has an exact idea of how a usage string should be like.

I liked your package enough to use it for my project, but since these were missing I have added this in my fork of the package. If these changes make sense feel free to engage me in this issue.

Usage string using default argparse.

$ ./varuh -h
usage: varuh [-h|--help] [-e|--encrypt] [-A|--add] [-p|--path] [-a|--list-all]
             [-s|--show] [-c|--copy] [-v|--version] [-I|--init "<value>"]
             [-d|--decrypt "<value>"] [-C|--clone "<value>"] [-R|--remove
             "<value>"] [-U|--use-db "<value>"] [-f|--find "<value>"]
             [-E|--edit "<value>"] [-l|--list-entry "<value>"] [-x|--export
             "<value>"] [-g|--genpass "<value>"]

             Password manager for the command line for Unix like operating
             systems

Arguments:

  -h  --help        Print help information
  -e  --encrypt     Encrypt the current database
  -A  --add         Add a new entry
  -p  --path        Show current database path
  -a  --list-all    List all entries in current database
  -s  --show        Show passwords when listing entries
  -c  --copy        Copy password to clipboard
  -v  --version     Show version information and exit
  -I  --init        Initialize a new database
  -d  --decrypt     Decrypt password database
  -C  --clone       Clone an entry with <id>
  -R  --remove      Remove an entry with <id>
  -U  --use-db      Set <path> as active database
  -f  --find        Search entries with <term>
  -E  --edit        Edit entry by <id>
  -l  --list-entry  List entry by <id>
  -x  --export      Export all entries to <filename>
  -g  --genpass     Generate password of given <length>

Usage string after my changes,

$ ./varuh -h
usage: varuh [-h|--help] [-I|--init "<value>"] [-d|--decrypt "<value>"]
             [-C|--clone "<value>"] [-R|--remove "<value>"] [-U|--use-db
             "<value>"] [-f|--find "<value>"] [-E|--edit "<value>"]
             [-l|--list-entry "<value>"] [-x|--export "<value>"] [-g|--genpass
             "<value>"] [-e|--encrypt] [-A|--add] [-p|--path] [-a|--list-all]
             [-s|--show] [-c|--copy] [-v|--version]

             Password manager for the command line for Unix like operating
             systems

Options:

  -h  --help                   Print help information
  -I  --init        <path>     Initialize a new database
  -d  --decrypt     <path>     Decrypt password database
  -C  --clone       <id>       Clone an entry with <id>
  -R  --remove      <id>       Remove an entry with <id>
  -U  --use-db      <path>     Set <path> as active database
  -f  --find        <term>     Search entries with <term>
  -E  --edit        <id>       Edit entry by <id>
  -l  --list-entry  <id>       List entry by <id>
  -x  --export      <filename> Export all entries to <filename>
  -g  --genpass     <length>   Generate password of given <length>
  -e  --encrypt                Encrypt the current database
  -A  --add                    Add a new entry
  -p  --path                   Show current database path
  -a  --list-all               List all entries in current database
  -s  --show                   Show passwords when listing entries
  -c  --copy                   Copy password to clipboard
  -v  --version                Show version information and exit


AUTHORS
    Copyright (C) 2021 Anand B Pillai <[email protected]>

subparser not implemented

So, I am trying to follow wyag tutorial. I am trying this with golang. So far so good. I found all equivalent go packages. But the parser in the tutorial uses subparser. I think I can do it without it too, But I noticed it's not implemented here.

Thanks for this package.

Argparse variables as Global variable

  1. Is there a way to set the argparse variables as GLOBAL one. Currently, the scope of argparse variables are confined only to main().
  2. Is there a way to declare it in var ( )?

Handle better newlines in help message

Hello,

I want to add a list to help message, so each item should be on a new line. Now this looks not very good:

      --input          Possible values:
not set - read from stdin;
gs://<path to file gzipped file> - read from
                       GCS;
pubsub://projects/<project>/subscriptions/<subscription> - fetch input value
                       from PubSub

While the original help string looks like:

	Help: "Possible values:\n" +
		"not set - read from stdin;\n" +
		"gs://<path to file gzipped file> - read from GCS;\n" +
		"pubsub://projects/<project>/subscriptions/<subscription> - fetch input value from PubSub"

FlagCounter display unexpectedly

Given a FlagCounter arg definition as following

verboseCounter = parser.FlagCounter("v", "verbose", &argparse.Options{
  Required: false,
  Validate: nil,
  Help:     "",
  Default:  0,
})

the help message displays it in the same style as an Int arg.

 [-v|--verbose <integer>]

however, it can not be used in the same way as an Int arg

-v 1
-v 2
-v 3

instead it should be used in the flag way.

-v
-vv
-vvv

support of equals from cli

It seems like it would be useful to be able to specify --path=/home/path/to/file like you can in the python version of argparse. Currently to get around this one has to specify --path /home/path/to/file with the space and it wont parse if there is an equal sign. It took some time before I realized that I needed to have spaces instead of an equal sign before it would parse it correctly.

Usage(err interface{}) only uses values of type error

Regarding func (*Command) Usage(err interface{}) string, only values of err with types subCommandError and error are used by the function. Because subCommandError is an implementation of error, the argument should really be of type error.

It would be nice if it also accounted for string and fmt.Stringer, but I think documentation should at least note what the supported types are.

Allow parser.ParseKnownArgs(...)

Using your library is nice, but I'd really like to be able to pass through additional arguments so I can wrap scripts and forward args I don't care about to them.

The error returned would then only check that required arguments are there. Setting all others as ignored

Repeated text in sub-command usage text

Thank you for the great library! As a former python argparse user this has helped getting a CLI together for some go work.

Working on a program with two levels of sub-commands I noticed the help info repeats with incorrect/incomplete argument usage. This is the not the case with doing -h on the sub-command.

This does not seem to be the same issue as #5 but might be related?

The command-advanced in examples shows this same behavior:

Repeated:

user@vubuntu:~/code/argparse/examples/commands-advanced$ ./commands-advanced dog
[sub]Command required
usage: zooprog dog <Command> [--wiggle] [-h|--help] --name "<value>"

               We are going to see dog

Commands:

  speak   Make the dog speak
  feed    Make the dog eat
  summon  Make the dog come over
  play    Make the dog play

Arguments:

      --wiggle  Makes the dog to wiggle its tail
  -h  --help    Print help information
      --name    Provide an optional name for the animal

usage: zooprog dog <Command> [--wiggle] [-h|--help] --name "<value>"

               We are going to see dog

Commands:

  speak   Make the dog speak
  feed    Make the dog eat
  summon  Make the dog come over
  play    Make the dog play

Arguments:

      --wiggle  Makes the dog to wiggle its tail
  -h  --help    Print help information
      --name    Provide an optional name for the animal

OK:

user@vubuntu:~/code/argparse/examples/commands-advanced$ ./commands-advanced dog -h
usage: zooprog dog <Command> [--wiggle] [-h|--help] --name "<value>"

               We are going to see dog

Commands:

  speak   Make the dog speak
  feed    Make the dog eat
  summon  Make the dog come over
  play    Make the dog play

Arguments:

      --wiggle  Makes the dog to wiggle its tail
  -h  --help    Print help information
      --name    Provide an optional name for the animal

Validation error messages should go to stderr not stdout

I'm using argparse as part of go-procfile-util, and capturing output of that command. Unfortunately, if flags are passed in, the command will exit non-zero but will have some output, which can be a bit confusing if you expect no output on error (my project doesn't have stdout unless there are no errors).

Would be great if all errors went to stderr instead of stdout.

Error when trying to run example in README.md

The example in README.md gives the following error when I try to run it:

./main.go:23:25: not enough arguments in call to parser.Command.Usage
	have ()
	want (interface {})

After checking the source code, I passed the err variable to parser.Usage, which resulted in the error being printed twice. So, I presume the fmt.Println call is redundant.

Running: go1.10 on Ubuntu 17.10.1 Linux 64-bit.

shorthand argument creation check

If i do some thing like this ("pp" on shorthand argument ):
parser.Int("pp","port",&argparse.Options{Required: false,Default: 10000, Help: "Work in dummy mode"})
there is no error on parser.Parse, and default value became 0. Are long name as shorthand allowed? If no, maybe it should be error value on this situation? If Yes - why default value differs from expectation.

Getting: import cycle not allowed using the example.

package main

import (
"fmt"
"github.com/akamensky/argparse"
"os"
)

func main() {
// Create new parser object
parser := argparse.NewParser("print", "Prints provided string to stdout")
// Create string flag
s := parser.String("s", "string", &argparse.Options{Required: true, Help: "String to print"})
// Parse input
err := parser.Parse(os.Args)
if err != nil {
// In case of error print error and print usage
// This can also be done by passing -h or --help flags
fmt.Print(parser.Usage(err))
}
// Finally print the collected string
fmt.Println(*s)
}

above is the source

go build first_argparse.go
output:
imports github.com/akamensky/argparse
imports github.com/akamensky/argparse: import cycle not allowed

~/go/src/cmdline_argparse $ go version
go version go1.17.1 darwin/amd64

[Suggestion] Improve doc of the File type parameter

The flag and perm arguments are a bit confusing. Some clarifications and examples might help.
On my mac, I find the even when I specify a non existing file I get a non nil File *. I am not sure if this is an issue or a bug in my usage:

pubkeyfile := registercmd.File("p", "public-key-file", os.O_RDONLY, 0, &argparse.Options{Help: "Public Key filename (.pem)"})
parser.Parse(os.Args)
if pubkeyfile == nil {
	log.Println("Invalid public key file")
} else {
	log.Println("Opened public key file")
}

BTW - This is my second project with argparse. Thanks for your efforts.

My first use (one a fork of the other) is at:

https://github.com/RajaSrinivasan/srctrace.git
https://github.com/RajaSrinivasan/repotrace.git

They can be viewed as basic and simple applications of argparse.

srini

expect File arg to take standard input / output stream as a value

When I define a File arg (like following) to specify an input file,

-i <input-file>

I wish we can specify the - value to input from the standard input stream. However, it will report error now.

if it's defined with a String arg, the help message will display like -i "<value>"(cannot tell this should be a file), not as expected very much.

It is the same case for the output file. I wish to specify the - value to output to standard output stream.

Write Wiki documentation for this project

Apparently GoDoc cannot show documentation for exported methods of un-exported structs, and it makes no sense to export parser and/or command, thus this project should provide its own documentation page.

Too many loops and cycling references

While this code works, it was something made over the weekend, just because I needed good library for this asap.

Might need to re-thinking the code to avoid cycling dependencies in the code as well as reduce number of loops in it.

[doc] the sub-command example in README

I'd like to add some examples in README.md, it will be helpful in my opinion.

If it is OK, I will try to update README tomorrow or someday I do not have homework....

support "h" custom argument

If I define

host := parser.String("h", "host", &argparse.Options{Required: false, Help: "listening host", Default: "127.0.0.1"})
// ...

I'll get a panic ->

panic: unable to add String: short name h occurs more than once

This is because there's a built-in -h/--help already occupied it.

For now I can workaround it by using a different letter, but It would be a nice to have support for h 😁

Help Command closes Program - undesirable in web chat app parsing

Hi i am trying to build a discord chat bot, and leveraging this package has been awesome for that, however when the parser is created a non overridable help argument is added which os.Exit(0) when triggered which is meaning users chatting the bot can make it close. I know this is probably a unexpected use case, i am willing to fork the project and workout a solution if you would like to give my guidance on how the end state should look.

enable required for positionals

Positionals (added in 1.4) currently ignore the Required option. It should be supported, with these basic requirements:

  • Required positionals must have a value supplied by the user (not by Default) or an error is thrown
  • If a positional is set to required, throw an error if there are already any positionals on this command which are NOT required
    -- This is necessary in order to avoid ambiguity of positional argument satisfaction: Say you have two positionals, the first is optional and the second is required. The user gives one value on the CLI. Which positional gets the value? Does the required positional get it IFF the optional has a default?
    -- Do not throw an error if there are optional positionals on a parent command of the command which has had Required positionals added
  • Allow optional positionals to follow Required positionals
  • Do not throw an error if there are Required positionals on commands which did not Happen

Some discussion of the problem is warranted before coding begins. This may not be an exhaustive list of requirements.

Missing Features

While I'm not entirely convinced that all features of argparse are useful, a few are really nifty.

Making a list of few features that I think could be added:

  • Positional arguments
    • Take arguments based on the position.
  • nargs functionality
    • Take constant or variable number of arguments that follow
    • Important for optional arguments
    • Does not make much sense for positional arguments
  • Repeated flags/options
    • Allow to repeat flags or optional arguments to specify more inputs
    • Support for multiple levels like -vvv

[bug] Commands not required

Hello, I have following code

parser := argparse.NewParser("...", "...")

verbose := parser.FlagCounter("v", "verbose", &argparse.Options{})
hosts := parser.StringList("", "host", &argparse.Options{Required: true})
username := parser.String("u", "user", &argparse.Options{Required: true})
password := parser.String("p", "password", &argparse.Options{Required: true})

// preset cmd
presetCmd := parser.NewCommand("preset", "Get and modify radio presets")
// get preset cmd
getPresetCmd := presetCmd.NewCommand("get", "Get the current radio preset")
// set preset cmd
setPresetCmd := presetCmd.NewCommand("set", "Set the current radio preset")
setPresetID := setPresetCmd.Int("", "id", &argparse.Options{Required: true})

// user cmd
userCmd := parser.NewCommand("user", "User")
getUserCmd := userCmd.NewCommand("get", "Get all users")

err := parser.Parse(os.Args)
if err != nil {
    fmt.Println(parser.Usage(err))
    return
}

When I start this with no arguments, I get the expected error message [sub]Command required.
When I start the program with just hosts, username and password, the subcommand is suddenly not needed.

EDIT: After reviewing your example code, the advanced-command example has the exact same bug. Start the example with just the --name argument and you reach

// This should be unreachable
log.Fatal("Uh-oh, something weird happened")

Options.Default should be ignored for Flag

package main

import (
	"fmt"
	"github.com/akamensky/argparse"
	"os"
)

func main() {
   parser := argparse.NewParser("accounts", "Prints provided string to stdout")
   noTest := parser.Flag("n", "no-test", &argparse.Options{Help: "boolean true/false", Default: true})

   err := parser.Parse(os.Args)
   if err != nil {
      fmt.Print(parser.Usage(err))
   }
   fmt.Println(*noTest)
}

why is this always true? the second should be false?

$ go run main.go 
true
$ go run main.go -n
true
$

[bug] Unable to detect if file flag was actually provided?

Hi There.

This has been my go-to library for argument parsing, and I recently tried to use this to parse file arguments. However, it seems impossible to determine if a flag was actually provided. For example:

configFile := parser.File("c", "config", etc)
parser.Parse()
if configFile != nil {
    // Do stuff with the file
}
// Do stuff if -c wasn't provided

This does not work, because the configFile is always non-nil, as the parser seems to work by overwriting the internal structures of os.File, and if the argument isn't provided, the configFile will still be non-nil. Furthermore, the standard library doesn't help in this regard, since all the regular functions assume that the file object is valid, so if I try something like configFile.Name(), it just panics.

Is there something I'm missing here, or is there no way to distinguish if the -c flag was provided, without reflection nonsense or panic handling?

Mutually exclusive groups

As Python's argparse implementation, is possible to have a mutually exclusive groups for arguments

`sdtin / stdout` default values for File?

I'm not quite sure of the size of my request, but here goes.

Looking at the implementation I see that the default should be a string, it being the path to the file to open, but I can't seem to make that point to the "real" standard streams. Perhaps it could be hardcoded that the strings "stdin", "stdout", "stderr" in the Option's Default for the File trigger that the file pointer points to os.Stdin / Stderr / Stdout?

Thoughts on a Lists

There is a question.
There are arguments with a parameter for different types (String, Float, Int).
There is also an argument of type List, which allows you to create a list of parameters of type String.
Wouldn't it be logical to make StringList, FloatList, IntList?

testFunction

I thought it would be nice to include a test function in the options.
If it is defined, when creating the argument, you should test the received value of the argument with its help. If it fails, finish processing with an error. This will help the user to handle a wide range of situations when the list of values ​​is limited, not providing for all cases in the library itself.

panic: runtime error: slice bounds out of range

If you use an argument and pass no value, the go program panics with panic: runtime error: slice bounds out of range.
PoC:

parser := argparse.NewParser("download", "Downloads URL matching provided string")
// Create string flag
searchQuery = parser.String("q", "query", &argparse.Options{Required: true, Help: "URL to download"})
// Parse input
err := parser.Parse(os.Args)
if err != nil {
	// In case of error print error and print usage
	// This can also be done by passing -h or --help flags
	fmt.Println(err.Error())
	fmt.Print(parser.Usage(parser))
}
go run main.go -q

Can't have duplicate switches in different commands?

If different commands both have switches that share the same short or long value, it errors with unable to add String: short name {} occurs more than once. This completely renders this library unusable for me unfortunately as many of my sub-commands do share the same switches (with different uses). Is this something that would be easy to fix or should I look for another library?

Add more examples

Need examples to cover following topics:

  • Flag and Flag shorthand combining
  • String, Selector and List
  • Int and Float
  • File
  • Required vs Optional arguments
  • Argument validation functions
  • Commands simple
  • Commands with sub-commands and arguments
  • Default values example

Each example must be independent and fully functional program

Allow unambiguous shortened long-options

With GNU getopt and friends (I believe Python argparse included, but I haven't tested it to write this issue report), long options may be abbreviated to the shortest unambiguous version and needn't be typed in full.

For example, in a program that has both --verbose and --version, --ver cannot work since it would match either of them, but --vers would act the same as --version, and --verb would act the same as --verbose.

How do I make a hidden argument?

For example, the user can define a hidden argument that is not shown on the help. I can't find an argument type to do this or any option field to set. How do I make a hidden one?

Add support for positional arguments

For some tools it makes more sense to use positional arguments instead of randomly located named arguments. The positional arguments must work as follows:

  1. Positional arguments can be placed only after named arguments and cannot mixed up with them
  2. Positional arguments order should be clearly defined in the code (possibly by order in which they are added)
  3. Positional argument parsing should account for shell expansions (namely wildcard in path arguments, which expands to multiple arguments)

[vote] Should sub-commands be required?

Right now if command has a sub-command (e.g. $ progname command <sub-command> or $ progname <command>) that sub-command is automatically required and not providing any will generate error response on parser.Parse(). This vote is consideration whether sub-commands must be always required, or they do not have to be required (do not generate err on parser.Parse() and instead delegate sub-command require/not-required decision to the developer who uses package.

Thumbs up - required, thumbs down - not required.

Combining a shorthand arguments with a parameter with flags

Hello!
Interesting: how critical is the design requirement:
"Shorthand arguments ONLY for parser.Flag () can be combined into single argument same as ps -aux or rm -rf"
It seems to me that it would be a good idea to give the opportunity to combine a shorthand arguments with a parameter with flags if it is written after them. I mean some thing like this:
tar -cvaf foo.tar.gz foo

Golang Argparse not picking correct value for multiple flags

I have a golang binary named test. I have two flags -p and -s. I want user to pass them like below scenarios:

  1. ./test -p
  2. ./test -s serviceName
  3. ./test -p -s serviceName

Means -p should be passed with empty value and -s should be passed with any service name. 1 and 2 are working fine but in third -p flag is taking value "-s". What i want from 3rd is -p should be empty value ("") and -s should be "serviceName"

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.