Skip to content

Commit

Permalink
Make compatible with pack 0.3.0
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Meyer <ameyer@pivotal.io>
  • Loading branch information
ameyer-pivotal committed Jul 23, 2019
1 parent 3b08815 commit 160af39
Show file tree
Hide file tree
Showing 11 changed files with 257 additions and 2 deletions.
12 changes: 10 additions & 2 deletions cmd/detector/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/buildpack/lifecycle"
"github.com/buildpack/lifecycle/cmd"
"github.com/buildpack/lifecycle/compat"
)

var (
Expand Down Expand Up @@ -42,9 +43,16 @@ func main() {
}

func detect() error {
order, err := lifecycle.ReadOrder(orderPath)
order, err := compat.ReadOrder(orderPath, buildpacksDir)
if err != nil {
return cmd.FailErr(err, "read buildpack order file")
return cmd.FailErr(err, "read legacy buildpack order file")
}

if len(order) == 0 {
order, err = lifecycle.ReadOrder(orderPath)
if err != nil {
return cmd.FailErr(err, "read buildpack order file")
}
}

group, plan, err := order.Detect(&lifecycle.DetectConfig{
Expand Down
110 changes: 110 additions & 0 deletions compat/compat.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package compat

import (
"path"
"path/filepath"
"strings"

"github.com/BurntSushi/toml"
"github.com/pkg/errors"

"github.com/buildpack/lifecycle"
)

type orderConfig struct {
Groups []groupConfig `toml:"groups"`
}

type groupConfig struct {
Buildpacks []buildpackRefConfig `toml:"buildpacks"`
}

type buildpackRefConfig struct {
ID string `toml:"id"`
Version string `toml:"version"`
Optional bool `toml:"optional,omitempty"`
}

func (b buildpackRefConfig) dir() string {
return strings.Replace(b.ID, "/", "_", -1)
}

func ReadOrder(path, buildpacksDir string) (lifecycle.BuildpackOrder, error) {
var legacyOrder orderConfig
if _, err := toml.DecodeFile(path, &legacyOrder); err != nil {
return nil, errors.Wrap(err, "decoding legacy order config")
}

return fromLegacy(legacyOrder, buildpacksDir)
}

func fromLegacy(legacyOrder orderConfig, buildpacksDir string) (lifecycle.BuildpackOrder, error) {
var order lifecycle.BuildpackOrder
for _, legacyGroup := range legacyOrder.Groups {
var bps []lifecycle.Buildpack
for _, legacyBuildpack := range legacyGroup.Buildpacks {
version, err := resolveVersion(legacyBuildpack, buildpacksDir)
if err != nil {
return nil, err
}
bps = append(bps, lifecycle.Buildpack{
ID: legacyBuildpack.ID,
Version: version,
Optional: legacyBuildpack.Optional,
})
}
order = append(order, lifecycle.BuildpackGroup{
Group: bps,
})
}
return order, nil
}

type buildpackTOML struct {
Buildpacks []buildpack `toml:"buildpacks"`
}

type buildpack struct {
ID string `toml:"id"`
Version string `toml:"version"`
}

func resolveVersion(bpRef buildpackRefConfig, buildpacksDir string) (string, error) {
if bpRef.Version != "latest" {
return bpRef.Version, nil
}

bpDir, err := filepath.Abs(filepath.Join(buildpacksDir, bpRef.dir()))
if err != nil {
return "", err
}

tomlPaths, err := filepath.Glob(path.Join(bpDir, "*", "buildpack.toml"))
if err != nil {
return "", err
}

var matchVersions []string
for _, tomlPath := range tomlPaths {
bpTOML := buildpackTOML{}
if _, err := toml.DecodeFile(tomlPath, &bpTOML); err != nil {
return "", err
}

for _, bp := range bpTOML.Buildpacks {
if bp.ID == bpRef.ID {
matchVersions = append(matchVersions, bp.Version)
}
}
}

if len(matchVersions) == 0 {
return "", errors.Errorf("no buildpacks with matching ID '%s'", bpRef.ID)
}

if len(matchVersions) > 1 {
return "", errors.Errorf("too many buildpacks with matching ID '%s'", bpRef.ID)
}

return matchVersions[0], nil
}
96 changes: 96 additions & 0 deletions compat/compat_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package compat_test

import (
"path/filepath"
"testing"

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

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

func TestCompat(t *testing.T) {
spec.Run(t, "testCompat", testCompat, spec.Parallel(), spec.Report(report.Terminal{}))
}

func testCompat(t *testing.T, when spec.G, it spec.S) {
when("#ReadOrder", func() {
when("order toml is v1", func() {
it("should parse groups", func() {
order, err := compat.ReadOrder(filepath.Join("testdata", "v1.order.toml"), filepath.Join("testdata", "buildpacks"))
h.AssertNil(t, err)
h.AssertEq(t, order, lifecycle.BuildpackOrder{
{
Group: []lifecycle.Buildpack{
{
ID: "buildpack.a",
Version: "buildpack.a.v1",
Optional: false,
},
{
ID: "buildpack.b",
Version: "buildpack.b.v1",
Optional: true,
},
},
},
{
Group: []lifecycle.Buildpack{
{
ID: "buildpack.c",
Version: "buildpack.c.v1",
Optional: false,
},
},
},
})
})

when("buildpack version latest", func() {
when("single matching buildpack", func() {
it("should resolve version", func() {
order, err := compat.ReadOrder(filepath.Join("testdata", "v1.order.single.toml"), filepath.Join("testdata", "buildpacks"))
h.AssertNil(t, err)
h.AssertEq(t, order, lifecycle.BuildpackOrder{
{
Group: []lifecycle.Buildpack{
{
ID: "buildpack.single",
Version: "buildpack.single.v1",
Optional: false,
},
},
},
})
})
})

when("multiple matching buildpacks", func() {
it("should error out", func() {
_, err := compat.ReadOrder(filepath.Join("testdata", "v1.order.dup.toml"), filepath.Join("testdata", "buildpacks"))
h.AssertError(t, err, "too many buildpacks with matching ID 'buildpack.dup'")
})
})

when("no matching buildpacks", func() {
it("should error out", func() {
_, err := compat.ReadOrder(filepath.Join("testdata", "v1.order.nonexistent.toml"), filepath.Join("testdata", "buildpacks"))
h.AssertError(t, err, "no buildpacks with matching ID 'buildpack.nonexistent'")

})
})
})
})

when("order toml is not v1 format", func() {
it("should return empty order", func() {
order, err := compat.ReadOrder(filepath.Join("testdata", "v2.order.toml"), "")
h.AssertNil(t, err)
h.AssertEq(t, len(order), 0)
})
})
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[[buildpacks]]
id = "buildpack.dup"
version = "buildpack.dup.v1"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[[buildpacks]]
id = "buildpack.dup"
version = "buildpack.dup.v2"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[[buildpacks]]
id = "buildpack.single"
version = "buildpack.single.v1"
4 changes: 4 additions & 0 deletions compat/testdata/v1.order.dup.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[[groups]]
[[groups.buildpacks]]
id = "buildpack.dup"
version = "latest"
4 changes: 4 additions & 0 deletions compat/testdata/v1.order.nonexistent.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[[groups]]
[[groups.buildpacks]]
id = "buildpack.nonexistent"
version = "latest"
4 changes: 4 additions & 0 deletions compat/testdata/v1.order.single.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[[groups]]
[[groups.buildpacks]]
id = "buildpack.single"
version = "latest"
15 changes: 15 additions & 0 deletions compat/testdata/v1.order.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[[groups]]
[[groups.buildpacks]]
id = "buildpack.a"
version = "buildpack.a.v1"

[[groups.buildpacks]]
id = "buildpack.b"
version = "buildpack.b.v1"
optional = true

[[groups]]
[[groups.buildpacks]]
id = "buildpack.c"
version = "buildpack.c.v1"
optional = false
5 changes: 5 additions & 0 deletions compat/testdata/v2.order.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[[order]]
[[order.group]]
id = "buildpack.a"
version = "buildpack.a.v1"
optional = false

0 comments on commit 160af39

Please sign in to comment.