Skip to content

sgreben/flagvar

Folders and files

NameName
Last commit message
Last commit date

Latest commit

d9853b6 · Sep 26, 2024

History

53 Commits
Sep 26, 2024
May 18, 2018
May 18, 2018
Sep 26, 2024
May 20, 2018
May 18, 2018
May 20, 2018
May 19, 2018
May 20, 2018
May 19, 2018
May 20, 2018
May 20, 2018
May 18, 2018
Oct 3, 2018
Oct 3, 2018
May 20, 2018
May 20, 2018
Sep 26, 2024
Jul 11, 2020
May 20, 2018
May 20, 2018
May 19, 2018
May 20, 2018
May 19, 2018
Oct 3, 2018
Sep 27, 2018
May 19, 2018
May 19, 2018
May 20, 2018
May 20, 2018
Aug 30, 2018
Aug 30, 2018
May 20, 2018
May 20, 2018
May 31, 2019
May 31, 2019
May 20, 2018
Jul 11, 2020
Jul 11, 2020
May 18, 2018
May 20, 2018
May 20, 2018
May 20, 2018
May 20, 2018
May 20, 2018
May 18, 2018
May 20, 2018
May 19, 2018

Repository files navigation

flagvar

Coverage

Test Go Reference Go Report Card

A collection of CLI argument types for the flag package.

import "github.com/sgreben/flagvar"

Or just copy & paste what you need. It's public domain.

Example

package main

import (
	"flag"
	"fmt"
	"github.com/sgreben/flagvar"
)

var (
	fruit    = flagvar.Enum{Choices: []string{"apple", "banana"}}
	urls     flagvar.URLs
	settings flagvar.Assignments
)

func main() {
	flag.Var(&fruit, "fruit", fmt.Sprintf("set a fruit (%s)", fruit.Help()))
	flag.Var(&urls, "url", "add a URL")
	flag.Var(&settings, "set", fmt.Sprintf("specify a setting (%s)", settings.Help()))
	flag.Parse()
}
$ go run main.go -set abc=xyz -url https://github.com
# no error

$ go run main.go -set abc=xyz -url ://github.com
invalid value "://github.com" for flag -url: parse ://github.com: missing protocol scheme

$ go run main.go -fruit kiwi
invalid value "kiwi" for flag -fruit: "kiwi" must be one of [apple banana]

$ go run main.go -h
Usage:
  -fruit value
        set a fruit (one of [apple banana])
  -set value
        specify a setting (a key/value pair KEY=VALUE)
  -url value
        add a URL

Conventions

  • Pluralized argument types (e.g. Strings, Assignments) can be specified repeatedly, the values are collected in a slice.
  • The resulting value is stored in .Value for singular types and in .Values for plural types
  • The original argument string is stored in .Text for singular types and in .Texts for plural types
  • -Set types (EnumSet, StringSet) de-duplicate provided values.
  • -CSV types (IntsCSV, EnumsCSV) accept comma-separated values and accumulate values across flag instances if their .Accumulate field is set to true.
  • Most types implement interface{ Help() string }, which produces a string suitable for inclusion in a help message.

Types

Here's a compact overview:

flagvar type example CLI arg type of resulting Go value
Alternative
Assignment KEY=VALUE struct{Key,Value}
Assignments KEY=VALUE []struct{Key,Value}
AssignmentsMap KEY=VALUE map[string]string
CIDR 127.0.0.1/24 struct{IPNet,IP}
CIDRs 127.0.0.1/24 []struct{IPNet,IP}
CIDRsCSV 127.0.0.1/16,10.1.2.3/8 []struct{IPNet,IP}
Enum apple string
Enums apple []string
EnumsCSV apple,banana []string
EnumSet apple []string
EnumSetCSV apple,banana []string
File ./README.md string
Files ./README.md []string
Floats 1.234 []float64
FloatsCSV 1.234,5.0 []float64
Glob src/**.js glob.Glob
Globs src/**.js []glob.Glob
Ints 1002 []int64
IntsCSV 123,1002 []int64
IP 127.0.0.1 net.IP
IPs 127.0.0.1 []net.IP
IPsCSV 127.0.0.1,10.1.2.3 []net.IP
JSON '{"a":1}' interface{}
JSONs '{"a":1}' []interface{}
Regexp [a-z]+ *regexp.Regexp
Regexps [a-z]+ []*regexp.Regexp
Strings "xyxy" []string
StringSet "xyxy" []string
StringSetCSV y,x,y []string
TCPAddr 127.0.0.1:10 net.TCPAddr
TCPAddrs 127.0.0.1:10 []net.TCPAddr
TCPAddrsCSV 127.0.0.1:10,:123 []net.TCPAddr
Template "{{.Size}}" *template.Template
Templates "{{.Size}}" []*template.Template
TemplateFile "/path/to/template.file" string
Time "10:30 AM" time.Time
Times "10:30 AM" []time.Time
TimeFormat "RFC3339" string
UDPAddr 127.0.0.1:10 net.UDPAddr
UDPAddrs 127.0.0.1:10 []net.UDPAddr
UDPAddrsCSV 127.0.0.1:10,:123 []net.UDPAddr
UnixAddr /example.sock net.UnixAddr
UnixAddrs /example.sock []net.UnixAddr
UnixAddrsCSV /example.sock,/other.sock []net.UnixAddr
URL https://github.com *url.URL
URLs https://github.com []*url.URL
Wrap
WrapCSV
WrapFunc
WrapPointer

Goals / design principles

  • Help avoid dependencies
    • Self-contained > DRY
    • Explicitly support copy & paste workflow
    • Copyable units should be easy to determine
    • Anonymous structs > shared types
  • "Code-you-own" feeling, even when imported as a package
    • No private fields / methods
    • No magic
    • Simple built-in types used wherever possible
    • Avoid introducing new concepts
  • Support "blind" usage
    • Zero values should be useful
    • Avoid introducing failure cases, handle any combination of parameters gracefully.
    • All "obvious things to try" should work.