From f2c33a87f0be926338ae6aaa351fd409659c14ce Mon Sep 17 00:00:00 2001 From: Arjun Sreedharan Date: Tue, 21 Jul 2020 14:22:28 -0400 Subject: [PATCH] Rewrite per RFC 0001 (#60) Signed-off-by: Arjun Sreedharan --- .packit | 0 README.md | 37 +- build.go | 105 +++++ build_test.go | 312 ++++++++++++++ buildpack.toml | 35 +- cmd/build/main.go | 48 --- cmd/build/main_test.go | 37 -- cmd/detect/main.go | 111 ----- cmd/detect/main_test.go | 169 -------- constants.go | 6 + dep/config.go | 38 -- dep/dep.go | 290 ------------- dep/dep_test.go | 395 ------------------ dep/mocks_test.go | 93 ----- dep/testdata/stub.tar.gz | Bin 186 -> 0 bytes detect.go | 16 + detect_test.go | 48 +++ fakes/build_plan_refinery.go | 33 ++ fakes/dependency_manager.go | 64 +++ fakes/entry_resolver.go | 32 ++ go.mod | 16 +- go.sum | 344 ++------------- init_test.go | 17 + integration.json | 3 + integration/default_test.go | 83 ++++ integration/init_test.go | 113 +++++ integration/integration_test.go | 168 -------- integration/layer_reuse_test.go | 102 +++++ integration/offline_test.go | 76 ++++ .../{simple_app => default_app}/Gopkg.toml | 0 integration/testdata/default_app/plan.toml | 5 + .../{simple_app => default_app}/site.go | 0 integration/testdata/simple_app/buildpack.yml | 3 - .../simple_app_with_target/Gopkg.toml | 4 - .../simple_app_with_target/buildpack.yml | 3 - .../simple_app_with_target/cmd/site/site.go | 27 -- .../Gopkg.toml | 4 - .../buildpack.yml | 7 - .../cmd/site/site.go | 33 -- .../simple_app_without_import_path/Gopkg.toml | 4 - .../buildpack.yml | 3 - .../simple_app_without_import_path/site.go | 27 -- integration/testdata/vendored_app/Gopkg.lock | 15 - integration/testdata/vendored_app/Gopkg.toml | 4 - .../testdata/vendored_app/buildpack.yml | 2 - integration/testdata/vendored_app/site.go | 27 -- .../github.com/ZiCog/shiny-thing/README.md | 44 -- .../github.com/ZiCog/shiny-thing/bar/bye.go | 11 - .../github.com/ZiCog/shiny-thing/bar/hello.go | 14 - .../github.com/ZiCog/shiny-thing/foo/bye.go | 11 - .../github.com/ZiCog/shiny-thing/foo/hello.go | 14 - .../ZiCog/shiny-thing/shiny-thing.go | 12 - integration/testdata/with_lockfile/Gopkg.lock | 15 - integration/testdata/with_lockfile/Gopkg.toml | 4 - .../testdata/with_lockfile/buildpack.yml | 2 - integration/testdata/with_lockfile/site.go | 27 -- .../with_lockfile_modified/Gopkg.lock | 15 - .../with_lockfile_modified/Gopkg.toml | 4 - .../with_lockfile_modified/buildpack.yml | 2 - .../testdata/with_lockfile_modified/site.go | 27 -- log_emitter.go | 19 + plan_entry_resolver.go | 37 ++ plan_entry_resolver_test.go | 54 +++ plan_refinery.go | 26 ++ plan_refinery_test.go | 48 +++ run/main.go | 29 ++ utils/utils.go | 36 -- 67 files changed, 1295 insertions(+), 2115 deletions(-) create mode 100644 .packit create mode 100644 build.go create mode 100644 build_test.go delete mode 100644 cmd/build/main.go delete mode 100644 cmd/build/main_test.go delete mode 100644 cmd/detect/main.go delete mode 100644 cmd/detect/main_test.go create mode 100644 constants.go delete mode 100644 dep/config.go delete mode 100644 dep/dep.go delete mode 100644 dep/dep_test.go delete mode 100644 dep/mocks_test.go delete mode 100644 dep/testdata/stub.tar.gz create mode 100644 detect.go create mode 100644 detect_test.go create mode 100644 fakes/build_plan_refinery.go create mode 100644 fakes/dependency_manager.go create mode 100644 fakes/entry_resolver.go create mode 100644 init_test.go create mode 100644 integration.json create mode 100644 integration/default_test.go create mode 100644 integration/init_test.go delete mode 100644 integration/integration_test.go create mode 100644 integration/layer_reuse_test.go create mode 100644 integration/offline_test.go rename integration/testdata/{simple_app => default_app}/Gopkg.toml (100%) create mode 100644 integration/testdata/default_app/plan.toml rename integration/testdata/{simple_app => default_app}/site.go (100%) delete mode 100644 integration/testdata/simple_app/buildpack.yml delete mode 100644 integration/testdata/simple_app_with_target/Gopkg.toml delete mode 100644 integration/testdata/simple_app_with_target/buildpack.yml delete mode 100644 integration/testdata/simple_app_with_target/cmd/site/site.go delete mode 100644 integration/testdata/simple_app_with_target_and_ldflags/Gopkg.toml delete mode 100644 integration/testdata/simple_app_with_target_and_ldflags/buildpack.yml delete mode 100644 integration/testdata/simple_app_with_target_and_ldflags/cmd/site/site.go delete mode 100644 integration/testdata/simple_app_without_import_path/Gopkg.toml delete mode 100644 integration/testdata/simple_app_without_import_path/buildpack.yml delete mode 100644 integration/testdata/simple_app_without_import_path/site.go delete mode 100644 integration/testdata/vendored_app/Gopkg.lock delete mode 100644 integration/testdata/vendored_app/Gopkg.toml delete mode 100644 integration/testdata/vendored_app/buildpack.yml delete mode 100644 integration/testdata/vendored_app/site.go delete mode 100644 integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/README.md delete mode 100644 integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/bar/bye.go delete mode 100644 integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/bar/hello.go delete mode 100644 integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/foo/bye.go delete mode 100644 integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/foo/hello.go delete mode 100644 integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/shiny-thing.go delete mode 100644 integration/testdata/with_lockfile/Gopkg.lock delete mode 100644 integration/testdata/with_lockfile/Gopkg.toml delete mode 100644 integration/testdata/with_lockfile/buildpack.yml delete mode 100644 integration/testdata/with_lockfile/site.go delete mode 100644 integration/testdata/with_lockfile_modified/Gopkg.lock delete mode 100644 integration/testdata/with_lockfile_modified/Gopkg.toml delete mode 100644 integration/testdata/with_lockfile_modified/buildpack.yml delete mode 100644 integration/testdata/with_lockfile_modified/site.go create mode 100644 log_emitter.go create mode 100644 plan_entry_resolver.go create mode 100644 plan_entry_resolver_test.go create mode 100644 plan_refinery.go create mode 100644 plan_refinery_test.go create mode 100644 run/main.go delete mode 100644 utils/utils.go diff --git a/.packit b/.packit new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md index b1a1285..cc1552d 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,14 @@ # Dep Cloud Native Buildpack -The Go Dep CNB builds a Go application binary, using the -[`dep`](https://golang.github.io/dep/docs/introduction.html) tool to package -dependencies. +The Dep CNB provides the +[`dep`](https://golang.github.io/dep/docs/introduction.html) executable. The +buildpack installs dep onto the `$PATH` which makes it available for subsequent +buildpacks and/or the final container image. ## Integration -The Dep CNB provides dep as a dependency. Downstream -buildpacks can require the node dependency by generating a [Build Plan +The Dep CNB provides `dep` as a dependency. Downstream +buildpacks can require the dep dependency by generating a [Build Plan TOML](https://github.com/buildpacks/spec/blob/master/buildpack.md#build-plan-toml) file that looks like the following: @@ -26,10 +27,16 @@ file that looks like the following: [requires.metadata] # Setting the build flag to true will ensure that the Dep - # depdendency is available on the $PATH for subsequent buildpacks during + # dependency is available on the $PATH for subsequent buildpacks during # their build phase. If you are writing a buildpack that needs to run Dep # during its build process, this flag should be set to true. build = true + + # Setting the launch flag to true will ensure that the Dep + # dependency is available on the $PATH for the running application. If you are + # writing an application that needs to run Dep at runtime, this flag should + # be set to true. + launch = true ``` ## Usage @@ -42,20 +49,4 @@ This builds the buildpack's Go source using GOOS=linux by default. You can suppl ## `buildpack.yml` Configuration -The `dep` requires a `buildpack.yml` file in the root of the application directory, and must contain the `import-path` directive. - -```yaml -go: - # this sets the go import-path (required) - import-path: hubgit.net/user/app - - # this allows you to override the location of the main package of the app - targets: ["./cmd/web"] - - # this allows you to set Go ldflags for compilation - ldflags: - main.version: v1.2.3 - main.sha: 1234567 -``` - -See `integration/testdata/` subfolders for examples. +The dep buildpack does not support configurations via `buildpack.yml`. diff --git a/build.go b/build.go new file mode 100644 index 0000000..11575c3 --- /dev/null +++ b/build.go @@ -0,0 +1,105 @@ +package dep + +import ( + "path/filepath" + "time" + + "github.com/paketo-buildpacks/packit" + "github.com/paketo-buildpacks/packit/chronos" + "github.com/paketo-buildpacks/packit/postal" +) + +//go:generate faux --interface EntryResolver --output fakes/entry_resolver.go +type EntryResolver interface { + Resolve([]packit.BuildpackPlanEntry) packit.BuildpackPlanEntry +} + +//go:generate faux --interface DependencyManager --output fakes/dependency_manager.go +type DependencyManager interface { + Resolve(path, id, version, stack string) (postal.Dependency, error) + Install(dependency postal.Dependency, cnbPath, layerPath string) error +} + +//go:generate faux --interface BuildPlanRefinery --output fakes/build_plan_refinery.go +type BuildPlanRefinery interface { + BillOfMaterials(postal.Dependency) packit.BuildpackPlanEntry +} + +func Build( + entries EntryResolver, + dependencies DependencyManager, + planRefinery BuildPlanRefinery, + clock chronos.Clock, + logger LogEmitter, +) packit.BuildFunc { + return func(context packit.BuildContext) (packit.BuildResult, error) { + logger.Title("%s %s", context.BuildpackInfo.Name, context.BuildpackInfo.Version) + + entry := entries.Resolve(context.Plan.Entries) + + dependency, err := dependencies.Resolve( + filepath.Join(context.CNBPath, "buildpack.toml"), + entry.Name, + entry.Version, + context.Stack) + if err != nil { + return packit.BuildResult{}, err + } + + bom := planRefinery.BillOfMaterials(dependency) + + depLayer, err := context.Layers.Get(Dep) + if err != nil { + return packit.BuildResult{}, err + } + + depLayer.Launch = entry.Metadata["launch"] == true + depLayer.Build = entry.Metadata["build"] == true + depLayer.Cache = entry.Metadata["build"] == true + + cachedSHA, ok := depLayer.Metadata[DependencyCacheKey].(string) + if ok && cachedSHA == dependency.SHA256 { + logger.Process("Reusing cached layer %s", depLayer.Path) + logger.Break() + + return packit.BuildResult{ + Plan: packit.BuildpackPlan{ + Entries: []packit.BuildpackPlanEntry{bom}, + }, + Layers: []packit.Layer{depLayer}, + }, nil + } + + logger.Process("Executing build process") + + err = depLayer.Reset() + if err != nil { + return packit.BuildResult{}, err + } + + logger.Subprocess("Installing Dep") + + duration, err := clock.Measure(func() error { + return dependencies.Install(dependency, context.CNBPath, depLayer.Path) + }) + if err != nil { + return packit.BuildResult{}, err + } + + logger.Action("Completed in %s", duration.Round(time.Millisecond)) + + depLayer.Metadata = map[string]interface{}{ + DependencyCacheKey: dependency.SHA256, + "built_at": clock.Now().Format(time.RFC3339Nano), + } + + return packit.BuildResult{ + Plan: packit.BuildpackPlan{ + Entries: []packit.BuildpackPlanEntry{bom}, + }, + Layers: []packit.Layer{ + depLayer, + }, + }, nil + } +} diff --git a/build_test.go b/build_test.go new file mode 100644 index 0000000..213b4ec --- /dev/null +++ b/build_test.go @@ -0,0 +1,312 @@ +package dep_test + +import ( + "bytes" + "errors" + "io/ioutil" + "os" + "path/filepath" + "testing" + "time" + + "github.com/paketo-buildpacks/dep" + "github.com/paketo-buildpacks/dep/fakes" + "github.com/paketo-buildpacks/packit" + "github.com/paketo-buildpacks/packit/chronos" + "github.com/paketo-buildpacks/packit/postal" + "github.com/sclevine/spec" + + . "github.com/onsi/gomega" +) + +func testBuild(t *testing.T, context spec.G, it spec.S) { + var ( + Expect = NewWithT(t).Expect + + layersDir string + workingDir string + cnbDir string + timestamp time.Time + entryResolver *fakes.EntryResolver + dependencyManager *fakes.DependencyManager + planRefinery *fakes.BuildPlanRefinery + buffer *bytes.Buffer + + build packit.BuildFunc + ) + + it.Before(func() { + var err error + layersDir, err = ioutil.TempDir("", "layers") + Expect(err).NotTo(HaveOccurred()) + + cnbDir, err = ioutil.TempDir("", "cnb") + Expect(err).NotTo(HaveOccurred()) + + workingDir, err = ioutil.TempDir("", "working-dir") + Expect(err).NotTo(HaveOccurred()) + + buffer = bytes.NewBuffer(nil) + logEmitter := dep.NewLogEmitter(buffer) + + timestamp = time.Now() + clock := chronos.NewClock(func() time.Time { + return timestamp + }) + + entryResolver = &fakes.EntryResolver{} + entryResolver.ResolveCall.Returns.BuildpackPlanEntry = packit.BuildpackPlanEntry{ + Name: "dep", + } + + dependencyManager = &fakes.DependencyManager{} + dependencyManager.ResolveCall.Returns.Dependency = postal.Dependency{ + ID: "dep", + Name: "dep-dependency-name", + SHA256: "dep-dependency-sha", + Stacks: []string{"some-stack"}, + URI: "dep-dependency-uri", + Version: "dep-dependency-version", + } + + planRefinery = &fakes.BuildPlanRefinery{} + planRefinery.BillOfMaterialsCall.Returns.BuildpackPlanEntry = packit.BuildpackPlanEntry{ + Name: "dep", + Metadata: map[string]interface{}{ + "name": "dep-dependency-name", + "sha256": "dep-dependency-sha", + "stacks": []string{"some-stack"}, + "uri": "dep-dependency-uri", + }, + } + build = dep.Build(entryResolver, dependencyManager, planRefinery, clock, logEmitter) + }) + + it.After(func() { + Expect(os.RemoveAll(layersDir)).To(Succeed()) + Expect(os.RemoveAll(cnbDir)).To(Succeed()) + Expect(os.RemoveAll(workingDir)).To(Succeed()) + }) + + it("returns a result that installs dep", func() { + result, err := build(packit.BuildContext{ + WorkingDir: workingDir, + CNBPath: cnbDir, + Stack: "some-stack", + BuildpackInfo: packit.BuildpackInfo{ + Name: "Some Buildpack", + Version: "some-version", + }, + Plan: packit.BuildpackPlan{ + Entries: []packit.BuildpackPlanEntry{ + { + Name: "dep", + }, + }, + }, + Layers: packit.Layers{Path: layersDir}, + }) + Expect(err).NotTo(HaveOccurred()) + + Expect(result).To(Equal(packit.BuildResult{ + Plan: packit.BuildpackPlan{ + Entries: []packit.BuildpackPlanEntry{ + { + Name: "dep", + Metadata: map[string]interface{}{ + "name": "dep-dependency-name", + "sha256": "dep-dependency-sha", + "stacks": []string{"some-stack"}, + "uri": "dep-dependency-uri", + }, + }, + }, + }, + Layers: []packit.Layer{ + { + Name: "dep", + Path: filepath.Join(layersDir, "dep"), + SharedEnv: packit.Environment{}, + BuildEnv: packit.Environment{}, + LaunchEnv: packit.Environment{}, + Build: false, + Launch: false, + Cache: false, + Metadata: map[string]interface{}{ + dep.DependencyCacheKey: "dep-dependency-sha", + "built_at": timestamp.Format(time.RFC3339Nano), + }, + }, + }, + })) + + Expect(filepath.Join(layersDir, "dep")).To(BeADirectory()) + + Expect(entryResolver.ResolveCall.Receives.BuildpackPlanEntrySlice).To(Equal([]packit.BuildpackPlanEntry{ + { + Name: "dep", + }, + })) + + Expect(dependencyManager.ResolveCall.Receives.Path).To(Equal(filepath.Join(cnbDir, "buildpack.toml"))) + Expect(dependencyManager.ResolveCall.Receives.Id).To(Equal("dep")) + Expect(dependencyManager.ResolveCall.Receives.Stack).To(Equal("some-stack")) + + Expect(dependencyManager.InstallCall.Receives.Dependency).To(Equal(postal.Dependency{ + ID: "dep", + Name: "dep-dependency-name", + SHA256: "dep-dependency-sha", + Stacks: []string{"some-stack"}, + URI: "dep-dependency-uri", + Version: "dep-dependency-version", + })) + Expect(dependencyManager.InstallCall.Receives.CnbPath).To(Equal(cnbDir)) + Expect(dependencyManager.InstallCall.Receives.LayerPath).To(Equal(filepath.Join(layersDir, "dep"))) + + Expect(planRefinery.BillOfMaterialsCall.Receives.Dependency).To(Equal(postal.Dependency{ + ID: "dep", + Name: "dep-dependency-name", + SHA256: "dep-dependency-sha", + Stacks: []string{"some-stack"}, + URI: "dep-dependency-uri", + Version: "dep-dependency-version", + })) + + Expect(buffer.String()).To(ContainSubstring("Some Buildpack some-version")) + Expect(buffer.String()).To(ContainSubstring("Executing build process")) + }) + + context("when the build plan entry includes the build, launch flag", func() { + it.Before(func() { + entryResolver.ResolveCall.Returns.BuildpackPlanEntry = packit.BuildpackPlanEntry{ + Name: "dep", + Metadata: map[string]interface{}{ + "launch": true, + "build": true, + }, + } + }) + + it("marks the dep layer as build, cache and launch", func() { + result, err := build(packit.BuildContext{ + WorkingDir: workingDir, + CNBPath: cnbDir, + Stack: "some-stack", + BuildpackInfo: packit.BuildpackInfo{ + Name: "Some Buildpack", + Version: "some-version", + }, + Plan: packit.BuildpackPlan{ + Entries: []packit.BuildpackPlanEntry{ + { + Name: "dep", + Metadata: map[string]interface{}{ + "launch": true, + "build": true, + }, + }, + }, + }, + Layers: packit.Layers{Path: layersDir}, + }) + Expect(err).NotTo(HaveOccurred()) + + Expect(result).To(Equal(packit.BuildResult{ + Plan: packit.BuildpackPlan{ + Entries: []packit.BuildpackPlanEntry{ + { + Name: "dep", + Metadata: map[string]interface{}{ + "name": "dep-dependency-name", + "sha256": "dep-dependency-sha", + "stacks": []string{"some-stack"}, + "uri": "dep-dependency-uri", + }, + }, + }, + }, + Layers: []packit.Layer{ + { + Name: "dep", + Path: filepath.Join(layersDir, "dep"), + SharedEnv: packit.Environment{}, + BuildEnv: packit.Environment{}, + LaunchEnv: packit.Environment{}, + Build: true, + Launch: true, + Cache: true, + Metadata: map[string]interface{}{ + dep.DependencyCacheKey: "dep-dependency-sha", + "built_at": timestamp.Format(time.RFC3339Nano), + }, + }, + }, + })) + }) + }) + + context("failure cases", func() { + context("when the dependency cannot be resolved", func() { + it.Before(func() { + dependencyManager.ResolveCall.Returns.Error = errors.New("failed to resolve dependency") + }) + + it("returns an error", func() { + _, err := build(packit.BuildContext{ + CNBPath: cnbDir, + Plan: packit.BuildpackPlan{ + Entries: []packit.BuildpackPlanEntry{ + {Name: "dep"}, + }, + }, + Layers: packit.Layers{Path: layersDir}, + Stack: "some-stack", + }) + Expect(err).To(MatchError("failed to resolve dependency")) + }) + }) + + context("when the dependency cannot be installed", func() { + it.Before(func() { + dependencyManager.InstallCall.Returns.Error = errors.New("failed to install dependency") + }) + + it("returns an error", func() { + _, err := build(packit.BuildContext{ + CNBPath: cnbDir, + Plan: packit.BuildpackPlan{ + Entries: []packit.BuildpackPlanEntry{ + {Name: "dep"}, + }, + }, + Layers: packit.Layers{Path: layersDir}, + Stack: "some-stack", + }) + Expect(err).To(MatchError("failed to install dependency")) + }) + }) + + context("when the layers directory cannot be written to", func() { + it.Before(func() { + Expect(os.Chmod(layersDir, 0000)).To(Succeed()) + }) + + it.After(func() { + Expect(os.Chmod(layersDir, os.ModePerm)).To(Succeed()) + }) + + it("returns an error", func() { + _, err := build(packit.BuildContext{ + CNBPath: cnbDir, + Plan: packit.BuildpackPlan{ + Entries: []packit.BuildpackPlanEntry{ + {Name: "dep"}, + }, + }, + Layers: packit.Layers{Path: layersDir}, + }) + Expect(err).To(MatchError(ContainSubstring("permission denied"))) + }) + }) + }) +} diff --git a/buildpack.toml b/buildpack.toml index 5201a54..a851760 100644 --- a/buildpack.toml +++ b/buildpack.toml @@ -1,30 +1,29 @@ api = "0.2" [buildpack] -id = "paketo-buildpacks/dep" -name = "Dep Buildpack" -version = "{{ .Version }}" -homepage = "https://github.com/paketo-buildpacks/dep" + id = "paketo-buildpacks/dep" + name = "Dep Buildpack" + homepage = "https://github.com/paketo-buildpacks/dep" [metadata] -include_files = ["bin/build","bin/detect","buildpack.toml","go.mod","go.sum"] -pre_package = "./scripts/build.sh" + include_files = ["bin/build", "bin/detect", "bin/run", "buildpack.toml"] + pre_package = "./scripts/build.sh" -[[metadata.dependencies]] -id = "dep" -name = "Dep" -sha256 = "79b3ab9e67bf51bae787faaa5c78782752d0e39ea7b0d99e485a181b63a49559" -source = "https://github.com/golang/dep/archive/v0.5.4.tar.gz" -source_sha256 = "929c8f759838f98323211ba408a831ea80d93b75beda8584b6d950f393a3298a" -stacks = ["org.cloudfoundry.stacks.cflinuxfs3","io.buildpacks.stacks.bionic", "io.paketo.stacks.tiny"] -uri = "https://buildpacks.cloudfoundry.org/dependencies/dep/dep-v0.5.4-linux-x64-cflinuxfs3-79b3ab9e.tgz" -version = "0.5.4" + [[metadata.dependencies]] + id = "dep" + name = "Dep" + sha256 = "79b3ab9e67bf51bae787faaa5c78782752d0e39ea7b0d99e485a181b63a49559" + source = "https://github.com/golang/dep/archive/v0.5.4.tar.gz" + source_sha256 = "929c8f759838f98323211ba408a831ea80d93b75beda8584b6d950f393a3298a" + stacks = ["org.cloudfoundry.stacks.cflinuxfs3","io.buildpacks.stacks.bionic", "io.paketo.stacks.tiny"] + uri = "https://buildpacks.cloudfoundry.org/dependencies/dep/dep-v0.5.4-linux-x64-cflinuxfs3-79b3ab9e.tgz" + version = "0.5.4" [[stacks]] -id = "org.cloudfoundry.stacks.cflinuxfs3" + id = "io.buildpacks.stacks.bionic" [[stacks]] -id = "io.buildpacks.stacks.bionic" + id = "org.cloudfoundry.stacks.cflinuxfs3" [[stacks]] -id = "io.paketo.stacks.tiny" + id = "io.paketo.stacks.tiny" diff --git a/cmd/build/main.go b/cmd/build/main.go deleted file mode 100644 index ac16b5c..0000000 --- a/cmd/build/main.go +++ /dev/null @@ -1,48 +0,0 @@ -package main - -import ( - "fmt" - "os" - - "github.com/cloudfoundry/libcfbuildpack/buildpackplan" - - "github.com/paketo-buildpacks/dep/dep" - "github.com/paketo-buildpacks/dep/utils" - - "github.com/cloudfoundry/libcfbuildpack/build" -) - -func main() { - context, err := build.DefaultBuild() - if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "failed to create a default build context: %s", err) - os.Exit(101) - } - - code, err := runBuild(context) - if err != nil { - context.Logger.BodyError("failure running build: %s", err.Error()) - } - - os.Exit(code) - -} - -func runBuild(context build.Build) (int, error) { - context.Logger.Title(context.Buildpack) - - runner := &utils.Command{} - - depContributor, willContribute, err := dep.NewContributor(context, runner) - if err != nil { - return context.Failure(102), err - } - - if willContribute { - if err := depContributor.Contribute(); err != nil { - return context.Failure(103), err - } - } - - return context.Success(buildpackplan.Plan{}) -} diff --git a/cmd/build/main_test.go b/cmd/build/main_test.go deleted file mode 100644 index 9767892..0000000 --- a/cmd/build/main_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package main - -import ( - "testing" - - "github.com/cloudfoundry/libcfbuildpack/build" - "github.com/cloudfoundry/libcfbuildpack/test" - "github.com/google/go-cmp/cmp" - "github.com/sclevine/spec" - "github.com/sclevine/spec/report" - - . "github.com/onsi/gomega" -) - -func TestUnitBuild(t *testing.T) { - spec.Run(t, "Build", testBuild, spec.Report(report.Terminal{})) -} - -func testBuild(t *testing.T, _ spec.G, it spec.S) { - var factory *test.BuildFactory - - it.Before(func() { - RegisterTestingT(t) - factory = test.NewBuildFactory(t) - }) - - it("always passes", func() { - code, err := runBuild(factory.Build) - if err != nil { - t.Error("Err in build : ", err) - } - - if diff := cmp.Diff(code, build.SuccessStatusCode); diff != "" { - t.Error("Problem : ", diff) - } - }) -} diff --git a/cmd/detect/main.go b/cmd/detect/main.go deleted file mode 100644 index 6bb1f9f..0000000 --- a/cmd/detect/main.go +++ /dev/null @@ -1,111 +0,0 @@ -package main - -import ( - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/buildpack/libbuildpack/buildplan" - "github.com/cloudfoundry/libcfbuildpack/detect" - "github.com/cloudfoundry/libcfbuildpack/helper" - "github.com/paketo-buildpacks/dep/dep" - "github.com/pkg/errors" -) - -const MissingGopkgErrorMsg = "no Gopkg.toml found at root level" -const EmptyTargetEnvVariableMsg = "BP_GO_TARGETS set but with empty value" -const GoDependency = "go" - -type BuildpackYAML struct { - Config Config `yaml:"go"` -} - -type Config struct { - ImportPath string `yaml:"import-path"` - Targets []string `yaml:"targets"` - LDFlags map[string]string `yaml:"ldflags"` -} - -func main() { - context, err := detect.DefaultDetect() - if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "failed to create a default detection context: %s", err) - os.Exit(100) - } - - code, err := runDetect(context) - if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "failed detection: %s", err) - } - - os.Exit(code) -} - -func runDetect(context detect.Detect) (int, error) { - goPkgFile := filepath.Join(context.Application.Root, "Gopkg.toml") - - if exists, err := helper.FileExists(goPkgFile); err != nil { - return detect.FailStatusCode, errors.Wrap(err, fmt.Sprintf("error checking filepath: %s", goPkgFile)) - } else if !exists { - return detect.FailStatusCode, fmt.Errorf(MissingGopkgErrorMsg) - } - - bpYmlFilePath := filepath.Join(context.Application.Root, "buildpack.yml") - if exists, err := helper.FileExists(bpYmlFilePath); err != nil { - return detect.FailStatusCode, errors.Wrap(err, fmt.Sprintf("error checking filepath: %s", bpYmlFilePath)) - } else if exists { - buildpackYaml := BuildpackYAML{} - if err := helper.ReadBuildpackYaml(bpYmlFilePath, &buildpackYaml); err != nil { - return detect.FailStatusCode, errors.Wrap(err, "error reading buildpack.yml") - } - - if environmentTargets, ok := os.LookupEnv("BP_GO_TARGETS"); ok { - if environmentTargets == "" { - return detect.FailStatusCode, errors.New(EmptyTargetEnvVariableMsg) - } - buildpackYaml.Config.Targets = strings.Split(environmentTargets, string(os.PathListSeparator)) - } - metadata := buildplan.Metadata{ - "build": true, - } - - if buildpackYaml.Config.ImportPath != "" { - metadata[dep.ImportPath] = buildpackYaml.Config.ImportPath - } - - if buildpackYaml.Config.Targets != nil { - metadata[dep.Targets] = buildpackYaml.Config.Targets - } - - return context.Pass(buildplan.Plan{ - Provides: []buildplan.Provided{{ - Name: dep.Dependency, - }}, - Requires: []buildplan.Required{{ - Name: dep.Dependency, - Metadata: metadata, - }, { - Name: GoDependency, - Metadata: buildplan.Metadata{ - "build": true, - }, - }}, - }) - } - - return context.Pass(buildplan.Plan{ - Provides: []buildplan.Provided{{ - Name: dep.Dependency, - }}, - Requires: []buildplan.Required{{ - Name: dep.Dependency, - Metadata: buildplan.Metadata{"build": true}, - }, { - Name: GoDependency, - Metadata: buildplan.Metadata{ - "build": true, - }, - }}, - }) -} diff --git a/cmd/detect/main_test.go b/cmd/detect/main_test.go deleted file mode 100644 index 9d4b466..0000000 --- a/cmd/detect/main_test.go +++ /dev/null @@ -1,169 +0,0 @@ -package main - -import ( - "os" - "path/filepath" - "testing" - - "github.com/buildpack/libbuildpack/buildplan" - "github.com/paketo-buildpacks/dep/dep" - - "github.com/cloudfoundry/libcfbuildpack/detect" - "github.com/cloudfoundry/libcfbuildpack/test" - "github.com/sclevine/spec" - "github.com/sclevine/spec/report" - - . "github.com/onsi/gomega" -) - -func TestUnitDetect(t *testing.T) { - spec.Run(t, "Detect", testDetect, spec.Report(report.Terminal{})) -} - -func testDetect(t *testing.T, when spec.G, it spec.S) { - var factory *test.DetectFactory - - const goPkgString = "This is a go pkg toml" - - it.Before(func() { - RegisterTestingT(t) - factory = test.NewDetectFactory(t) - }) - - when("there is no Gopkg.toml", func() { - it("should fail", func() { - code, err := runDetect(factory.Detect) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal(MissingGopkgErrorMsg)) - Expect(code).To(Equal(detect.FailStatusCode)) - }) - }) - - when("Gopkg.toml exists and buildpack.yml does not exist", func() { - it("should pass and not write import-path in the buildplan", func() { - test.WriteFile(t, filepath.Join(factory.Detect.Application.Root, "Gopkg.toml"), goPkgString) - - code, err := runDetect(factory.Detect) - Expect(err).NotTo(HaveOccurred()) - Expect(code).To(Equal(detect.PassStatusCode)) - Expect(factory.Plans.Plan).To(Equal(buildplan.Plan{ - Provides: []buildplan.Provided{{Name: dep.Dependency}}, - Requires: []buildplan.Required{{ - Name: dep.Dependency, - Metadata: buildplan.Metadata{"build": true}, - }, { - Name: GoDependency, - Metadata: buildplan.Metadata{"build": true}, - }}, - })) - }) - - when("Gopkg.toml exists and buildpack.yml specifies an `import-path` and go targets", func() { - - var bpYmlString string - - it.Before(func() { - bpYmlString = `--- - -go: - import-path: some/app - targets: ["./path/to/first", "./path/to/second"]` - test.WriteFile(t, filepath.Join(factory.Detect.Application.Root, "buildpack.yml"), bpYmlString) - test.WriteFile(t, filepath.Join(factory.Detect.Application.Root, "Gopkg.toml"), goPkgString) - }) - - it.After(func() { - Expect(os.Unsetenv("BP_GO_TARGETS")).To(Succeed()) - }) - - it("adds the `import-path` and targets to the build plan", func() { - - code, err := runDetect(factory.Detect) - Expect(err).ToNot(HaveOccurred()) - Expect(code).To(Equal(detect.PassStatusCode)) - - plan := buildplan.Plan{ - Provides: []buildplan.Provided{{Name: dep.Dependency}}, - Requires: []buildplan.Required{{ - Name: dep.Dependency, - Metadata: buildplan.Metadata{ - "build": true, - "import-path": "some/app", - "targets": []string{"./path/to/first", "./path/to/second"}, - }, - }, { - Name: GoDependency, - Metadata: buildplan.Metadata{"build": true}, - }}, - } - - Expect(factory.Plans.Plan).To(Equal(plan)) - }) - - when("BP_GO_TARGETS environment variable is set", func() { - it("should use the BP_GO_TARGETS value in the build plan", func() { - err := os.Setenv("BP_GO_TARGETS", "./path/to/third:./path/to/fourth") - Expect(err).NotTo(HaveOccurred()) - - code, err := runDetect(factory.Detect) - Expect(err).ToNot(HaveOccurred()) - Expect(code).To(Equal(detect.PassStatusCode)) - - plan := buildplan.Plan{ - Provides: []buildplan.Provided{{Name: dep.Dependency}}, - Requires: []buildplan.Required{{ - Name: dep.Dependency, - Metadata: buildplan.Metadata{ - "build": true, - "import-path": "some/app", - "targets": []string{"./path/to/third", "./path/to/fourth"}}, - }, { - Name: GoDependency, - Metadata: buildplan.Metadata{"build": true}, - }}, - } - - Expect(factory.Plans.Plan).To(Equal(plan)) - }) - }) - - when("BP_GO_TARGETS environment variable is set but empty", func() { - it("should use fail the detect phase", func() { - err := os.Setenv("BP_GO_TARGETS", "") - Expect(err).NotTo(HaveOccurred()) - - code, err := runDetect(factory.Detect) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal(EmptyTargetEnvVariableMsg)) - Expect(code).To(Equal(detect.FailStatusCode)) - - }) - }) - - }) - - when("Gopkg.toml exists and buildpack.yml empty", func() { - it("passes detect and does not add import-path to the buildplan", func() { - bpYmlString := "" - test.WriteFile(t, filepath.Join(factory.Detect.Application.Root, "buildpack.yml"), bpYmlString) - - test.WriteFile(t, filepath.Join(factory.Detect.Application.Root, "Gopkg.toml"), goPkgString) - - code, err := runDetect(factory.Detect) - Expect(err).NotTo(HaveOccurred()) - Expect(code).To(Equal(detect.PassStatusCode)) - - Expect(factory.Plans.Plan).To(Equal(buildplan.Plan{ - Provides: []buildplan.Provided{{Name: dep.Dependency}}, - Requires: []buildplan.Required{{ - Name: dep.Dependency, - Metadata: buildplan.Metadata{"build": true}, - }, { - Name: GoDependency, - Metadata: buildplan.Metadata{"build": true}, - }}, - })) - }) - }) - }) -} diff --git a/constants.go b/constants.go new file mode 100644 index 0000000..891fc0d --- /dev/null +++ b/constants.go @@ -0,0 +1,6 @@ +package dep + +const ( + Dep = "dep" + DependencyCacheKey = "dependency-sha" +) diff --git a/dep/config.go b/dep/config.go deleted file mode 100644 index 8e1576b..0000000 --- a/dep/config.go +++ /dev/null @@ -1,38 +0,0 @@ -package dep - -import ( - "io/ioutil" - "os" - "path/filepath" - "strings" - - "gopkg.in/yaml.v2" -) - -type Config struct { - Targets []string `yaml:"targets"` - LDFlags map[string]string `yaml:"ldflags"` -} - -func LoadConfig(appRoot string) (Config, error) { - configPath := filepath.Join(appRoot, "buildpack.yml") - var config struct { - Go Config `yaml:"go"` - } - if _, err := os.Stat(configPath); err == nil { - yamlFile, err := ioutil.ReadFile(configPath) - if err != nil { - return Config{}, err - } - err = yaml.Unmarshal(yamlFile, &config) - if err != nil { - return Config{}, err - } - } - - if buildTarget := os.Getenv("BP_GO_TARGETS"); buildTarget != "" { - config.Go.Targets = strings.Split(buildTarget, ":") - } - - return config.Go, nil -} diff --git a/dep/dep.go b/dep/dep.go deleted file mode 100644 index a0b4b88..0000000 --- a/dep/dep.go +++ /dev/null @@ -1,290 +0,0 @@ -package dep - -import ( - "crypto/sha256" - "encoding/hex" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "strconv" - "strings" - "time" - - "github.com/cloudfoundry/libcfbuildpack/build" - "github.com/cloudfoundry/libcfbuildpack/helper" - "github.com/cloudfoundry/libcfbuildpack/layers" - "github.com/cloudfoundry/libcfbuildpack/logger" -) - -const ( - Dependency = "dep" - Packages = "packages" - lockFile = "Gopkg.lock" - AppBinary = "app-binary" - ImportPath = "import-path" - Targets = "targets" - MissingImportPathErrorMsg = "no import-path found in buildpack.yml" -) - -type Contributor struct { - context build.Build - runner Runner - depLayer layers.DependencyLayer - packagesLayer layers.Layer - appBinaryLayer layers.Layer - logger logger.Logger - goDepPackages Identifiable - appDirName string - installDir string - vendored bool - Targets []string - config Config -} - -type Identifiable struct { - Name string - Checksum string -} - -func (l Identifiable) Identity() (string, string) { - return l.Name, l.Checksum -} - -type Runner interface { - Run(dir, bin string, args ...string) (string, error) - RunSilent(dir, bin string, args ...string) (string, error) - CustomRun(dir string, env []string, out, err io.Writer, bin string, args ...string) error -} - -func NewContributor(context build.Build, runner Runner) (Contributor, bool, error) { - dependency, wantDependency, err := context.Plans.GetShallowMerged(Dependency) - if err != nil { - return Contributor{}, false, nil - } else if !wantDependency { - return Contributor{}, false, nil - } - - importPath, exists := dependency.Metadata[ImportPath] - if !exists { - return Contributor{}, false, fmt.Errorf(MissingImportPathErrorMsg) - } - - vendored, err := isVendored(context) - if err != nil { - return Contributor{}, false, err - } - - contributor := Contributor{ - context: context, - runner: runner, - packagesLayer: context.Layers.Layer(Packages), - appBinaryLayer: context.Layers.Layer(AppBinary), - vendored: vendored, - logger: context.Logger, - } - - targets, exists := dependency.Metadata[Targets] - if exists { - if targets, ok := targets.([]interface{}); ok { - contributor.Targets = make([]string, len(targets)) - for i, v := range targets { - contributor.Targets[i] = fmt.Sprint(v) - } - } - } - - appDirName, ok := importPath.(string) - if !ok { - return Contributor{}, false, nil - } - - contributor.appDirName = appDirName - contributor.installDir = filepath.Join(contributor.packagesLayer.Root, "src", contributor.appDirName) - - return contributor, true, nil -} - -func (c *Contributor) Contribute() error { - - if err := c.ContributeDep(); err != nil { - return err - } - - if err := c.ContributePackages(); err != nil { - return err - } - - if err := c.ContributeBinary(); err != nil { - return err - } - - if err := c.ContributeStartCommand(); err != nil { - return err - } - - return c.DeleteAppDir() -} - -func (c *Contributor) ContributeDep() error { - if c.vendored { - c.logger.Info("Note: skipping dep installation due to non-empty vendor directory.") - return nil - } - - deps, err := c.context.Buildpack.Dependencies() - if err != nil { - return err - } - - dep, err := deps.Best(Dependency, "*", c.context.Stack) - if err != nil { - return err - } - - c.depLayer = c.context.Layers.DependencyLayer(dep) - - return c.depLayer.Contribute(func(artifact string, layer layers.DependencyLayer) error { - layer.Logger.Body("Expanding to %s", layer.Root) - return helper.ExtractTarGz(artifact, layer.Root, 1) - }, layers.Build, layers.Cache) -} - -func (c *Contributor) ContributePackages() error { - if err := c.setPackagesMetadata(); err != nil { - return err - } - - return c.packagesLayer.Contribute(c.goDepPackages, func(layer layers.Layer) error { - if err := helper.CopyDirectory(c.context.Application.Root, c.installDir); err != nil { - return err - } - - if c.vendored { - c.logger.Info("Note: skipping `dep ensure` due to non-empty vendor directory.") - return nil - } - - layer.Logger.Body("Fetching any unsaved dependencies (using `dep ensure`)") - depBin := filepath.Join(c.depLayer.Root, "dep") - return c.runner.CustomRun(c.installDir, - []string{fmt.Sprintf("GOPATH=%s", c.packagesLayer.Root)}, - os.Stdout, os.Stderr, - depBin, "ensure") - - }) -} -func (c *Contributor) ContributeBinary() error { - var err error - c.config, err = LoadConfig(c.context.Application.Root) - if err != nil { - return err - } - - return c.appBinaryLayer.Contribute(getAppBinaryMetadata(), func(layer layers.Layer) error { - layer.Logger.Body("Running `go install`") - args := []string{"install", "-buildmode", "pie", "-tags", "cloudfoundry"} - - if len(c.config.LDFlags) > 0 { - var ldflags []string - for ldflagKey, ldflagValue := range c.config.LDFlags { - ldflags = append(ldflags, fmt.Sprintf("-X %s=%s", ldflagKey, ldflagValue)) - } - args = append(args, "-ldflags", strings.Join(ldflags, " ")) - } - - if len(c.Targets) > 0 { - args = append(args, c.Targets...) - } - - return c.runner.CustomRun(c.installDir, []string{ - fmt.Sprintf("GOPATH=%s", c.packagesLayer.Root), - fmt.Sprintf("GOBIN=%s", filepath.Join(layer.Root, "bin")), - }, os.Stdout, os.Stderr, - "go", args...) - }, layers.Launch) -} - -func (c *Contributor) ContributeStartCommand() error { - appName := filepath.Base(c.appDirName) - if len(c.Targets) > 0 { - appName = filepath.Base(c.Targets[0]) - } - - appBinaryPath := filepath.Join(c.appBinaryLayer.Root, "bin", appName) - - return c.context.Layers.WriteApplicationMetadata(layers.Metadata{ - Processes: []layers.Process{ - { - Type: "web", - Command: appBinaryPath, - Direct: c.context.Stack == "io.paketo.stacks.tiny", - }, - }, - }) -} - -func (c *Contributor) setPackagesMetadata() error { - meta := Identifiable{"Dep Packages", strconv.FormatInt(time.Now().UnixNano(), 16)} - - if exists, err := helper.FileExists(filepath.Join(c.context.Application.Root, lockFile)); err != nil { - return err - } else if exists { - out, err := ioutil.ReadFile(filepath.Join(c.context.Application.Root, lockFile)) - if err != nil { - return err - } - - hash := sha256.Sum256(out) - meta.Checksum = hex.EncodeToString(hash[:]) - } - - c.goDepPackages = meta - return nil -} - -func (c Contributor) DeleteAppDir() error { - files, err := ioutil.ReadDir(c.context.Application.Root) - if err != nil { - return err - } - - for _, file := range files { - if err := os.RemoveAll(filepath.Join(c.context.Application.Root, file.Name())); err != nil { - return err - } - } - - return nil -} - -func isVendored(context build.Build) (bool, error) { - vendorPath := filepath.Join(context.Application.Root, "vendor") - vendorDirExists, err := helper.FileExists(vendorPath) - if err != nil { - return false, err - } - - if vendorDirExists { - files, err := ioutil.ReadDir(vendorPath) - if err != nil { - return false, err - } - - for _, file := range files { - if file.IsDir() { - return true, nil - } - } - } - - return false, nil -} - -func getAppBinaryMetadata() Identifiable { - timeNow := strconv.FormatInt(time.Now().UnixNano(), 32) - hash := sha256.Sum256([]byte(timeNow)) - checksum := hex.EncodeToString(hash[:]) - return Identifiable{Name: "App Binary", Checksum: checksum} -} diff --git a/dep/dep_test.go b/dep/dep_test.go deleted file mode 100644 index 701eb6f..0000000 --- a/dep/dep_test.go +++ /dev/null @@ -1,395 +0,0 @@ -package dep_test - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "testing" - - "github.com/cloudfoundry/libcfbuildpack/buildpackplan" - "github.com/cloudfoundry/libcfbuildpack/layers" - - "github.com/cloudfoundry/libcfbuildpack/test" - "github.com/golang/mock/gomock" - "github.com/paketo-buildpacks/dep/dep" - "github.com/sclevine/spec" - "github.com/sclevine/spec/report" - - . "github.com/onsi/gomega" -) - -//go:generate mockgen -source=dep.go -destination=mocks_test.go -package=dep_test - -func TestUnitDep(t *testing.T) { - spec.Run(t, "Go Dep", testDep, spec.Report(report.Terminal{})) -} - -func testDep(t *testing.T, when spec.G, it spec.S) { - var ( - factory *test.BuildFactory - mockRunner *MockRunner - mockCtrl *gomock.Controller - packageName string - ) - - it.Before(func() { - RegisterTestingT(t) - factory = test.NewBuildFactory(t) - mockCtrl = gomock.NewController(t) - mockRunner = NewMockRunner(mockCtrl) - packageName = "app" - }) - - when("NewContributor", func() { - it("returns true if dep exists in the buildplan", func() { - - factory.AddPlan(generateMetadata( - buildpackplan.Metadata{ - dep.ImportPath: packageName, - dep.Targets: []interface{}{}, - }), - ) - - _, willContribute, err := dep.NewContributor(factory.Build, mockRunner) - Expect(err).NotTo(HaveOccurred()) - Expect(willContribute).To(BeTrue()) - }) - - it("returns false if a build plan does not exist", func() { - _, willContribute, err := dep.NewContributor(factory.Build, mockRunner) - - Expect(err).NotTo(HaveOccurred()) - Expect(willContribute).To(BeFalse()) - }) - - it("reads targets from the buildplan", func() { - - factory.AddPlan(generateMetadata( - buildpackplan.Metadata{ - dep.ImportPath: packageName, - dep.Targets: []interface{}{"first", "second"}, - }), - ) - - contributor, willContribute, err := dep.NewContributor(factory.Build, mockRunner) - Expect(err).NotTo(HaveOccurred()) - Expect(willContribute).To(BeTrue()) - Expect(contributor.Targets).To(Equal([]string{"first", "second"})) - }) - - it("returns an error if import-path not specified in buildplan", func() { - - factory.AddPlan(generateMetadata( - buildpackplan.Metadata{ - dep.Targets: []interface{}{}, - }), - ) - - _, willContribute, err := dep.NewContributor(factory.Build, mockRunner) - - Expect(willContribute).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring(dep.MissingImportPathErrorMsg)) - }) - }) - - when("ContributeDep", func() { - it("installs dep when included in the build plan", func() { - - factory.AddPlan(generateMetadata( - buildpackplan.Metadata{ - dep.ImportPath: packageName, - }), - ) - - stubFixture := filepath.Join("testdata", "stub.tar.gz") - factory.AddDependency(dep.Dependency, stubFixture) - - contributor, willContribute, err := dep.NewContributor(factory.Build, mockRunner) - Expect(err).NotTo(HaveOccurred()) - Expect(willContribute).To(BeTrue()) - Expect(contributor.ContributeDep()).To(Succeed()) - - layer := factory.Build.Layers.Layer(dep.Dependency) - Expect(layer).To(test.HaveLayerMetadata(true, true, false)) - Expect(filepath.Join(layer.Root, "stub.txt")).To(BeARegularFile()) - }) - - }) - - when("ContributePackages", func() { - it.Pend("runs dep ensure", func() { - - factory.AddPlan(generateMetadata( - buildpackplan.Metadata{ - dep.ImportPath: packageName, - }), - ) - - layer := factory.Build.Layers.Layer(dep.Packages) - - installDir := filepath.Join(layer.Root, "src", packageName) - mockRunner.EXPECT().CustomRun(installDir, - []string{fmt.Sprintf("GOPATH=%s", factory.Build.Layers.Layer(dep.Packages).Root)}, - os.Stdout, os.Stderr, - gomock.Any(), "ensure").Return(nil) - - contributor, willContribute, err := dep.NewContributor(factory.Build, mockRunner) - Expect(err).NotTo(HaveOccurred()) - Expect(willContribute).To(BeTrue()) - Expect(contributor.ContributePackages()).To(Succeed()) - }) - }) - - when("ContributeBinary", func() { - it("runs go install", func() { - - factory.AddPlan(generateMetadata( - buildpackplan.Metadata{ - dep.ImportPath: packageName, - }), - ) - - appBinaryLayer := factory.Build.Layers.Layer(dep.AppBinary) - appBinaryLayer.Touch() - packagesLayer := factory.Build.Layers.Layer(dep.Packages) - installDir := filepath.Join(packagesLayer.Root, "src", packageName) - - mockRunner.EXPECT().CustomRun(installDir, []string{ - fmt.Sprintf("GOPATH=%s", packagesLayer.Root), - fmt.Sprintf("GOBIN=%s", filepath.Join(appBinaryLayer.Root, "bin")), - }, os.Stdout, os.Stderr, "go", "install", "-buildmode", "pie", "-tags", "cloudfoundry") - contributor, willContribute, err := dep.NewContributor(factory.Build, mockRunner) - Expect(err).NotTo(HaveOccurred()) - Expect(willContribute).To(BeTrue()) - Expect(contributor.ContributeBinary()).To(Succeed()) - }) - - when("given ldflags", func() { - it.Before(func() { - Expect(ioutil.WriteFile(filepath.Join(factory.Build.Application.Root, "buildpack.yml"), - []byte(`--- -go: - ldflags: - main.linker_flag: linked_flag - main.other_linker_flag: other_linked_flag`), - os.FileMode(0666))).To(Succeed()) - }) - - it("runs `go install` with these ldflags", func() { - - factory.AddPlan(generateMetadata( - buildpackplan.Metadata{ - dep.ImportPath: packageName, - }), - ) - - appBinaryLayer := factory.Build.Layers.Layer(dep.AppBinary) - appBinaryLayer.Touch() - packagesLayer := factory.Build.Layers.Layer(dep.Packages) - installDir := filepath.Join(packagesLayer.Root, "src", packageName) - - mockRunner.EXPECT().CustomRun(installDir, []string{ - fmt.Sprintf("GOPATH=%s", packagesLayer.Root), - fmt.Sprintf("GOBIN=%s", filepath.Join(appBinaryLayer.Root, "bin")), - }, os.Stdout, os.Stderr, "go", "install", "-buildmode", "pie", "-tags", "cloudfoundry", "-ldflags", gomock.Any()).Do(func(args ...interface{}) { - Expect(args[11]).To(ContainSubstring("-X main.linker_flag=linked_flag")) - Expect(args[11]).To(ContainSubstring("-X main.other_linker_flag=other_linked_flag")) - }) - contributor, willContribute, err := dep.NewContributor(factory.Build, mockRunner) - Expect(err).NotTo(HaveOccurred()) - Expect(willContribute).To(BeTrue()) - Expect(contributor.ContributeBinary()).To(Succeed()) - - }) - }) - - when("targets are defined", func() { - it("runs go install with the targets", func() { - factory.AddPlan(generateMetadata( - buildpackplan.Metadata{ - dep.ImportPath: packageName, - dep.Targets: []interface{}{"first", "second"}, - }), - ) - - appBinaryLayer := factory.Build.Layers.Layer(dep.AppBinary) - appBinaryLayer.Touch() - packagesLayer := factory.Build.Layers.Layer(dep.Packages) - installDir := filepath.Join(packagesLayer.Root, "src", packageName) - - mockRunner.EXPECT().CustomRun(installDir, []string{ - fmt.Sprintf("GOPATH=%s", packagesLayer.Root), - fmt.Sprintf("GOBIN=%s", filepath.Join(appBinaryLayer.Root, "bin")), - }, os.Stdout, os.Stderr, "go", "install", "-buildmode", "pie", "-tags", "cloudfoundry", "first", "second") - contributor, willContribute, err := dep.NewContributor(factory.Build, mockRunner) - Expect(err).NotTo(HaveOccurred()) - Expect(willContribute).To(BeTrue()) - Expect(contributor.ContributeBinary()).To(Succeed()) - }) - - when("given ldflags", func() { - it.Before(func() { - Expect(ioutil.WriteFile(filepath.Join(factory.Build.Application.Root, "buildpack.yml"), - []byte(`--- -go: - ldflags: - main.linker_flag: linked_flag - main.other_linker_flag: other_linked_flag`), - os.FileMode(0666))).To(Succeed()) - }) - - it("runs `go install` with these ldflags", func() { - factory.AddPlan(generateMetadata( - buildpackplan.Metadata{ - dep.ImportPath: packageName, - dep.Targets: []interface{}{"first", "second"}, - }), - ) - - appBinaryLayer := factory.Build.Layers.Layer(dep.AppBinary) - appBinaryLayer.Touch() - packagesLayer := factory.Build.Layers.Layer(dep.Packages) - installDir := filepath.Join(packagesLayer.Root, "src", packageName) - - mockRunner.EXPECT().CustomRun(installDir, []string{ - fmt.Sprintf("GOPATH=%s", packagesLayer.Root), - fmt.Sprintf("GOBIN=%s", filepath.Join(appBinaryLayer.Root, "bin")), - }, os.Stdout, os.Stderr, "go", "install", "-buildmode", "pie", "-tags", "cloudfoundry", "-ldflags", gomock.Any(), "first", "second").Do(func(args ...interface{}) { - Expect(args[11]).To(ContainSubstring("-X main.linker_flag=linked_flag")) - Expect(args[11]).To(ContainSubstring("-X main.other_linker_flag=other_linked_flag")) - }) - contributor, willContribute, err := dep.NewContributor(factory.Build, mockRunner) - Expect(err).NotTo(HaveOccurred()) - Expect(willContribute).To(BeTrue()) - Expect(contributor.ContributeBinary()).To(Succeed()) - }) - }) - }) - }) - - when("ContributeStartCommand", func() { - when("no targets are defined", func() { - it("will use import-path as the start command", func() { - - factory.AddPlan(generateMetadata( - buildpackplan.Metadata{ - dep.ImportPath: packageName, - }), - ) - - appBinaryLayer := factory.Build.Layers.Layer(dep.AppBinary) - appBinaryLayer.Touch() - - contributor, _, err := dep.NewContributor(factory.Build, mockRunner) - Expect(err).NotTo(HaveOccurred()) - Expect(contributor.ContributeStartCommand()).To(Succeed()) - - appBinaryPath := filepath.Join(appBinaryLayer.Root, "bin", filepath.Base(packageName)) - - Expect(factory.Build.Layers).To(test.HaveApplicationMetadata(layers.Metadata{ - Processes: []layers.Process{ - { - Type: "web", - Command: appBinaryPath, - Direct: false, - }, - }, - })) - }) - - when("the tiny stack id is io.paketo.stacks.tiny", func() { - it("will use import-path as the start command on tiny stack", func() { - factory.AddPlan(generateMetadata( - buildpackplan.Metadata{ - dep.ImportPath: packageName, - }), - ) - - factory.Build.Stack = "io.paketo.stacks.tiny" - - appBinaryLayer := factory.Build.Layers.Layer(dep.AppBinary) - appBinaryLayer.Touch() - - contributor, _, err := dep.NewContributor(factory.Build, mockRunner) - Expect(err).NotTo(HaveOccurred()) - Expect(contributor.ContributeStartCommand()).To(Succeed()) - - appBinaryPath := filepath.Join(appBinaryLayer.Root, "bin", filepath.Base(packageName)) - - Expect(factory.Build.Layers).To(test.HaveApplicationMetadata(layers.Metadata{ - Processes: []layers.Process{ - { - Type: "web", - Command: appBinaryPath, - Direct: true, - }, - }, - })) - }) - }) - }) - - when("targets are defined", func() { - it("will use first target as the start command", func() { - factory.AddPlan(generateMetadata( - buildpackplan.Metadata{ - dep.ImportPath: packageName, - dep.Targets: []interface{}{"./cmd/first", "./cmd/second"}, - }), - ) - - appBinaryLayer := factory.Build.Layers.Layer(dep.AppBinary) - appBinaryLayer.Touch() - - contributor, _, err := dep.NewContributor(factory.Build, mockRunner) - Expect(err).NotTo(HaveOccurred()) - Expect(contributor.ContributeStartCommand()).To(Succeed()) - - appBinaryPath := filepath.Join(appBinaryLayer.Root, "bin", "first") - - Expect(factory.Build.Layers).To(test.HaveApplicationMetadata(layers.Metadata{ - Processes: []layers.Process{ - { - Type: "web", - Command: appBinaryPath, - Direct: false, - }, - }, - })) - }) - }) - - }) - - when("deleteAppDir", func() { - it("succesfully deletes all contents of appDir", func() { - dummyFile := filepath.Join(factory.Build.Application.Root, "dummy") - Expect(ioutil.WriteFile(dummyFile, []byte("baller"), 0777)) - - factory.AddPlan(generateMetadata( - buildpackplan.Metadata{ - dep.ImportPath: packageName, - }), - ) - - contributor, willContribute, err := dep.NewContributor(factory.Build, mockRunner) - Expect(err).NotTo(HaveOccurred()) - Expect(willContribute).To(BeTrue()) - - Expect(contributor.DeleteAppDir()).To(Succeed()) - appDirContents, err := ioutil.ReadDir(factory.Build.Application.Root) - Expect(err).NotTo(HaveOccurred()) - Expect(appDirContents).To(BeEmpty()) - - }) - }) -} - -func generateMetadata(metadata buildpackplan.Metadata) buildpackplan.Plan { - return buildpackplan.Plan{ - Name: dep.Dependency, - Metadata: metadata, - } -} diff --git a/dep/mocks_test.go b/dep/mocks_test.go deleted file mode 100644 index 36203e0..0000000 --- a/dep/mocks_test.go +++ /dev/null @@ -1,93 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: dep.go - -// Package dep_test is a generated GoMock package. -package dep_test - -import ( - gomock "github.com/golang/mock/gomock" - io "io" - reflect "reflect" -) - -// MockRunner is a mock of Runner interface -type MockRunner struct { - ctrl *gomock.Controller - recorder *MockRunnerMockRecorder -} - -// MockRunnerMockRecorder is the mock recorder for MockRunner -type MockRunnerMockRecorder struct { - mock *MockRunner -} - -// NewMockRunner creates a new mock instance -func NewMockRunner(ctrl *gomock.Controller) *MockRunner { - mock := &MockRunner{ctrl: ctrl} - mock.recorder = &MockRunnerMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockRunner) EXPECT() *MockRunnerMockRecorder { - return m.recorder -} - -// Run mocks base method -func (m *MockRunner) Run(dir, bin string, args ...string) (string, error) { - m.ctrl.T.Helper() - varargs := []interface{}{dir, bin} - for _, a := range args { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "Run", varargs...) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Run indicates an expected call of Run -func (mr *MockRunnerMockRecorder) Run(dir, bin interface{}, args ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{dir, bin}, args...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockRunner)(nil).Run), varargs...) -} - -// RunSilent mocks base method -func (m *MockRunner) RunSilent(dir, bin string, args ...string) (string, error) { - m.ctrl.T.Helper() - varargs := []interface{}{dir, bin} - for _, a := range args { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "RunSilent", varargs...) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// RunSilent indicates an expected call of RunSilent -func (mr *MockRunnerMockRecorder) RunSilent(dir, bin interface{}, args ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{dir, bin}, args...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RunSilent", reflect.TypeOf((*MockRunner)(nil).RunSilent), varargs...) -} - -// CustomRun mocks base method -func (m *MockRunner) CustomRun(dir string, env []string, out, err io.Writer, bin string, args ...string) error { - m.ctrl.T.Helper() - varargs := []interface{}{dir, env, out, err, bin} - for _, a := range args { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "CustomRun", varargs...) - ret0, _ := ret[0].(error) - return ret0 -} - -// CustomRun indicates an expected call of CustomRun -func (mr *MockRunnerMockRecorder) CustomRun(dir, env, out, err, bin interface{}, args ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{dir, env, out, err, bin}, args...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CustomRun", reflect.TypeOf((*MockRunner)(nil).CustomRun), varargs...) -} diff --git a/dep/testdata/stub.tar.gz b/dep/testdata/stub.tar.gz deleted file mode 100644 index 0ec3feb0a3f33d999762ed596e8bdc9a37a90b4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 186 zcmb2|=3w}2wltc7`R%1du0skU2R_!m6M4@x)h|~3B~!N)XLC~V#gE0gyh>8F6FdId zw=Dl~VflHplHE`5nZMSNU3%r1<<8?t9a`I+Wjf7{y}TolJXIq%=bcd@XZEa;T#eZg zr*6jkEnIW|+0iYlX5CERb6lj}<@bwv`^eU8j{>)v{zJEB{yToO`2Sq9**+mnQE`7N k|8IA{?pj!0GEeVQ~&?~ diff --git a/detect.go b/detect.go new file mode 100644 index 0000000..8cac4d0 --- /dev/null +++ b/detect.go @@ -0,0 +1,16 @@ +package dep + +import "github.com/paketo-buildpacks/packit" + +func Detect() packit.DetectFunc { + return func(context packit.DetectContext) (packit.DetectResult, error) { + return packit.DetectResult{ + Plan: packit.BuildPlan{ + Provides: []packit.BuildPlanProvision{ + {Name: "dep"}, + }, + Requires: nil, + }, + }, nil + } +} diff --git a/detect_test.go b/detect_test.go new file mode 100644 index 0000000..79bbcae --- /dev/null +++ b/detect_test.go @@ -0,0 +1,48 @@ +package dep_test + +import ( + "io/ioutil" + "os" + "testing" + + "github.com/paketo-buildpacks/dep" + "github.com/paketo-buildpacks/packit" + "github.com/sclevine/spec" + + . "github.com/onsi/gomega" +) + +func testDetect(t *testing.T, context spec.G, it spec.S) { + var ( + Expect = NewWithT(t).Expect + + workingDir string + detect packit.DetectFunc + ) + + it.Before(func() { + var err error + workingDir, err = ioutil.TempDir("", "working-dir") + Expect(err).NotTo(HaveOccurred()) + + detect = dep.Detect() + }) + + it.After(func() { + Expect(os.RemoveAll(workingDir)).To(Succeed()) + }) + + context("returns a plan that provides dep", func() { + it("detects", func() { + result, err := detect(packit.DetectContext{ + WorkingDir: workingDir, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(result.Plan).To(Equal(packit.BuildPlan{ + Provides: []packit.BuildPlanProvision{ + {Name: "dep"}, + }, + })) + }) + }) +} diff --git a/fakes/build_plan_refinery.go b/fakes/build_plan_refinery.go new file mode 100644 index 0000000..571a45d --- /dev/null +++ b/fakes/build_plan_refinery.go @@ -0,0 +1,33 @@ +package fakes + +import ( + "sync" + + "github.com/paketo-buildpacks/packit" + "github.com/paketo-buildpacks/packit/postal" +) + +type BuildPlanRefinery struct { + BillOfMaterialsCall struct { + sync.Mutex + CallCount int + Receives struct { + Dependency postal.Dependency + } + Returns struct { + BuildpackPlanEntry packit.BuildpackPlanEntry + } + Stub func(postal.Dependency) packit.BuildpackPlanEntry + } +} + +func (f *BuildPlanRefinery) BillOfMaterials(param1 postal.Dependency) packit.BuildpackPlanEntry { + f.BillOfMaterialsCall.Lock() + defer f.BillOfMaterialsCall.Unlock() + f.BillOfMaterialsCall.CallCount++ + f.BillOfMaterialsCall.Receives.Dependency = param1 + if f.BillOfMaterialsCall.Stub != nil { + return f.BillOfMaterialsCall.Stub(param1) + } + return f.BillOfMaterialsCall.Returns.BuildpackPlanEntry +} diff --git a/fakes/dependency_manager.go b/fakes/dependency_manager.go new file mode 100644 index 0000000..86449d5 --- /dev/null +++ b/fakes/dependency_manager.go @@ -0,0 +1,64 @@ +package fakes + +import ( + "sync" + + "github.com/paketo-buildpacks/packit/postal" +) + +type DependencyManager struct { + InstallCall struct { + sync.Mutex + CallCount int + Receives struct { + Dependency postal.Dependency + CnbPath string + LayerPath string + } + Returns struct { + Error error + } + Stub func(postal.Dependency, string, string) error + } + ResolveCall struct { + sync.Mutex + CallCount int + Receives struct { + Path string + Id string + Version string + Stack string + } + Returns struct { + Dependency postal.Dependency + Error error + } + Stub func(string, string, string, string) (postal.Dependency, error) + } +} + +func (f *DependencyManager) Install(param1 postal.Dependency, param2 string, param3 string) error { + f.InstallCall.Lock() + defer f.InstallCall.Unlock() + f.InstallCall.CallCount++ + f.InstallCall.Receives.Dependency = param1 + f.InstallCall.Receives.CnbPath = param2 + f.InstallCall.Receives.LayerPath = param3 + if f.InstallCall.Stub != nil { + return f.InstallCall.Stub(param1, param2, param3) + } + return f.InstallCall.Returns.Error +} +func (f *DependencyManager) Resolve(param1 string, param2 string, param3 string, param4 string) (postal.Dependency, error) { + f.ResolveCall.Lock() + defer f.ResolveCall.Unlock() + f.ResolveCall.CallCount++ + f.ResolveCall.Receives.Path = param1 + f.ResolveCall.Receives.Id = param2 + f.ResolveCall.Receives.Version = param3 + f.ResolveCall.Receives.Stack = param4 + if f.ResolveCall.Stub != nil { + return f.ResolveCall.Stub(param1, param2, param3, param4) + } + return f.ResolveCall.Returns.Dependency, f.ResolveCall.Returns.Error +} diff --git a/fakes/entry_resolver.go b/fakes/entry_resolver.go new file mode 100644 index 0000000..42e5602 --- /dev/null +++ b/fakes/entry_resolver.go @@ -0,0 +1,32 @@ +package fakes + +import ( + "sync" + + "github.com/paketo-buildpacks/packit" +) + +type EntryResolver struct { + ResolveCall struct { + sync.Mutex + CallCount int + Receives struct { + BuildpackPlanEntrySlice []packit.BuildpackPlanEntry + } + Returns struct { + BuildpackPlanEntry packit.BuildpackPlanEntry + } + Stub func([]packit.BuildpackPlanEntry) packit.BuildpackPlanEntry + } +} + +func (f *EntryResolver) Resolve(param1 []packit.BuildpackPlanEntry) packit.BuildpackPlanEntry { + f.ResolveCall.Lock() + defer f.ResolveCall.Unlock() + f.ResolveCall.CallCount++ + f.ResolveCall.Receives.BuildpackPlanEntrySlice = param1 + if f.ResolveCall.Stub != nil { + return f.ResolveCall.Stub(param1) + } + return f.ResolveCall.Returns.BuildpackPlanEntry +} diff --git a/go.mod b/go.mod index 56fc2c1..02d5e80 100644 --- a/go.mod +++ b/go.mod @@ -1,20 +1,12 @@ module github.com/paketo-buildpacks/dep -go 1.12 +go 1.14 require ( - cloud.google.com/go v0.60.0 // indirect - github.com/buildpack/libbuildpack v1.25.11 - github.com/cloudfoundry/dagger v0.0.0-20200715130837-921c7f62ccb1 - github.com/cloudfoundry/libcfbuildpack v1.91.23 - github.com/golang/mock v1.4.3 - github.com/google/go-cmp v0.5.0 - github.com/mattn/go-colorable v0.1.7 // indirect - github.com/mitchellh/mapstructure v1.3.2 // indirect + github.com/BurntSushi/toml v0.3.1 github.com/onsi/gomega v1.10.1 - github.com/pkg/errors v0.9.1 + github.com/paketo-buildpacks/occam v0.0.16 + github.com/paketo-buildpacks/packit v0.2.2 github.com/sclevine/spec v1.4.0 golang.org/x/net v0.0.0-20200707034311-ab3426394381 // indirect - golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae // indirect - gopkg.in/yaml.v2 v2.3.0 ) diff --git a/go.sum b/go.sum index 2bb3536..654e8d6 100644 --- a/go.sum +++ b/go.sum @@ -1,89 +1,30 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0 h1:GGslhk/BU052LPlnI1vpp3fcbUs+hQ3E+Doti/3/vF8= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.60.0 h1:R+tDlceO7Ss+zyvtsdhTxacDyZ1k99xwskQ4FT7ruoM= -cloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/ForestEckhardt/freezer v0.0.0-20200630185456-a126adb8de1b h1:5ah4g+sbKU2LvMIOeR0+a4PIzrXRxJTqjZwXOdOdQsA= +github.com/ForestEckhardt/freezer v0.0.0-20200630185456-a126adb8de1b/go.mod h1:Tp5MaiHIfM9TOqTFYlqHsittmOnFGsUcUVDX+AtbNrI= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM= github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA= -github.com/buildpack/libbuildpack v1.25.11 h1:dsvBRoD90s48tyndN5lQFvJFWpp7bKbSZ3V2wTiDxQc= -github.com/buildpack/libbuildpack v1.25.11/go.mod h1:Fb1Eg3vT+B3i5l46aF6WsW7naCAYpCZmAv9UzIYs614= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cheggaaa/pb/v3 v3.0.4 h1:QZEPYOj2ix6d5oEg63fbHmpolrnNiwjUsk+h74Yt4bM= github.com/cheggaaa/pb/v3 v3.0.4/go.mod h1:7rgWxLrAUcFMkvJuv09+DYi7mMUYi8nO9iOWcvGJPfw= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudfoundry/dagger v0.0.0-20200715130837-921c7f62ccb1 h1:v5u++JnV56oIrXQc63FNBDF8Pvh+tYpRyVlmwTBIhzY= -github.com/cloudfoundry/dagger v0.0.0-20200715130837-921c7f62ccb1/go.mod h1:ZI2AHokNgEOGEMM5qWmpCMT5YEtZ7WHqAPSxOrr9hII= -github.com/cloudfoundry/libcfbuildpack v1.91.23 h1:RCorc4zL0D4+mG2z/qOueFyYGz1j3rM+e3Vbb37KPLg= -github.com/cloudfoundry/libcfbuildpack v1.91.23/go.mod h1:h95FwHvbelcd0cSOhLC8SGEZXLwCMYh1dZo2kCr7lsA= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/cloudfoundry/packit v0.0.4/go.mod h1:9xu1MT6SrenSB4oFOXtruMapQ+vdfGXLzBZDnPjhYrM= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -92,357 +33,136 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg= -github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.13.0 h1:M76yO2HkZASFjXL0HSoZJ1AYEmQxNJmY41Jx1zNUq1Y= +github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34= -github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/paketo-buildpacks/occam v0.0.16 h1:RnEizv5F5O5LL1VeOiOh8WkNosybbEPOMys6730yopw= +github.com/paketo-buildpacks/occam v0.0.16/go.mod h1:i3WI2yc5Nji45iNpW+IiiEy3f2BvbIfbLi24VKVOK0I= +github.com/paketo-buildpacks/packit v0.1.0/go.mod h1:b40wtWWAcgB47+vYGDD9KKhzOtBjI8KPqGxwGvV+XNs= github.com/paketo-buildpacks/packit v0.2.2 h1:iaTlvhF5sWiuBlz/NAM+Ycj9XkXK2tgyuZD81HLsVmY= github.com/paketo-buildpacks/packit v0.2.2/go.mod h1:b40wtWWAcgB47+vYGDD9KKhzOtBjI8KPqGxwGvV+XNs= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8= github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/ulikunitz/xz v0.5.7 h1:YvTNdFzX6+W5m9msiYg/zpkSURPPtOlzbqYjrFn7Yt4= github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= -github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/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-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24 h1:R8bzl0244nw47n1xKs1MUMAaTNgjavKcN/aX2Ss3+Fo= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1 h1:gZpLHxUX5BdYLA08Lj4YCJNN/jk7KtquiArPoeX0WvA= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= -gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/init_test.go b/init_test.go new file mode 100644 index 0000000..03620d3 --- /dev/null +++ b/init_test.go @@ -0,0 +1,17 @@ +package dep_test + +import ( + "testing" + + "github.com/sclevine/spec" + "github.com/sclevine/spec/report" +) + +func TestUnitDep(t *testing.T) { + suite := spec.New("dep", spec.Report(report.Terminal{}), spec.Parallel()) + suite("Build", testBuild) + suite("Detect", testDetect) + suite("PlanEntryResolver", testPlanEntryResolver) + suite("PlanRefinery", testPlanRefinery) + suite.Run(t) +} diff --git a/integration.json b/integration.json new file mode 100644 index 0000000..5b06e1a --- /dev/null +++ b/integration.json @@ -0,0 +1,3 @@ +{ + "build-plan": "github.com/ForestEckhardt/build-plan" +} diff --git a/integration/default_test.go b/integration/default_test.go new file mode 100644 index 0000000..0ba3d9e --- /dev/null +++ b/integration/default_test.go @@ -0,0 +1,83 @@ +package integration_test + +import ( + "fmt" + "os" + "path/filepath" + "testing" + "time" + + "github.com/paketo-buildpacks/occam" + "github.com/sclevine/spec" + + . "github.com/onsi/gomega" + . "github.com/paketo-buildpacks/occam/matchers" +) + +func testDefault(t *testing.T, context spec.G, it spec.S) { + var ( + Expect = NewWithT(t).Expect + pack occam.Pack + docker occam.Docker + ) + + it.Before(func() { + pack = occam.NewPack() + docker = occam.NewDocker() + }) + + context("when building a simple app", func() { + var ( + image occam.Image + container occam.Container + name string + source string + ) + + it.Before(func() { + var err error + name, err = occam.RandomName() + Expect(err).NotTo(HaveOccurred()) + }) + + it.After(func() { + Expect(docker.Container.Remove.Execute(container.ID)).To(Succeed()) + Expect(docker.Image.Remove.Execute(image.ID)).To(Succeed()) + Expect(docker.Volume.Remove.Execute(occam.CacheVolumeNames(name))).To(Succeed()) + Expect(os.RemoveAll(source)).To(Succeed()) + }) + + it("builds an oci image with dep installed", func() { + var err error + source, err = occam.Source(filepath.Join("testdata", "default_app")) + Expect(err).NotTo(HaveOccurred()) + + var logs fmt.Stringer + image, logs, err = pack.WithNoColor().Build. + WithNoPull(). + WithBuildpacks( + buildpack, + buildPlanBuildpack, + ). + Execute(name, source) + Expect(err).NotTo(HaveOccurred(), logs.String()) + + Expect(logs).To(ContainLines( + fmt.Sprintf("%s %s", buildpackInfo.Buildpack.Name, version), + " Executing build process", + " Installing Dep", + MatchRegexp(` Completed in ([0-9]*(\.[0-9]*)?[a-z]+)+`), + )) + + container, err = docker.Container.Run.WithCommand("dep --help && sleep infinity").Execute(image.ID) + Expect(err).NotTo(HaveOccurred()) + + time.Sleep(5 * time.Second) + out, err := docker.Container.Logs.Execute(container.ID) + Expect(err).NotTo(HaveOccurred()) + + Expect(out.String()).To(ContainSubstring("Dep is a tool for managing dependencies for Go projects")) + + }) + }) +} diff --git a/integration/init_test.go b/integration/init_test.go new file mode 100644 index 0000000..52df7b1 --- /dev/null +++ b/integration/init_test.go @@ -0,0 +1,113 @@ +package integration_test + +import ( + "bytes" + "encoding/json" + "os" + "path/filepath" + "strings" + "testing" + "time" + + "github.com/BurntSushi/toml" + "github.com/paketo-buildpacks/occam" + "github.com/paketo-buildpacks/packit/pexec" + "github.com/sclevine/spec" + "github.com/sclevine/spec/report" + + . "github.com/onsi/gomega" +) + +var ( + buildpack string + buildPlanBuildpack string + offlineBuildpack string + buildpackInfo struct { + Buildpack struct { + ID string + Name string + } + } + config struct { + BuildPlan string `json:"build-plan"` + } +) + +var version string + +func TestIntegration(t *testing.T) { + Expect := NewWithT(t).Expect + + root, err := filepath.Abs("./..") + Expect(err).ToNot(HaveOccurred()) + + file, err := os.Open("../buildpack.toml") + Expect(err).NotTo(HaveOccurred()) + + _, err = toml.DecodeReader(file, &buildpackInfo) + Expect(err).NotTo(HaveOccurred()) + Expect(file.Close()).To(Succeed()) + + file, err = os.Open("../integration.json") + Expect(err).NotTo(HaveOccurred()) + + Expect(json.NewDecoder(file).Decode(&config)).To(Succeed()) + Expect(file.Close()).To(Succeed()) + + buildpackStore := occam.NewBuildpackStore() + + version, err = GetGitVersion() + Expect(err).NotTo(HaveOccurred()) + + buildpack, err = buildpackStore.Get. + WithVersion(version). + Execute(root) + Expect(err).NotTo(HaveOccurred()) + + offlineBuildpack, err = buildpackStore.Get. + WithOfflineDependencies(). + WithVersion(version). + Execute(root) + Expect(err).NotTo(HaveOccurred()) + + buildPlanBuildpack, err = buildpackStore.Get. + Execute(config.BuildPlan) + Expect(err).NotTo(HaveOccurred()) + + SetDefaultEventuallyTimeout(5 * time.Second) + + suite := spec.New("Integration", spec.Report(report.Terminal{}), spec.Parallel()) + suite("Default", testDefault) + suite("Offline", testOffline) + suite("RebuildLayerReuse", testRebuildLayerReuse) + suite.Run(t) +} + +func GetGitVersion() (string, error) { + gitExec := pexec.NewExecutable("git") + revListOut := bytes.NewBuffer(nil) + + err := gitExec.Execute(pexec.Execution{ + Args: []string{"rev-list", "--tags", "--max-count=1"}, + Stdout: revListOut, + }) + + if revListOut.String() == "" { + return "0.0.0", nil + } + + if err != nil { + return "", err + } + + stdout := bytes.NewBuffer(nil) + err = gitExec.Execute(pexec.Execution{ + Args: []string{"describe", "--tags", strings.TrimSpace(revListOut.String())}, + Stdout: stdout, + }) + if err != nil { + return "", err + } + + return strings.TrimSpace(strings.TrimPrefix(stdout.String(), "v")), nil +} diff --git a/integration/integration_test.go b/integration/integration_test.go deleted file mode 100644 index 7ab6bc7..0000000 --- a/integration/integration_test.go +++ /dev/null @@ -1,168 +0,0 @@ -package integration_test - -import ( - "fmt" - "os" - "os/exec" - "path/filepath" - "testing" - - "github.com/paketo-buildpacks/dep/dep" - - "github.com/cloudfoundry/dagger" - . "github.com/onsi/gomega" - "github.com/sclevine/spec" - "github.com/sclevine/spec/report" -) - -var ( - depURI, goURI string -) - -func Package(root, version string, cached bool) (string, error) { - var cmd *exec.Cmd - - bpPath := filepath.Join(root, "artifact") - if cached { - cmd = exec.Command(".bin/packager", "--archive", "--version", version, fmt.Sprintf("%s-cached", bpPath)) - } else { - cmd = exec.Command(".bin/packager", "--archive", "--uncached", "--version", version, bpPath) - } - - cmd.Env = append(os.Environ(), fmt.Sprintf("PACKAGE_DIR=%s", bpPath)) - cmd.Dir = root - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - err := cmd.Run() - - if cached { - return fmt.Sprintf("%s-cached.tgz", bpPath), err - } - - return fmt.Sprintf("%s.tgz", bpPath), err -} - -func BeforeSuite() { - bpDir, err := filepath.Abs("./..") - Expect(err).NotTo(HaveOccurred()) - - depURI, err = Package(bpDir, "1.2.3", false) - Expect(err).ToNot(HaveOccurred()) - - goURI, err = dagger.GetLatestCommunityBuildpack("paketo-buildpacks", "go-compiler") - Expect(err).ToNot(HaveOccurred()) -} - -func AfterSuite() { - Expect(dagger.DeleteBuildpack(depURI)).To(Succeed()) - Expect(dagger.DeleteBuildpack(goURI)).To(Succeed()) -} - -func TestIntegration(t *testing.T) { - RegisterTestingT(t) - BeforeSuite() - spec.Run(t, "Integration", testIntegration, spec.Report(report.Terminal{}), spec.Parallel()) - AfterSuite() -} - -func testIntegration(t *testing.T, when spec.G, it spec.S) { - var ( - Expect func(interface{}, ...interface{}) GomegaAssertion - app *dagger.App - err error - ) - - it.Before(func() { - Expect = NewWithT(t).Expect - }) - - it.After(func() { - if app != nil { - Expect(app.Destroy()).To(Succeed()) - } - }) - - it("should successfully build a simple app", func() { - appRoot := filepath.Join("testdata", "simple_app") - - app, err = dagger.PackBuild(appRoot, goURI, depURI) - Expect(err).NotTo(HaveOccurred()) - - Expect(app.Start()).To(Succeed()) - body, _, err := app.HTTPGet("/") - Expect(err).ToNot(HaveOccurred()) - Expect(body).To(ContainSubstring("Hello, World!")) - Expect(body).To(MatchRegexp(`PATH=.*/layers/paketo-buildpacks_dep/app-binary/bin`)) - - Expect(app.BuildLogs()).To(MatchRegexp("Dep.*: Contributing to layer")) - }) - - it("should fail to build if the app does not specify import-path", func() { - appRoot := filepath.Join("testdata", "simple_app_without_import_path") - _, err := dagger.PackBuild(appRoot, goURI, depURI) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring(dep.MissingImportPathErrorMsg)) - }) - - it("should successfully build a simple app with target", func() { - appRoot := filepath.Join("testdata", "simple_app_with_target") - - app, err = dagger.PackBuild(appRoot, goURI, depURI) - Expect(err).NotTo(HaveOccurred()) - - Expect(app.Start()).To(Succeed()) - body, _, err := app.HTTPGet("/") - Expect(err).ToNot(HaveOccurred()) - Expect(body).To(ContainSubstring("Hello, World!")) - - Expect(app.BuildLogs()).To(MatchRegexp("Dep.*: Contributing to layer")) - }) - - it("uses the vendored packages when the app is vendored", func() { - appDir := filepath.Join("testdata", "vendored_app") - app, err = dagger.PackBuild(appDir, goURI, depURI) - Expect(err).ToNot(HaveOccurred()) - - Expect(app.BuildLogs()).To(ContainSubstring("Note: skipping `dep ensure` due to non-empty vendor directory.")) - - Expect(app.Start()).To(Succeed()) - _, _, err = app.HTTPGet("/") - Expect(err).ToNot(HaveOccurred()) - }) - - it("uses updated source code on a rebuild", func() { - appRoot := filepath.Join("testdata", "with_lockfile") - - app, err = dagger.PackBuild(appRoot, goURI, depURI) - Expect(err).NotTo(HaveOccurred()) - - Expect(err).ToNot(HaveOccurred()) - Expect(app.BuildLogs()).To(MatchRegexp("Dep.*: Contributing to layer")) - - _, imageID, _, err := app.Info() - Expect(err).NotTo(HaveOccurred()) - - appRoot = filepath.Join("testdata", "with_lockfile_modified") - app, err = dagger.PackBuildNamedImage(imageID, appRoot, goURI, depURI) - Expect(err).NotTo(HaveOccurred()) - Expect(app.Start()).To(Succeed()) - - body, _, err := app.HTTPGet("/") - Expect(err).NotTo(HaveOccurred()) - Expect(body).To(ContainSubstring("The source changed!")) - }) - - when("the app specifies ldflags", func() { - it("should build the app with those build flags", func() { - app, err = dagger.PackBuild(filepath.Join("testdata", "simple_app_with_target_and_ldflags"), goURI, depURI) - Expect(err).ToNot(HaveOccurred()) - - Expect(app.Start()).To(Succeed()) - - body, _, err := app.HTTPGet("/") - Expect(err).NotTo(HaveOccurred()) - Expect(body).To(ContainSubstring("main.version: v1.2.3")) - Expect(body).To(ContainSubstring("main.sha: 7a82056")) - }) - }) -} diff --git a/integration/layer_reuse_test.go b/integration/layer_reuse_test.go new file mode 100644 index 0000000..c91a348 --- /dev/null +++ b/integration/layer_reuse_test.go @@ -0,0 +1,102 @@ +package integration_test + +import ( + "fmt" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/paketo-buildpacks/occam" + "github.com/sclevine/spec" + + . "github.com/onsi/gomega" +) + +func testRebuildLayerReuse(t *testing.T, context spec.G, it spec.S) { + var ( + Expect = NewWithT(t).Expect + + docker occam.Docker + pack occam.Pack + + imageIDs map[string]struct{} + containerIDs map[string]struct{} + + name string + source string + ) + + it.Before(func() { + var err error + name, err = occam.RandomName() + Expect(err).NotTo(HaveOccurred()) + + docker = occam.NewDocker() + pack = occam.NewPack() + imageIDs = map[string]struct{}{} + containerIDs = map[string]struct{}{} + }) + + it.After(func() { + for id := range containerIDs { + Expect(docker.Container.Remove.Execute(id)).To(Succeed()) + } + + for id := range imageIDs { + Expect(docker.Image.Remove.Execute(id)).To(Succeed()) + } + + Expect(docker.Volume.Remove.Execute(occam.CacheVolumeNames(name))).To(Succeed()) + Expect(os.RemoveAll(source)).To(Succeed()) + }) + + context("an app is rebuilt and dep dependency is unchanged", func() { + it("reuses a layer from a previous build", func() { + var ( + err error + logs fmt.Stringer + firstImage occam.Image + secondImage occam.Image + ) + + source, err = occam.Source(filepath.Join("testdata", "default_app")) + Expect(err).NotTo(HaveOccurred()) + + build := pack.WithNoColor().Build. + WithNoPull(). + WithBuildpacks( + buildpack, + buildPlanBuildpack, + ) + + firstImage, logs, err = build.Execute(name, source) + Expect(err).NotTo(HaveOccurred()) + + imageIDs[firstImage.ID] = struct{}{} + + Expect(firstImage.Buildpacks).To(HaveLen(2)) + + Expect(firstImage.Buildpacks[0].Key).To(Equal(buildpackInfo.Buildpack.ID)) + Expect(firstImage.Buildpacks[0].Layers).To(HaveKey("dep")) + + Expect(logs.String()).To(ContainSubstring(" Executing build process")) + + // Second pack build + secondImage, logs, err = build.Execute(name, source) + Expect(err).NotTo(HaveOccurred()) + + imageIDs[secondImage.ID] = struct{}{} + + Expect(secondImage.Buildpacks).To(HaveLen(2)) + + Expect(secondImage.Buildpacks[0].Key).To(Equal(buildpackInfo.Buildpack.ID)) + Expect(secondImage.Buildpacks[0].Layers).To(HaveKey("dep")) + + Expect(logs.String()).NotTo(ContainSubstring(" Executing build process")) + Expect(logs.String()).To(ContainSubstring(fmt.Sprintf(" Reusing cached layer /layers/%s/dep", strings.ReplaceAll(buildpackInfo.Buildpack.ID, "/", "_")))) + + Expect(secondImage.Buildpacks[0].Layers["dep"].Metadata["built_at"]).To(Equal(firstImage.Buildpacks[0].Layers["dep"].Metadata["built_at"])) + }) + }) +} diff --git a/integration/offline_test.go b/integration/offline_test.go new file mode 100644 index 0000000..86641d1 --- /dev/null +++ b/integration/offline_test.go @@ -0,0 +1,76 @@ +package integration_test + +import ( + "fmt" + "os" + "path/filepath" + "testing" + "time" + + "github.com/paketo-buildpacks/occam" + "github.com/sclevine/spec" + + . "github.com/onsi/gomega" +) + +func testOffline(t *testing.T, context spec.G, it spec.S) { + var ( + Expect = NewWithT(t).Expect + pack occam.Pack + docker occam.Docker + ) + + it.Before(func() { + pack = occam.NewPack() + docker = occam.NewDocker() + }) + + context("when offline", func() { + var ( + image occam.Image + container occam.Container + + name string + source string + ) + + it.Before(func() { + var err error + name, err = occam.RandomName() + Expect(err).NotTo(HaveOccurred()) + }) + + it.After(func() { + Expect(docker.Container.Remove.Execute(container.ID)).To(Succeed()) + Expect(docker.Image.Remove.Execute(image.ID)).To(Succeed()) + Expect(docker.Volume.Remove.Execute(occam.CacheVolumeNames(name))).To(Succeed()) + Expect(os.RemoveAll(source)).NotTo(HaveOccurred()) + }) + + it("builds an oci image with dep installed", func() { + var err error + source, err = occam.Source(filepath.Join("testdata", "default_app")) + Expect(err).NotTo(HaveOccurred()) + + var logs fmt.Stringer + image, logs, err = pack.WithNoColor().Build. + WithNoPull(). + WithBuildpacks( + offlineBuildpack, + buildPlanBuildpack). + WithNetwork("none"). + Execute(name, source) + + Expect(err).NotTo(HaveOccurred(), logs.String()) + + container, err = docker.Container.Run.WithCommand("dep --help && sleep infinity").Execute(image.ID) + Expect(err).NotTo(HaveOccurred()) + + time.Sleep(5 * time.Second) + out, err := docker.Container.Logs.Execute(container.ID) + Expect(err).NotTo(HaveOccurred()) + + Expect(out.String()).To(ContainSubstring("Dep is a tool for managing dependencies for Go projects")) + }) + }) +} diff --git a/integration/testdata/simple_app/Gopkg.toml b/integration/testdata/default_app/Gopkg.toml similarity index 100% rename from integration/testdata/simple_app/Gopkg.toml rename to integration/testdata/default_app/Gopkg.toml diff --git a/integration/testdata/default_app/plan.toml b/integration/testdata/default_app/plan.toml new file mode 100644 index 0000000..f143766 --- /dev/null +++ b/integration/testdata/default_app/plan.toml @@ -0,0 +1,5 @@ +[[requires]] + name = "dep" + + [requires.metadata] + launch = true diff --git a/integration/testdata/simple_app/site.go b/integration/testdata/default_app/site.go similarity index 100% rename from integration/testdata/simple_app/site.go rename to integration/testdata/default_app/site.go diff --git a/integration/testdata/simple_app/buildpack.yml b/integration/testdata/simple_app/buildpack.yml deleted file mode 100644 index 5e8ef79..0000000 --- a/integration/testdata/simple_app/buildpack.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -go: - import-path: hubgit.net/user/app diff --git a/integration/testdata/simple_app_with_target/Gopkg.toml b/integration/testdata/simple_app_with_target/Gopkg.toml deleted file mode 100644 index 5308f2f..0000000 --- a/integration/testdata/simple_app_with_target/Gopkg.toml +++ /dev/null @@ -1,4 +0,0 @@ - -[[constraint]] - branch = "master" - name = "github.com/ZiCog/shiny-thing" diff --git a/integration/testdata/simple_app_with_target/buildpack.yml b/integration/testdata/simple_app_with_target/buildpack.yml deleted file mode 100644 index d0bf34b..0000000 --- a/integration/testdata/simple_app_with_target/buildpack.yml +++ /dev/null @@ -1,3 +0,0 @@ -go: - import-path: hubgit.net/user/app - targets: ["./cmd/site"] \ No newline at end of file diff --git a/integration/testdata/simple_app_with_target/cmd/site/site.go b/integration/testdata/simple_app_with_target/cmd/site/site.go deleted file mode 100644 index 6801daf..0000000 --- a/integration/testdata/simple_app_with_target/cmd/site/site.go +++ /dev/null @@ -1,27 +0,0 @@ -package main - -import ( - "fmt" - "net/http" - "os" - - "github.com/ZiCog/shiny-thing/foo" -) - -func main() { - foo.Do() - http.HandleFunc("/", hello) - port := "8080" - if os.Getenv("PORT") != "" { - port = os.Getenv("PORT") - } - fmt.Println(fmt.Sprintf("listening on %s...", port)) - err := http.ListenAndServe(":"+port, nil) - if err != nil { - panic(err) - } -} - -func hello(res http.ResponseWriter, req *http.Request) { - fmt.Fprintln(res, "Hello, World!") -} diff --git a/integration/testdata/simple_app_with_target_and_ldflags/Gopkg.toml b/integration/testdata/simple_app_with_target_and_ldflags/Gopkg.toml deleted file mode 100644 index 5308f2f..0000000 --- a/integration/testdata/simple_app_with_target_and_ldflags/Gopkg.toml +++ /dev/null @@ -1,4 +0,0 @@ - -[[constraint]] - branch = "master" - name = "github.com/ZiCog/shiny-thing" diff --git a/integration/testdata/simple_app_with_target_and_ldflags/buildpack.yml b/integration/testdata/simple_app_with_target_and_ldflags/buildpack.yml deleted file mode 100644 index 8294873..0000000 --- a/integration/testdata/simple_app_with_target_and_ldflags/buildpack.yml +++ /dev/null @@ -1,7 +0,0 @@ -go: - import-path: hubgit.net/user/app - targets: ["./cmd/site"] - ldflags: - main.version: v1.2.3 - main.sha: 7a82056 - diff --git a/integration/testdata/simple_app_with_target_and_ldflags/cmd/site/site.go b/integration/testdata/simple_app_with_target_and_ldflags/cmd/site/site.go deleted file mode 100644 index f1d5f8c..0000000 --- a/integration/testdata/simple_app_with_target_and_ldflags/cmd/site/site.go +++ /dev/null @@ -1,33 +0,0 @@ -package main - -import ( - "fmt" - "net/http" - "os" - - "github.com/ZiCog/shiny-thing/foo" -) - -var ( - version string - sha string -) -func main() { - foo.Do() - http.HandleFunc("/", hello) - port := "8080" - if os.Getenv("PORT") != "" { - port = os.Getenv("PORT") - } - fmt.Println(fmt.Sprintf("listening on %s...", port)) - err := http.ListenAndServe(":"+port, nil) - if err != nil { - panic(err) - } -} - -func hello(res http.ResponseWriter, req *http.Request) { - fmt.Fprintln(res, "Hello, World!") - fmt.Fprintf(res, "main.version: %s\n", version) - fmt.Fprintf(res, "main.sha: %s\n", sha) -} diff --git a/integration/testdata/simple_app_without_import_path/Gopkg.toml b/integration/testdata/simple_app_without_import_path/Gopkg.toml deleted file mode 100644 index 5308f2f..0000000 --- a/integration/testdata/simple_app_without_import_path/Gopkg.toml +++ /dev/null @@ -1,4 +0,0 @@ - -[[constraint]] - branch = "master" - name = "github.com/ZiCog/shiny-thing" diff --git a/integration/testdata/simple_app_without_import_path/buildpack.yml b/integration/testdata/simple_app_without_import_path/buildpack.yml deleted file mode 100644 index 58554be..0000000 --- a/integration/testdata/simple_app_without_import_path/buildpack.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -go: - import-path: diff --git a/integration/testdata/simple_app_without_import_path/site.go b/integration/testdata/simple_app_without_import_path/site.go deleted file mode 100644 index 6801daf..0000000 --- a/integration/testdata/simple_app_without_import_path/site.go +++ /dev/null @@ -1,27 +0,0 @@ -package main - -import ( - "fmt" - "net/http" - "os" - - "github.com/ZiCog/shiny-thing/foo" -) - -func main() { - foo.Do() - http.HandleFunc("/", hello) - port := "8080" - if os.Getenv("PORT") != "" { - port = os.Getenv("PORT") - } - fmt.Println(fmt.Sprintf("listening on %s...", port)) - err := http.ListenAndServe(":"+port, nil) - if err != nil { - panic(err) - } -} - -func hello(res http.ResponseWriter, req *http.Request) { - fmt.Fprintln(res, "Hello, World!") -} diff --git a/integration/testdata/vendored_app/Gopkg.lock b/integration/testdata/vendored_app/Gopkg.lock deleted file mode 100644 index 5e9c7b1..0000000 --- a/integration/testdata/vendored_app/Gopkg.lock +++ /dev/null @@ -1,15 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - branch = "master" - name = "github.com/ZiCog/shiny-thing" - packages = ["foo"] - revision = "e9e19444ccf5362bba846441c4700a49a94b8118" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "f508e7d90d5c3c48e1df5c85f51b6a6bfd4f99f4d6fa4d515d678c07e30a5da6" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/integration/testdata/vendored_app/Gopkg.toml b/integration/testdata/vendored_app/Gopkg.toml deleted file mode 100644 index 5308f2f..0000000 --- a/integration/testdata/vendored_app/Gopkg.toml +++ /dev/null @@ -1,4 +0,0 @@ - -[[constraint]] - branch = "master" - name = "github.com/ZiCog/shiny-thing" diff --git a/integration/testdata/vendored_app/buildpack.yml b/integration/testdata/vendored_app/buildpack.yml deleted file mode 100644 index 13f4aa3..0000000 --- a/integration/testdata/vendored_app/buildpack.yml +++ /dev/null @@ -1,2 +0,0 @@ -go: - import-path: hubgit.net/user/app diff --git a/integration/testdata/vendored_app/site.go b/integration/testdata/vendored_app/site.go deleted file mode 100644 index 6801daf..0000000 --- a/integration/testdata/vendored_app/site.go +++ /dev/null @@ -1,27 +0,0 @@ -package main - -import ( - "fmt" - "net/http" - "os" - - "github.com/ZiCog/shiny-thing/foo" -) - -func main() { - foo.Do() - http.HandleFunc("/", hello) - port := "8080" - if os.Getenv("PORT") != "" { - port = os.Getenv("PORT") - } - fmt.Println(fmt.Sprintf("listening on %s...", port)) - err := http.ListenAndServe(":"+port, nil) - if err != nil { - panic(err) - } -} - -func hello(res http.ResponseWriter, req *http.Request) { - fmt.Fprintln(res, "Hello, World!") -} diff --git a/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/README.md b/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/README.md deleted file mode 100644 index 99446cd..0000000 --- a/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/README.md +++ /dev/null @@ -1,44 +0,0 @@ -shiny-thing -=========== - -shiny-thing is just me playing with Go packages in a repo. - -TODO: Show how to put a program (with main) in this repo - - -Assumming we have src, pkg and bin directories under our GOPATH - -How to fetch packages from a git hub repo - - $ go get github.com/ZiCog/shiny-thing/foo - $ go get github.com/ZiCog/shiny-thing/bar - -Note: the above will become the package names -Note: if get fails then "rm -rf mygo/src/github.com/ZiCog/shiny-thing" -and try again. - -Or get the whole bunch at once - - $ go get github.com/ZiCog/shiny-thing - -How to build Go packages (these are package names) - - $ go build github.com/ZiCog/shiny-thing/foo - $ go build github.com/ZiCog/shiny-thing/bar - -How to install Go packages (under pkg, these are package names again) - - $ go install github.com/ZiCog/shiny-thing/bar - $ go install github.com/ZiCog/shiny-thing/foo - -How to build a Go program (Something with main in it) - - $ go build myprog - -How to install the program (under src) - - $ go install myprog - -Or you can just run it - - $ go run myprog diff --git a/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/bar/bye.go b/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/bar/bye.go deleted file mode 100644 index 8dfbc71..0000000 --- a/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/bar/bye.go +++ /dev/null @@ -1,11 +0,0 @@ -package bar - -import ( - "fmt" -) - -// Done says it has done something -func Done() { - fmt.Println("Bye from bar") -} - diff --git a/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/bar/hello.go b/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/bar/hello.go deleted file mode 100644 index 87dc7ce..0000000 --- a/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/bar/hello.go +++ /dev/null @@ -1,14 +0,0 @@ -/* - The bar package implements bar functionality -*/ -package bar - -import ( - "fmt" -) - -// Do does something -func Do() { - fmt.Println("Hello from bar") -} - diff --git a/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/foo/bye.go b/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/foo/bye.go deleted file mode 100644 index e5ad710..0000000 --- a/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/foo/bye.go +++ /dev/null @@ -1,11 +0,0 @@ -package foo - -import ( - "fmt" -) - -// Done says it has done something -func Done() { - fmt.Println("Bye from foo!") -} - diff --git a/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/foo/hello.go b/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/foo/hello.go deleted file mode 100644 index 735e302..0000000 --- a/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/foo/hello.go +++ /dev/null @@ -1,14 +0,0 @@ -/* - The hello package does something interesting -*/ -package foo - -import ( - "fmt" -) - -// Do does something with nothing -func Do() { - fmt.Println("Hello from foo!") -} - diff --git a/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/shiny-thing.go b/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/shiny-thing.go deleted file mode 100644 index b760491..0000000 --- a/integration/testdata/vendored_app/vendor/github.com/ZiCog/shiny-thing/shiny-thing.go +++ /dev/null @@ -1,12 +0,0 @@ -/* - A package comment. - Only present in one file of the package. -*/ -package main - -import "fmt" - -func main() { - fmt.Println("Hello, 世界") -} - diff --git a/integration/testdata/with_lockfile/Gopkg.lock b/integration/testdata/with_lockfile/Gopkg.lock deleted file mode 100644 index 5e9c7b1..0000000 --- a/integration/testdata/with_lockfile/Gopkg.lock +++ /dev/null @@ -1,15 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - branch = "master" - name = "github.com/ZiCog/shiny-thing" - packages = ["foo"] - revision = "e9e19444ccf5362bba846441c4700a49a94b8118" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "f508e7d90d5c3c48e1df5c85f51b6a6bfd4f99f4d6fa4d515d678c07e30a5da6" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/integration/testdata/with_lockfile/Gopkg.toml b/integration/testdata/with_lockfile/Gopkg.toml deleted file mode 100644 index 5308f2f..0000000 --- a/integration/testdata/with_lockfile/Gopkg.toml +++ /dev/null @@ -1,4 +0,0 @@ - -[[constraint]] - branch = "master" - name = "github.com/ZiCog/shiny-thing" diff --git a/integration/testdata/with_lockfile/buildpack.yml b/integration/testdata/with_lockfile/buildpack.yml deleted file mode 100644 index 13f4aa3..0000000 --- a/integration/testdata/with_lockfile/buildpack.yml +++ /dev/null @@ -1,2 +0,0 @@ -go: - import-path: hubgit.net/user/app diff --git a/integration/testdata/with_lockfile/site.go b/integration/testdata/with_lockfile/site.go deleted file mode 100644 index 6801daf..0000000 --- a/integration/testdata/with_lockfile/site.go +++ /dev/null @@ -1,27 +0,0 @@ -package main - -import ( - "fmt" - "net/http" - "os" - - "github.com/ZiCog/shiny-thing/foo" -) - -func main() { - foo.Do() - http.HandleFunc("/", hello) - port := "8080" - if os.Getenv("PORT") != "" { - port = os.Getenv("PORT") - } - fmt.Println(fmt.Sprintf("listening on %s...", port)) - err := http.ListenAndServe(":"+port, nil) - if err != nil { - panic(err) - } -} - -func hello(res http.ResponseWriter, req *http.Request) { - fmt.Fprintln(res, "Hello, World!") -} diff --git a/integration/testdata/with_lockfile_modified/Gopkg.lock b/integration/testdata/with_lockfile_modified/Gopkg.lock deleted file mode 100644 index 5e9c7b1..0000000 --- a/integration/testdata/with_lockfile_modified/Gopkg.lock +++ /dev/null @@ -1,15 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - branch = "master" - name = "github.com/ZiCog/shiny-thing" - packages = ["foo"] - revision = "e9e19444ccf5362bba846441c4700a49a94b8118" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "f508e7d90d5c3c48e1df5c85f51b6a6bfd4f99f4d6fa4d515d678c07e30a5da6" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/integration/testdata/with_lockfile_modified/Gopkg.toml b/integration/testdata/with_lockfile_modified/Gopkg.toml deleted file mode 100644 index 5308f2f..0000000 --- a/integration/testdata/with_lockfile_modified/Gopkg.toml +++ /dev/null @@ -1,4 +0,0 @@ - -[[constraint]] - branch = "master" - name = "github.com/ZiCog/shiny-thing" diff --git a/integration/testdata/with_lockfile_modified/buildpack.yml b/integration/testdata/with_lockfile_modified/buildpack.yml deleted file mode 100644 index 13f4aa3..0000000 --- a/integration/testdata/with_lockfile_modified/buildpack.yml +++ /dev/null @@ -1,2 +0,0 @@ -go: - import-path: hubgit.net/user/app diff --git a/integration/testdata/with_lockfile_modified/site.go b/integration/testdata/with_lockfile_modified/site.go deleted file mode 100644 index c65725f..0000000 --- a/integration/testdata/with_lockfile_modified/site.go +++ /dev/null @@ -1,27 +0,0 @@ -package main - -import ( - "fmt" - "net/http" - "os" - - "github.com/ZiCog/shiny-thing/foo" -) - -func main() { - foo.Do() - http.HandleFunc("/", hello) - port := "8080" - if os.Getenv("PORT") != "" { - port = os.Getenv("PORT") - } - fmt.Println(fmt.Sprintf("listening on %s...", port)) - err := http.ListenAndServe(":"+port, nil) - if err != nil { - panic(err) - } -} - -func hello(res http.ResponseWriter, req *http.Request) { - fmt.Fprintln(res, "The source changed!") -} diff --git a/log_emitter.go b/log_emitter.go new file mode 100644 index 0000000..006fa4a --- /dev/null +++ b/log_emitter.go @@ -0,0 +1,19 @@ +package dep + +import ( + "io" + + "github.com/paketo-buildpacks/packit/scribe" +) + +type LogEmitter struct { + // Logger is embedded and therefore delegates all of its functions to the + // LogEmitter. + scribe.Logger +} + +func NewLogEmitter(output io.Writer) LogEmitter { + return LogEmitter{ + Logger: scribe.NewLogger(output), + } +} diff --git a/plan_entry_resolver.go b/plan_entry_resolver.go new file mode 100644 index 0000000..a2775de --- /dev/null +++ b/plan_entry_resolver.go @@ -0,0 +1,37 @@ +package dep + +import ( + "github.com/paketo-buildpacks/packit" +) + +type PlanEntryResolver struct { + logger LogEmitter +} + +func NewPlanEntryResolver(logger LogEmitter) PlanEntryResolver { + return PlanEntryResolver{ + logger: logger, + } +} + +func (r PlanEntryResolver) Resolve(entries []packit.BuildpackPlanEntry) packit.BuildpackPlanEntry { + + // there's no data right now to heuristically pick an entry + chosenEntry := entries[0] + + if chosenEntry.Metadata == nil { + chosenEntry.Metadata = map[string]interface{}{} + } + + for _, entry := range entries { + if entry.Metadata["build"] == true { + chosenEntry.Metadata["build"] = true + } + + if entry.Metadata["launch"] == true { + chosenEntry.Metadata["launch"] = true + } + } + + return chosenEntry +} diff --git a/plan_entry_resolver_test.go b/plan_entry_resolver_test.go new file mode 100644 index 0000000..6bca06b --- /dev/null +++ b/plan_entry_resolver_test.go @@ -0,0 +1,54 @@ +package dep_test + +import ( + "bytes" + "testing" + + dep "github.com/paketo-buildpacks/dep" + "github.com/paketo-buildpacks/packit" + "github.com/sclevine/spec" + + . "github.com/onsi/gomega" +) + +func testPlanEntryResolver(t *testing.T, context spec.G, it spec.S) { + var ( + Expect = NewWithT(t).Expect + + buffer *bytes.Buffer + resolver dep.PlanEntryResolver + ) + + it.Before(func() { + buffer = bytes.NewBuffer(nil) + resolver = dep.NewPlanEntryResolver(dep.NewLogEmitter(buffer)) + }) + + context("when entry flags differ", func() { + context("OR's them together on best plan entry", func() { + it("has all flags", func() { + entry := resolver.Resolve([]packit.BuildpackPlanEntry{ + { + Name: "dep", + Metadata: map[string]interface{}{ + "launch": true, + }, + }, + { + Name: "dep", + Metadata: map[string]interface{}{ + "build": true, + }, + }, + }) + Expect(entry).To(Equal(packit.BuildpackPlanEntry{ + Name: "dep", + Metadata: map[string]interface{}{ + "build": true, + "launch": true, + }, + })) + }) + }) + }) +} diff --git a/plan_refinery.go b/plan_refinery.go new file mode 100644 index 0000000..864fdb4 --- /dev/null +++ b/plan_refinery.go @@ -0,0 +1,26 @@ +package dep + +import ( + "github.com/paketo-buildpacks/packit" + "github.com/paketo-buildpacks/packit/postal" +) + +type PlanRefinery struct{} + +func NewPlanRefinery() PlanRefinery { + return PlanRefinery{} +} + +func (r PlanRefinery) BillOfMaterials(dependency postal.Dependency) packit.BuildpackPlanEntry { + return packit.BuildpackPlanEntry{ + Name: dependency.ID, + Version: dependency.Version, + Metadata: map[string]interface{}{ + "licenses": []string{}, + "name": dependency.Name, + "sha256": dependency.SHA256, + "stacks": dependency.Stacks, + "uri": dependency.URI, + }, + } +} diff --git a/plan_refinery_test.go b/plan_refinery_test.go new file mode 100644 index 0000000..a79f6c8 --- /dev/null +++ b/plan_refinery_test.go @@ -0,0 +1,48 @@ +package dep_test + +import ( + "testing" + + dep "github.com/paketo-buildpacks/dep" + "github.com/paketo-buildpacks/packit" + "github.com/paketo-buildpacks/packit/postal" + "github.com/sclevine/spec" + + . "github.com/onsi/gomega" +) + +func testPlanRefinery(t *testing.T, context spec.G, it spec.S) { + var ( + Expect = NewWithT(t).Expect + + refinery dep.PlanRefinery + ) + + it.Before(func() { + refinery = dep.NewPlanRefinery() + }) + + context("BillOfMaterials", func() { + it("returns a refined build plan entry", func() { + entry := refinery.BillOfMaterials(postal.Dependency{ + ID: "some-id", + Name: "some-name", + Stacks: []string{"some-stack"}, + URI: "some-uri", + SHA256: "some-sha", + Version: "some-version", + }) + Expect(entry).To(Equal(packit.BuildpackPlanEntry{ + Name: "some-id", + Version: "some-version", + Metadata: map[string]interface{}{ + "licenses": []string{}, + "name": "some-name", + "sha256": "some-sha", + "stacks": []string{"some-stack"}, + "uri": "some-uri", + }, + })) + }) + }) +} diff --git a/run/main.go b/run/main.go new file mode 100644 index 0000000..07e7dc1 --- /dev/null +++ b/run/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "os" + + "github.com/paketo-buildpacks/dep" + "github.com/paketo-buildpacks/packit" + "github.com/paketo-buildpacks/packit/cargo" + "github.com/paketo-buildpacks/packit/chronos" + "github.com/paketo-buildpacks/packit/postal" +) + +func main() { + logEmitter := dep.NewLogEmitter(os.Stdout) + entryResolver := dep.NewPlanEntryResolver(logEmitter) + dependencyManager := postal.NewService(cargo.NewTransport()) + planRefinery := dep.NewPlanRefinery() + + packit.Run( + dep.Detect(), + dep.Build( + entryResolver, + dependencyManager, + planRefinery, + chronos.DefaultClock, + logEmitter, + ), + ) +} diff --git a/utils/utils.go b/utils/utils.go deleted file mode 100644 index 472fc6d..0000000 --- a/utils/utils.go +++ /dev/null @@ -1,36 +0,0 @@ -package utils - -import ( - "bytes" - "io" - "io/ioutil" - "os" - "os/exec" -) - -type Command struct{} - -func (c *Command) Run(dir, bin string, args ...string) (string, error) { - logs := &bytes.Buffer{} - err := c.run(dir, []string{}, io.MultiWriter(os.Stdout, logs), io.MultiWriter(os.Stderr, logs), bin, args...) - return logs.String(), err -} - -func (c *Command) RunSilent(dir, bin string, args ...string) (string, error) { - logs := &bytes.Buffer{} - err := c.run(dir, []string{}, io.MultiWriter(ioutil.Discard, logs), io.MultiWriter(ioutil.Discard, logs), bin, args...) - return logs.String(), err -} - -func (c *Command) CustomRun(dir string, env []string, out, err io.Writer, bin string, args ...string) error { - return c.run(dir, env, out, err, bin, args...) -} - -func (c *Command) run(dir string, env []string, out, err io.Writer, bin string, args ...string) error { - cmd := exec.Command(bin, args...) - cmd.Dir = dir - cmd.Stdout = out - cmd.Stderr = err - cmd.Env = append(os.Environ(), env...) - return cmd.Run() -}