-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add check for go version, treat errs as warning
Signed-off-by: Tobias Brumhard <tobias.brumhard@mail.schwarz>
- Loading branch information
Showing
5 changed files
with
216 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package exec | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"fmt" | ||
"os/exec" | ||
"strings" | ||
) | ||
|
||
var ErrInvalidArgs = errors.New("invalid command args") | ||
|
||
var _ Command = (*execCmd)(nil) | ||
|
||
type Command interface { | ||
// Run executes the command and returns stdout as string as well as an error if the command failed. | ||
// The error is of type ErrWithStderr and can be type asserted to that to get the exact stderr output. | ||
Run() (string, error) | ||
// Args returns all the command's args including the executable name as the first item. | ||
Args() []string | ||
} | ||
|
||
type execCmd struct { | ||
*exec.Cmd | ||
} | ||
|
||
func (ec *execCmd) Run() (string, error) { | ||
stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{} | ||
ec.Stdout, ec.Stderr = stdout, stderr | ||
|
||
if err := ec.Cmd.Run(); err != nil { | ||
return "", &ErrWithStderr{ | ||
Wrapped: err, | ||
Args: ec.Cmd.Args, | ||
StdErr: stderr.Bytes(), | ||
} | ||
} | ||
|
||
return stdout.String(), nil | ||
} | ||
|
||
func (ec *execCmd) Args() []string { | ||
return ec.Cmd.Args | ||
} | ||
|
||
func NewExecCmd(args []string, opts ...NewExecCmdOption) Command { | ||
cmd := exec.Command(args[0], args[1:]...) | ||
for _, opt := range opts { | ||
opt(cmd) | ||
} | ||
|
||
return &execCmd{Cmd: cmd} | ||
} | ||
|
||
type NewExecCmdOption func(*exec.Cmd) | ||
|
||
func WithTargetDir(targetDir string) NewExecCmdOption { | ||
return func(c *exec.Cmd) { | ||
c.Dir = targetDir | ||
} | ||
} | ||
|
||
type ErrWithStderr struct { | ||
Wrapped error | ||
StdErr []byte | ||
Args []string | ||
} | ||
|
||
func (e *ErrWithStderr) Error() string { | ||
if len(e.StdErr) > 0 { | ||
return fmt.Sprintf("failed running `%s`, %q: %s", strings.Join(e.Args, " "), e.StdErr, e.Wrapped.Error()) | ||
} | ||
|
||
return fmt.Sprintf("failed running `%s`, make sure %s is available: %s", strings.Join(e.Args, " "), e.Args[0], e.Wrapped.Error()) | ||
} | ||
|
||
func (e *ErrWithStderr) Unwrap() error { | ||
return e.Wrapped | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package exec | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/pkg/errors" | ||
) | ||
|
||
// CommandGroup contains commands that are run one after another. | ||
// As soon as one command fails the whole CommandGroup will be stopped and all other | ||
// not yet executed commands are skipped. | ||
type CommandGroup struct { | ||
// func run before any of the commands is executed | ||
PreRun func() error | ||
// Commands to run | ||
Commands []Command | ||
} | ||
|
||
func (cg *CommandGroup) Run() error { | ||
if len(cg.Commands) == 0 { | ||
return nil | ||
} | ||
|
||
if cg.PreRun != nil { | ||
if err := cg.PreRun(); err != nil { | ||
var skipsCmds []string | ||
for _, cmd := range cg.Commands { | ||
skipsCmds = append(skipsCmds, fmt.Sprintf("`%s`", strings.Join(cmd.Args(), " "))) | ||
} | ||
|
||
return errors.Wrapf(err, "skipping %s", strings.Join(skipsCmds, ", ")) | ||
} | ||
} | ||
|
||
for _, cmd := range cg.Commands { | ||
if _, err := cmd.Run(); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package gocli | ||
|
||
import ( | ||
"bytes" | ||
"os/exec" | ||
"strings" | ||
|
||
"github.com/Masterminds/semver/v3" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
var ErrMalformedGoVersionOutput = errors.New("malformed go version output") | ||
|
||
func Semver() (*semver.Version, error) { | ||
stdout := &bytes.Buffer{} | ||
|
||
goVersion := exec.Command("go", "version") | ||
goVersion.Stdout = stdout | ||
|
||
err := goVersion.Run() | ||
if err != nil { | ||
return nil, errors.Wrap(err, "failed checking go version") | ||
} | ||
|
||
versionParts := strings.Split(stdout.String(), " ") | ||
if len(versionParts) != 4 { | ||
return nil, errors.Wrap(ErrMalformedGoVersionOutput, stdout.String()) | ||
} | ||
|
||
goSemverString := strings.TrimPrefix(versionParts[2], "go") | ||
goSemver, err := semver.NewVersion(goSemverString) | ||
if err != nil { | ||
return nil, errors.Wrap(ErrMalformedGoVersionOutput, stdout.String()) | ||
} | ||
|
||
return goSemver, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package gocli_test | ||
|
||
import ( | ||
"runtime" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/schwarzit/go-template/pkg/gocli" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func Test_Semver(t *testing.T) { | ||
version, err := gocli.Semver() | ||
require.NoError(t, err) | ||
// check that the version this test was build with matches the go version provided by goexec.Semver. | ||
require.Equal(t, strings.TrimPrefix(runtime.Version(), "go"), version.String()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters