Skip to content

Commit

Permalink
Add ChangeToFlag to allow changing the current working directory.
Browse files Browse the repository at this point in the history
  • Loading branch information
mitar authored and alecthomas committed Jan 3, 2022
1 parent 88dcc90 commit f5bd146
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
19 changes: 19 additions & 0 deletions util.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package kong

import (
"fmt"
"os"
"reflect"
)

// ConfigFlag uses the configured (via kong.Configuration(loader)) configuration loader to load configuration
Expand Down Expand Up @@ -33,3 +35,20 @@ func (v VersionFlag) BeforeApply(app *Kong, vars Vars) error {
app.Exit(0)
return nil
}

// ChangeDirFlag changes the current working directory to a path specified by a flag
// early in the parsing process, changing how other flags resolve relative paths.
//
// Use this flag to provide a "git -C" like functionality.
type ChangeDirFlag string

// Decode is used to create a side effect of changing the current working directory.
func (c ChangeDirFlag) Decode(ctx *DecodeContext) error {
var path string
err := ctx.Scan.PopValueInto("string", &path)
if err != nil {
return err
}
ctx.Value.Target.Set(reflect.ValueOf(ChangeDirFlag(path)))
return os.Chdir(path)
}
22 changes: 22 additions & 0 deletions util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package kong
import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"

Expand Down Expand Up @@ -42,3 +43,24 @@ func TestVersionFlag(t *testing.T) {
require.Equal(t, "0.1.1", strings.TrimSpace(w.String()))
require.Equal(t, 0, called)
}

func TestChangeDirFlag(t *testing.T) {
cwd, err := os.Getwd()
require.NoError(t, err)
defer os.Chdir(cwd) // nolint: errcheck

dir := t.TempDir()
file := filepath.Join(dir, "out.txt")
err = os.WriteFile(file, []byte("foobar"), 0o600)
require.NoError(t, err)

var cli struct {
ChangeDir ChangeDirFlag `short:"C"`
Path string `arg:"" type:"existingfile"`
}

p := Must(&cli)
_, err = p.Parse([]string{"-C", dir, "out.txt"})
require.NoError(t, err)
require.Equal(t, file, cli.Path)
}

0 comments on commit f5bd146

Please sign in to comment.