Skip to content

Commit

Permalink
fix: existing file/dir always checks default
Browse files Browse the repository at this point in the history
updated existing file/dir mappers to early return if already set;
added tests for existing file/dir mappers;
  • Loading branch information
pyqlsa authored and alecthomas committed May 16, 2022
1 parent 3c21644 commit 0aaa4c1
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
16 changes: 16 additions & 0 deletions mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,14 @@ func existingFileMapper(r *Registry) MapperFunc {
if err != nil {
return err
}

if ctx.Value.Set {
// early return to avoid checking extra files that may not exist;
// this hack only works because the value provided on the cli is
// checked before the default value is checked (if default is set).
return nil
}

if path != "-" {
path = ExpandPath(path)
stat, err := os.Stat(path)
Expand Down Expand Up @@ -640,6 +648,14 @@ func existingDirMapper(r *Registry) MapperFunc {
if err != nil {
return err
}

if ctx.Value.Set {
// early return to avoid checking extra dirs that may not exist;
// this hack only works because the value provided on the cli is
// checked before the default value is checked (if default is set).
return nil
}

path = ExpandPath(path)
stat, err := os.Stat(path)
if err != nil {
Expand Down
66 changes: 66 additions & 0 deletions mapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,72 @@ func TestFileMapper(t *testing.T) {
require.Equal(t, os.Stdin, cli.File)
}

//nolint:dupl
func TestExistingFileMapper(t *testing.T) {
type CLI struct {
File string `type:"existingfile"`
}
var cli CLI
p := mustNew(t, &cli)
_, err := p.Parse([]string{"--file", "testdata/file.txt"})
require.NoError(t, err)
require.NotNil(t, cli.File)
p = mustNew(t, &cli)
_, err = p.Parse([]string{"--file", "testdata/missing.txt"})
require.Error(t, err)
require.Contains(t, err.Error(), "missing.txt: no such file or directory")
p = mustNew(t, &cli)
_, err = p.Parse([]string{"--file", "testdata/"})
require.Error(t, err)
require.Contains(t, err.Error(), "exists but is a directory")
}

func TestExistingFileMapperDefaultMissing(t *testing.T) {
type CLI struct {
File string `type:"existingfile" default:"testdata/missing.txt"`
}
var cli CLI
p := mustNew(t, &cli)
file := "testdata/file.txt"
_, err := p.Parse([]string{"--file", file})
require.NoError(t, err)
require.NotNil(t, cli.File)
require.Contains(t, cli.File, file)
}

//nolint:dupl
func TestExistingDirMapper(t *testing.T) {
type CLI struct {
Dir string `type:"existingdir"`
}
var cli CLI
p := mustNew(t, &cli)
_, err := p.Parse([]string{"--dir", "testdata/"})
require.NoError(t, err)
require.NotNil(t, cli.Dir)
p = mustNew(t, &cli)
_, err = p.Parse([]string{"--dir", "missingdata/"})
require.Error(t, err)
require.Contains(t, err.Error(), "missingdata: no such file or directory")
p = mustNew(t, &cli)
_, err = p.Parse([]string{"--dir", "testdata/file.txt"})
require.Error(t, err)
require.Contains(t, err.Error(), "exists but is not a directory")
}

func TestExistingDirMapperDefaultMissing(t *testing.T) {
type CLI struct {
Dir string `type:"existingdir" default:"missing-dir"`
}
var cli CLI
p := mustNew(t, &cli)
dir := "testdata"
_, err := p.Parse([]string{"--dir", dir})
require.NoError(t, err)
require.NotNil(t, cli.Dir)
require.Contains(t, cli.Dir, dir)
}

func TestMapperPlaceHolder(t *testing.T) {
var cli struct {
Flag string
Expand Down

0 comments on commit 0aaa4c1

Please sign in to comment.