Skip to content

Commit

Permalink
Add -version flag to all binaries
Browse files Browse the repository at this point in the history
- Added acceptance test suite

Signed-off-by: Andrew Meyer <ameyer@pivotal.io>
Signed-off-by: Javier Romero <jromero@pivotal.io>
  • Loading branch information
ameyer-pivotal committed Jul 15, 2019
1 parent f0fa0c3 commit e632d95
Show file tree
Hide file tree
Showing 12 changed files with 184 additions and 32 deletions.
8 changes: 7 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
sudo: required
services:
- docker

install:
- set -e

jobs:
include:
- stage: unit test
language: go
go:
- 1.11.x
- 1.12.x
env:
- GO111MODULE=on
go_import_path: github.com/buildpack/lifecycle
script: |
make test
branches:
only:
- master
20 changes: 13 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# Go parameters
export GO111MODULE = on
GOCMD?=go
GOENV=GO111MODULE=on GOOS=linux GOARCH=amd64 CGO_ENABLED=0
GOBUILD=$(GOCMD) build -mod=vendor
GOENV=GOOS=linux GOARCH=amd64 CGO_ENABLED=0
GOBUILD=$(GOCMD) build -mod=vendor -ldflags '-X "github.com/buildpack/lifecycle/cmd.buildVersion=$(LIFECYCLE_BUILD_VERSION)"'
GOTEST=$(GOCMD) test -mod=vendor
LIFECYCLE_VERSION?=dev
ARCHIVE_NAME=lifecycle-$(LIFECYCLE_VERSION)+linux.x86-64
LIFECYCLE_VERSION?=0.0.0
LIFECYCLE_BUILD_VERSION?=$(LIFECYCLE_VERSION)+$$(git rev-parse --short HEAD)
ARCHIVE_NAME=lifecycle-v$(LIFECYCLE_VERSION)+linux.x86-64

all: test build package
build:
Expand All @@ -27,8 +28,13 @@ format:
vet:
$(GOCMD) vet $$($(GOCMD) list ./... | grep -v /testdata/)

test: format imports vet
$(GOTEST) -v ./...
test: unit acceptance

unit: format imports vet
$(GOTEST) -v -count=1 -parallel=1 ./...

acceptance: format imports vet
$(GOTEST) -v -count=1 -parallel=1 -tags=acceptance ./acceptance/...

clean:
rm -rf ./out
Expand Down
87 changes: 87 additions & 0 deletions acceptance/acceptance_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// +build acceptance

package acceptance

import (
"os"
"os/exec"
"path/filepath"
"strings"
"testing"

"github.com/sclevine/spec"
"github.com/sclevine/spec/report"

h "github.com/buildpack/lifecycle/testhelpers"
)

func TestAcceptance(t *testing.T) {
spec.Run(t, "acceptance", testAcceptance, spec.Sequential(), spec.Report(report.Terminal{}))
}

func testAcceptance(t *testing.T, when spec.G, it spec.S) {

when("All", func() {
when("version flag is set", func() {
for _, data := range [][]string{
{"analyzer: only -version is present", "analyzer -version"},
{"analyzer: other params are set", "analyzer -daemon -version some/image"},

{"builder: only -version is present", "builder -version"},
{"builder: other params are set", "builder -app=/some/dir -version some/image"},

{"cacher: only -version is present", "cacher -version"},
{"cacher: other params are set", "cacher -path=/some/dir -version"},

{"detector: only -version is present", "detector -version"},
{"detector: other params are set", "detector -app=/some/dir -version"},

{"exporter: only -version is present", "exporter -version"},
{"exporter: other params are set", "exporter -analyzed=/some/file -version some/image"},

{"restorer: only -version is present", "restorer -version"},
{"restorer: other params are set", "restorer -path=/some/dir -version"},
} {
desc := data[0]
binary, args := parseCommand(data[1])

when(desc, func() {
it("only prints the version", func() {
output, err := lifecycleCmd(t, binary, args...).CombinedOutput()
if err != nil {
t.Error(err)
}

h.AssertStringContains(t, string(output), "some-version")
})
})
}
})
})
}

