diff --git a/.runny.yaml b/.runny.yaml index 6a9821f..b011c28 100644 --- a/.runny.yaml +++ b/.runny.yaml @@ -3,6 +3,7 @@ env: - FOO=fooster - BAR=barbara commands: + # Commands I use when developing runny clean: run: | go clean ./... @@ -21,12 +22,33 @@ commands: run: go generate ./... test: run: go test ./... - test-env: + + # Demo commands to showcase various features of runny + demo-env: env: - FOO=baz run: echo $FOO $BAR - test-args: + demo-args: argnames: - aa - bb run: echo $aa is not $bb and $bb is not $aa + demo-multiline-command: + # Unlike Makefiles, runny makes it simple to run commands that span over multiple lines. Just write them exactly as + # you would in a regular script. + run: | + for x in 1 2 3; do + echo $x + done + demo-broken: + run: foo bar + + demo-broken-dependency: + needs: + - demo-broken + run: ls + + demo-unknown-dependency: + needs: + - unknown + run: ls diff --git a/runny/cmd.go b/runny/cmd.go index 139178d..e3117ff 100644 --- a/runny/cmd.go +++ b/runny/cmd.go @@ -1,15 +1,26 @@ package runny import ( + "fmt" "os" + + "github.com/fatih/color" ) func Run() { + exitWithError := func(err error) { + errStr := fmt.Sprintf("%v\n", err) + red := color.New(color.FgRed) + red.Fprint(os.Stderr, errStr) + os.Exit(1) + } + runny, err := readConfig(".runny.yaml") if err != nil { - errorColor.Printf("Problem reading config: %v\n", err) + exitWithError(err) } + // Parse command-line options args := os.Args[1:] for len(args) > 0 && args[0][0] == '-' { option := args[0] @@ -20,19 +31,17 @@ func Run() { case "-v", "--verbose": runny.verbose = true default: - errorColor.Printf("Unknown option: %s\n", option) - os.Exit(1) + exitWithError(fmt.Errorf("unknown option: %s", option)) } args = args[1:] } - // read command line args + // Process runny command if len(args) > 0 { name := CommandName(args[0]) err := runny.Execute(name, args[1:]...) if err != nil { - errorColor.Println(err) - os.Exit(1) + exitWithError(err) } } else { runny.PrintCommands() diff --git a/runny/constants.go b/runny/constants.go index ddd3c67..c3ca9ac 100644 --- a/runny/constants.go +++ b/runny/constants.go @@ -5,4 +5,3 @@ import "github.com/fatih/color" var defaultShell = "/bin/bash" var primaryColor *color.Color = color.New(color.Bold) var secondaryColor *color.Color = color.New(color.FgHiBlack) -var errorColor *color.Color = color.New(color.FgRed) diff --git a/runny/model.go b/runny/model.go index 37b025a..5a80973 100644 --- a/runny/model.go +++ b/runny/model.go @@ -27,17 +27,16 @@ type Config struct { verbose bool } -func (c *Config) GetShell() Shell { +func (c *Config) GetShell() (Shell, error) { shellString := c.Shell if len(shellString) == 0 { shellString = defaultShell } shell, err := NewShell(shellString) if err != nil { - errorColor.Printf("Error: %v\n", err) - os.Exit(1) + return nil, err } - return shell + return shell, nil } func (c *Config) PrintHelp() { @@ -84,12 +83,14 @@ func (c *Config) PrintCommands() { } func (c *Config) Execute(name CommandName, args ...string) error { - shell := c.GetShell() + shell, err := c.GetShell() + if err != nil { + return err + } + command, ok := c.Commands[name] if !ok { - errorMsg := fmt.Sprintf("unknown command: %s", name) - errorColor.Println(errorMsg) - return fmt.Errorf(errorMsg) + return fmt.Errorf("unknown command: %s", name) } env := append(c.Env, command.Env...) @@ -111,7 +112,6 @@ func (c *Config) Execute(name CommandName, args ...string) error { for _, name := range command.Needs { err := c.Execute(name) if err != nil { - errorColor.Print(err) return err } } diff --git a/runny/shell.go b/runny/shell.go index d6d49d9..a794724 100644 --- a/runny/shell.go +++ b/runny/shell.go @@ -36,9 +36,9 @@ func (b BashShell) Run(command string, extraArgs []string, echoStdout, verbose b cmd := exec.Command(b.command, args...) cmd.Env = env + cmd.Stderr = os.Stderr if echoStdout { cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr } return cmd.Run()