Skip to content

Commit

Permalink
Better errors when a target fails.
Browse files Browse the repository at this point in the history
  • Loading branch information
ejholmes committed Jan 24, 2017
1 parent 52d87e7 commit 813434b
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 5 deletions.
34 changes: 29 additions & 5 deletions plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ const (
// targets.
const Walkfile = "Walkfile"

// NoWalkfileError can be returned when a target doesn't have a Walkfile present
// in it's directory.
type NoWalkfileError struct {
Dir string
}

func (e *NoWalkfileError) Error() string {
return fmt.Sprintf("no %s in %s", Walkfile, e.Dir)
}

// Rule defines what a target depends on, and how to execute it.
type Rule interface {
// Dependencies returns the name of the targets that this target depends
Expand Down Expand Up @@ -277,7 +287,10 @@ func (t *target) Name() string {

// Exec executes the rule with "exec" as the first argument.
func (t *target) Exec(ctx context.Context) error {
cmd := t.ruleCommand(ctx, PhaseExec)
cmd, err := t.ruleCommand(ctx, PhaseExec)
if err != nil {
return err
}
return cmd.Run()
}

Expand All @@ -290,7 +303,10 @@ func (t *target) Dependencies(ctx context.Context) ([]string, error) {
}

b := new(bytes.Buffer)
cmd := t.ruleCommand(ctx, PhaseDeps)
cmd, err := t.ruleCommand(ctx, PhaseDeps)
if err != nil {
return nil, err
}
cmd.Stdout = b

if err := cmd.Run(); err != nil {
Expand All @@ -315,13 +331,17 @@ func (t *target) Dependencies(ctx context.Context) ([]string, error) {
return deps, scanner.Err()
}

func (t *target) ruleCommand(ctx context.Context, phase string) *exec.Cmd {
func (t *target) ruleCommand(ctx context.Context, phase string) (*exec.Cmd, error) {
if t.rulefile == "" {
return nil, &NoWalkfileError{Dir: filepath.Dir(t.name)}
}

name := filepath.Base(t.path)
cmd := exec.CommandContext(ctx, t.rulefile, phase, name)
cmd.Stdout = t.stdout
cmd.Stderr = t.stderr
cmd.Dir = t.dir
return cmd
return cmd, nil
}

// verboseTarget simply wraps a target to print to to stdout when it's Exec'd.
Expand All @@ -338,7 +358,11 @@ func (t *verboseTarget) Exec(ctx context.Context) error {
prefix = "error"
color = "31"
}
fmt.Fprintf(t.stdout, "%s\t%s\n", ansi(color, "%s", prefix), t.target.Name())
line := fmt.Sprintf("%s\t%s", ansi(color, "%s", prefix), t.target.Name())
if err != nil {
line = fmt.Sprintf("%s\t%s", line, err)
}
fmt.Fprintf(t.stdout, "%s\n", line)
if err != nil {
return &targetError{t.target, err}
}
Expand Down
34 changes: 34 additions & 0 deletions plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,40 @@ func TestTarget_Dependencies_EmptyTarget(t *testing.T) {
assert.Equal(t, []string{"test/000-empty-dependency/a", "test/000-empty-dependency/b"}, deps)
}

func TestPlan_Error(t *testing.T) {
clean(t)

b := new(bytes.Buffer)
plan := newPlan()
plan.NewTarget = NewTarget(TargetOptions{
Stdout: b,
})
err := plan.Plan(ctx, "test/000-cancel/fail")
assert.NoError(t, err)

err = plan.Exec(ctx, NewSemaphore(0))
assert.Error(t, err)

assert.Equal(t, "error\ttest/000-cancel/fail\texit status 1\n", b.String())
}

func TestPlan_NoWalkfile(t *testing.T) {
clean(t)

b := new(bytes.Buffer)
plan := newPlan()
plan.NewTarget = NewTarget(TargetOptions{
Stdout: b,
})
err := plan.Plan(ctx, "test/000-no-walkfile/all")
assert.NoError(t, err)

err = plan.Exec(ctx, NewSemaphore(0))
assert.Error(t, err)

assert.Equal(t, "error\ttest/000-no-walkfile/all\tno Walkfile in test/000-no-walkfile\n", b.String())
}

func TestPrefixWriter(t *testing.T) {
b := new(bytes.Buffer)
w := &prefixWriter{w: b, prefix: []byte("prefix: ")}
Expand Down

0 comments on commit 813434b

Please sign in to comment.