Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 0 additions & 1 deletion .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,4 @@ formatters:
- gofmt
- gofumpt
- goimports
- golines

15 changes: 11 additions & 4 deletions cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,14 @@ func (c *Broccli) getFlagSetPtrs(
flagInstance := cmd.flags[flagName]
if flagInstance.valueType == TypeBool {
flagNamePtrs[flagName] = fset.Bool(flagName, false, "")
flagAliasPtrs[flagInstance.alias] = fset.Bool(flagInstance.alias, false, "")
if flagInstance.alias != "" {
flagAliasPtrs[flagInstance.alias] = fset.Bool(flagInstance.alias, false, "")
}
} else {
flagNamePtrs[flagName] = fset.String(flagName, "", "")
flagAliasPtrs[flagInstance.alias] = fset.String(flagInstance.alias, "", "")
if flagInstance.alias != "" {
flagAliasPtrs[flagInstance.alias] = fset.String(flagInstance.alias, "", "")
}
}
}

Expand Down Expand Up @@ -335,15 +339,18 @@ func (c *Broccli) processFlags(
if flag.valueType == TypeBool {
c.parsedFlags[name] = "false"
//nolint:forcetypeassert
if *(nflags[name]).(*bool) || *(aflags[cmd.flags[name].alias]).(*bool) {
if *(nflags[name]).(*bool) || (cmd.flags[name].alias != "" && *(aflags[cmd.flags[name].alias]).(*bool)) {
c.parsedFlags[name] = "true"
}

continue
}

//nolint:forcetypeassert
aliasValue := *(aflags[flag.alias]).(*string)
aliasValue := ""
if flag.alias != "" {
aliasValue = *(aflags[flag.alias]).(*string)
}
//nolint:forcetypeassert
nameValue := *(nflags[name]).(*string)

Expand Down
192 changes: 156 additions & 36 deletions cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,57 +9,183 @@ import (
"testing"
)

// TestCLI creates a test CLI instance with a single command with flags and test
// basic functionality.
func TestCLI(t *testing.T) {
t.Parallel()

f, err := os.CreateTemp(t.TempDir(), "stdout")
func initTestCLI(t *testing.T) (*os.File, *os.File) {
tmpFile, err := os.CreateTemp(t.TempDir(), "stdout")
if err != nil {
t.Error("error creating temporary file")

return nil, nil
}

defer func() {
err := os.Remove(f.Name())
devNull, err := os.OpenFile("/dev/null", os.O_APPEND, 0o600)
if err != nil {
t.Error("error opening temporary file")

err := os.Remove(tmpFile.Name())
if err != nil {
t.Error("error removing temporary file")
}
}()

devNull, err := os.OpenFile("/dev/null", os.O_APPEND, 0o600)
if err != nil {
t.Error("error opening temporary file")
err = tmpFile.Close()
if err != nil {
t.Error("error closing temporary file")
}

return nil, nil
}

os.Stdout = devNull
os.Stderr = devNull

return tmpFile, devNull
}

func removeTestFiles(t *testing.T, tmpFile *os.File, devNull *os.File) {
err := os.Remove(tmpFile.Name())
if err != nil {
t.Error("error removing temporary file")
}

err = tmpFile.Close()
if err != nil {
t.Error("error closing temporary file")
}

err = devNull.Close()
if err != nil {
t.Error("error closing /dev/null")
}
}

// TestCLIStringFlag tests a CLI instance with single flag instance.
func TestCLIStringFlag(t *testing.T) {
t.Parallel()

tmpFile, devNull := initTestCLI(t)
defer func() {
removeTestFiles(t, tmpFile, devNull)
}()

broccli := NewBroccli("Example", "App", "Author <a@example.com>")
cmd1 := broccli.Command("cmd", "Prints out a string", func(_ context.Context, c *Broccli) int {
text := c.Flag("text")
if text == "tekst" {
return 2
}

return 3
})
cmd1.Flag("text", "t", "Text", "Text to check", TypeString, IsRequired)

os.Args = []string{"test", "wrongcmd"}
got := broccli.Run(context.Background())
if got != 1 {
t.Errorf("CLI.Run() should have returned 1 instead of %d", got)
}

os.Args = []string{"test", "cmd"}
got = broccli.Run(context.Background())
if got != 1 {
t.Errorf("CLI.Run() should have returned 1 instead of %d", got)
}

os.Args = []string{"test", "cmd", "-t", "tekst"}
got = broccli.Run(context.Background())
if got != 2 {
t.Errorf("CLI.Run() should have returned 2 instead of %d", got)
}

os.Args = []string{"test", "cmd", "-t", "return3"}
got = broccli.Run(context.Background())
if got != 3 {
t.Errorf("CLI.Run() should have returned 3 instead of %d", got)
}

os.Args = []string{"test", "cmd", "--text", "tekst"}
got = broccli.Run(context.Background())
if got != 2 {
t.Errorf("CLI.Run() should have returned 2 instead of %d", got)
}

os.Args = []string{"test", "cmd", "--text", "return3"}
got = broccli.Run(context.Background())
if got != 3 {
t.Errorf("CLI.Run() should have returned 3 instead of %d", got)
}
}

// TestCLIStringFlagNoAlias tests a CLI instance with single flag that does not have an alias.
func TestCLIStringFlagNoAlias(t *testing.T) {
t.Parallel()

tmpFile, devNull := initTestCLI(t)
defer func() {
removeTestFiles(t, tmpFile, devNull)
}()

broccli := NewBroccli("Example", "App", "Author <a@example.com>")
cmd1 := broccli.Command("cmd", "Prints out a string", func(_ context.Context, c *Broccli) int {
text := c.Flag("text")
text2 := c.Flag("text2")
if text == "tekst" {
return 2
}
if text2 == "tekst2" {
return 4
}

return 3
})
cmd1.Flag("text", "", "Text", "Text to check", TypeString, IsRequired)
cmd1.Flag("text2", "", "Text2", "Text2 to check", TypeString, IsRequired)

os.Args = []string{"test", "wrongcmd"}
got := broccli.Run(context.Background())
if got != 1 {
t.Errorf("CLI.Run() should have returned 1 instead of %d", got)
}

os.Args = []string{"test", "cmd"}
got = broccli.Run(context.Background())
if got != 1 {
t.Errorf("CLI.Run() should have returned 1 instead of %d", got)
}

os.Args = []string{"test", "cmd", "--text", "tekst", "--text2", "tekst2"}
got = broccli.Run(context.Background())
if got != 2 {
t.Errorf("CLI.Run() should have returned 2 instead of %d", got)
}

os.Args = []string{"test", "cmd", "--text", "return3", "--text2", "return3"}
got = broccli.Run(context.Background())
if got != 3 {
t.Errorf("CLI.Run() should have returned 3 instead of %d", got)
}
}

// TestCLIVariousFlags tests a CLI with various types of flags
func TestCLIVariousFlags(t *testing.T) {
t.Parallel()

tmpFile, devNull := initTestCLI(t)
defer func() {
removeTestFiles(t, tmpFile, devNull)
}()

c := NewBroccli("Example", "App", "Author <a@example.com>")
cmd1 := c.Command("cmd1", "Prints out a string", func(_ context.Context, c *Broccli) int {
_, _ = fmt.Fprintf(f, "TESTVALUE:%s%s\n\n", c.Flag("tekst"), c.Flag("alphanumdots"))
_, _ = fmt.Fprintf(tmpFile, "TESTVALUE:%s%s\n\n", c.Flag("tekst"), c.Flag("alphanumdots"))

if c.Flag("bool") == "true" {
_, _ = fmt.Fprintf(f, "BOOL:true")
_, _ = fmt.Fprintf(tmpFile, "BOOL:true")
}

return 2
})
cmd1.Flag("tekst", "t", "Text", "Text to print", TypeString, IsRequired)
cmd1.Flag(
"alphanumdots",
"a",
"Alphanum with dots",
"Can have dots",
TypeAlphanumeric,
AllowDots,
)
cmd1.Flag(
"make-required",
"r",
"",
"Make alphanumdots required",
TypeBool,
0,
cmd1.Flag("alphanumdots", "a", "Alphanum with dots", "Can have dots", TypeAlphanumeric, AllowDots)
cmd1.Flag("make-required", "r", "", "Make alphanumdots required", TypeBool, 0,
OnTrue(func(c *Command) {
c.flags["alphanumdots"].flags |= IsRequired
}),
Expand All @@ -68,48 +194,42 @@ func TestCLI(t *testing.T) {
cmd1.Flag("bool", "b", "", "Bool value", TypeBool, 0)

os.Args = []string{"test", "cmd1"}

got := c.Run(context.Background())
if got != 1 {
t.Errorf("CLI.Run() should have returned 1 instead of %d", got)
}

os.Args = []string{"test", "cmd1", "-t", ""}

got = c.Run(context.Background())
if got != 1 {
t.Errorf("CLI.Run() should have returned 1 instead of %d", got)
}

os.Args = []string{"test", "cmd1", "--tekst", "Tekst123", "--alphanumdots"}

got = c.Run(context.Background())
if got != 2 {
t.Errorf("CLI.Run() should have returned 2 instead of %d", got)
}

os.Args = []string{"test", "cmd1", "--tekst", "Tekst123", "-r"}

got = c.Run(context.Background())
if got != 1 {
t.Errorf("CLI.Run() should have returned 1 instead of %d", got)
}

os.Args = []string{"test", "cmd1", "--tekst", "Tekst123", "--alphanumdots", "aZ0-9"}

got = c.Run(context.Background())
if got != 1 {
t.Errorf("CLI.Run() should have returned 1 instead of %d", got)
}

os.Args = []string{"test", "cmd1", "--tekst", "Tekst123", "--alphanumdots", "aZ0.9", "-b"}

got = c.Run(context.Background())
if got != 2 {
t.Errorf("CLI.Run() should have returned 2 instead of %d", got)
}

f2, err := os.Open(f.Name())
f2, err := os.Open(tmpFile.Name())
if err != nil {
t.Error("error opening temporary file")
}
Expand Down
2 changes: 1 addition & 1 deletion version.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package broccli

// VERSION is the current version of the module.
const VERSION = "3.1.0"
const VERSION = "3.2.0"