Skip to content

Commit

Permalink
Improve detector log output: when detect fails, print output as info …
Browse files Browse the repository at this point in the history
…level

Signed-off-by: Natalie Arellano <[email protected]>
  • Loading branch information
natalieparellano committed Dec 9, 2022
1 parent da5da9b commit ed6582a
Show file tree
Hide file tree
Showing 16 changed files with 491 additions and 188 deletions.
23 changes: 17 additions & 6 deletions acceptance/detector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func testDetector(t *testing.T, when spec.G, it spec.S) {
"docker",
"run",
"--rm",
"--env", "CNB_ORDER_PATH=/cnb/orders/empty_order.toml",
"--env", "CNB_ORDER_PATH=/cnb/orders/fail_detect_order.toml",
"--env", "CNB_PLATFORM_API="+latestPlatformAPI,
detectImage,
)
Expand All @@ -116,9 +116,16 @@ func testDetector(t *testing.T, when spec.G, it spec.S) {
if !ok {
t.Fatalf("expected an error of type exec.ExitError")
}
h.AssertEq(t, failErr.ExitCode(), 20) // platform code for cmd.FailedDetect
expected := "No buildpack groups passed detection."
h.AssertStringContains(t, string(output), expected)
h.AssertEq(t, failErr.ExitCode(), 20) // platform code for failed detect with errors

expected1 := `======== Output: fail_detect_buildpack@some_version ========
Opted out of detection
======== Results ========
fail: fail_detect_buildpack@some_version
`
h.AssertStringContains(t, string(output), expected1)
expected2 := "No buildpack groups passed detection."
h.AssertStringContains(t, string(output), expected2)
})
})

Expand All @@ -140,7 +147,7 @@ func testDetector(t *testing.T, when spec.G, it spec.S) {
})

it("writes group.toml and plan.toml at the default locations", func() {
h.DockerRunAndCopy(t,
output := h.DockerRunAndCopy(t,
containerName,
copyDir,
"/layers",
Expand Down Expand Up @@ -170,6 +177,10 @@ func testDetector(t *testing.T, when spec.G, it spec.S) {
h.AssertEq(t, buildPlan.Entries[0].Requires[0].Name, "some_requirement")
h.AssertEq(t, buildPlan.Entries[0].Requires[0].Metadata["some_metadata_key"], "some_metadata_val")
h.AssertEq(t, buildPlan.Entries[0].Requires[0].Metadata["version"], "some_version")

// check output
h.AssertStringContains(t, output, "simple_buildpack simple_buildpack_version")
h.AssertStringDoesNotContain(t, output, "======== Results ========") // log output is info level as detect passed
})
})

Expand Down Expand Up @@ -408,7 +419,7 @@ func testDetector(t *testing.T, when spec.G, it spec.S) {
if !ok {
t.Fatalf("expected an error of type exec.ExitError")
}
h.AssertEq(t, failErr.ExitCode(), 100) // platform code for cmd.FailedDetect
h.AssertEq(t, failErr.ExitCode(), 100) // platform code for failed detect
expected := "No buildpack groups passed detection."
h.AssertStringContains(t, string(output), expected)
})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash

echo "Opted out of detection"

exit 100
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
api = "0.9"
[buildpack]
id = "fail_detect_buildpack"
version = "some_version"
name = "Fail Detect Buildpack"
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[[order]]

[[order.group]]
id = "fail_detect_buildpack"
version = "some_version"
2 changes: 1 addition & 1 deletion analyzer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ func testAnalyzer(platformAPI string) func(t *testing.T, when spec.G, it spec.S)

if testing.Verbose() {
analyzer.Logger = cmd.DefaultLogger
h.AssertNil(t, cmd.SetLogLevel("debug"))
h.AssertNil(t, cmd.DefaultLogger.SetLevel("debug"))
}
})

