talos/pkg/argsbuilder/argsbuilder_args.go
Andrey Smirnov a6b010a8b4
chore: update Go to 1.19, Linux to 5.15.58
See https://go.dev/doc/go1.19

Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
2022-08-03 17:03:58 +04:00

133 lines
2.5 KiB
Go

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package argsbuilder
import (
"fmt"
"sort"
"strings"
"github.com/talos-systems/talos/pkg/machinery/generic/maps"
)
// Key represents an arg key.
type Key = string
// Value represents an arg value.
type Value = string
// Args represents a set of args.
type Args map[Key]Value
// MustMerge implements the ArgsBuilder interface.
func (a Args) MustMerge(args Args, setters ...MergeOption) {
if err := a.Merge(args, setters...); err != nil {
panic(err)
}
}
// Merge implements the ArgsBuilder interface.
//
//nolint:gocyclo
func (a Args) Merge(args Args, setters ...MergeOption) error {
var opts MergeOptions
for _, s := range setters {
s(&opts)
}
policies := opts.Policies
if policies == nil {
policies = MergePolicies{}
}
for key, val := range args {
policy := policies[key]
switch policy {
case MergeDenied:
return NewDenylistError(key)
case MergeAdditive:
values := strings.Split(a[key], ",")
definedValues := map[string]struct{}{}
i := 0
for _, v := range values {
definedValues[strings.TrimSpace(v)] = struct{}{}
if v != "" {
values[i] = v
i++
}
}
values = values[:i]
for _, v := range strings.Split(val, ",") {
v = strings.TrimSpace(v)
if _, defined := definedValues[v]; !defined {
values = append(values, v)
}
}
a[key] = strings.Join(values, ",")
case MergeOverwrite:
a[key] = val
}
}
return nil
}
// Set implements the ArgsBuilder interface.
func (a Args) Set(k, v Key) ArgsBuilder {
a[k] = v
return a
}
// Args implements the ArgsBuilder interface.
func (a Args) Args() []string {
keys := maps.Keys(a)
sort.Strings(keys)
args := []string{}
for _, key := range keys {
args = append(args, fmt.Sprintf("--%s=%s", key, a[key]))
}
return args
}
// Get returns an args value.
func (a Args) Get(k Key) Value {
return a[k]
}
// Contains checks if an arg key exists.
func (a Args) Contains(k Key) bool {
_, ok := a[k]
return ok
}
// DenyListError represents an error indicating that an argument was supplied
// that is not allowed.
type DenyListError struct {
s string
}
// NewDenylistError returns a DenyListError.
func NewDenylistError(s string) error {
return &DenyListError{s}
}
// Error implements the Error interface.
func (b *DenyListError) Error() string {
return fmt.Sprintf("extra arg %q is not allowed", b.s)
}