integrii / flaggy

Idiomatic Go input parsing with subcommands, positional values, and flags at any position. No required project or package layout and no external dependencies.
The Unlicense
858 stars 30 forks source link

How do you display default values in help text? #46

Closed atc0005 closed 5 years ago

atc0005 commented 5 years ago

Summary

I'm very new to Go and am getting used to syntax and the overall mindset of using it, so it's likely that I'm missing something. As I was looking over the feature list and examples one of the features that really drew my eye was how default values for options appeared to be automatically displayed in help output.

So far I can't figure out how to display default values for configured flags.

I also can't seem to figure out how to display help output for invalid/unconfigured flags, but it's probably something else I'm doing wrong.

Desired Results

From the README:

  Flags:
       --version  Displays the program version string.
    -h --help  Displays help with available flag, subcommand, and positional value parameters.
    -s --stringFlag  This is a test string flag that does some stringy string stuff.
    -i --intFlg  This is a test int flag that does some interesting int stuff. (default: 5)
    -b --boolFlag  This is a test bool flag that does some booly bool stuff. (default: true)
    -d --durationFlag  This is a test duration flag that does some untimely stuff.

Is this support available? If so, how do I go about using it?

Example program

Here is a brief example program:

package main

import (
    "fmt"

    "github.com/integrii/flaggy"
)

func main() {

    optKeepOldest := false
    optRemove := false

    flaggy.SetName("Test")
    flaggy.SetDescription("Short example to illustrate issue")

        // attempt to show Help output when invalid flags/options are used
       // (does not seem to work?)
    flaggy.DefaultParser.ShowHelpOnUnexpected = true

    // Add flags
    flaggy.Bool(&optKeepOldest, "ko", "keep-old", "Keep oldest files instead of newer")
    flaggy.Bool(&optRemove, "rm", "remove", "Remove matched files")

    flaggy.Parse()

    fmt.Printf("%v\n", optKeepOldest)
    fmt.Printf("%v\n", optRemove)

}

Package version used

Contents of my go.mod file:

module testing

go 1.12

require github.com/integrii/flaggy v1.2.1-0.20190517180110-07ea7eb77404 // indirect

Environment

integrii commented 5 years ago

Hey @atc0005! Welcome to Go and thanks for trying out Flaggy.

The default value is populated by looking at the pointer being passed into the function that sets up the flag (like flaggy.Bool()). Whatever value the target of the pointer has should be shown as the default in the help.

However, it looks like this somehow broke and nobody noticed! I am going to look into this some more and let you know whats up. I verified this is broken by running the examples in the examples directory.

atc0005 commented 5 years ago

@integrii Thanks!

atc0005 commented 5 years ago

@integrii Off-topic, but how would you prefer that users ask questions regarding the use of the Flaggy package? Is there a mailing list, an IRC/Slack channel or are you open to receiving questions in this GitHub project?

integrii commented 5 years ago

This Github project is probably the best place to ask questions. I haven't created any kind of other user group to speak of. I might have made a channel on the Golang Slack, but it's too hard to keep a lot of Slack teams open at once.

integrii commented 5 years ago

This should be fixed now in release 1.2.2! Make sure you run go get -u github.com/integrii/flaggy to get the latest version.

atc0005 commented 5 years ago

This should be fixed now in release 1.2.2!

Awesome, thanks!

For what it is worth, when using Go modules and running go get -u github.com/integrii/flaggy, my go.mod file was modified to reference the last stable tag that has a leading 'v' character: v1.2.0

My notes from my first attempt at upgrading to the 1.2.2 tag are below. The TL;DR is that running go get -u github.com/integrii/flaggy@1.2.2 is a solid workaround for the lack of a 'v' prefix for the latest tag.


I was able to force upgrading to tag 1.2.2 by manually replacing the existing version in the go.mod file with the full git commit: `425304205580254c6ea87908f35848c46eb99d5e

I then ran go mod tidy which caused the git commit to be replaced with v1.2.1-0.20190821014744-425304205580 (note the trailing 12 char git commit hash).

I think I recall reading that this is basically +0.0.1 to the last stable version that has a 'v' prefix and some other numerical values (presumably date/time and 12 char git commit hash) used to create a pseudo

If go mod finds a new stable with the leading 'v' prefix it will fetch that when running go get -u github.com/integrii/flaggy.

At least that is my understanding, and as I said before I'm new, so take this feedback with a grain of salt.

atc0005 commented 5 years ago

This Github project is probably the best place to ask questions. I haven't created any kind of other user group to speak of. I might have made a channel on the Golang Slack, but it's too hard to keep a lot of Slack teams open at once.

Acknowledged, I'll try not to fill the repo with RTM-response worthy questions. ;)

atc0005 commented 5 years ago

@integrii

Are integers and string variables the only types whose default values are displayed in the help output? I don't see the default value for a bool type in the output.

Updated test program:

package main

import (
        "fmt"

        "github.com/integrii/flaggy"
)

func main() {

        optBool := false
        optIntegerTestVar := 1
        optStringTestVar := "My test string"

        flaggy.SetName("Test")
        flaggy.SetDescription("Short example to illustrate issue")

        flaggy.DefaultParser.ShowHelpOnUnexpected = true

        // Add flags
        flaggy.Bool(&optBool, "bo", "bool", "Boolean test option")
        flaggy.Int(&optIntegerTestVar, "int", "inttest", "Integer test option")
        flaggy.String(&optStringTestVar, "str", "stringtest", "String test option")

        // Parse the flag
        flaggy.Parse()

        fmt.Printf("%v\n", optBool)
        fmt.Printf("%v\n", optIntegerTestVar)
        fmt.Printf("%v\n", optStringTestVar)

}

Output:

$ go run main.go -h
Test - Short example to illustrate issue

  Flags:
       --version  Displays the program version string.
    -h --help  Displays help with available flag, subcommand, and positional value parameters.
    -bo --bool  Boolean test option
    -int --inttest  Integer test option (default: 1)
    -str --stringtest  String test option (default: My test string)
integrii commented 5 years ago

Nice job getting that going.
When building flaggy, I chose to hide the default value for bool flags that were set to their default value of false.

If you set your bool flag to true, you should see it appear in the help as you're expecting. I think the logic there was:

Bool flags are either supplied or they aren't. If they aren't, its false. Matter of fact, setting a bool to false, requires you to explicitly call out the false like this: -bo=false.

You are very right about the releases requiring a v to be valid semver and considered for go modules. I went in and edited the releases to fix this up for future users. Whoops!

atc0005 commented 5 years ago

Nice job getting that going.

Thank you! I'm slowly getting past the, "I have absolutely no clue what I'm doing phase" and feel like I'm starting to make progress (in general re my studies in using Go).

When building flaggy, I chose to hide the default value for bool flags that were set to their default value of false.

If you set your bool flag to true, you should see it appear in the help as you're expecting. I think the logic there was:

Bool flags are either supplied or they aren't. If they aren't, its false. Matter of fact, setting a bool to false, requires you to explicitly call out the false like this: -bo=false.

That makes sense. It was surprising, but perhaps because I wasn't stepping back and thinking about it logically. Thanks for spelling that out for me.

You are very right about the releases requiring a v to be valid semver and considered for go modules. I went in and edited the releases to fix this up for future users. Whoops!

Awesome, thanks!