diff --git a/pkg/dist/buildmodule.go b/pkg/dist/buildmodule.go index 75d10d44e..ec3dc99ec 100644 --- a/pkg/dist/buildmodule.go +++ b/pkg/dist/buildmodule.go @@ -59,6 +59,6 @@ type Target struct { } type Distribution struct { - Name string `json:"name" toml:"name"` + Name string `json:"name,omitempty" toml:"name,omitempty"` Versions []string `json:"versions,omitempty" toml:"versions,omitempty"` } diff --git a/pkg/dist/buildpack_descriptor.go b/pkg/dist/buildpack_descriptor.go index e54e89c1b..5714fd0c0 100644 --- a/pkg/dist/buildpack_descriptor.go +++ b/pkg/dist/buildpack_descriptor.go @@ -1,6 +1,7 @@ package dist import ( + "encoding/json" "fmt" "sort" "strings" @@ -84,7 +85,33 @@ func (b *BuildpackDescriptor) EnsureTargetSupport(os, arch, distroName, distroVe } } } - return fmt.Errorf("buildpack %s does not support target: (%s %s, %s@%s)", style.Symbol(b.Info().FullName()), os, arch, distroName, distroVersion) + type osDistribution struct { + Name string `json:"name,omitempty"` + Version string `json:"version,omitempty"` + } + type target struct { + OS string `json:"os"` + Arch string `json:"arch"` + Distribution osDistribution `json:"distribution"` + } + return fmt.Errorf( + "unable to satisfy target os/arch constraints; build image: %s, buildpack %s: %s", + toJSONMaybe(target{ + OS: os, + Arch: arch, + Distribution: osDistribution{Name: distroName, Version: distroVersion}, + }), + style.Symbol(b.Info().FullName()), + toJSONMaybe(b.Targets()), + ) +} + +func toJSONMaybe(v interface{}) string { + b, err := json.Marshal(v) + if err != nil { + return fmt.Sprintf("%s", v) // hopefully v is a Stringer + } + return string(b) } func (b *BuildpackDescriptor) Kind() string { diff --git a/pkg/dist/buildpack_descriptor_test.go b/pkg/dist/buildpack_descriptor_test.go index cbeb9d3e8..9edc2772d 100644 --- a/pkg/dist/buildpack_descriptor_test.go +++ b/pkg/dist/buildpack_descriptor_test.go @@ -207,7 +207,7 @@ func testBuildpackDescriptor(t *testing.T, when spec.G, it spec.S) { h.AssertNil(t, bp.EnsureStackSupport("some.stack.id", []string{}, true)) h.AssertError(t, bp.EnsureTargetSupport("some-other-os", "fake-arch", "fake-distro", "0.0"), - "buildpack 'some.buildpack.id@some.buildpack.version' does not support target: (some-other-os fake-arch, fake-distro@0.0)") + `unable to satisfy target os/arch constraints; build image: {"os":"some-other-os","arch":"fake-arch","distribution":{"name":"fake-distro","version":"0.0"}}, buildpack 'some.buildpack.id@some.buildpack.version': [{"os":"fake-os","arch":"fake-arch"}]`) }) it("succeeds with distribution", func() { @@ -260,7 +260,7 @@ func testBuildpackDescriptor(t *testing.T, when spec.G, it spec.S) { h.AssertNil(t, bp.EnsureStackSupport("some.stack.id", []string{}, true)) h.AssertError(t, bp.EnsureTargetSupport("some-other-os", "fake-arch", "fake-distro", "0.0"), - "buildpack 'some.buildpack.id@some.buildpack.version' does not support target: (some-other-os fake-arch, fake-distro@0.0)") + `unable to satisfy target os/arch constraints; build image: {"os":"some-other-os","arch":"fake-arch","distribution":{"name":"fake-distro","version":"0.0"}}, buildpack 'some.buildpack.id@some.buildpack.version': [{"os":"fake-os","arch":"fake-arch","distributions":[{"name":"fake-distro","versions":["0.1"]},{"name":"another-distro","versions":["0.22"]}]}]`) }) })