diff --git a/cmd/skopeo/flag.go b/cmd/skopeo/flag.go index 89774ebd98..88082b7040 100644 --- a/cmd/skopeo/flag.go +++ b/cmd/skopeo/flag.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "strconv" "github.com/urfave/cli" @@ -73,3 +74,37 @@ func (ob *optionalStringValue) String() string { } return ob.value } + +// optionalInt is a int with a separate presence flag. +type optionalInt struct { + present bool + value int +} + +// optionalInt is a cli.Generic == flag.Value implementation equivalent to +// the one underlying flag.Int, except that it records whether the flag has been set. +// This is distinct from optionalInt to (pretend to) force callers to use +// newoptionalInt +type optionalIntValue optionalInt + +func newOptionalIntValue(p *optionalInt) cli.Generic { + p.present = false + return (*optionalIntValue)(p) +} + +func (ob *optionalIntValue) Set(s string) error { + v, err := strconv.Atoi(s) + if err != nil { + return err + } + ob.value = v + ob.present = true + return nil +} + +func (ob *optionalIntValue) String() string { + if !ob.present { + return "" // This is, sadly, not round-trip safe: --flag= is interpreted as {present:true, value:""} + } + return fmt.Sprintf("%d", ob.value) +}