Hardcode platform/buildpack APIs
Signed-off-by: Emily Casey <ecasey@vmware.com>
This commit is contained in:
parent
cddc9b9a43
commit
36db452da0
40
Makefile
40
Makefile
|
|
@ -4,19 +4,20 @@ PWD?=$(subst /,\,${CURDIR})
|
|||
LDFLAGS=-s -w
|
||||
BLANK:=
|
||||
/:=\$(BLANK)
|
||||
LIFECYCLE_VERSION?=$(shell type VERSION)
|
||||
else
|
||||
/:=/
|
||||
LIFECYCLE_VERSION?=$(shell cat VERSION)
|
||||
endif
|
||||
|
||||
GOCMD?=go
|
||||
GOARCH?=amd64
|
||||
GOENV=GOARCH=$(GOARCH) CGO_ENABLED=0
|
||||
LIFECYCLE_DESCRIPTOR_PATH?=lifecycle.toml
|
||||
LIFECYCLE_VERSION:=$(shell $(GOCMD) run tools/descriptor/main.go version $(LIFECYCLE_DESCRIPTOR_PATH))
|
||||
LDFLAGS=-s -w
|
||||
LDFLAGS+=-X 'github.com/buildpacks/lifecycle/cmd.SCMRepository=$(SCM_REPO)'
|
||||
LDFLAGS+=-X 'github.com/buildpacks/lifecycle/cmd.SCMCommit=$(SCM_COMMIT)'
|
||||
LDFLAGS+=$(shell $(GOCMD) run tools/descriptor/main.go build-args $(LIFECYCLE_DESCRIPTOR_PATH))
|
||||
LDFLAGS+=-X 'github.com/buildpacks/lifecycle/cmd.Version=$(LIFECYCLE_VERSION)'
|
||||
GOBUILD:=go build $(GOFLAGS) -ldflags "$(LDFLAGS)"
|
||||
GOTEST=$(GOCMD) test $(GOFLAGS)
|
||||
SCM_REPO?=github.com/buildpacks/lifecycle
|
||||
|
|
@ -54,7 +55,6 @@ $(BUILD_DIR)/linux/lifecycle/lifecycle:
|
|||
@echo "> Building lifecycle/lifecycle for linux..."
|
||||
mkdir -p $(OUT_DIR)
|
||||
$(DOCKER_RUN) sh -c 'apk add build-base && $(GOENV) $(GOBUILD) -o /out/lifecycle -a ./cmd/lifecycle'
|
||||
$(BUILD_DIR)/linux/lifecycle/lifecycle: $(GOFILES)
|
||||
|
||||
build-linux-launcher: $(BUILD_DIR)/linux/lifecycle/launcher
|
||||
|
||||
|
|
@ -89,20 +89,19 @@ $(BUILD_DIR)/windows/lifecycle/lifecycle.toml:
|
|||
|
||||
$(BUILD_DIR)/windows/lifecycle/lifecycle.exe: export GOOS:=windows
|
||||
$(BUILD_DIR)/windows/lifecycle/lifecycle.exe: OUT_DIR?=$(BUILD_DIR)$/$(GOOS)$/lifecycle
|
||||
$(BUILD_DIR)/windows/lifecycle/lifecycle.exe: descriptor-windows
|
||||
$(BUILD_DIR)/windows/lifecycle/lifecycle.exe: $(GOFILES)
|
||||
$(BUILD_DIR)/windows/lifecycle/lifecycle.exe:
|
||||
@echo "> Building lifecycle/lifecycle for Windows..."
|
||||
$(GOBUILD) -o $(OUT_DIR)$/lifecycle.exe -a ./cmd/lifecycle
|
||||
$(BUILD_DIR)/windows/lifecycle/lifecycle.exe: $(GOFILES)
|
||||
|
||||
build-windows-launcher: $(BUILD_DIR)/windows/lifecycle/launcher.exe
|
||||
|
||||
$(BUILD_DIR)/windows/lifecycle/launcher.exe: export GOOS:=windows
|
||||
$(BUILD_DIR)/windows/lifecycle/launcher.exe: OUT_DIR?=$(BUILD_DIR)$/$(GOOS)$/lifecycle
|
||||
$(BUILD_DIR)/windows/lifecycle/launcher.exe: $(GOFILES)
|
||||
$(BUILD_DIR)/windows/lifecycle/launcher.exe:
|
||||
@echo "> Building lifecycle/launcher for Windows..."
|
||||
$(GOBUILD) -o $(OUT_DIR)$/launcher.exe -a ./cmd/launcher
|
||||
$(BUILD_DIR)/windows/lifecycle/launcher.exe: $(GOFILES)
|
||||
|
||||
build-windows-symlinks: export GOOS:=windows
|
||||
build-windows-symlinks: OUT_DIR?=$(BUILD_DIR)$/$(GOOS)$/lifecycle
|
||||
|
|
@ -136,23 +135,32 @@ $(BUILD_DIR)/darwin/lifecycle/lifecycle.toml:
|
|||
mkdir -p $(BUILD_DIR)/darwin/lifecycle
|
||||
cp $(LIFECYCLE_DESCRIPTOR_PATH) $(BUILD_DIR)/darwin/lifecycle/lifecycle.toml
|
||||
|
||||
build-darwin: $(BUILD_DIR)/darwin/lifecycle
|
||||
$(BUILD_DIR)/darwin/lifecycle: export GOOS:=darwin
|
||||
$(BUILD_DIR)/darwin/lifecycle: OUT_DIR:=$(BUILD_DIR)/$(GOOS)/lifecycle
|
||||
$(BUILD_DIR)/darwin/lifecycle:
|
||||
@echo "> Building for macos..."
|
||||
mkdir -p $(OUT_DIR)
|
||||
$(GOENV) $(GOBUILD) -o $(OUT_DIR)/launcher -a ./cmd/launcher
|
||||
test $$(du -m $(OUT_DIR)/launcher|cut -f 1) -le 4
|
||||
build-darwin: descriptor-darwin build-darwin-lifecycle build-darwin-launcher
|
||||
|
||||
build-darwin-lifecycle: $(BUILD_DIR)/darwin/lifecycle/lifecycle
|
||||
$(BUILD_DIR)/darwin/lifecycle/lifecycle: export GOOS:=darwin
|
||||
$(BUILD_DIR)/darwin/lifecycle/lifecycle: OUT_DIR:=$(BUILD_DIR)/$(GOOS)/lifecycle
|
||||
$(BUILD_DIR)/darwin/lifecycle/lifecycle: $(GOFILES)
|
||||
$(BUILD_DIR)/darwin/lifecycle/lifecycle:
|
||||
@echo "> Building lifecycle for macos..."
|
||||
$(GOENV) $(GOBUILD) -o $(OUT_DIR)/lifecycle -a ./cmd/lifecycle
|
||||
@echo "> Creating lifecycle symlinks for macos..."
|
||||
ln -sf lifecycle $(OUT_DIR)/detector
|
||||
ln -sf lifecycle $(OUT_DIR)/analyzer
|
||||
ln -sf lifecycle $(OUT_DIR)/restorer
|
||||
ln -sf lifecycle $(OUT_DIR)/builder
|
||||
ln -sf lifecycle $(OUT_DIR)/exporter
|
||||
ln -sf lifecycle $(OUT_DIR)/rebaser
|
||||
$(BUILD_DIR)/darwin/lifecycle: $(GOFILES)
|
||||
$(BUILD_DIR)/darwin/lifecycle: descriptor-darwin
|
||||
|
||||
build-darwin-launcher: $(BUILD_DIR)/darwin/lifecycle/launcher
|
||||
$(BUILD_DIR)/darwin/lifecycle/launcher: export GOOS:=darwin
|
||||
$(BUILD_DIR)/darwin/lifecycle/launcher: OUT_DIR:=$(BUILD_DIR)/$(GOOS)/lifecycle
|
||||
$(BUILD_DIR)/darwin/lifecycle/launcher: $(GOFILES)
|
||||
$(BUILD_DIR)/darwin/lifecycle/launcher:
|
||||
@echo "> Building launcher for macos..."
|
||||
mkdir -p $(OUT_DIR)
|
||||
$(GOENV) $(GOBUILD) -o $(OUT_DIR)/launcher -a ./cmd/launcher
|
||||
test $$(du -m $(OUT_DIR)/launcher|cut -f 1) -le 4
|
||||
|
||||
install-goimports:
|
||||
@echo "> Installing goimports..."
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package acceptance
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
|
@ -32,13 +31,11 @@ func TestVersion(t *testing.T) {
|
|||
|
||||
outDir := filepath.Join(buildDir, runtime.GOOS, "lifecycle")
|
||||
h.AssertNil(t, os.MkdirAll(outDir, 0755))
|
||||
descriptorPath, err := filepath.Abs(filepath.Join("testdata/lifecycle.toml"))
|
||||
h.AssertNil(t, err)
|
||||
|
||||
h.MakeAndCopyLifecycle(t,
|
||||
runtime.GOOS,
|
||||
outDir,
|
||||
"LIFECYCLE_DESCRIPTOR_PATH="+descriptorPath,
|
||||
"LIFECYCLE_VERSION=some-version",
|
||||
"SCM_COMMIT="+expectedCommit,
|
||||
)
|
||||
spec.Run(t, "acceptance", testVersion, spec.Parallel(), spec.Report(report.Terminal{}))
|
||||
|
|
@ -53,87 +50,6 @@ type testCase struct {
|
|||
|
||||
func testVersion(t *testing.T, when spec.G, it spec.S) {
|
||||
when("All", func() {
|
||||
when("CNB_PLATFORM_API", func() {
|
||||
for _, phase := range []string{
|
||||
"analyzer",
|
||||
"builder",
|
||||
"detector",
|
||||
"exporter",
|
||||
"restorer",
|
||||
"rebaser",
|
||||
"lifecycle",
|
||||
} {
|
||||
phase := phase
|
||||
when("is unsupported", func() {
|
||||
it(phase+"/should fail with error message and exit code 11", func() {
|
||||
cmd := lifecycleCmd(phase)
|
||||
cmd.Env = append(os.Environ(), "CNB_PLATFORM_API=1.4")
|
||||
|
||||
_, exitCode, err := h.RunE(cmd)
|
||||
h.AssertError(t, err, fmt.Sprintf("platform API version '1.4' is incompatible with the lifecycle"))
|
||||
h.AssertEq(t, exitCode, 11)
|
||||
})
|
||||
})
|
||||
|
||||
when("is deprecated", func() {
|
||||
when("CNB_DEPRECATION_MODE is unset", func() {
|
||||
it(phase+"/should warn", func() {
|
||||
cmd := lifecycleCmd(phase, "-version")
|
||||
cmd.Env = []string{
|
||||
"CNB_PLATFORM_API=1.3",
|
||||
}
|
||||
|
||||
out, _, err := h.RunE(cmd)
|
||||
h.AssertNil(t, err)
|
||||
h.AssertStringContains(t, out, "Platform API '1.3' is deprecated")
|
||||
})
|
||||
})
|
||||
|
||||
when("CNB_DEPRECATION_MODE=warn", func() {
|
||||
it(phase+"/should warn", func() {
|
||||
cmd := lifecycleCmd(phase, "-version")
|
||||
cmd.Env = []string{
|
||||
"CNB_PLATFORM_API=1.3",
|
||||
"CNB_DEPRECATION_MODE=warn",
|
||||
}
|
||||
|
||||
out, _, err := h.RunE(cmd)
|
||||
h.AssertNil(t, err)
|
||||
h.AssertStringContains(t, out, "Platform API '1.3' is deprecated")
|
||||
})
|
||||
})
|
||||
|
||||
when("CNB_DEPRECATION_MODE=quiet", func() {
|
||||
it(phase+"/should not warn", func() {
|
||||
cmd := lifecycleCmd(phase, "-version")
|
||||
cmd.Env = []string{
|
||||
"CNB_PLATFORM_API=1.3",
|
||||
"CNB_DEPRECATION_MODE=quiet",
|
||||
}
|
||||
|
||||
out, _, err := h.RunE(cmd)
|
||||
h.AssertNil(t, err)
|
||||
h.AssertStringDoesNotContain(t, out, "deprecated")
|
||||
})
|
||||
})
|
||||
|
||||
when("CNB_DEPRECATION_MODE=error", func() {
|
||||
it(phase+"/should error", func() {
|
||||
cmd := lifecycleCmd(phase, "-version")
|
||||
cmd.Env = []string{
|
||||
"CNB_PLATFORM_API=1.3",
|
||||
"CNB_DEPRECATION_MODE=error",
|
||||
}
|
||||
|
||||
_, exitCode, err := h.RunE(cmd)
|
||||
h.AssertError(t, err, fmt.Sprintf("platform API version '1.3' is incompatible with the lifecycle"))
|
||||
h.AssertEq(t, exitCode, 11)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
when("version flag is set", func() {
|
||||
for _, tc := range []testCase{
|
||||
{
|
||||
|
|
@ -220,7 +136,6 @@ func testVersion(t *testing.T, when spec.G, it spec.S) {
|
|||
w(tc.description, func() {
|
||||
it("only prints the version", func() {
|
||||
cmd := lifecycleCmd(tc.command, tc.args...)
|
||||
cmd.Env = []string{"CNB_PLATFORM_API=2.0"}
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run %v\n OUTPUT: %s\n ERROR: %s\n", cmd.Args, output, err)
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
[apis]
|
||||
[apis.buildpack]
|
||||
deprecated = ["0.9"]
|
||||
supported = ["0.9", "1.2"]
|
||||
[apis.platform]
|
||||
deprecated = ["1"]
|
||||
supported = ["1.3","2.4"]
|
||||
|
||||
[lifecycle]
|
||||
version = "some-version"
|
||||
|
|
@ -58,7 +58,7 @@ func testAnalyzer(t *testing.T, when spec.G, it spec.S) {
|
|||
Logger: &log.Logger{Handler: &discard.Handler{}},
|
||||
}
|
||||
if testing.Verbose() {
|
||||
analyzer.Logger = cmd.Logger
|
||||
analyzer.Logger = cmd.DefaultLogger
|
||||
cmd.SetLogLevel("debug")
|
||||
}
|
||||
mockCtrl = gomock.NewController(t)
|
||||
|
|
|
|||
23
api/apis.go
23
api/apis.go
|
|
@ -6,11 +6,32 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
Platform = newApisMustParse([]string{"0.3", "0.4"}, nil)
|
||||
Buildpack = newApisMustParse([]string{"0.3", "0.4"}, nil)
|
||||
)
|
||||
|
||||
type APIs struct {
|
||||
Supported []*Version
|
||||
Deprecated []*Version
|
||||
}
|
||||
|
||||
// newApisMustParse calls NewApis and panics on error
|
||||
func newApisMustParse(supported []string, deprecated []string) APIs {
|
||||
apis, err := NewAPIs(supported, deprecated)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return apis
|
||||
}
|
||||
|
||||
// NewApis constructs an instance of APIs
|
||||
// supported must be a superset of deprecated
|
||||
// deprecated APIs greater than 1.0 should should not include minor versions
|
||||
// supported APIs should always include minor versions
|
||||
// Examples:
|
||||
// deprecated API 1 implies all 1.x APIs are deprecated
|
||||
// supported API 1 implies only 1.0 is supported
|
||||
func NewAPIs(supported []string, deprecated []string) (APIs, error) {
|
||||
apis := APIs{}
|
||||
for _, api := range supported {
|
||||
|
|
@ -40,6 +61,7 @@ func validateDeprecated(apis APIs, d string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// IsSupported returns true or false depending on whether the target API is supported
|
||||
func (a APIs) IsSupported(target string) bool {
|
||||
tAPI := MustParse(target)
|
||||
for _, sAPI := range a.Supported {
|
||||
|
|
@ -50,6 +72,7 @@ func (a APIs) IsSupported(target string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// IsDeprecated returns true or false depending on whether the target API is deprecated
|
||||
func (a APIs) IsDeprecated(target string) bool {
|
||||
tAPI := MustParse(target)
|
||||
for _, dAPI := range a.Deprecated {
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ func Exit(err error) {
|
|||
if err == nil {
|
||||
os.Exit(0)
|
||||
}
|
||||
Logger.Errorf("%s\n", err)
|
||||
DefaultLogger.Errorf("%s\n", err)
|
||||
if err, ok := err.(*ErrorFail); ok {
|
||||
os.Exit(err.Code)
|
||||
}
|
||||
|
|
@ -63,6 +63,6 @@ func Exit(err error) {
|
|||
}
|
||||
|
||||
func ExitWithVersion() {
|
||||
Logger.Infof(buildVersion())
|
||||
DefaultLogger.Infof(buildVersion())
|
||||
os.Exit(0)
|
||||
}
|
||||
|
|
|
|||
30
cmd/flags.go
30
cmd/flags.go
|
|
@ -12,12 +12,14 @@ var (
|
|||
DefaultAnalyzedPath = filepath.Join(".", "analyzed.toml")
|
||||
DefaultAppDir = filepath.Join(rootDir, "workspace")
|
||||
DefaultBuildpacksDir = filepath.Join(rootDir, "cnb", "buildpacks")
|
||||
DefaultDeprecationMode = DeprecationModeWarn
|
||||
DefaultGroupPath = filepath.Join(".", "group.toml")
|
||||
DefaultLauncherPath = filepath.Join(rootDir, "cnb", "lifecycle", "launcher"+execExt)
|
||||
DefaultLayersDir = filepath.Join(rootDir, "layers")
|
||||
DefaultLogLevel = "info"
|
||||
DefaultOrderPath = filepath.Join(rootDir, "cnb", "order.toml")
|
||||
DefaultPlanPath = filepath.Join(".", "plan.toml")
|
||||
DefaultPlatformAPI = "0.3"
|
||||
DefaultPlatformDir = filepath.Join(rootDir, "platform")
|
||||
DefaultProcessType = "web"
|
||||
DefaultProjectMetadataPath = filepath.Join(".", "project-metadata.toml")
|
||||
|
|
@ -31,6 +33,7 @@ const (
|
|||
EnvBuildpacksDir = "CNB_BUILDPACKS_DIR"
|
||||
EnvCacheDir = "CNB_CACHE_DIR"
|
||||
EnvCacheImage = "CNB_CACHE_IMAGE"
|
||||
EnvDeprecationMode = "CNB_DEPRECATION_MODE"
|
||||
EnvGID = "CNB_GROUP_ID"
|
||||
EnvGroupPath = "CNB_GROUP_PATH"
|
||||
EnvLaunchCacheDir = "CNB_LAUNCH_CACHE_DIR"
|
||||
|
|
@ -39,6 +42,7 @@ const (
|
|||
EnvNoColor = "CNB_NO_COLOR" // defaults to false
|
||||
EnvOrderPath = "CNB_ORDER_PATH"
|
||||
EnvPlanPath = "CNB_PLAN_PATH"
|
||||
EnvPlatformAPI = "CNB_PLATFORM_API"
|
||||
EnvPlatformDir = "CNB_PLATFORM_DIR"
|
||||
EnvPreviousImage = "CNB_PREVIOUS_IMAGE"
|
||||
EnvProcessType = "CNB_PROCESS_TYPE"
|
||||
|
|
@ -56,15 +60,15 @@ const (
|
|||
var flagSet = flag.NewFlagSet("lifecycle", flag.ExitOnError)
|
||||
|
||||
func FlagAnalyzedPath(dir *string) {
|
||||
flagSet.StringVar(dir, "analyzed", envOrDefault(EnvAnalyzedPath, DefaultAnalyzedPath), "path to analyzed.toml")
|
||||
flagSet.StringVar(dir, "analyzed", EnvOrDefault(EnvAnalyzedPath, DefaultAnalyzedPath), "path to analyzed.toml")
|
||||
}
|
||||
|
||||
func FlagAppDir(dir *string) {
|
||||
flagSet.StringVar(dir, "app", envOrDefault(EnvAppDir, DefaultAppDir), "path to app directory")
|
||||
flagSet.StringVar(dir, "app", EnvOrDefault(EnvAppDir, DefaultAppDir), "path to app directory")
|
||||
}
|
||||
|
||||
func FlagBuildpacksDir(dir *string) {
|
||||
flagSet.StringVar(dir, "buildpacks", envOrDefault(EnvBuildpacksDir, DefaultBuildpacksDir), "path to buildpacks directory")
|
||||
flagSet.StringVar(dir, "buildpacks", EnvOrDefault(EnvBuildpacksDir, DefaultBuildpacksDir), "path to buildpacks directory")
|
||||
}
|
||||
|
||||
func FlagCacheDir(dir *string) {
|
||||
|
|
@ -80,7 +84,7 @@ func FlagGID(gid *int) {
|
|||
}
|
||||
|
||||
func FlagGroupPath(path *string) {
|
||||
flagSet.StringVar(path, "group", envOrDefault(EnvGroupPath, DefaultGroupPath), "path to group.toml")
|
||||
flagSet.StringVar(path, "group", EnvOrDefault(EnvGroupPath, DefaultGroupPath), "path to group.toml")
|
||||
}
|
||||
|
||||
func FlagLaunchCacheDir(dir *string) {
|
||||
|
|
@ -92,7 +96,7 @@ func FlagLauncherPath(path *string) {
|
|||
}
|
||||
|
||||
func FlagLayersDir(dir *string) {
|
||||
flagSet.StringVar(dir, "layers", envOrDefault(EnvLayersDir, DefaultLayersDir), "path to layers directory")
|
||||
flagSet.StringVar(dir, "layers", EnvOrDefault(EnvLayersDir, DefaultLayersDir), "path to layers directory")
|
||||
}
|
||||
|
||||
func FlagNoColor(skip *bool) {
|
||||
|
|
@ -100,15 +104,15 @@ func FlagNoColor(skip *bool) {
|
|||
}
|
||||
|
||||
func FlagOrderPath(path *string) {
|
||||
flagSet.StringVar(path, "order", envOrDefault(EnvOrderPath, DefaultOrderPath), "path to order.toml")
|
||||
flagSet.StringVar(path, "order", EnvOrDefault(EnvOrderPath, DefaultOrderPath), "path to order.toml")
|
||||
}
|
||||
|
||||
func FlagPlanPath(path *string) {
|
||||
flagSet.StringVar(path, "plan", envOrDefault(EnvPlanPath, DefaultPlanPath), "path to plan.toml")
|
||||
flagSet.StringVar(path, "plan", EnvOrDefault(EnvPlanPath, DefaultPlanPath), "path to plan.toml")
|
||||
}
|
||||
|
||||
func FlagPlatformDir(dir *string) {
|
||||
flagSet.StringVar(dir, "platform", envOrDefault(EnvPlatformDir, DefaultPlatformDir), "path to platform directory")
|
||||
flagSet.StringVar(dir, "platform", EnvOrDefault(EnvPlatformDir, DefaultPlatformDir), "path to platform directory")
|
||||
}
|
||||
|
||||
func FlagPreviousImage(image *string) {
|
||||
|
|
@ -116,7 +120,7 @@ func FlagPreviousImage(image *string) {
|
|||
}
|
||||
|
||||
func FlagReportPath(path *string) {
|
||||
flagSet.StringVar(path, "report", envOrDefault(EnvReportPath, DefaultReportPath), "path to report.toml")
|
||||
flagSet.StringVar(path, "report", EnvOrDefault(EnvReportPath, DefaultReportPath), "path to report.toml")
|
||||
}
|
||||
|
||||
func FlagRunImage(image *string) {
|
||||
|
|
@ -132,7 +136,7 @@ func FlagSkipRestore(skip *bool) {
|
|||
}
|
||||
|
||||
func FlagStackPath(path *string) {
|
||||
flagSet.StringVar(path, "stack", envOrDefault(EnvStackPath, DefaultStackPath), "path to stack.toml")
|
||||
flagSet.StringVar(path, "stack", EnvOrDefault(EnvStackPath, DefaultStackPath), "path to stack.toml")
|
||||
}
|
||||
|
||||
func FlagTags(tags *StringSlice) {
|
||||
|
|
@ -152,11 +156,11 @@ func FlagVersion(version *bool) {
|
|||
}
|
||||
|
||||
func FlagLogLevel(level *string) {
|
||||
flagSet.StringVar(level, "log-level", envOrDefault(EnvLogLevel, DefaultLogLevel), "logging level")
|
||||
flagSet.StringVar(level, "log-level", EnvOrDefault(EnvLogLevel, DefaultLogLevel), "logging level")
|
||||
}
|
||||
|
||||
func FlagProjectMetadataPath(projectMetadataPath *string) {
|
||||
flagSet.StringVar(projectMetadataPath, "project-metadata", envOrDefault(EnvProjectMetadataPath, DefaultProjectMetadataPath), "path to project-metadata.toml")
|
||||
flagSet.StringVar(projectMetadataPath, "project-metadata", EnvOrDefault(EnvProjectMetadataPath, DefaultProjectMetadataPath), "path to project-metadata.toml")
|
||||
}
|
||||
|
||||
func FlagProcessType(processType *string) {
|
||||
|
|
@ -196,7 +200,7 @@ func boolEnv(k string) bool {
|
|||
return b
|
||||
}
|
||||
|
||||
func envOrDefault(key string, defaultVal string) string {
|
||||
func EnvOrDefault(key string, defaultVal string) string {
|
||||
if envVal := os.Getenv(key); envVal != "" {
|
||||
return envVal
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,28 +15,20 @@ func main() {
|
|||
}
|
||||
|
||||
func runLaunch() error {
|
||||
defaultProcessType := cmd.DefaultProcessType
|
||||
if v := os.Getenv(cmd.EnvProcessType); v != "" {
|
||||
defaultProcessType = v
|
||||
}
|
||||
layersDir := cmd.DefaultLayersDir
|
||||
if v := os.Getenv(cmd.EnvLayersDir); v != "" {
|
||||
layersDir = v
|
||||
}
|
||||
appDir := cmd.DefaultAppDir
|
||||
if v := os.Getenv(cmd.EnvAppDir); v != "" {
|
||||
appDir = v
|
||||
platformAPI := cmd.EnvOrDefault(cmd.EnvPlatformAPI, cmd.DefaultPlatformAPI)
|
||||
if err := cmd.VerifyPlatformAPI(platformAPI); err != nil {
|
||||
cmd.Exit(err)
|
||||
}
|
||||
|
||||
var md launch.Metadata
|
||||
if _, err := toml.DecodeFile(launch.GetMetadataFilePath(layersDir), &md); err != nil {
|
||||
if _, err := toml.DecodeFile(launch.GetMetadataFilePath(cmd.EnvOrDefault(cmd.EnvLayersDir, cmd.DefaultLayersDir)), &md); err != nil {
|
||||
return cmd.FailErr(err, "read metadata")
|
||||
}
|
||||
|
||||
launcher := &launch.Launcher{
|
||||
DefaultProcessType: defaultProcessType,
|
||||
LayersDir: layersDir,
|
||||
AppDir: appDir,
|
||||
DefaultProcessType: cmd.EnvOrDefault(cmd.EnvProcessType, cmd.DefaultProcessType),
|
||||
LayersDir: cmd.EnvOrDefault(cmd.EnvLayersDir, cmd.DefaultLayersDir),
|
||||
AppDir: cmd.EnvOrDefault(cmd.EnvAppDir, cmd.DefaultAppDir),
|
||||
Processes: md.Processes,
|
||||
Buildpacks: md.Buildpacks,
|
||||
Env: env.NewLaunchEnv(os.Environ()),
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ func (a *analyzeCmd) Args(nargs int, args []string) error {
|
|||
return cmd.FailErrCode(errors.New("image argument is required"), cmd.CodeInvalidArgs, "parse arguments")
|
||||
}
|
||||
if a.cacheImageTag == "" && a.cacheDir == "" {
|
||||
cmd.Logger.Warn("Not restoring cached layer metadata, no cache flag specified.")
|
||||
cmd.DefaultLogger.Warn("Not restoring cached layer metadata, no cache flag specified.")
|
||||
}
|
||||
a.imageName = args[0]
|
||||
return nil
|
||||
|
|
@ -129,7 +129,7 @@ func (aa analyzeArgs) analyze(group lifecycle.BuildpackGroup, cacheStore lifecyc
|
|||
analyzedMD, err := (&lifecycle.Analyzer{
|
||||
Buildpacks: group.Group,
|
||||
LayersDir: aa.layersDir,
|
||||
Logger: cmd.Logger,
|
||||
Logger: cmd.DefaultLogger,
|
||||
SkipLayers: aa.skipLayers,
|
||||
}).Analyze(img, cacheStore)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -65,12 +65,12 @@ func (c *createCmd) Args(nargs int, args []string) error {
|
|||
|
||||
c.imageName = args[0]
|
||||
if c.launchCacheDir != "" && !c.useDaemon {
|
||||
cmd.Logger.Warn("Ignoring -launch-cache, only intended for use with -daemon")
|
||||
cmd.DefaultLogger.Warn("Ignoring -launch-cache, only intended for use with -daemon")
|
||||
c.launchCacheDir = ""
|
||||
}
|
||||
|
||||
if c.cacheImageTag == "" && c.cacheDir == "" {
|
||||
cmd.Logger.Warn("Not restoring or caching layer data, no cache flag specified.")
|
||||
cmd.DefaultLogger.Warn("Not restoring or caching layer data, no cache flag specified.")
|
||||
}
|
||||
|
||||
if c.previousImage == "" {
|
||||
|
|
@ -110,7 +110,7 @@ func (c *createCmd) Exec() error {
|
|||
return err
|
||||
}
|
||||
|
||||
cmd.Logger.Phase("DETECTING")
|
||||
cmd.DefaultLogger.Phase("DETECTING")
|
||||
group, plan, err := detectArgs{
|
||||
buildpacksDir: c.buildpacksDir,
|
||||
appDir: c.appDir,
|
||||
|
|
@ -121,7 +121,7 @@ func (c *createCmd) Exec() error {
|
|||
return cmd.FailErrCode(err, cmd.CodeFailed, "detect")
|
||||
}
|
||||
|
||||
cmd.Logger.Phase("ANALYZING")
|
||||
cmd.DefaultLogger.Phase("ANALYZING")
|
||||
analyzedMD, err := analyzeArgs{
|
||||
imageName: c.previousImage,
|
||||
layersDir: c.layersDir,
|
||||
|
|
@ -134,13 +134,13 @@ func (c *createCmd) Exec() error {
|
|||
}
|
||||
|
||||
if !c.skipRestore {
|
||||
cmd.Logger.Phase("RESTORING")
|
||||
cmd.DefaultLogger.Phase("RESTORING")
|
||||
if err := restore(c.layersDir, group, cacheStore); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
cmd.Logger.Phase("BUILDING")
|
||||
cmd.DefaultLogger.Phase("BUILDING")
|
||||
err = buildArgs{
|
||||
buildpacksDir: c.buildpacksDir,
|
||||
layersDir: c.layersDir,
|
||||
|
|
@ -151,7 +151,7 @@ func (c *createCmd) Exec() error {
|
|||
return err
|
||||
}
|
||||
|
||||
cmd.Logger.Phase("EXPORTING")
|
||||
cmd.DefaultLogger.Phase("EXPORTING")
|
||||
return exportArgs{
|
||||
stackPath: c.stackPath,
|
||||
imageNames: append([]string{c.imageName}, c.additionalTags...),
|
||||
|
|
|
|||
|
|
@ -76,16 +76,16 @@ func (da detectArgs) detect() (lifecycle.BuildpackGroup, lifecycle.BuildPlan, er
|
|||
AppDir: da.appDir,
|
||||
PlatformDir: da.platformDir,
|
||||
BuildpacksDir: da.buildpacksDir,
|
||||
Logger: cmd.Logger,
|
||||
Logger: cmd.DefaultLogger,
|
||||
})
|
||||
if err != nil {
|
||||
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.")
|
||||
cmd.DefaultLogger.Error("No buildpack groups passed detection.")
|
||||
cmd.DefaultLogger.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.")
|
||||
cmd.DefaultLogger.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")
|
||||
|
|
|
|||
|
|
@ -81,12 +81,12 @@ func (e *exportCmd) Args(nargs int, args []string) error {
|
|||
|
||||
e.imageNames = args
|
||||
if e.launchCacheDir != "" && !e.useDaemon {
|
||||
cmd.Logger.Warn("Ignoring -launch-cache, only intended for use with -daemon")
|
||||
cmd.DefaultLogger.Warn("Ignoring -launch-cache, only intended for use with -daemon")
|
||||
e.launchCacheDir = ""
|
||||
}
|
||||
|
||||
if e.cacheImageTag == "" && e.cacheDir == "" {
|
||||
cmd.Logger.Warn("Will not cache data, no cache flag specified.")
|
||||
cmd.DefaultLogger.Warn("Will not cache data, no cache flag specified.")
|
||||
}
|
||||
|
||||
if err := image.ValidateDestinationTags(e.useDaemon, e.imageNames...); err != nil {
|
||||
|
|
@ -127,14 +127,14 @@ func (e *exportCmd) Exec() error {
|
|||
return cmd.FailErr(err, "read buildpack group")
|
||||
}
|
||||
|
||||
analyzedMD, err := parseOptionalAnalyzedMD(cmd.Logger, e.analyzedPath)
|
||||
analyzedMD, err := parseOptionalAnalyzedMD(cmd.DefaultLogger, e.analyzedPath)
|
||||
if err != nil {
|
||||
return cmd.FailErrCode(err, cmd.CodeInvalidArgs, "parse analyzed metadata")
|
||||
}
|
||||
|
||||
cacheStore, err := initCache(e.cacheImageTag, e.cacheDir)
|
||||
if err != nil {
|
||||
cmd.Logger.Infof("no stack metadata found at path '%s', stack metadata will not be exported\n", e.stackPath)
|
||||
cmd.DefaultLogger.Infof("no stack metadata found at path '%s', stack metadata will not be exported\n", e.stackPath)
|
||||
}
|
||||
|
||||
return e.export(group, cacheStore, analyzedMD)
|
||||
|
|
@ -164,17 +164,17 @@ func (ea exportArgs) export(group lifecycle.BuildpackGroup, cacheStore lifecycle
|
|||
if !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
cmd.Logger.Debugf("no project metadata found at path '%s', project metadata will not be exported\n", ea.projectMetadataPath)
|
||||
cmd.DefaultLogger.Debugf("no project metadata found at path '%s', project metadata will not be exported\n", ea.projectMetadataPath)
|
||||
}
|
||||
|
||||
exporter := &lifecycle.Exporter{
|
||||
Buildpacks: group.Group,
|
||||
Logger: cmd.Logger,
|
||||
Logger: cmd.DefaultLogger,
|
||||
LayerFactory: &layers.Factory{
|
||||
ArtifactsDir: artifactsDir,
|
||||
UID: ea.uid,
|
||||
GID: ea.uid,
|
||||
Logger: cmd.Logger,
|
||||
Logger: cmd.DefaultLogger,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -224,7 +224,7 @@ func (ea exportArgs) export(group lifecycle.BuildpackGroup, cacheStore lifecycle
|
|||
|
||||
if cacheStore != nil {
|
||||
if cacheErr := exporter.Cache(ea.layersDir, cacheStore); cacheErr != nil {
|
||||
cmd.Logger.Warnf("Failed to export cache: %v\n", cacheErr)
|
||||
cmd.DefaultLogger.Warnf("Failed to export cache: %v\n", cacheErr)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
@ -236,7 +236,7 @@ func initDaemonImage(imagName string, runImageRef string, analyzedMD lifecycle.A
|
|||
}
|
||||
|
||||
if analyzedMD.Image != nil {
|
||||
cmd.Logger.Debugf("Reusing layers from image with id '%s'", analyzedMD.Image.Reference)
|
||||
cmd.DefaultLogger.Debugf("Reusing layers from image with id '%s'", analyzedMD.Image.Reference)
|
||||
opts = append(opts, local.WithPreviousImage(analyzedMD.Image.Reference))
|
||||
}
|
||||
|
||||
|
|
@ -270,7 +270,7 @@ func initRemoteImage(imageName string, runImageRef string, analyzedMD lifecycle.
|
|||
}
|
||||
|
||||
if analyzedMD.Image != nil {
|
||||
cmd.Logger.Infof("Reusing layers from image '%s'", analyzedMD.Image.Reference)
|
||||
cmd.DefaultLogger.Infof("Reusing layers from image '%s'", analyzedMD.Image.Reference)
|
||||
ref, err := name.ParseReference(analyzedMD.Image.Reference, name.WeakValidation)
|
||||
if err != nil {
|
||||
return nil, "", cmd.FailErr(err, "parse analyzed registry")
|
||||
|
|
@ -337,7 +337,7 @@ func resolveStack(stackPath, runImageRef, registry string) (lifecycle.StackMetad
|
|||
var stackMD lifecycle.StackMetadata
|
||||
_, err := toml.DecodeFile(stackPath, &stackMD)
|
||||
if err != nil {
|
||||
cmd.Logger.Infof("no stack metadata found at path '%s', stack metadata will not be exported\n", stackPath)
|
||||
cmd.DefaultLogger.Infof("no stack metadata found at path '%s', stack metadata will not be exported\n", stackPath)
|
||||
}
|
||||
if runImageRef == "" {
|
||||
if stackMD.RunImage.Image == "" {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
if err := cmd.VerifyCompatibility(); err != nil {
|
||||
platformAPI := cmd.EnvOrDefault(cmd.EnvPlatformAPI, cmd.DefaultPlatformAPI)
|
||||
if err := cmd.VerifyPlatformAPI(platformAPI); err != nil {
|
||||
cmd.Exit(err)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ func (r *rebaseCmd) Exec() error {
|
|||
}
|
||||
|
||||
rebaser := &lifecycle.Rebaser{
|
||||
Logger: cmd.Logger,
|
||||
Logger: cmd.DefaultLogger,
|
||||
}
|
||||
report, err := rebaser.Rebase(appImage, newBaseImage, r.imageNames[1:])
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ func (r *restoreCmd) Args(nargs int, args []string) error {
|
|||
return cmd.FailErrCode(errors.New("received unexpected Args"), cmd.CodeInvalidArgs, "parse arguments")
|
||||
}
|
||||
if r.cacheImageTag == "" && r.cacheDir == "" {
|
||||
cmd.Logger.Warn("Not restoring cached layer data, no cache flag specified.")
|
||||
cmd.DefaultLogger.Warn("Not restoring cached layer data, no cache flag specified.")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@ func restore(layersDir string, group lifecycle.BuildpackGroup, cacheStore lifecy
|
|||
restorer := &lifecycle.Restorer{
|
||||
LayersDir: layersDir,
|
||||
Buildpacks: group.Group,
|
||||
Logger: cmd.Logger,
|
||||
Logger: cmd.DefaultLogger,
|
||||
}
|
||||
|
||||
if err := restorer.Restore(cacheStore); err != nil {
|
||||
|
|
|
|||
|
|
@ -19,9 +19,8 @@ func init() {
|
|||
//color.Disable(!terminal.IsTerminal(int(os.Stdout.Fd())))
|
||||
}
|
||||
|
||||
// Default logger
|
||||
var (
|
||||
Logger = &logger{
|
||||
DefaultLogger = &Logger{
|
||||
&log.Logger{
|
||||
Handler: &handler{
|
||||
writer: os.Stdout,
|
||||
|
|
@ -33,17 +32,17 @@ var (
|
|||
phaseStyle = color.New(color.FgCyan).SprintfFunc()
|
||||
)
|
||||
|
||||
type logger struct {
|
||||
type Logger struct {
|
||||
*log.Logger
|
||||
}
|
||||
|
||||
func (l *logger) Phase(name string) {
|
||||
func (l *Logger) Phase(name string) {
|
||||
l.Infof(phaseStyle("===> %s", name))
|
||||
}
|
||||
|
||||
func SetLogLevel(level string) *ErrorFail {
|
||||
var err error
|
||||
Logger.Level, err = log.ParseLevel(level)
|
||||
DefaultLogger.Level, err = log.ParseLevel(level)
|
||||
if err != nil {
|
||||
return FailErrCode(err, CodeInvalidArgs, "parse log level")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package cmd
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/buildpacks/lifecycle/api"
|
||||
)
|
||||
|
|
@ -16,17 +15,7 @@ var (
|
|||
// SCMRepository is the source repository.
|
||||
SCMRepository = ""
|
||||
|
||||
// SupportedPlatformAPIs contains a comma separated list of supported platforms APIs
|
||||
SupportedPlatformAPIs string
|
||||
// DepreactedPlatformAPIs contains a comma separated list of depreacted platforms APIs
|
||||
DeprecatedPlatformAPIs string
|
||||
|
||||
EnvPlatformAPI = "CNB_PLATFORM_API"
|
||||
EnvDeprecationMode = "CNB_DEPRECATION_MODE"
|
||||
|
||||
// DefaultPlatformAPI specifies platform API to provide when "CNB_PLATFORM_API" is unset
|
||||
DefaultPlatformAPI = "0.3"
|
||||
DefaultDeprecationMode = "warn"
|
||||
DeprecationMode = EnvOrDefault(EnvDeprecationMode, DefaultDeprecationMode)
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -45,21 +34,18 @@ func buildVersion() string {
|
|||
return fmt.Sprintf("%s+%s", Version, SCMCommit)
|
||||
}
|
||||
|
||||
func VerifyCompatibility() error {
|
||||
apis, _ := api.NewAPIs(splitApis(SupportedPlatformAPIs), splitApis(DeprecatedPlatformAPIs))
|
||||
|
||||
requestedAPI := envOrDefault(EnvPlatformAPI, DefaultPlatformAPI)
|
||||
if apis.IsSupported(requestedAPI) {
|
||||
if apis.IsDeprecated(requestedAPI) {
|
||||
switch envOrDefault(EnvDeprecationMode, DeprecationModeWarn) {
|
||||
func VerifyPlatformAPI(requestedAPI string) error {
|
||||
if api.Platform.IsSupported(requestedAPI) {
|
||||
if api.Platform.IsDeprecated(requestedAPI) {
|
||||
switch DeprecationMode {
|
||||
case DeprecationModeQuiet:
|
||||
break
|
||||
case DeprecationModeError:
|
||||
return platformAPIError(requestedAPI)
|
||||
case DeprecationModeWarn:
|
||||
Logger.Warnf("Platform API '%s' is deprecated", requestedAPI)
|
||||
DefaultLogger.Warnf("Platform API '%s' is deprecated", requestedAPI)
|
||||
default:
|
||||
Logger.Warnf("Platform API '%s' is deprecated", requestedAPI)
|
||||
DefaultLogger.Warnf("Platform API '%s' is deprecated", requestedAPI)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
@ -67,14 +53,6 @@ func VerifyCompatibility() error {
|
|||
return platformAPIError(requestedAPI)
|
||||
}
|
||||
|
||||
func splitApis(joined string) []string {
|
||||
supported := strings.Split(joined, `,`)
|
||||
if len(supported) == 1 && supported[0] == "" {
|
||||
supported = nil
|
||||
}
|
||||
return supported
|
||||
}
|
||||
|
||||
func platformAPIError(requestedAPI string) error {
|
||||
return FailErrCode(
|
||||
fmt.Errorf("set platform API: platform API version '%s' is incompatible with the lifecycle", requestedAPI),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
package cmd_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/apex/log/handlers/memory"
|
||||
"github.com/sclevine/spec"
|
||||
"github.com/sclevine/spec/report"
|
||||
|
||||
"github.com/buildpacks/lifecycle/api"
|
||||
"github.com/buildpacks/lifecycle/cmd"
|
||||
h "github.com/buildpacks/lifecycle/testhelpers"
|
||||
)
|
||||
|
||||
func TestPlatformAPI(t *testing.T) {
|
||||
spec.Run(t, "PlatformAPI", testPlatformAPI, spec.Sequential(), spec.Report(report.Terminal{}))
|
||||
}
|
||||
|
||||
func testPlatformAPI(t *testing.T, when spec.G, it spec.S) {
|
||||
when("VerifyPlatformAPI", func() {
|
||||
var (
|
||||
logHandler *memory.Handler
|
||||
)
|
||||
|
||||
it.Before(func() {
|
||||
var err error
|
||||
api.Platform, err = api.NewAPIs([]string{"1.2", "2.1"}, []string{"1"})
|
||||
h.AssertNil(t, err)
|
||||
logHandler = memory.New()
|
||||
cmd.DefaultLogger = &cmd.Logger{Logger: &log.Logger{Handler: logHandler}}
|
||||
})
|
||||
|
||||
when("is unsupported", func() {
|
||||
it("error with exit code 11", func() {
|
||||
err := cmd.VerifyPlatformAPI("2.2")
|
||||
failErr, ok := err.(*cmd.ErrorFail)
|
||||
if !ok {
|
||||
t.Fatalf("expected an error of type cmd.ErrorFail")
|
||||
}
|
||||
h.AssertEq(t, failErr.Code, 11)
|
||||
})
|
||||
})
|
||||
|
||||
when("is deprecated", func() {
|
||||
when("default deprecation mode", func() {
|
||||
it("should warn", func() {
|
||||
err := cmd.VerifyPlatformAPI("1.1")
|
||||
h.AssertNil(t, err)
|
||||
h.AssertEq(t, len(logHandler.Entries), 1)
|
||||
h.AssertEq(t, logHandler.Entries[0].Level, log.WarnLevel)
|
||||
h.AssertEq(t, logHandler.Entries[0].Message, "Platform API '1.1' is deprecated")
|
||||
})
|
||||
})
|
||||
|
||||
when("CNB_DEPRECATION_MODE=warn", func() {
|
||||
it("should warn", func() {
|
||||
cmd.DeprecationMode = cmd.DeprecationModeWarn
|
||||
err := cmd.VerifyPlatformAPI("1.1")
|
||||
h.AssertNil(t, err)
|
||||
h.AssertEq(t, len(logHandler.Entries), 1)
|
||||
h.AssertEq(t, logHandler.Entries[0].Level, log.WarnLevel)
|
||||
h.AssertEq(t, logHandler.Entries[0].Message, "Platform API '1.1' is deprecated")
|
||||
})
|
||||
})
|
||||
|
||||
when("CNB_DEPRECATION_MODE=quiet", func() {
|
||||
it("should succeed silently", func() {
|
||||
cmd.DeprecationMode = cmd.DeprecationModeQuiet
|
||||
err := cmd.VerifyPlatformAPI("1.1")
|
||||
h.AssertNil(t, err)
|
||||
h.AssertEq(t, len(logHandler.Entries), 0)
|
||||
})
|
||||
})
|
||||
|
||||
when("CNB_DEPRECATION_MODE=error", func() {
|
||||
it("error with exit code 11", func() {
|
||||
cmd.DeprecationMode = cmd.DeprecationModeError
|
||||
err := cmd.VerifyPlatformAPI("1.1")
|
||||
failErr, ok := err.(*cmd.ErrorFail)
|
||||
if !ok {
|
||||
t.Fatalf("expected an error of type cmd.ErrorFail")
|
||||
}
|
||||
h.AssertEq(t, failErr.Code, 11)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
@ -54,7 +54,7 @@ func testRestorer(t *testing.T, when spec.G, it spec.S) {
|
|||
Logger: &log.Logger{Handler: &discard.Handler{}},
|
||||
}
|
||||
if testing.Verbose() {
|
||||
restorer.Logger = cmd.Logger
|
||||
restorer.Logger = cmd.DefaultLogger
|
||||
cmd.SetLogLevel("debug")
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,87 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
type Descriptor struct {
|
||||
APIs `toml:"apis"`
|
||||
Lifecycle Lifecycle `toml:"lifecycle"`
|
||||
}
|
||||
|
||||
type Lifecycle struct {
|
||||
Version string `toml:"version"`
|
||||
}
|
||||
|
||||
type APIs struct {
|
||||
Buildpack APISet `toml:"buildpack"`
|
||||
Platform APISet `toml:"platform"`
|
||||
}
|
||||
|
||||
type APISet struct {
|
||||
Deprecated []string
|
||||
Supported []string
|
||||
}
|
||||
|
||||
const (
|
||||
gitRepository = "github.com/buildpacks/lifecycle"
|
||||
)
|
||||
|
||||
// build-args generates ldflags from descriptor
|
||||
// version parses and print version from descriptor
|
||||
func main() {
|
||||
if len(os.Args) != 3 {
|
||||
usageAndExit()
|
||||
}
|
||||
descriptorPath := os.Args[2]
|
||||
descriptor := Descriptor{}
|
||||
_, err := toml.DecodeFile(descriptorPath, &descriptor)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to decode '%s': %s", descriptorPath, err)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
switch os.Args[1] { //just print the version
|
||||
case "version":
|
||||
fmt.Print(descriptor.Lifecycle.Version)
|
||||
case "build-args":
|
||||
fmt.Print(buildArgs(descriptor))
|
||||
default:
|
||||
usageAndExit()
|
||||
}
|
||||
}
|
||||
|
||||
func buildArgs(descriptor Descriptor) string {
|
||||
flags := []string{
|
||||
fmt.Sprintf(
|
||||
"-X 'github.com/buildpacks/lifecycle/cmd.DeprecatedBuildpackAPIs=%s'",
|
||||
strings.Join(descriptor.Buildpack.Deprecated, `,`),
|
||||
),
|
||||
fmt.Sprintf(
|
||||
"-X 'github.com/buildpacks/lifecycle/cmd.SupportedBuildpackAPIs=%s'",
|
||||
strings.Join(descriptor.Buildpack.Supported, `,`),
|
||||
),
|
||||
fmt.Sprintf(
|
||||
"-X 'github.com/buildpacks/lifecycle/cmd.DeprecatedPlatformAPIs=%s'",
|
||||
strings.Join(descriptor.Platform.Deprecated, `,`),
|
||||
),
|
||||
fmt.Sprintf(
|
||||
"-X 'github.com/buildpacks/lifecycle/cmd.SupportedPlatformAPIs=%s'",
|
||||
strings.Join(descriptor.Platform.Supported, `,`),
|
||||
),
|
||||
fmt.Sprintf(
|
||||
"-X 'github.com/buildpacks/lifecycle/cmd.Version=%s'",
|
||||
descriptor.Lifecycle.Version,
|
||||
),
|
||||
}
|
||||
return strings.Join(flags, " ")
|
||||
}
|
||||
|
||||
func usageAndExit() {
|
||||
fmt.Println("USAGE: tools/descriptor/main.go [build-args, version] <path-to-lifecycle-descriptor-file>")
|
||||
os.Exit(1)
|
||||
}
|
||||
Loading…
Reference in New Issue