Skip to content

Commit

Permalink
Fix for windows long/short names
Browse files Browse the repository at this point in the history
  • Loading branch information
jkieboom committed Jun 17, 2024
1 parent 173d9ae commit 3924073
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 71 deletions.
52 changes: 9 additions & 43 deletions assert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ package flags

import (
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
"path"
"runtime"
"testing"

"github.com/sergi/go-diff/diffmatchpatch"
)

func assertCallerInfo() (string, int) {
Expand Down Expand Up @@ -128,50 +126,18 @@ func assertParseFail(t *testing.T, typ ErrorType, msg string, data interface{},
return ret
}

func diff(a, b string) (string, error) {
atmp, err := ioutil.TempFile("", "help-diff")

if err != nil {
return "", err
}

btmp, err := ioutil.TempFile("", "help-diff")

if err != nil {
return "", err
}

if _, err := io.WriteString(atmp, a); err != nil {
return "", err
}

if _, err := io.WriteString(btmp, b); err != nil {
return "", err
}

ret, err := exec.Command("diff", "-u", "-d", "--label", "got", atmp.Name(), "--label", "expected", btmp.Name()).Output()

os.Remove(atmp.Name())
os.Remove(btmp.Name())

if err.Error() == "exit status 1" {
return string(ret), nil
}

return string(ret), err
}

func assertDiff(t *testing.T, actual, expected, msg string) {
if actual == expected {
return
}

ret, err := diff(actual, expected)
dmp := diffmatchpatch.New()
diffs := dmp.DiffMain(actual, expected, false)

if err != nil {
assertErrorf(t, "Unexpected diff error: %s", err)
assertErrorf(t, "Unexpected %s, expected:\n\n%s\n\nbut got\n\n%s", msg, expected, actual)
} else {
assertErrorf(t, "Unexpected %s:\n\n%s", msg, ret)
if len(diffs) == 0 {
return
}

pretty := dmp.DiffPrettyText(diffs)
assertErrorf(t, "Unexpected %s:\n\n%s", msg, pretty)
}
15 changes: 13 additions & 2 deletions completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,21 @@ func (c *completion) completeOptionNames(s *parseState, prefix string, match str
var results []Completion
repeats := map[string]bool{}

var longprefix string
var shortprefix string

if prefix == "/" {
longprefix = "/"
shortprefix = "/"
} else {
longprefix = "--"
shortprefix = "-"
}

for name, opt := range s.lookup.longNames {
if strings.HasPrefix(name, match) && !opt.Hidden {
results = append(results, Completion{
Item: defaultLongOptDelimiter + name,
Item: longprefix + name,
Description: opt.Description,
})

Expand All @@ -108,7 +119,7 @@ func (c *completion) completeOptionNames(s *parseState, prefix string, match str
for name, opt := range s.lookup.shortNames {
if _, exist := repeats[name]; !exist && strings.HasPrefix(name, match) && !opt.Hidden {
results = append(results, Completion{
Item: string(defaultShortOptDelimiter) + name,
Item: shortprefix + name,
Description: opt.Description,
})
}
Expand Down
46 changes: 29 additions & 17 deletions completion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"path/filepath"
"reflect"
"runtime"
"sort"
"strings"
"testing"
)
Expand Down Expand Up @@ -81,6 +82,14 @@ type completionTest struct {

var completionTests []completionTest

func makeLongName(option string) string {
return defaultLongOptDelimiter + option
}

func makeShortName(option string) string {
return string(defaultShortOptDelimiter) + option
}

func init() {
_, sourcefile, _, _ := runtime.Caller(0)
completionTestSourcedir := filepath.Join(filepath.SplitList(path.Dir(sourcefile))...)
Expand All @@ -97,15 +106,15 @@ func init() {
completionTests = []completionTest{
{
// Short names
[]string{"-"},
[]string{"--debug", "--required", "--verbose", "--version", "-i"},
[]string{makeShortName("")},
[]string{makeLongName("debug"), makeLongName("required"), makeLongName("verbose"), makeLongName("version"), makeShortName("i")},
false,
},

{
// Short names full
[]string{"-i"},
[]string{"-i"},
[]string{makeShortName("i")},
[]string{makeShortName("i")},
false,
},

Expand Down Expand Up @@ -137,8 +146,8 @@ func init() {

{
// Long names partial
[]string{"--ver"},
[]string{"--verbose", "--version"},
[]string{makeLongName("ver")},
[]string{makeLongName("verbose"), makeLongName("version")},
false,
},

Expand Down Expand Up @@ -197,69 +206,69 @@ func init() {

{
// Flag filename
[]string{"rm", "-f", path.Join(completionTestSourcedir, "completion")},
[]string{"rm", makeShortName("f"), filepath.Join(completionTestSourcedir, "completion")},
completionTestFilename,
false,
},

{
// Flag short concat last filename
[]string{"rm", "-of", path.Join(completionTestSourcedir, "completion")},
[]string{"rm", "-of", filepath.Join(completionTestSourcedir, "completion")},
completionTestFilename,
false,
},

{
// Flag concat filename
[]string{"rm", "-f" + path.Join(completionTestSourcedir, "completion")},
[]string{"rm", "-f" + filepath.Join(completionTestSourcedir, "completion")},
[]string{"-f" + completionTestFilename[0], "-f" + completionTestFilename[1]},
false,
},

{
// Flag equal concat filename
[]string{"rm", "-f=" + path.Join(completionTestSourcedir, "completion")},
[]string{"rm", "-f=" + filepath.Join(completionTestSourcedir, "completion")},
[]string{"-f=" + completionTestFilename[0], "-f=" + completionTestFilename[1]},
false,
},

{
// Flag concat long filename
[]string{"rm", "--filename=" + path.Join(completionTestSourcedir, "completion")},
[]string{"rm", "--filename=" + filepath.Join(completionTestSourcedir, "completion")},
[]string{"--filename=" + completionTestFilename[0], "--filename=" + completionTestFilename[1]},
false,
},

{
// Flag long filename
[]string{"rm", "--filename", path.Join(completionTestSourcedir, "completion")},
[]string{"rm", "--filename", filepath.Join(completionTestSourcedir, "completion")},
completionTestFilename,
false,
},

{
// To subdir
[]string{"rm", "--filename", path.Join(completionTestSourcedir, "examples/bash-")},
[]string{path.Join(completionTestSourcedir, "examples/bash-completion/")},
[]string{"rm", "--filename", filepath.Join(completionTestSourcedir, "examples/bash-")},
[]string{filepath.Join(completionTestSourcedir, "examples/bash-completion/")},
false,
},

{
// Subdirectory
[]string{"rm", "--filename", path.Join(completionTestSourcedir, "examples") + "/"},
[]string{"rm", "--filename", filepath.Join(completionTestSourcedir, "examples") + "/"},
completionTestSubdir,
false,
},

{
// Custom completed
[]string{"rename", "-c", "hello un"},
[]string{"rename", makeShortName("c"), "hello un"},
[]string{"hello universe"},
false,
},
{
// Multiple flag filename
[]string{"add-multi-flag", "-f", filepath.Join(completionTestSourcedir, "completion")},
[]string{"add-multi-flag", makeShortName("f"), filepath.Join(completionTestSourcedir, "completion")},
completionTestFilename,
false,
},
Expand All @@ -282,6 +291,9 @@ func TestCompletion(t *testing.T) {
items[i] = v.Item
}

sort.Strings(items)
sort.Strings(test.Completed)

if !reflect.DeepEqual(items, test.Completed) {
t.Errorf("Args: %#v, %#v\n Expected: %#v\n Got: %#v", test.Args, test.ShowDescriptions, test.Completed, items)
}
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ module github.com/jessevdk/go-flags

go 1.20

require golang.org/x/sys v0.21.0
require (
github.com/sergi/go-diff v1.3.1
golang.org/x/sys v0.21.0
)
18 changes: 18 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,2 +1,20 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
2 changes: 1 addition & 1 deletion help_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ Arguments:
Available commands:
bommand A command with only hidden options
command A command (aliases: cm, cmd)
parent A command with a sub command
parent A parent command
`
} else {
expected = `Usage:
Expand Down
2 changes: 1 addition & 1 deletion parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func TestDefaults(t *testing.T) {
{
msg: "non-zero value arguments, expecting overwritten arguments",
args: []string{"-3=true"},
expectedErr: "bool flag `-3' cannot have an argument",
expectedErr: "bool flag `" + makeShortName("3") + "' cannot have an argument",
},
{
msg: "zero value arguments, expecting overwritten arguments",
Expand Down
8 changes: 7 additions & 1 deletion termsize.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@
package flags

import (
"flag"

"golang.org/x/sys/unix"
)

func getTerminalColumns() int {
if flag.Lookup("test.v") != nil {
return defaultTermSize
}

ws, err := unix.IoctlGetWinsize(0, unix.TIOCGWINSZ)
if err != nil {
return 80
return defaultTermSize
}
return int(ws.Col)
}
3 changes: 3 additions & 0 deletions termsize_defaults.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package flags

const defaultTermSize = 80
2 changes: 1 addition & 1 deletion termsize_nosysioctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
package flags

func getTerminalColumns() int {
return 80
return defaultTermSize
}
11 changes: 7 additions & 4 deletions termsize_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package flags

import (
"flag"
"syscall"
"unsafe"
)
Expand Down Expand Up @@ -66,21 +67,23 @@ func GetConsoleScreenBufferInfo(handle uintptr) (*CONSOLE_SCREEN_BUFFER_INFO, er
}

func getTerminalColumns() int {
defaultWidth := 80
if flag.Lookup("test.v") != nil {
return defaultTermSize
}

stdoutHandle, err := getStdHandle(syscall.STD_OUTPUT_HANDLE)
if err != nil {
return defaultWidth
return defaultTermSize
}

info, err := GetConsoleScreenBufferInfo(stdoutHandle)
if err != nil {
return defaultWidth
return defaultTermSize
}

if info.MaximumWindowSize.X > 0 {
return int(info.MaximumWindowSize.X)
}

return defaultWidth
return defaultTermSize
}

0 comments on commit 3924073

Please sign in to comment.