Skip to content

Commit

Permalink
Merge pull request #90 from paketo-buildpacks/update-updaters
Browse files Browse the repository at this point in the history
Stop using regex to update dependencies in builder.toml, package.toml, and buildpack.toml
  • Loading branch information
Daniel Mikusa authored Oct 4, 2021
2 parents 755dae2 + 78f10e6 commit eb2c8cb
Show file tree
Hide file tree
Showing 5 changed files with 333 additions and 106 deletions.
86 changes: 78 additions & 8 deletions carton/buildpack_dependency.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@
package carton

import (
"bytes"
"fmt"
"io/ioutil"
"os"
"regexp"

"github.com/paketo-buildpacks/libpak/bard"
"github.com/paketo-buildpacks/libpak/internal"
"github.com/pelletier/go-toml"
)

const (
Expand Down Expand Up @@ -55,26 +57,94 @@ func (b BuildpackDependency) Update(options ...Option) {
logger.Headerf("URI: %s", b.URI)
logger.Headerf("SHA256: %s", b.SHA256)

versionExp, err := regexp.Compile(b.VersionPattern)
if err != nil {
config.exitHandler.Error(fmt.Errorf("unable to compile regex %s\n%w", b.VersionPattern, err))
return
}

c, err := ioutil.ReadFile(b.BuildpackPath)
if err != nil {
config.exitHandler.Error(fmt.Errorf("unable to read %s\n%w", b.BuildpackPath, err))
return
}

s := fmt.Sprintf(BuildpackDependencyPattern, b.ID, b.VersionPattern)
r, err := regexp.Compile(s)
if err != nil {
config.exitHandler.Error(fmt.Errorf("unable to compile regex %s\n%w", s, err))
// save any leading comments, this is to preserve license headers
// inline comments will be lost
comments := []byte{}
for i, line := range bytes.SplitAfter(c, []byte("\n")) {
if bytes.HasPrefix(line, []byte("#")) || (i > 0 && len(bytes.TrimSpace(line)) == 0) {
comments = append(comments, line...)
} else {
break // stop on first comment
}
}

md := make(map[string]interface{})
if err := toml.Unmarshal(c, &md); err != nil {
config.exitHandler.Error(fmt.Errorf("unable to decode md%s\n%w", b.BuildpackPath, err))
return
}

metadataUnwrapped, found := md["metadata"]
if !found {
config.exitHandler.Error(fmt.Errorf("unable to find metadata block"))
return
}

metadata, ok := metadataUnwrapped.(map[string]interface{})
if !ok {
config.exitHandler.Error(fmt.Errorf("unable to cast metadata"))
return
}

dependenciesUnwrapped, found := metadata["dependencies"]
if !found {
config.exitHandler.Error(fmt.Errorf("unable to find dependencies block"))
return
}

dependencies, ok := dependenciesUnwrapped.([]map[string]interface{})
if !ok {
config.exitHandler.Error(fmt.Errorf("unable to cast dependencies"))
return
}

if !r.Match(c) {
config.exitHandler.Error(fmt.Errorf("unable to match '%s' '%s'", b.ID, b.VersionPattern))
for _, dep := range dependencies {
depIdUnwrapped, found := dep["id"]
if !found {
continue
}
depId, ok := depIdUnwrapped.(string)
if !ok {
continue
}

if depId == b.ID {
depVersionUnwrapped, found := dep["version"]
if !found {
continue
}

depVersion, ok := depVersionUnwrapped.(string)
if !ok {
continue
}
if versionExp.MatchString(depVersion) {
dep["version"] = b.Version
dep["uri"] = b.URI
dep["sha256"] = b.SHA256
}
}
}

c, err = toml.Marshal(md)
if err != nil {
config.exitHandler.Error(fmt.Errorf("unable to encode md %s\n%w", b.BuildpackPath, err))
return
}

s = fmt.Sprintf(BuildpackDependencySubstitution, b.Version, b.URI, b.SHA256)
c = r.ReplaceAll(c, []byte(s))
c = append(comments, c...)

if err := ioutil.WriteFile(b.BuildpackPath, c, 0644); err != nil {
config.exitHandler.Error(fmt.Errorf("unable to write %s\n%w", b.BuildpackPath, err))
Expand Down
52 changes: 45 additions & 7 deletions carton/buildpack_dependency_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/stretchr/testify/mock"

"github.com/paketo-buildpacks/libpak/carton"
"github.com/paketo-buildpacks/libpak/internal"
)

func testBuildpackDependency(t *testing.T, context spec.G, it spec.S) {
Expand Down Expand Up @@ -54,7 +55,14 @@ func testBuildpackDependency(t *testing.T, context spec.G, it spec.S) {
})

it("updates dependency", func() {
Expect(ioutil.WriteFile(path, []byte(`id = "test-id"
Expect(ioutil.WriteFile(path, []byte(`api = "0.6"
[buildpack]
id = "some-buildpack"
name = "Some Buildpack"
version = "1.2.3"
[[metadata.dependencies]]
id = "test-id"
name = "Test Name"
version = "test-version-1"
uri = "test-uri-1"
Expand All @@ -73,17 +81,34 @@ stacks = [ "test-stack" ]

d.Update(carton.WithExitHandler(exitHandler))

Expect(ioutil.ReadFile(path)).To(Equal([]byte(`id = "test-id"
Expect(ioutil.ReadFile(path)).To(internal.MatchTOML(`api = "0.6"
[buildpack]
id = "some-buildpack"
name = "Some Buildpack"
version = "1.2.3"
[[metadata.dependencies]]id = "test-id"
name = "Test Name"
version = "test-version-2"
uri = "test-uri-2"
sha256 = "test-sha256-2"
stacks = [ "test-stack" ]
`)))
`))
})

it("updates indented dependency", func() {
Expect(ioutil.WriteFile(path, []byte(` id = "test-id"
Expect(ioutil.WriteFile(path, []byte(`# it should preserve
# these comments
# exactly
api = "0.6"
[buildpack]
id = "some-buildpack"
name = "Some Buildpack"
version = "1.2.3"
[[metadata.dependencies]]
id = "test-id"
name = "Test Name"
version = "test-version-1"
uri = "test-uri-1"
Expand All @@ -102,13 +127,26 @@ stacks = [ "test-stack" ]

d.Update(carton.WithExitHandler(exitHandler))

Expect(ioutil.ReadFile(path)).To(Equal([]byte(` id = "test-id"
body, err := ioutil.ReadFile(path)
Expect(err).NotTo(HaveOccurred())
Expect(string(body)).To(HavePrefix(`# it should preserve
# these comments
# exactly
api = "0.6"`))
Expect(body).To(internal.MatchTOML(`api = "0.6"
[buildpack]
id = "some-buildpack"
name = "Some Buildpack"
version = "1.2.3"
[[metadata.dependencies]]
id = "test-id"
name = "Test Name"
version = "test-version-2"
uri = "test-uri-2"
sha256 = "test-sha256-2"
stacks = [ "test-stack" ]
`)))
`))
})

}
2 changes: 1 addition & 1 deletion carton/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ func (p Package) Create(options ...Option) {
}

var files []string
for d, _ := range entries {
for d := range entries {
files = append(files, d)
}
sort.Strings(files)
Expand Down
Loading

0 comments on commit eb2c8cb

Please sign in to comment.