Are you still coding your go cli handling by hand? Time to stop and rethink better ways to do it now.
Take a look at this go command line handling file:
The help text "path to serve files from" shows up three times:
$ grep -1 'path to serve' OpenSesame_cliDef.go
Port string // listening port
Path string // path to serve files from
Help bool // show usage help
--
flag.StringVar(&Opts.Path, "path", "./",
"path to serve files from")
flag.BoolVar(&Opts.Help, "help", false,
--
const usageSummary = " -port\tlistening port (OPENSESAME_PORT)\n -path\tpath to serve files from (OPENSESAME_PATH)\n -help\tshow usage help (OPENSESAME_HELP)\n\nDetails:\n\n"
If coding by hand, most probably the first occurrence will be omitted. But that's kind of pity, as the help text is helpful in explaining what exactly the Path string
variable is for:
Path string // path to serve files from
Also, if coding by hand, the second and third occurrences will very easily get out of sync if not be taken care of all the time.
All these violate the DRY (Don't Repeat Yourself) principle. How to avoid it? The answer is this file:
from which we can see that the help text "path to serve files from" is defined only once but get automatically put into three different proper places.
This is the go cli handling code auto generation we are talking about. Look at the above two files, which one is more easier to maintain? With cli handling code auto generation feature out there, don't code it manually next time when you do cli handling again.
What if you already have a manually written cli handling code? Well, converting it to automatically generated is not that hard at all. Here are just two simple steps,
introduce config.go, which ports the existing cli handling from existing code into auto-generated
config.go
file.implemented -d, -c, & -help, which adds more business logic handling for the newly added command line flags/parameters.
Very simple, no sweat at all. All thanks to the auto-generated config.go
file.
OK, now comes to the question, how is the config.go
file auto-generated? Let me answer it with another example, that starts everything from the beginning, with all the following explanation borrowed from here
This section will work through every steps how the program is created.
-
Initialize an empty project.
The
_proj.yaml
file will later be used to -
Initialize project wireframe using the standard Go
flag
package, by- Edit the
_cli.yaml
cli arguments definition file - Then do
go generate
(enabled like this), or directly invoke the_cliGen.sh
script - Finally do
go build
- Edit the
- Provide the initial OpenSesame functionality
- Update OpenSesame code to make use of the auto-generated cli wireframe
- The auto-generated cli wireframe code are not set in stones, they can later be further amended, just like the real-world cases. For e.g.
-
Update cli definition of
port
value - Update usage doc
- Enable
UsageSummary
- etc.
-
Update cli definition of
This finished a full Initialize
-> Make use
-> More changes to cli definitions
cycle.
Make sure to check out the rest of the above quoted wiki, Go command line flag handling code auto generation, from which you can see that using the same .yaml
driven file, not only the go standard flag
command line handling code can be automatically generated, but viper
and cobra
as well, and all the way to the full-featured cli code that can set the argument values at three different levels:
So the priority of setting the Host
value is, from lowest priority to the highest:
- self-config file
- environment variable
- command line
Three different levels.
Top comments (0)