Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: add YAML support to server#6934

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
ammario merged 42 commits intomainfromyaml
Apr 7, 2023
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
42 commits
Select commitHold shift + click to select a range
0d08b84
big wip
ammarioMar 30, 2023
fce8e5f
SimpleString isomorphism!!!
ammarioMar 30, 2023
2844497
Support scalars
ammarioMar 30, 2023
4960df8
ComplexObjects work!
ammarioMar 30, 2023
2a2c926
golden files work!
ammarioMar 30, 2023
056437f
Fixup YAML types
ammarioMar 30, 2023
c2428ff
give default value in comment
ammarioMar 30, 2023
8b210dc
Merge remote-tracking branch 'origin/main' into yaml
ammarioMar 30, 2023
26d7f21
Merge remote-tracking branch 'origin/main' into yaml
ammarioMar 31, 2023
38fa539
Add values.YAMLConfigPath
ammarioMar 31, 2023
64b167a
Merge remote-tracking branch 'origin/main' into yaml
ammarioMar 31, 2023
7edea99
Add YAML to core clibase parsing
ammarioMar 31, 2023
3ab35c1
Server Test WIP
ammarioMar 31, 2023
38155da
More WIP
ammarioMar 31, 2023
451c149
Merge remote-tracking branch 'origin/main' into yaml
ammarioApr 1, 2023
c72f67c
hmm
ammarioApr 1, 2023
9d61ca7
Cant find a clean way to do this..
ammarioApr 4, 2023
5b61b7b
Mediocre solution
ammarioApr 4, 2023
4923d92
hmm
ammarioApr 4, 2023
b6f982c
Merge remote-tracking branch 'origin/main' into yaml
ammarioApr 4, 2023
781786b
New, better YAML
ammarioApr 6, 2023
b03999a
clibase passes
ammarioApr 6, 2023
d018838
Fix UnknownOptions errors
ammarioApr 6, 2023
fe93d7f
Work on nil normalization
ammarioApr 6, 2023
0af47bb
Server tests pass!
ammarioApr 6, 2023
4a1df77
Merge remote-tracking branch 'origin/main' into yaml
ammarioApr 6, 2023
64255b3
make gen + self review cleanup
ammarioApr 6, 2023
99d6068
Generate docs
ammarioApr 6, 2023
300484b
make gen
ammarioApr 6, 2023
4cf5a21
Add --debug-options
ammarioApr 6, 2023
abc92d9
Normalize golden files
ammarioApr 6, 2023
a958324
fix log path
ammarioApr 7, 2023
8ead9fc
minor fix
ammarioApr 7, 2023
6eb19f6
Fix mutability bug in PrepareAll
ammarioApr 7, 2023
f77460f
Address review comments
ammarioApr 7, 2023
4e63bd5
Merge remote-tracking branch 'origin/main' into yaml
ammarioApr 7, 2023
2a96c70
Fix windows?
ammarioApr 7, 2023
7ae7cad
Small improvements
ammarioApr 7, 2023
09d5a35
Reduce YAML ident to 2
ammarioApr 7, 2023
d6506c6
Log mystery error
ammarioApr 7, 2023
551e55d
fixup! Log mystery error
ammarioApr 7, 2023
c3f3317
ecdsa
ammarioApr 7, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions.golangci.yaml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -194,6 +194,7 @@ issues:
linters:
# We use assertions rather than explicitly checking errors in tests
- errcheck
- forcetypeassert

fix: true
max-issues-per-linter: 0
Expand Down
2 changes: 1 addition & 1 deletionMakefile
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -518,7 +518,7 @@ update-golden-files: cli/testdata/.gen-golden helm/tests/testdata/.gen-golden sc
.PHONY: update-golden-files