Expand Down
4 changes: 2 additions & 2 deletions buildpack/detect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ func testDetect(t *testing.T, when spec.G, it spec.S) {
if err != nil {
t.Fatalf("Unexpected error:\n%s\n", err)
}
if s := h.AllLogs(logHandler); !strings.Contains(s,
if s := h.AllLogsFromHandler(logHandler); !strings.Contains(s,
`buildpack A has a "version" key. This key is deprecated in build plan requirements in buildpack API 0.3. "metadata.version" should be used instead`,
) {
t.Fatalf("Expected log to contain warning:\n%s\n", s)
Expand All @@ -266,7 +266,7 @@ func testDetect(t *testing.T, when spec.G, it spec.S) {
if err != nil {
t.Fatalf("Unexpected error:\n%s\n", err)
}
if s := h.AllLogs(logHandler); !strings.Contains(s,
if s := h.AllLogsFromHandler(logHandler); !strings.Contains(s,
`buildpack A has a "version" key. This key is deprecated in build plan requirements in buildpack API 0.3. "metadata.version" should be used instead`,
) {
t.Fatalf("Expected log to contain warning:\n%s\n", s)
Expand Down
2 changes: 1 addition & 1 deletion cmd/apis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func testVerifyAPIs(t *testing.T, when spec.G, it spec.S) {

it.Before(func() {
logHandler = memory.New()
logger = &cmd.Logger{Logger: &log.Logger{Handler: logHandler}}
logger = &llog.DefaultLogger{Logger: &log.Logger{Handler: logHandler}}
})

when("VerifyPlatformAPI", func() {
Expand Down
2 changes: 1 addition & 1 deletion cmd/lifecycle/cli/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func Run(c Command, asSubcommand bool) {
if printVersion {
cmd.ExitWithVersion()
}
if err := cmd.SetLogLevel(logLevel); err != nil {
if err := cmd.DefaultLogger.SetLevel(logLevel); err != nil {
cmd.Exit(err)
}
if err := c.Args(flagSet.NArg(), flagSet.Args()); err != nil {
Expand Down
70 changes: 4 additions & 66 deletions cmd/logs.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
package cmd

import (
"io"
"os"
"sync"

"github.com/apex/log"
"github.com/heroku/color"
)

const (
errorLevelText = "ERROR: "
warnLevelText = "Warning: "
"github.com/buildpacks/lifecycle/log"
)

func init() {
Expand All @@ -20,68 +14,12 @@ func init() {
}

var (
DefaultLogger = &Logger{
&log.Logger{
Handler: &handler{
writer: Stdout,
},
},
}
Stdout = color.NewConsole(os.Stdout)
Stderr = color.NewConsole(os.Stderr)
warnStyle = color.New(color.FgYellow, color.Bold).SprintfFunc()
errorStyle = color.New(color.FgRed, color.Bold).SprintfFunc()
phaseStyle = color.New(color.FgCyan).SprintfFunc()
DefaultLogger = log.NewDefaultLogger(Stdout)
Stdout = color.NewConsole(os.Stdout)
Stderr = color.NewConsole(os.Stderr)
)

type Logger struct {
*log.Logger
}

func (l *Logger) Phase(name string) {
l.Infof(phaseStyle("===> %s", name))
}

func SetLogLevel(level string) *ErrorFail {
var err error
DefaultLogger.Level, err = log.ParseLevel(level)
if err != nil {
return FailErrCode(err, CodeForInvalidArgs, "parse log level")
}

return nil
}

func DisableColor(noColor bool) {
Stdout.DisableColors(noColor)
Stderr.DisableColors(noColor)
}

type handler struct {
mu sync.Mutex
writer io.Writer
}

func (h *handler) HandleLog(entry *log.Entry) error {
h.mu.Lock()
defer h.mu.Unlock()

var err error
switch entry.Level {
case log.WarnLevel:
_, err = h.writer.Write([]byte(warnStyle(warnLevelText) + appendMissingLineFeed(entry.Message)))
case log.ErrorLevel:
_, err = h.writer.Write([]byte(errorStyle(errorLevelText) + appendMissingLineFeed(entry.Message)))
default:
_, err = h.writer.Write([]byte(appendMissingLineFeed(entry.Message)))
}
return err
}

func appendMissingLineFeed(msg string) string {
buff := []byte(msg)
if buff[len(buff)-1] != '\n' {
buff = append(buff, '\n')
}
return string(buff)
}
Loading

0 comments on commit ed6582a

Please sign in to comment.