...

Text file src/github.com/peterbourgon/ff/v3/README.md

Documentation: github.com/peterbourgon/ff/v3

     1# ff [![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/github.com/peterbourgon/ff/v3) [![Latest Release](https://img.shields.io/github/release/peterbourgon/ff.svg?style=flat-square)](https://github.com/peterbourgon/ff/releases/latest) [![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fpeterbourgon%2Fff%2Fbadge&style=flat-square&label=build)](https://github.com/peterbourgon/ff/actions?query=workflow%3ATest)
     2
     3ff stands for flags-first, and provides an opinionated way to populate a
     4[flag.FlagSet](https://golang.org/pkg/flag#FlagSet) with configuration data from
     5the environment. By default, it parses only from the command line, but you can
     6enable parsing from environment variables (lower priority) and/or a
     7configuration file (lowest priority).
     8
     9Building a commandline application in the style of `kubectl` or `docker`?
    10Consider [package ffcli](https://pkg.go.dev/github.com/peterbourgon/ff/v3/ffcli),
    11a natural companion to, and extension of, package ff.
    12
    13## Usage
    14
    15Define a flag.FlagSet in your func main.
    16
    17```go
    18import (
    19	"flag"
    20	"os"
    21	"time"
    22
    23	"github.com/peterbourgon/ff/v3"
    24)
    25
    26func main() {
    27	fs := flag.NewFlagSet("my-program", flag.ExitOnError)
    28	var (
    29		listenAddr = fs.String("listen-addr", "localhost:8080", "listen address")
    30		refresh    = fs.Duration("refresh", 15*time.Second, "refresh interval")
    31		debug      = fs.Bool("debug", false, "log debug information")
    32		_          = fs.String("config", "", "config file (optional)")
    33	)
    34```
    35
    36Then, call ff.Parse instead of fs.Parse.
    37[Options](https://pkg.go.dev/github.com/peterbourgon/ff/v3#Option)
    38are available to control parse behavior.
    39
    40```go
    41	ff.Parse(fs, os.Args[1:],
    42		ff.WithEnvVarPrefix("MY_PROGRAM"),
    43		ff.WithConfigFileFlag("config"),
    44		ff.WithConfigFileParser(ff.PlainParser),
    45	)
    46```
    47
    48This example will parse flags from the commandline args, just like regular
    49package flag, with the highest priority. (The flag's default value will be used
    50only if the flag remains unset after parsing all provided sources of
    51configuration.)
    52
    53Additionally, the example will look in the environment for variables with a
    54`MY_PROGRAM` prefix. Flag names are capitalized, and separator characters are
    55converted to underscores. In this case, for example, `MY_PROGRAM_LISTEN_ADDR`
    56would match to `listen-addr`.
    57
    58Finally, if a `-config` file is specified, the example will try to parse it
    59using the PlainParser, which expects files in this format.
    60
    61
    62```
    63listen-addr localhost:8080
    64refresh 30s
    65debug true
    66```
    67
    68You could also use the JSONParser, which expects a JSON object.
    69
    70```json
    71{
    72	"listen-addr": "localhost:8080",
    73	"refresh": "30s",
    74	"debug": true
    75}
    76```
    77
    78Or, you could write your own config file parser.
    79
    80```go
    81// ConfigFileParser interprets the config file represented by the reader
    82// and calls the set function for each parsed flag pair.
    83type ConfigFileParser func(r io.Reader, set func(name, value string) error) error
    84```
    85
    86## Flags and env vars
    87
    88One common use case is to allow configuration from both flags and env vars.
    89
    90```go
    91package main
    92
    93import (
    94	"flag"
    95	"fmt"
    96	"os"
    97
    98	"github.com/peterbourgon/ff/v3"
    99)
   100
   101func main() {
   102	fs := flag.NewFlagSet("myservice", flag.ExitOnError)
   103	var (
   104		port  = fs.Int("port", 8080, "listen port for server (also via PORT)")
   105		debug = fs.Bool("debug", false, "log debug information (also via DEBUG)")
   106	)
   107	ff.Parse(fs, os.Args[1:], ff.WithEnvVarNoPrefix())
   108
   109	fmt.Printf("port %d, debug %v\n", *port, *debug)
   110}
   111```
   112
   113```
   114$ env PORT=9090 myservice
   115port 9090, debug false
   116$ env PORT=9090 DEBUG=1 myservice -port=1234
   117port 1234, debug true
   118```

View as plain text