Skip to content

Commit

Permalink
Merge pull request #2 from urfave/extending-example
Browse files Browse the repository at this point in the history
Extending "setter" capabilities and example with state
  • Loading branch information
meatballhat committed Jul 1, 2023
2 parents b9823d7 + fe9f97c commit e20e7ba
Show file tree
Hide file tree
Showing 7 changed files with 273 additions and 26 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -3,3 +3,4 @@
*.o
*.out
*.so
/.local/
14 changes: 13 additions & 1 deletion Makefile
@@ -1,12 +1,21 @@
BENCHTIME ?= 10s
STRINGER := .local/bin/stringer

.PHONY: all
all: test
all: generate test

.PHONY: clean
clean:
rm -f coverage.out

.PHONY: distclean
distclean: clean
rm -f $(STRINGER)

.PHONY: generate
generate: $(STRINGER)
PATH=$(PWD)/.local/bin:$(PATH) go generate ./...

.PHONY: test
test:
go test -v -coverprofile=coverage.out ./...
Expand All @@ -18,3 +27,6 @@ bench:
.PHONY: show-cover
show-cover:
go tool cover -func=coverage.out

$(STRINGER):
GOBIN=$(PWD)/.local/bin go install golang.org/x/tools/cmd/stringer@latest
10 changes: 5 additions & 5 deletions argh.go
Expand Up @@ -10,22 +10,22 @@ import (
)

var (
tracingEnabled = os.Getenv("ARGH_TRACING") == "enabled"
traceLogger *log.Logger
isTracingOn = os.Getenv("ARGH_TRACING") == "on"
traceLogger *log.Logger

Error = errors.New("argh error")
)