func lifecycleCmd(t *testing.T, name string, args ...string) *exec.Cmd {
cmdArgs := append(
[]string{
"run",
"-ldflags", "-X github.com/buildpack/lifecycle/cmd.buildVersion=some-version",
"./cmd/" + name + "/main.go",
}, args...,
)

wd, err := os.Getwd()
h.AssertNil(t, err)

cmd := exec.Command(
"go",
cmdArgs...,
)
cmd.Dir = filepath.Dir(wd)

return cmd
}

func parseCommand(command string) (binary string, args []string) {
parts := strings.Split(command, " ")
return parts[0], parts[1:]
}
8 changes: 4 additions & 4 deletions builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package lifecycle

import (
"bytes"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
Expand All @@ -19,7 +19,7 @@ type Builder struct {
Env BuildEnv
Buildpacks []*Buildpack
Plan Plan
Out, Err io.Writer
Out, Err *log.Logger
}

type BuildEnv interface {
Expand Down Expand Up @@ -96,8 +96,8 @@ func (b *Builder) Build() (*BuildMetadata, error) {
cmd.Env = b.Env.List()
cmd.Dir = appDir
cmd.Stdin = planIn
cmd.Stdout = b.Out
cmd.Stderr = b.Err
cmd.Stdout = b.Out.Writer()
cmd.Stderr = b.Err.Writer()
if err := cmd.Run(); err != nil {
return nil, err
}
Expand Down
8 changes: 6 additions & 2 deletions builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -56,6 +57,9 @@ func testBuilder(t *testing.T, when spec.G, it spec.S) {
mkdir(t, layersDir, appDir, filepath.Join(platformDir, "env"))
mkfile(t, "replace = true", filepath.Join(appDir, "dep-replace"))

outLog := log.New(io.MultiWriter(stdout, it.Out()), "", 0)
errLog := log.New(io.MultiWriter(stderr, it.Out()), "", 0)

buildpackDir := filepath.Join("testdata", "buildpack")
builder = &lifecycle.Builder{
PlatformDir: platformDir,
Expand All @@ -74,8 +78,8 @@ func testBuilder(t *testing.T, when spec.G, it spec.S) {
"dep2-keep": {"v": "5"},
"dep2-replace": {"v": "6"},
},
Out: io.MultiWriter(stdout, it.Out()),
Err: io.MultiWriter(stderr, it.Out()),
Out: outLog,
Err: errLog,
}
})

Expand Down
7 changes: 7 additions & 0 deletions cmd/analyzer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ var (
uid int
useDaemon bool
useHelpers bool
printVersion bool
)

func init() {
Expand All @@ -43,13 +44,19 @@ func init() {
cmd.FlagUseDaemon(&useDaemon)
cmd.FlagUseCredHelpers(&useHelpers)
cmd.FlagSkipLayers(&skipLayers)
cmd.FlagVersion(&printVersion)
}

func main() {
// suppress output from libraries, lifecycle will not use standard logger
log.SetOutput(ioutil.Discard)

flag.Parse()

if printVersion {
cmd.ExitWithVersion()
}

if flag.NArg() > 1 {
cmd.Exit(cmd.FailErrCode(fmt.Errorf("received %d args expected 1", flag.NArg()), cmd.CodeInvalidArgs, "parse arguments"))
}
Expand Down
12 changes: 10 additions & 2 deletions cmd/builder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ var (
layersDir string
appDir string
platformDir string
printVersion bool
)

func init() {
Expand All @@ -29,13 +30,19 @@ func init() {
cmd.FlagLayersDir(&layersDir)
cmd.FlagAppDir(&appDir)
cmd.FlagPlatformDir(&platformDir)
cmd.FlagVersion(&printVersion)
}

func main() {
// suppress output from libraries, lifecycle will not use standard logger
log.SetOutput(ioutil.Discard)

flag.Parse()

if printVersion {
cmd.ExitWithVersion()
}

if flag.NArg() != 0 {
cmd.Exit(cmd.FailCode(cmd.CodeInvalidArgs, "parse arguments"))
}
Expand Down Expand Up @@ -63,15 +70,16 @@ func build() error {
Environ: os.Environ,
Map: lifecycle.POSIXBuildEnv,
}

builder := &lifecycle.Builder{
PlatformDir: platformDir,
LayersDir: layersDir,
AppDir: appDir,
Env: env,
Buildpacks: group.Buildpacks,
Plan: plan,
Out: os.Stdout,
Err: os.Stderr,
Out: log.New(os.Stdout, "", 0),
Err: log.New(os.Stderr, "", 0),
}

metadata, err := builder.Build()
Expand Down
7 changes: 7 additions & 0 deletions cmd/cacher/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ var (
groupPath string
uid int
gid int
printVersion bool
)

func init() {
Expand All @@ -32,13 +33,19 @@ func init() {
cmd.FlagGroupPath(&groupPath)
cmd.FlagUID(&uid)
cmd.FlagGID(&gid)
cmd.FlagVersion(&printVersion)
}

func main() {
// suppress output from libraries, lifecycle will not use standard logger
log.SetOutput(ioutil.Discard)

flag.Parse()

if printVersion {
cmd.ExitWithVersion()
}

if flag.NArg() > 0 {
cmd.Exit(cmd.FailErrCode(errors.New("received unexpected args"), cmd.CodeInvalidArgs, "parse arguments"))
}
Expand Down
18 changes: 16 additions & 2 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ func FlagSkipLayers(skip *bool) {
flag.BoolVar(skip, "skip-layers", boolEnv(EnvSkipLayers), "do not provide layer metadata to buildpacks")
}

func FlagVersion(version *bool) {
flag.BoolVar(version, "version", false, "show version")
}

const (
CodeFailed = 1
// 2: reserved
Expand All @@ -129,6 +133,12 @@ const (
CodeFailedSave = 10
)

var (
buildVersion = "0.0.0"
OutLogger = log.New(os.Stdout, "", 0)
ErrLogger = log.New(os.Stderr, "", 0)
)

type ErrorFail struct {
Err error
Code int
Expand Down Expand Up @@ -163,14 +173,18 @@ func Exit(err error) {
if err == nil {
os.Exit(0)
}
logger := log.New(os.Stderr, "", 0)
logger.Printf("Error: %s\n", err)
ErrLogger.Printf("Error: %s\n", err)
if err, ok := err.(*ErrorFail); ok {
os.Exit(err.Code)
}
os.Exit(CodeFailed)
}

func ExitWithVersion() {
OutLogger.Printf(buildVersion)
os.Exit(0)
}

func intEnv(k string) int {
v := os.Getenv(k)
d, err := strconv.Atoi(v)
Expand Down
14 changes: 8 additions & 6 deletions cmd/detector/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,29 @@ var (
appDir string
platformDir string
orderPath string

groupPath string
planPath string
groupPath string
planPath string
printVersion bool
)

func init() {
cmd.FlagBuildpacksDir(&buildpacksDir)
cmd.FlagAppDir(&appDir)
cmd.FlagPlatformDir(&platformDir)
cmd.FlagOrderPath(&orderPath)

cmd.FlagGroupPath(&groupPath)
cmd.FlagPlanPath(&planPath)
cmd.FlagVersion(&printVersion)
}

func main() {
// suppress output from libraries, lifecycle will not use standard logger
log.SetOutput(ioutil.Discard)

flag.Parse()
if flag.NArg() != 0 {
cmd.Exit(cmd.FailCode(cmd.CodeInvalidArgs, "parse arguments"))

if printVersion {
cmd.ExitWithVersion()
}
cmd.Exit(detect())
}
Expand All @@ -57,6 +58,7 @@ func detect() error {
Out: log.New(os.Stdout, "", 0),
Err: log.New(os.Stderr, "", 0),
})

if group == nil {
return cmd.FailCode(cmd.CodeFailedDetect, "detect")
}
Expand Down
Loading

0 comments on commit e632d95

Please sign in to comment.