Home > database >  golang check if cli integer flag exists
golang check if cli integer flag exists

Time:02-25

I'm able to see if a flag exists when its a bool. I'm trying to figure out how to see if a flag exits if its integer, if it does exist use the value if not ignore.

For example, the code below does something if either Bool flags are used. BUT I want to set a flag for -month ie go run appname.go -month=01 should then save the value of 01 but if -month is not used then it should be ignored like a bool flag. In the code below I got around this by making a default value of 0 so if no -month flag is used the value is 0. Is there a better way to do this?

package main

import (
    "flag"
    "fmt"
    "time"
)

func main() {
    //Adding flags
    useCron := flag.Bool("cron", false, "-cron, uses cron flags and defaults to true")
    useNow := flag.Bool("now", false, "-now, uses cron flags and defaults to true")
    useMonth := flag.Int("month", 0, "-month, specify a month")
    flag.Parse()

    //If -cron flag is used
    if *useCron {
        fmt.Printf("Cron set using cron run as date")
        return
    } else if *useNow {
        fmt.Printf("Use Current date")
        return
    }

    if *useMonth != 0 {
        fmt.Printf("month %v\n", *useMonth)
    }
}

CodePudding user response:

See the documentation and example for the flag.Value interface :

You may define a custom type, which implements flag.Value, for example :

type CliInt struct {
    IsSet bool
    Val   int
}

func (i *CliInt) String() string {
    if !i.IsSet {
        return "<not set>"
    }
    return strconv.Itoa(i.Val)
}

func (i *CliInt) Set(value string) error {
    v, err := strconv.Atoi(value)
    if err != nil {
        return err
    }

    i.IsSet = true
    i.Val = v
    return nil
}

and then use flag.Var() to bind it :

    flag.Var(&i1, "i1", "1st int to parse")
    flag.Var(&i2, "i2", "2nd int to parse")

after calling flag.Parse(), you may check the .IsSet flag to see if that flag was set.

playground


Another way is to call flag.Visit() after calling flag.Parse() :

    var isSet1, isSet2 bool

    i1 := flag.Int("i1", 0, "1st int to parse")
    i2 := flag.Int("i2", 0, "2nd int to parse")

    flag.Parse([]string{"-i1=123"})

    // flag.Visit will only visit flags which have been explicitly set :
    flag.Visit(func(fl *flag.Flag) {
        if fl.Name == "i1" {
            isSet1 = true
        }
        if fl.Name == "i2" {
            isSet2 = true
        }
    })

playground

CodePudding user response:

In the bool flag also you can't check if exist or not because you are checking the default false value. If you will change it to true you will always get it as exists.

useCron := flag.Bool("cron", true, "-cron, uses cron flags and defaults to true")
useNow := flag.Bool("now", true, "-now, uses cron flags and defaults to true")

The same goes for any other data type, we can only check the default values.

You can use flag.NFlag().
This function returns a number of flags set by the CLI.
This option makes sense when all the options are required.

@LeGEC answer fulfills your requirement.

  • Related