From 2890f1baa58d00f1ec56a8e2831b8d1c75823472 Mon Sep 17 00:00:00 2001 From: Dustin Blackman Date: Sat, 1 Feb 2020 10:28:00 -0500 Subject: [PATCH] add pkg-root flag --- README.md | 14 +++++++----- cmd/gomodrun/main.go | 30 +++++++++++++++++++------ pkg.go | 23 ++++++++++++------- pkg_test.go | 30 ++++++++++++++++++++++--- tests/alternative-tools-dir/go.mod | 5 +++++ tests/alternative-tools-dir/go.sum | 2 ++ tests/alternative-tools-dir/go.tools.go | 7 ++++++ 7 files changed, 88 insertions(+), 23 deletions(-) create mode 100644 tests/alternative-tools-dir/go.mod create mode 100644 tests/alternative-tools-dir/go.sum create mode 100644 tests/alternative-tools-dir/go.tools.go diff --git a/README.md b/README.md index 607896e..3b6ad70 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,9 @@ The forgotten go tool that executes and caches binaries included in go.mod files # Convert a JSON object to a Go struct, properly passing in stdin. echo example.json | gomodrun gojson > example.go + + # Specifiy alternative root directory containing a go.mod and tools file. + gomodrun -r ./alternative-tools-dir golangci-lint run ``` ## Installation @@ -98,11 +101,12 @@ import ( ) func main() { - exitCode, err := gomodrun.Run("golangci-lint", []string{"run"}, gomodrun.Options{ - Stdin: os.Stdin, - Stdout: os.Stdout, - Stderr: os.Stderr, - Env: os.Environ(), + exitCode, err := gomodrun.Run("golangci-lint", []string{"run"}, &gomodrun.Options{ + Stdin: os.Stdin, + Stdout: os.Stdout, + Stderr: os.Stderr, + Env: os.Environ(), + PkgRoot: "", }) } ``` diff --git a/cmd/gomodrun/main.go b/cmd/gomodrun/main.go index 0ff11e2..8334208 100644 --- a/cmd/gomodrun/main.go +++ b/cmd/gomodrun/main.go @@ -34,20 +34,36 @@ https://github.com/dustinblackman/gomodrun/commit/%s The forgotten go tool that executes and caches binaries included in go.mod files. Usage: - gomodrun cli-name [parameters] + gomodrun [flags] cli-name [parameters] Example: gomodrun golangci-lint run - echo example.json | gomodrun gojson > example.go`, version, date, commit) + echo example.json | gomodrun gojson > example.go + gomodrun -r ./alternative-tools-dir golangci-lint run + +Flags: + -r, --pkg-root string Specify alternative root directory containing a go.mod and tools file. Defaults to walking up the file tree to locate go.mod.`, version, date, commit) os.Exit(0) } - exitCode, err := gomodrun.Run(os.Args[1], os.Args[2:], gomodrun.Options{ - Stdin: os.Stdin, - Stdout: os.Stdout, - Stderr: os.Stderr, - Env: os.Environ(), + cmdPosition := 1 + argsPosition := 2 + pkgRoot := "" + + if os.Args[1] == "-r" || os.Args[1] == "--pkg-root" { + pkgRoot = os.Args[2] + cmdPosition += 2 + argsPosition += 2 + } + + exitCode, err := gomodrun.Run(os.Args[cmdPosition], os.Args[argsPosition:], &gomodrun.Options{ + Stdin: os.Stdin, + Stdout: os.Stdout, + Stderr: os.Stderr, + Env: os.Environ(), + PkgRoot: pkgRoot, }) + if err != nil { exitWithError(err) } diff --git a/pkg.go b/pkg.go index 0a84383..6d1dec6 100644 --- a/pkg.go +++ b/pkg.go @@ -19,10 +19,11 @@ import ( // Options contains parameters that are passed to `exec.Command` when running the binary. type Options struct { - Stdin io.Reader - Stdout io.Writer - Stderr io.Writer - Env []string + Stdin io.Reader // Stdin passed to tool. + Stdout io.Writer // Stdout passed to tool. + Stderr io.Writer // Stderr passed to tool. + Env []string // Array of environment variables passed to tool. + PkgRoot string // Root directory of go.mod with tools } // GetPkgRoot gets your projects package root, allowing you to run gomodrun from any sub directory. @@ -31,6 +32,7 @@ func GetPkgRoot() (string, error) { if err != nil { return "", err } + for { if _, err := os.Stat(path.Join(currentDir, "go.mod")); !os.IsNotExist(err) { absPath, err := filepath.Abs(currentDir) @@ -170,10 +172,15 @@ func GetCachedBin(pkgRoot, binName, cmdPath string) (string, error) { } // Run executes your binary. -func Run(binName string, args []string, options Options) (int, error) { - pkgRoot, err := GetPkgRoot() - if err != nil { - return -1, err +func Run(binName string, args []string, options *Options) (int, error) { + var err error + pkgRoot := options.PkgRoot + + if pkgRoot == "" { + pkgRoot, err = GetPkgRoot() + if err != nil { + return -1, err + } } cmdPath, err := GetCommandVersionedPkgPath(pkgRoot, binName) diff --git a/pkg_test.go b/pkg_test.go index 3650ec8..f2894bd 100644 --- a/pkg_test.go +++ b/pkg_test.go @@ -74,21 +74,45 @@ var _ = Describe("pkg", func() { Context("Run", func() { It("should return exit code 0 when binary exits with 0", func() { - exitCode, err := gomodrun.Run("hello-world", []string{}, gomodrun.Options{}) + exitCode, err := gomodrun.Run("hello-world", []string{}, &gomodrun.Options{}) Expect(err).To(BeNil()) Expect(exitCode).To(Equal(0)) }) It("should return exit code 1 when the binary exists with 1", func() { - exitCode, err := gomodrun.Run("hello-world", []string{"1"}, gomodrun.Options{}) + exitCode, err := gomodrun.Run("hello-world", []string{"1"}, &gomodrun.Options{}) Expect(err).To(BeNil()) Expect(exitCode).To(Equal(1)) }) It("should return an error when the binary does not exist", func() { - exitCode, err := gomodrun.Run("not-real", []string{}, gomodrun.Options{}) + exitCode, err := gomodrun.Run("not-real", []string{}, &gomodrun.Options{}) Expect(err).ToNot(BeNil()) Expect(exitCode).To(Equal(-1)) }) + + Context("Alternative tools directory", func() { + options := &gomodrun.Options{ + PkgRoot: path.Join(cwd, "./tests/alternative-tools-dir"), + } + + It("should return exit code 0 when binary exits with 0", func() { + exitCode, err := gomodrun.Run("hello-world", []string{}, options) + Expect(err).To(BeNil()) + Expect(exitCode).To(Equal(0)) + }) + + It("should return exit code 1 when the binary exists with 1", func() { + exitCode, err := gomodrun.Run("hello-world", []string{"1"}, options) + Expect(err).To(BeNil()) + Expect(exitCode).To(Equal(1)) + }) + + It("should return an error when the binary does not exist", func() { + exitCode, err := gomodrun.Run("not-real", []string{}, options) + Expect(err).ToNot(BeNil()) + Expect(exitCode).To(Equal(-1)) + }) + }) }) }) diff --git a/tests/alternative-tools-dir/go.mod b/tests/alternative-tools-dir/go.mod new file mode 100644 index 0000000..ee09b2e --- /dev/null +++ b/tests/alternative-tools-dir/go.mod @@ -0,0 +1,5 @@ +module github.com/dustinblackman/gomodrun-test + +go 1.13 + +require github.com/dustinblackman/go-hello-world-test v0.0.2 diff --git a/tests/alternative-tools-dir/go.sum b/tests/alternative-tools-dir/go.sum new file mode 100644 index 0000000..b470a1a --- /dev/null +++ b/tests/alternative-tools-dir/go.sum @@ -0,0 +1,2 @@ +github.com/dustinblackman/go-hello-world-test v0.0.2 h1:DcAbKiyeohJ/c/3m5c7h3tQGKA8q7J9eahZpAjo3ZZs= +github.com/dustinblackman/go-hello-world-test v0.0.2/go.mod h1:wbYSnWUoM4tqbraqvRvVuK6jV7YV4Gv+d/lTltepZyA= diff --git a/tests/alternative-tools-dir/go.tools.go b/tests/alternative-tools-dir/go.tools.go new file mode 100644 index 0000000..a84abea --- /dev/null +++ b/tests/alternative-tools-dir/go.tools.go @@ -0,0 +1,7 @@ +// +build tools + +package gomodrun + +import ( + _ "github.com/dustinblackman/go-hello-world-test/hello-world" +)