Search code examples
gocommand-line-interfaceflags

golang / urfave.cli: can't get to set flags manually


We have an app which receives an urfave cli context object in a func:

import "gopkg.in/urfave/cli.v1"

func runApp(ctx *cli.Context) {
   cache := ctx.GlobalInt(MyFlag.Name)
   .... // do more stuff
}

I am trying to call runApp without the whole cli stuff, directly from code. Hence I have to build the ctx manually:


func MyTest() {
  fs := flag.NewFlagSet("", flag.ExitOnError)
  app := cli.NewApp()
  fs.Set(MyFlag.Name, "5000")
  ctx := cli.NewContext(app, fs, nil)
  runApp(ctx)
}

But it actually looks like the flag is never set, runApp never sees the value I set by hand.

What am I doing wrong? Can this actually be done at all?


Solution

  • It looks like MyFlag.Name this field is not actually defined as a flag. To define it as a flag, you need do this: fs.String(MyFlag.Name, "5000", "usageOfTheFlag")
    After this you can use fs.Set for MyFlag.Name.

    var MyFlag = flag.Flag{
        Name: "TestFlag",
    }
    
    func MyTest() {
      fs := flag.NewFlagSet("", flag.ExitOnError)
      app := cli.NewApp()
      // define a flag with default value
      fs.String(MyFlag.Name, "5000", "usageOfTheFlag")
      // set a new value
      err := fs.Set(MyFlag.Name, "5000")
    
      if err != nil {
         fmt.Println(err)
         return
      }
    
      ctx := cli.NewContext(app, fs, nil)
      runApp(ctx)
    }
    
    func runApp(ctx *cli.Context) {
       cache := ctx.GlobalInt(MyFlag.Name)
       .... // do more stuff
    }
    

    If you would do an error checking on fs.Set with your flag name without define it as a flag:

    // fs.String(MyFlag.Name, "5000", "usageOfTheFlag")
    err := fs.Set(MyFlag.Name, "5000")
    
        if err != nil {
            fmt.Println(err)
            return
        }
    

    You would get this error with the name of the flag that is currently not defined as a flag. In this example it is "TestFlag":

    no such flag -TestFlag
    

    Thus MyFlag.Name didn't get the new value and because of it your program didn't see your new value.