func init() {
if !tracingEnabled {
if !isTracingOn {
return
}

traceLogger = log.New(os.Stderr, "ARGH TRACING: ", 0)
traceLogger = log.New(os.Stderr, "## ARGH TRACE ", 0)
}

func tracef(format string, v ...any) {
if !tracingEnabled {
if !isTracingOn {
return
}

Expand Down
193 changes: 173 additions & 20 deletions example_test.go
@@ -1,6 +1,7 @@
package argh_test

import (
"encoding/json"
"fmt"
"log"
"os"
Expand All @@ -9,31 +10,57 @@ import (
)

func ExampleParserConfig_simple() {
state := map[string]argh.CommandFlag{}

pCfg := argh.NewParserConfig()
pCfg.Prog = &argh.CommandConfig{
NValue: argh.OneOrMoreValue,
ValueNames: []string{"val"},
Flags: &argh.Flags{
Map: map[string]argh.FlagConfig{
"a": {
NValue: 2,
On: func(cf argh.CommandFlag) {
fmt.Printf("prog -a Name: %[1]q\n", cf.Name)
fmt.Printf("prog -a Values: %[1]q\n", cf.Values)
fmt.Printf("prog -a len(Nodes): %[1]v\n", len(cf.Nodes))
},
},
},
pCfg.Prog.NValue = argh.OneOrMoreValue
pCfg.Prog.ValueNames = []string{"val"}
pCfg.Prog.On = func(cf argh.CommandFlag) {
state["prog"] = cf

fmt.Printf("prog Name: %[1]q\n", cf.Name)
fmt.Printf("prog Values: %[1]q\n", cf.Values)
fmt.Printf("prog len(Nodes): %[1]v\n", len(cf.Nodes))
}

pCfg.Prog.SetFlagConfig("a", &argh.FlagConfig{
NValue: 2,
On: func(cf argh.CommandFlag) {
state["a"] = cf

fmt.Printf("prog -a Name: %[1]q\n", cf.Name)
fmt.Printf("prog -a Values: %[1]q\n", cf.Values)
fmt.Printf("prog -a len(Nodes): %[1]v\n", len(cf.Nodes))
},
})

pCfg.Prog.SetFlagConfig("b", &argh.FlagConfig{
Persist: true,
On: func(cf argh.CommandFlag) {
fmt.Printf("prog Name: %[1]q\n", cf.Name)
fmt.Printf("prog Values: %[1]q\n", cf.Values)
fmt.Printf("prog len(Nodes): %[1]v\n", len(cf.Nodes))
state["b"] = cf

fmt.Printf("prog -b Name: %[1]q\n", cf.Name)
fmt.Printf("prog -b Values: %[1]q\n", cf.Values)
fmt.Printf("prog -b len(Nodes): %[1]v\n", len(cf.Nodes))
},
}
})

pCfg.Prog.SetCommandConfig("sub", &argh.CommandConfig{
NValue: 3,
ValueNames: []string{"pilot", "navigator", "comms"},
On: func(cf argh.CommandFlag) {
state["sub"] = cf

fmt.Printf("prog sub Name: %[1]q\n", cf.Name)
fmt.Printf("prog sub Values: %[1]q\n", cf.Values)
fmt.Printf("prog sub len(Nodes): %[1]v\n", len(cf.Nodes))
},
})

// simulate command line args
os.Args = []string{"hello", "-a=from", "the", "ether"}
os.Args = []string{
"hello", "-a=from", "the", "ether", "sub", "marge", "patty", "selma", "-b",
}

pt, err := argh.ParseArgs(os.Args, pCfg)
if err != nil {
Expand All @@ -46,11 +73,137 @@ func ExampleParserConfig_simple() {
log.Fatal("no parse tree?")
}

enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")

fmt.Printf("state: ")

if err := enc.Encode(state); err != nil {
log.Fatalf("failed to jsonify: %v", err)
}

// Output:
// prog -a Name: "a"
// prog -a Values: map["0":"from" "1":"the"]
// prog -a len(Nodes): 4
// prog -b Name: "b"
// prog -b Values: map[]
// prog -b len(Nodes): 0
// prog sub Name: "sub"
// prog sub Values: map["comms":"selma" "navigator":"patty" "pilot":"marge"]
// prog sub len(Nodes): 8
// prog Name: "hello"
// prog Values: map["val":"ether"]
// prog len(Nodes): 4
// prog len(Nodes): 6
// state: {
// "a": {
// "Name": "a",
// "Values": {
// "0": "from",
// "1": "the"
// },
// "Nodes": [
// {},
// {
// "Literal": "from"
// },
// {},
// {
// "Literal": "the"
// }
// ]
// },
// "b": {
// "Name": "b",
// "Values": null,
// "Nodes": null
// },
// "prog": {
// "Name": "hello",
// "Values": {
// "val": "ether"
// },
// "Nodes": [
// {},
// {
// "Name": "a",
// "Values": {
// "0": "from",
// "1": "the"
// },
// "Nodes": [
// {},
// {
// "Literal": "from"
// },
// {},
// {
// "Literal": "the"
// }
// ]
// },
// {},
// {
// "Literal": "ether"
// },
// {},
// {
// "Name": "sub",
// "Values": {
// "comms": "selma",
// "navigator": "patty",
// "pilot": "marge"
// },
// "Nodes": [
// {},
// {
// "Literal": "marge"
// },
// {},
// {
// "Literal": "patty"
// },
// {},
// {
// "Literal": "selma"
// },
// {},
// {
// "Name": "b",
// "Values": null,
// "Nodes": null
// }
// ]
// }
// ]
// },
// "sub": {
// "Name": "sub",
// "Values": {
// "comms": "selma",
// "navigator": "patty",
// "pilot": "marge"
// },
// "Nodes": [
// {},
// {
// "Literal": "marge"
// },
// {},
// {
// "Literal": "patty"
// },
// {},
// {
// "Literal": "selma"
// },
// {},
// {
// "Name": "b",
// "Values": null,
// "Nodes": null
// }
// ]
// }
// }
}
45 changes: 45 additions & 0 deletions parser_config.go
Expand Up @@ -99,6 +99,19 @@ func (cCfg *CommandConfig) GetCommandConfig(name string) (CommandConfig, bool) {
return cCfg.Commands.Get(name)
}

func (cCfg *CommandConfig) SetCommandConfig(name string, sCfg *CommandConfig) {
tracef("CommandConfig.SetCommandConfig(%q, ...)", name)

if cCfg.Commands == nil {
cCfg.Commands = &Commands{Map: map[string]CommandConfig{}}
}

sCfg.init()
sCfg.Flags.Parent = cCfg.Flags

cCfg.Commands.Set(name, sCfg)
}

func (cCfg *CommandConfig) GetFlagConfig(name string) (FlagConfig, bool) {
tracef("CommandConfig.GetFlagConfig(%q)", name)

Expand All @@ -109,6 +122,16 @@ func (cCfg *CommandConfig) GetFlagConfig(name string) (FlagConfig, bool) {
return cCfg.Flags.Get(name)
}

func (cCfg *CommandConfig) SetFlagConfig(name string, flCfg *FlagConfig) {
tracef("CommandConfig.SetFlagConfig(%q, ...)", name)

if cCfg.Flags == nil {
cCfg.Flags = &Flags{Map: map[string]FlagConfig{}}
}

cCfg.Flags.Set(name, flCfg)
}

type FlagConfig struct {
NValue NValue
Persist bool
Expand Down Expand Up @@ -146,6 +169,16 @@ func (fl *Flags) Get(name string) (FlagConfig, bool) {
return flCfg, ok
}

func (fl *Flags) Set(name string, flCfg *FlagConfig) {
tracef("Flags.Get(%q)", name)

if fl.Map == nil {
fl.Map = map[string]FlagConfig{}
}

fl.Map[name] = *flCfg
}

type Commands struct {
Map map[string]CommandConfig
}
Expand All @@ -160,3 +193,15 @@ func (cmd *Commands) Get(name string) (CommandConfig, bool) {
cmdCfg, ok := cmd.Map[name]
return cmdCfg, ok
}

func (cmd *Commands) Set(name string, cCfg *CommandConfig) {
tracef("Commands.Set(%q, ...)", name)

if cmd.Map == nil {
cmd.Map = map[string]CommandConfig{}
}

cCfg.init()

cmd.Map[name] = *cCfg
}
1 change: 1 addition & 0 deletions token.go
@@ -1,3 +1,4 @@
//go:generate stringer -type Token .
package argh

import "fmt"
Expand Down
35 changes: 35 additions & 0 deletions token_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit e20e7ba

Please sign in to comment.