Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds Info and Debug logger functionality #254

Merged
merged 13 commits into from
Dec 2, 2021
Merged
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ require (
github.com/pelletier/go-toml v1.9.4
github.com/sclevine/spec v1.4.0
github.com/ulikunitz/xz v0.5.10
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect
golang.org/x/sys v0.0.0-20210603125802-9665404d3644 // indirect
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d // indirect
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e // indirect
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
)
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d h1:20cMwl2fHAzkJMEA+8J4JgqBQcQGzbisXo31MIeenXI=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand All @@ -103,8 +103,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I=
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
Expand Down
1 change: 1 addition & 0 deletions scribe/bar.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/cheggaaa/pb/v3"
)

// Deprecated: Bar will be removed in the next major release
type Bar struct {
w io.Writer
p *pb.ProgressBar
Expand Down
6 changes: 6 additions & 0 deletions scribe/color.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"strconv"
)

// A set of common text colors.
var (
BlackColor = NewColor(false, 0, -1)
RedColor = NewColor(false, 1, -1)
Expand All @@ -16,8 +17,13 @@ var (
GrayColor = NewColor(false, 244, -1)
)

// A Color is a function that takes a string as an input and returns a string
// with the proper terminal graphic commands.
type Color func(message string) string

// NewColor returns a Color function that will make text bold based on the
// boolean value of bold and set the text foreground and background, using fg
// and bg respectively, to any color in the 8 bit color space.
func NewColor(bold bool, fg, bg int) Color {
return func(message string) string {
prefix := "\x1b["
Expand Down
19 changes: 19 additions & 0 deletions scribe/emitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,27 @@ import (
"github.com/paketo-buildpacks/packit/postal"
)

// An Emitter embeds the scribe.Logger type to provide an interface for
// complicated shared logging tasks.
type Emitter struct {
// Logger is embedded and therefore delegates all of its functions to the
// Emitter.
Logger
}

// NewEmitter returns an emitter that writes to the given output.
func NewEmitter(output io.Writer) Emitter {
return Emitter{
Logger: NewLogger(output),
}
}

// SelectedDependency takes in a buildpack plan entry, a postal dependency, and
// the current time, and prints out a message giving the name and version of
// the dependency as well as the source of the request for that given
// dependency, it will also print a deprecation warning and an EOL warning
// based if the given dependency is set to be deprecated within the next 30 or
// is past that window.
func (e Emitter) SelectedDependency(entry packit.BuildpackPlanEntry, dependency postal.Dependency, now time.Time) {
source, ok := entry.Metadata["version-source"].(string)
if !ok {
Expand All @@ -45,6 +54,8 @@ func (e Emitter) SelectedDependency(entry packit.BuildpackPlanEntry, dependency
e.Break()
}

// Candidates takes a priority sorted list of buildpack plan entries and prints
// out a formatted table in priority order removing any duplicate entries.
func (e Emitter) Candidates(entries []packit.BuildpackPlanEntry) {
e.Subprocess("Candidate version sources (in priority order):")

Expand All @@ -70,6 +81,8 @@ Entries:
}

source := [2]string{versionSource, version}

// Removes any duplicate entries
for _, s := range sources {
if s == source {
continue Entries
Expand All @@ -86,6 +99,10 @@ Entries:
e.Break()
}

// LaunchProcesses take a list of processes and a map of process specific
// enivronment varables and prints out a formatted table including the type
// name, whether or not it is a default process, the command, arguments, and
// any process specific environment variables.
func (e Emitter) LaunchProcesses(processes []packit.Process, processEnvs ...map[string]packit.Environment) {
e.Process("Assigning launch processes:")

Expand Down Expand Up @@ -138,6 +155,8 @@ func (e Emitter) LaunchProcesses(processes []packit.Process, processEnvs ...map[
e.Break()
}

// EnvironmentVariables take a layer and prints out a formatted table of the
// build and launch time environment variables set in the layer.
func (e Emitter) EnvironmentVariables(layer packit.Layer) {
buildEnv := packit.Environment{}
launchEnv := packit.Environment{}
Expand Down
269 changes: 269 additions & 0 deletions scribe/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,269 @@
package scribe_test

import (
"fmt"
"log"
"os"
"time"

"github.com/paketo-buildpacks/packit"
"github.com/paketo-buildpacks/packit/postal"
"github.com/paketo-buildpacks/packit/scribe"
)

func ExampleEmitter() {
emitter := scribe.NewEmitter(os.Stdout)

emitter.Title("Title")
emitter.Process("Process")
emitter.Subprocess("Subprocess")
emitter.Action("Action")
emitter.Detail("Detail")
emitter.Subdetail("Subdetail")
emitter.Break()
emitter.Title("Next line")

// Output:
// Title
// Process
// Subprocess
// Action
// Detail
// Subdetail
//
// Next line
}

func ExampleEmitter_SelectedDependency() {
emitter := scribe.NewEmitter(os.Stdout)

deprecationDate, err := time.Parse(time.RFC3339, "2021-04-01T00:00:00Z")
if err != nil {
log.Fatal(err)
}

entry := packit.BuildpackPlanEntry{
Metadata: map[string]interface{}{"version-source": "some-source"},
}

dependency := postal.Dependency{
Name: "Some Dependency",
Version: "some-version",
DeprecationDate: deprecationDate,
}

emitter.Title("SelectedDependency")
emitter.SelectedDependency(entry, dependency, deprecationDate.Add(-30*24*time.Hour))
emitter.SelectedDependency(entry, dependency, deprecationDate.Add(-29*24*time.Hour))
emitter.SelectedDependency(entry, dependency, deprecationDate.Add(24*time.Hour))

// Output:
// SelectedDependency
// Selected Some Dependency version (using some-source): some-version
//
// Selected Some Dependency version (using some-source): some-version
// Version some-version of Some Dependency will be deprecated after 2021-04-01.
// Migrate your application to a supported version of Some Dependency before this time.
//
// Selected Some Dependency version (using some-source): some-version
// Version some-version of Some Dependency is deprecated.
// Migrate your application to a supported version of Some Dependency.
//
}

func ExampleEmitter_Candidates() {
emitter := scribe.NewEmitter(os.Stdout)

emitter.Candidates([]packit.BuildpackPlanEntry{
{
Metadata: map[string]interface{}{
"version-source": "some-source",
"version": "some-version",
},
},
{
Metadata: map[string]interface{}{
"version": "other-version",
},
},
})

// Output:
// Candidate version sources (in priority order):
// some-source -> "some-version"
// <unknown> -> "other-version"
//
}

func ExampleEmitter_LaunchProcesses() {
emitter := scribe.NewEmitter(os.Stdout)

processes := []packit.Process{
{
Type: "some-type",
Command: "some-command",
},
{
Type: "web",
Command: "web-command",
Default: true,
},
{
Type: "some-other-type",
Command: "some-other-command",
Args: []string{"some", "args"},
},
}

processEnvs := []map[string]packit.Environment{
{
"web": packit.Environment{
"WEB_VAR.default": "some-env",
},
},
{
"web": packit.Environment{
"ANOTHER_WEB_VAR.default": "another-env",
},
},
}

emitter.LaunchProcesses(processes)
emitter.LaunchProcesses(processes, processEnvs...)

// Output:
// Assigning launch processes:
// some-type: some-command
// web (default): web-command
// some-other-type: some-other-command some args

// Assigning launch processes:
// some-type: some-command
// web (default): web-command
// ANOTHER_WEB_VAR -> "another-env"
// WEB_VAR -> "some-env"
// some-other-type: some-other-command some args
}

func ExampleEmitter_EnvironmentVariables() {
emitter := scribe.NewEmitter(os.Stdout)

emitter.EnvironmentVariables(packit.Layer{
BuildEnv: packit.Environment{
"NODE_HOME.default": "/some/path",
"NODE_ENV.default": "some-env",
"NODE_VERBOSE.default": "some-bool",
},
LaunchEnv: packit.Environment{
"NODE_HOME.default": "/some/path",
"NODE_ENV.default": "another-env",
"NODE_VERBOSE.default": "another-bool",
},
SharedEnv: packit.Environment{
"SHARED_ENV.default": "shared-env",
},
})

// Output:
// Configuring build environment
// NODE_ENV -> "some-env"
// NODE_HOME -> "/some/path"
// NODE_VERBOSE -> "some-bool"
// SHARED_ENV -> "shared-env"
//
// Configuring launch environment
// NODE_ENV -> "another-env"
// NODE_HOME -> "/some/path"
// NODE_VERBOSE -> "another-bool"
// SHARED_ENV -> "shared-env"
//
}

func ExampleFormattedList() {
fmt.Println(scribe.FormattedList{
"third",
"first",
"second",
}.String())

// Output:
// first
// second
// third
}

func ExampleFormattedMap() {
fmt.Println(scribe.FormattedMap{
"third": 3,
"first": 1,
"second": 2,
}.String())

// Output:
// first -> "1"
// second -> "2"
// third -> "3"
}

func ExampleNewFormattedMapFromEnvironment() {
fmt.Println(scribe.NewFormattedMapFromEnvironment(packit.Environment{
"OVERRIDE.override": "some-value",
"DEFAULT.default": "some-value",
"PREPEND.prepend": "some-value",
"PREPEND.delim": ":",
"APPEND.append": "some-value",
"APPEND.delim": ":",
}).String())

// Output:
// APPEND -> "$APPEND:some-value"
// DEFAULT -> "some-value"
// OVERRIDE -> "some-value"
// PREPEND -> "some-value:$PREPEND"
}

func ExampleLogger() {
logger := scribe.NewLogger(os.Stdout)

logger.Title("Title")
logger.Process("Process")
logger.Subprocess("Subprocess")
logger.Action("Action")
logger.Detail("Detail")
logger.Subdetail("Subdetail")
logger.Break()
logger.Title("Next line")

// Output:
// Title
// Process
// Subprocess
// Action
// Detail
// Subdetail
//
// Next line
}

func ExampleLogger_WithLevel() {
logger := scribe.NewLogger(os.Stdout)

logger.Title("First line")
logger.Debug.Title("Debug line")
logger.Title("Next line")
logger.Break()

logger = logger.WithLevel("DEBUG")

logger.Title("First line")
logger.Debug.Title("Debug line")
logger.Title("Next line")

// Output:
// First line
// Next line
//
// First line
// Debug line
// Next line
}
Loading