Skip to content

Commit

Permalink
Merge pull request #346 from buildpacks/feature/exit-code-detector-no…
Browse files Browse the repository at this point in the history
…-groups

feat: use more specific codes during detect
  • Loading branch information
ekcasey authored Jul 29, 2020
2 parents f76b3e6 + abe415c commit d16b743
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 17 deletions.
7 changes: 4 additions & 3 deletions cmd/exit.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ const (
CodeInvalidArgs = 3
// 4: CodeInvalidEnv
// 5: CodeNotFound
CodeFailedDetect = 6
CodeFailedBuild = 7
CodeFailedLaunch = 8
CodeFailedDetect = 100
CodeFailedDetectWithErrors = 101
CodeFailedBuild = 7
CodeFailedLaunch = 8
// 9: CodeFailedUpdate
CodeFailedSave = 10
CodeIncompatible = 11
Expand Down
10 changes: 8 additions & 2 deletions cmd/lifecycle/detector.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,17 @@ func (da detectArgs) detect() (lifecycle.BuildpackGroup, lifecycle.BuildPlan, er
Logger: cmd.Logger,
})
if err != nil {
if err == lifecycle.ErrFail {
switch err {
case lifecycle.ErrFailedDetection:
cmd.Logger.Error("No buildpack groups passed detection.")
cmd.Logger.Error("Please check that you are running against the correct path.")
return lifecycle.BuildpackGroup{}, lifecycle.BuildPlan{}, cmd.FailErrCode(err, cmd.CodeFailedDetect, "detect")
case lifecycle.ErrBuildpack:
cmd.Logger.Error("No buildpack groups passed detection.")
return lifecycle.BuildpackGroup{}, lifecycle.BuildPlan{}, cmd.FailErrCode(err, cmd.CodeFailedDetectWithErrors, "detect")
default:
return lifecycle.BuildpackGroup{}, lifecycle.BuildPlan{}, cmd.FailErrCode(err, 1, "detect")
}
return lifecycle.BuildpackGroup{}, lifecycle.BuildPlan{}, cmd.FailErrCode(err, cmd.CodeFailedDetect, "detect")
}

return group, plan, nil
Expand Down
29 changes: 22 additions & 7 deletions detector.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ const (
EnvBuildpackDir = "CNB_BUILDPACK_DIR"
)

var ErrFail = errors.New("no buildpacks participating")
var ErrFailedDetection = errors.New("no buildpacks participating")
var ErrBuildpack = errors.New("buildpack(s) failed with err")

type BuildPlan struct {
Entries []BuildPlanEntry `toml:"entries"`
Expand Down Expand Up @@ -83,6 +84,7 @@ func (c *DetectConfig) process(done []Buildpack) ([]Buildpack, []BuildPlanEntry,

results := detectResults{}
detected := true
buildpackErr := false
for i, bp := range done {
run := runs[i]
switch run.Code {
Expand All @@ -98,14 +100,19 @@ func (c *DetectConfig) process(done []Buildpack) ([]Buildpack, []BuildPlanEntry,
detected = detected && bp.Optional
case -1:
c.Logger.Debugf("err: %s", bp)
buildpackErr = true
detected = detected && bp.Optional
default:
c.Logger.Debugf("err: %s (%d)", bp, run.Code)
buildpackErr = true
detected = detected && bp.Optional
}
}
if !detected {
return nil, nil, ErrFail
if buildpackErr {
return nil, nil, ErrBuildpack
}
return nil, nil, ErrFailedDetection
}

i := 0
Expand Down Expand Up @@ -159,7 +166,7 @@ func (c *DetectConfig) runTrial(i int, trial detectTrial) (depMap, detectTrial,
retry = true
if !bp.Optional {
c.Logger.Debugf("fail: %s requires %s", bp, name)
return ErrFail
return ErrFailedDetection
}
c.Logger.Debugf("skip: %s requires %s", bp, name)
trial = trial.remove(bp)
Expand All @@ -172,7 +179,7 @@ func (c *DetectConfig) runTrial(i int, trial detectTrial) (depMap, detectTrial,
retry = true
if !bp.Optional {
c.Logger.Debugf("fail: %s provides unused %s", bp, name)
return ErrFail
return ErrFailedDetection
}
c.Logger.Debugf("skip: %s provides unused %s", bp, name)
trial = trial.remove(bp)
Expand All @@ -184,7 +191,7 @@ func (c *DetectConfig) runTrial(i int, trial detectTrial) (depMap, detectTrial,

if len(trial) == 0 {
c.Logger.Debugf("fail: no viable buildpacks in group")
return nil, nil, ErrFail
return nil, nil, ErrFailedDetection
}
return deps, trial, nil
}
Expand Down Expand Up @@ -301,10 +308,14 @@ func (bo BuildpackOrder) Detect(c *DetectConfig) (BuildpackGroup, BuildPlan, err

func (bo BuildpackOrder) detect(done, next []Buildpack, optional bool, wg *sync.WaitGroup, c *DetectConfig) ([]Buildpack, []BuildPlanEntry, error) {
ngroup := BuildpackGroup{Group: next}
buildpackErr := false
for _, group := range bo {
// FIXME: double-check slice safety here
found, plan, err := group.append(ngroup).detect(done, wg, c)
if err == ErrFail {
if err == ErrBuildpack {
buildpackErr = true
}
if err == ErrFailedDetection || err == ErrBuildpack {
wg = &sync.WaitGroup{}
continue
}
Expand All @@ -313,7 +324,11 @@ func (bo BuildpackOrder) detect(done, next []Buildpack, optional bool, wg *sync.
if optional {
return ngroup.detect(done, wg, c)
}
return nil, nil, ErrFail

if buildpackErr {
return nil, nil, ErrBuildpack
}
return nil, nil, ErrFailedDetection
}

func hasID(bps []Buildpack, id string) bool {
Expand Down
33 changes: 28 additions & 5 deletions detector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func testDetector(t *testing.T, when spec.G, it spec.S) {
_, _, err := lifecycle.BuildpackOrder{
{Group: []lifecycle.Buildpack{{ID: "E", Version: "v1"}}},
}.Detect(config)
if err != lifecycle.ErrFail {
if err != lifecycle.ErrFailedDetection {
t.Fatalf("Unexpected error:\n%s\n", err)
}

Expand Down Expand Up @@ -127,7 +127,7 @@ func testDetector(t *testing.T, when spec.G, it spec.S) {

it("should fail if the group is empty", func() {
_, _, err := lifecycle.BuildpackOrder([]lifecycle.BuildpackGroup{{}}).Detect(config)
if err != lifecycle.ErrFail {
if err != lifecycle.ErrFailedDetection {
t.Fatalf("Unexpected error:\n%s\n", err)
}

Expand All @@ -148,7 +148,7 @@ func testDetector(t *testing.T, when spec.G, it spec.S) {
{ID: "B", Version: "v1", Optional: true},
}},
}.Detect(config)
if err != lifecycle.ErrFail {
if err != lifecycle.ErrFailedDetection {
t.Fatalf("Unexpected error:\n%s\n", err)
}

Expand All @@ -163,6 +163,29 @@ func testDetector(t *testing.T, when spec.G, it spec.S) {
}
})

it("should fail with specific error if any bp detect fails in an unexpected way", func() {
mkappfile("100", "detect-status")
mkappfile("0", "detect-status-A-v1")
mkappfile("127", "detect-status-B-v1")
_, _, err := lifecycle.BuildpackOrder{
{Group: []lifecycle.Buildpack{
{ID: "A", Version: "v1", Optional: false},
{ID: "B", Version: "v1", Optional: false},
}},
}.Detect(config)
if err != lifecycle.ErrBuildpack {
t.Fatalf("Unexpected error:\n%s\n", err)
}

if s := allLogs(logHandler); !strings.HasSuffix(s,
"======== Results ========\n"+
"pass: A@v1\n"+
"err: B@v1 (127)\n",
) {
t.Fatalf("Unexpected log:\n%s\n", s)
}
})

it("should select an appropriate env type", func() {
mkappfile("0", "detect-status-A-v1.clear", "detect-status-B-v1")

Expand Down Expand Up @@ -297,7 +320,7 @@ func testDetector(t *testing.T, when spec.G, it spec.S) {
{ID: "C", Version: "v1"},
}},
}.Detect(config)
if err != lifecycle.ErrFail {
if err != lifecycle.ErrFailedDetection {
t.Fatalf("Unexpected error:\n%s\n", err)
}

Expand Down Expand Up @@ -325,7 +348,7 @@ func testDetector(t *testing.T, when spec.G, it spec.S) {
{ID: "C", Version: "v1", Optional: true},
}},
}.Detect(config)
if err != lifecycle.ErrFail {
if err != lifecycle.ErrFailedDetection {
t.Fatalf("Unexpected error:\n%s\n", err)
}

Expand Down

0 comments on commit d16b743

Please sign in to comment.