Go Recipes - The param package

Table of Contents

The param package

All the programs under github.com/nickwells use a common package for handling parameters. This package is called param and it offers a range of features to make it easier to use the programs.

For other recipes see here.

Getting started

Summary

To use the param package you must first create a set of parameters (a PSet), populating the parameters you want to add and otherwise setting the default behaviour. Once you have a PSet you can call Parse on it to set the parameter values ready for the rest of the program to use them. As follows:

var goodbye bool
func addParams(ps *param.PSet) error {
      ps.Add("goodbye",
                  psetter.Bool{Value: &goodbye},
                  "Say Goodbye")
      return nil
}

If you are using gosh to run the code you will need to use the 'global' parameter for the code shown above.

Then at the start of your main func add the following lines to construct the parameter set, parse the program arguments and use the values set.

ps := paramset.NewOrDie(addParams)
ps.Parse()

if goodbye {
        fmt.Println("Goodbye, World!")
} else {
        fmt.Println("Hello, World!")
}

Discussion

The recommended way of creating a parameter set is through the paramset package which will create a PSet with the standard helper set. This in turn prepopulates the standard parameters. These standard parameters provide help on the parameters available, program usage descriptions and parameters to control the behaviour of the standard parsing and troubleshooting.

Note the use of the paramset.NewOrDie func; this checks for errors when constructing the parameter set and if an error is found it will report it and exit. If you want to handle errors yourself you can use the paramset.New func which will return a PSet and an error which you should check to make sure is nil before proceding. Any error returned when constructing the parameter set is non-recoverable and should be treated as a fatal error.

Using the param package to get help

Summary

The param package allows the programmer to generate a comprehensive manual. This manual can be accessed through the common parameters that param provides. In addition to sections describing the available parameters, the manual can also have sections of notes describing features of the program, examples of program usage and references to other programs.

The following gives the standard help message for a command called prog:

prog -help

For the complete help message:

prog -help-full

You can get help on individual parameters; this can be useful if you just want to know what a single parameter does. This gives help just for the help parameter itself:

prog -help-param help

You can get help on groups of parameters; this gives help just for the collection of common help parameters:

prog -help-group common.params-help

Applying a parameter every time your program runs

Summary

if you want to run your program with a set of common parameters every time you can put these parameters in a configuration file or in environment variables. To see if your program has any alternative parameter sources defined, run it as follows.

prog -help-show sources

Note that parameter names in configuration files don't start with a leading dash. Any environment variables will start with a program-specific prefix and any dashes in the parameter name will be replaced with an underscore.

Discussion

You add parameters to the configuration file, one per line, with the parameter name (no leading dash) at the start of the line followed by an equals ("=") and then the parameter value. If the parameter does not take a value you can just give the parameter name. Blank lines are ignored and white space around the parts of the line are ignored.

You can comment the file: any text from a "#" to the end of line is ignored. You can also keep configuration parameters in other files and import them with an @include directive. This might be more useful for commands with a lot of configuration parameters especially ones shared between multiple programs.

At first it might seem that the configuration file pathnames are unnecessarily long but they are chosen to ensure uniqueness when each program may potentially have its own configuration file and other competing naming systems might be in use. The directories holding the files are named for the Go module name and the base directories are named according to the XDG spec.

All the Go programs under github.com/nickwells use the same standard for configuration file naming, they are of the form:

XDG-config-directory / Go-module / program-or-package / common.cfg

Command line parameter completion

Most modern shells offer command-specific parameter completion at the command prompt, the param package can help set this up.

Summary

If you are using zsh you can get your program to generate the parameter expansion file to support this. To find out more details run your program as follows:

prog -help-group common.params-completion

You only need to generate the file once though you should repeat this (replacing the old completion file with a new one) when you upgrade your program to a more recent version with more parameters.

If you want to generate a new completions file or replace an existing one you will also need to specify where the completion file should be written.

Note that there is a single configuration file for parameter completion that is shared between all programs using the github.com/nickwells/param.mod/v5/param package. You can set the completions directory once in that file and then you won't need to set it for each program when you are building the completion rules.

Troubleshooting

If a program has several configuration files and environment prefixes that can be used to set parameters it can be hard to understand what parameters are being set and where. This can make you program behaviour hard to understand. Another problem can arise when you have configuration files shared between several programs. The param package offers some standard parameters to help you debug this.

The first parameter that you might find useful shows if and where the available parameters have been set. Run your program as follows:

prog -params-show-where-set

If you have a configuration file shared between programs (which can be useful when you have a suite of programs which share some configuration) it can happen that you have misspelled some parameter names. To identify unused parameters run your program as follows:

prog -params-show-unused

You can also use the common parameters to control the behaviour around error handling.

Author: Nick Wells

Created: 2023-08-26 Sat 21:48

Validate