cli/testdata/.gen-golden: $(wildcard cli/testdata/*.golden) $(wildcard cli/*.tpl) $(GO_SRC_FILES)
go test ./cli -run=TestCommandHelp -update
go test ./cli -run="Test(CommandHelp|ServerYAML)" -update
touch "$@"

helm/tests/testdata/.gen-golden: $(wildcard helm/tests/testdata/*.golden) $(GO_SRC_FILES)
Expand Down
13 changes: 4 additions & 9 deletionscli/clibase/clibase.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,15 +14,10 @@ import (

// Group describes a hierarchy of groups that an option or command belongs to.
type Group struct {
Parent *Group `json:"parent,omitempty"`
Name string `json:"name,omitempty"`
Children []Group `json:"children,omitempty"`
Description string `json:"description,omitempty"`
}

func (g *Group) AddChild(child Group) {
child.Parent = g
g.Children = append(g.Children, child)
Parent *Group `json:"parent,omitempty"`
Name string `json:"name,omitempty"`
YAML string `json:"yaml,omitempty"`
Description string `json:"description,omitempty"`
}

// Ancestry returns the group and all of its parents, in order.
Expand Down
44 changes: 34 additions & 10 deletionscli/clibase/cmd.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,6 +13,7 @@ import (
"github.com/spf13/pflag"
"golang.org/x/exp/slices"
"golang.org/x/xerrors"
"gopkg.in/yaml.v3"
)

// Cmd describes an executable command.
Expand DownExpand Up@@ -76,10 +77,8 @@ func (c *Cmd) PrepareAll() error {
}
var merr error

slices.SortFunc(c.Options, func(a, b Option) bool {
return a.Flag < b.Flag
})
for _, opt := range c.Options {
for i := range c.Options {
opt := &c.Options[i]
if opt.Name == "" {
switch {
case opt.Flag != "":
Expand All@@ -102,6 +101,10 @@ func (c *Cmd) PrepareAll() error {
}
}
}

slices.SortFunc(c.Options, func(a, b Option) bool {
return a.Name < b.Name
})
slices.SortFunc(c.Children, func(a, b *Cmd) bool {
return a.Name() < b.Name()
})
Expand DownExpand Up@@ -262,17 +265,38 @@ func (inv *Invocation) run(state *runState) error {
parsedArgs = inv.parsedFlags.Args()
}

// Set defaults for flags that weren't set by the user.
skipDefaults := make(map[int]struct{}, len(inv.Command.Options))
// Set value sources for flags.
for i, opt := range inv.Command.Options {
if fl := inv.parsedFlags.Lookup(opt.Flag); fl != nil && fl.Changed {
skipDefaults[i] = struct{}{}
inv.Command.Options[i].ValueSource = ValueSourceFlag
}
}

// Read YAML configs, if any.
for _, opt := range inv.Command.Options {
path, ok := opt.Value.(*YAMLConfigPath)
if !ok || path.String() == "" {
continue
}
if opt.envChanged {
skipDefaults[i] = struct{}{}

byt, err := os.ReadFile(path.String())
if err != nil {
return xerrors.Errorf("reading yaml: %w", err)
}

var n yaml.Node
err = yaml.Unmarshal(byt, &n)
if err != nil {
return xerrors.Errorf("decoding yaml: %w", err)
}

err = inv.Command.Options.UnmarshalYAML(&n)
if err != nil {
return xerrors.Errorf("applying yaml: %w", err)
}
}
err = inv.Command.Options.SetDefaults(skipDefaults)

err = inv.Command.Options.SetDefaults()
if err != nil {
return xerrors.Errorf("setting defaults: %w", err)
}
Expand Down
107 changes: 73 additions & 34 deletionscli/clibase/cmd_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,6 +4,7 @@ import (
"bytes"
"context"
"fmt"
"os"
"strings"
"testing"

Expand DownExpand Up@@ -555,42 +556,80 @@ func TestCommand_EmptySlice(t *testing.T) {
func TestCommand_DefaultsOverride(t *testing.T) {
t.Parallel()

var got string
cmd := &clibase.Cmd{
Options: clibase.OptionSet{
{
Name: "url",
Flag: "url",
Default: "def.com",
Env: "URL",
Value: clibase.StringOf(&got),
},
},
Handler: (func(i *clibase.Invocation) error {
_, _ = fmt.Fprintf(i.Stdout, "%s", got)
return nil
}),
test := func(name string, want string, fn func(t *testing.T, inv *clibase.Invocation)) {
t.Run(name, func(t *testing.T) {
t.Parallel()

var (
got string
config clibase.YAMLConfigPath
)
cmd := &clibase.Cmd{
Options: clibase.OptionSet{
{
Name: "url",
Flag: "url",
Default: "def.com",
Env: "URL",
Value: clibase.StringOf(&got),
YAML: "url",
},
{
Name: "config",
Flag: "config",
Default: "",
Value: &config,
},
},
Handler: (func(i *clibase.Invocation) error {
_, _ = fmt.Fprintf(i.Stdout, "%s", got)
return nil
}),
}

inv := cmd.Invoke()
stdio := fakeIO(inv)
fn(t, inv)
err := inv.Run()
require.NoError(t, err)
require.Equal(t, want, stdio.Stdout.String())
})
}

// Base case
inv := cmd.Invoke()
stdio := fakeIO(inv)
err := inv.Run()
require.NoError(t, err)
require.Equal(t, "def.com", stdio.Stdout.String())
test("DefaultOverNothing", "def.com", func(t *testing.T, inv *clibase.Invocation) {})

// Flag overrides
inv = cmd.Invoke("--url", "good.com")
stdio = fakeIO(inv)
err = inv.Run()
require.NoError(t, err)
require.Equal(t, "good.com", stdio.Stdout.String())
test("FlagOverDefault", "good.com", func(t *testing.T, inv *clibase.Invocation) {
inv.Args = []string{"--url", "good.com"}
})

// Env overrides
inv = cmd.Invoke()
inv.Environ.Set("URL", "good.com")
stdio = fakeIO(inv)
err = inv.Run()
require.NoError(t, err)
require.Equal(t, "good.com", stdio.Stdout.String())
test("EnvOverDefault", "good.com", func(t *testing.T, inv *clibase.Invocation) {
inv.Environ.Set("URL", "good.com")
})

test("FlagOverEnv", "good.com", func(t *testing.T, inv *clibase.Invocation) {
inv.Environ.Set("URL", "bad.com")
inv.Args = []string{"--url", "good.com"}
})

test("FlagOverYAML", "good.com", func(t *testing.T, inv *clibase.Invocation) {
fi, err := os.CreateTemp(t.TempDir(), "config.yaml")
require.NoError(t, err)
defer fi.Close()

_, err = fi.WriteString("url: bad.com")
require.NoError(t, err)

inv.Args = []string{"--config", fi.Name(), "--url", "good.com"}
})

test("YAMLOverDefault", "good.com", func(t *testing.T, inv *clibase.Invocation) {
fi, err := os.CreateTemp(t.TempDir(), "config.yaml")
require.NoError(t, err)
defer fi.Close()

_, err = fi.WriteString("url: good.com")
require.NoError(t, err)

inv.Args = []string{"--config", fi.Name()}
})
}
50 changes: 41 additions & 9 deletionscli/clibase/option.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,12 +2,23 @@ package clibase

import (
"os"
"strings"

"github.com/hashicorp/go-multierror"
"github.com/spf13/pflag"
"golang.org/x/xerrors"
)

type ValueSource string

const (
ValueSourceNone ValueSource = ""
ValueSourceFlag ValueSource = "flag"
ValueSourceEnv ValueSource = "env"
ValueSourceYAML ValueSource = "yaml"
ValueSourceDefault ValueSource = "default"
)

// Option is a configuration option for a CLI application.
type Option struct {
Name string `json:"name,omitempty"`
Expand DownExpand Up@@ -47,7 +58,18 @@ type Option struct {

Hidden bool `json:"hidden,omitempty"`

envChanged bool
ValueSource ValueSource `json:"value_source,omitempty"`
}

func (o Option) YAMLPath() string {
if o.YAML == "" {
return ""
}
var gs []string
for _, g := range o.Group.Ancestry() {
gs = append(gs, g.YAML)
}
return strings.Join(append(gs, o.YAML), ".")
}

// OptionSet is a group of options that can be applied to a command.
Expand DownExpand Up@@ -135,8 +157,7 @@ func (s *OptionSet) ParseEnv(vs []EnvVar) error {
continue
}

opt.envChanged = true
(*s)[i] = opt
(*s)[i].ValueSource = ValueSourceEnv
if err := opt.Value.Set(envVal); err != nil {
merr = multierror.Append(
merr, xerrors.Errorf("parse %q: %w", opt.Name, err),
Expand All@@ -148,8 +169,8 @@ func (s *OptionSet) ParseEnv(vs []EnvVar) error {
}

// SetDefaults sets the default values for each Option, skipping values
// thathavealreadybeen set as indicated by the skip map.
func (s *OptionSet) SetDefaults(skip map[int]struct{}) error {
// that alreadyhave a value source.
func (s *OptionSet) SetDefaults() error {
if s == nil {
return nil
}
Expand All@@ -158,10 +179,8 @@ func (s *OptionSet) SetDefaults(skip map[int]struct{}) error {

for i, opt := range *s {
// Skip values that may have already been set by the user.
if len(skip) > 0 {
if _, ok := skip[i]; ok {
continue
}
if opt.ValueSource != ValueSourceNone {
continue
}

if opt.Default == "" {
Expand All@@ -178,6 +197,7 @@ func (s *OptionSet) SetDefaults(skip map[int]struct{}) error {
)
continue
}
(*s)[i].ValueSource = ValueSourceDefault
if err := opt.Value.Set(opt.Default); err != nil {
merr = multierror.Append(
merr, xerrors.Errorf("parse %q: %w", opt.Name, err),
Expand All@@ -186,3 +206,15 @@ func (s *OptionSet) SetDefaults(skip map[int]struct{}) error {
}
return merr.ErrorOrNil()
}

// ByName returns the Option with the given name, or nil if no such option
// exists.
func (s *OptionSet) ByName(name string) *Option {
for i := range *s {
opt := &(*s)[i]
if opt.Name == name {
return opt
}
}
return nil
}
8 changes: 4 additions & 4 deletionscli/clibase/option_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,7 +49,7 @@ func TestOptionSet_ParseFlags(t *testing.T) {
},
}

err := os.SetDefaults(nil)
err := os.SetDefaults()
require.NoError(t, err)

err = os.FlagSet().Parse([]string{"--name", "foo", "--name", "bar"})
Expand DownExpand Up@@ -111,7 +111,7 @@ func TestOptionSet_ParseEnv(t *testing.T) {
},
}

err := os.SetDefaults(nil)
err := os.SetDefaults()
require.NoError(t, err)

err = os.ParseEnv(clibase.ParseEnviron([]string{"CODER_WORKSPACE_NAME="}, "CODER_"))
Expand All@@ -133,7 +133,7 @@ func TestOptionSet_ParseEnv(t *testing.T) {
},
}

err := os.SetDefaults(nil)
err := os.SetDefaults()
require.NoError(t, err)

err = os.ParseEnv([]clibase.EnvVar{
Expand All@@ -157,7 +157,7 @@ func TestOptionSet_ParseEnv(t *testing.T) {
},
}

err := os.SetDefaults(nil)
err := os.SetDefaults()
require.NoError(t, err)

err = os.ParseEnv([]clibase.EnvVar{
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp