Skip to content

Commit

Permalink
Implement file:// downloads for artifacts
Browse files Browse the repository at this point in the history
This can be used with dependency mapping bindings to volume mount in external pre-cached artifacts.

Signed-off-by: Daniel Mikusa <[email protected]>
  • Loading branch information
Daniel Mikusa committed Aug 17, 2021
1 parent f35c763 commit 0e35505
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 1 deletion.
38 changes: 38 additions & 0 deletions dependency_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"io"
"io/ioutil"
"net/http"
"net/url"
"os"
"path/filepath"
"reflect"
Expand Down Expand Up @@ -187,6 +188,43 @@ func (d *DependencyCache) Artifact(dependency BuildpackDependency, mods ...Reque
}

func (d DependencyCache) download(uri string, destination string, mods ...RequestModifierFunc) error {
url, err := url.Parse(uri)
if err != nil {
return fmt.Errorf("unable to parse URI %s\n%w", uri, err)
}

if url.Scheme == "file" {
return d.downloadFile(url.Path, destination, mods...)
}

return d.downloadHttp(uri, destination, mods...)
}

func (d DependencyCache) downloadFile(source string, destination string, mods ...RequestModifierFunc) error {
if err := os.MkdirAll(filepath.Dir(destination), 0755); err != nil {
return fmt.Errorf("unable to make directory %s\n%w", filepath.Dir(destination), err)
}

out, err := os.OpenFile(destination, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
if err != nil {
return fmt.Errorf("unable to open destination file %s\n%w", destination, err)
}
defer out.Close()

input, err := os.Open(source)
if err != nil {
return fmt.Errorf("unable to open source file %s\n%w", source, err)
}
defer out.Close()

if _, err := io.Copy(out, input); err != nil {
return fmt.Errorf("unable to copy from %s to %s\n%w", source, destination, err)
}

return nil
}

func (d DependencyCache) downloadHttp(uri string, destination string, mods ...RequestModifierFunc) error {
req, err := http.NewRequest("GET", uri, nil)
if err != nil {
return fmt.Errorf("unable to create new GET request for %s\n%w", uri, err)
Expand Down
22 changes: 21 additions & 1 deletion dependency_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ func testDependencyCache(t *testing.T, context spec.G, it spec.S) {
Expect(ioutil.ReadAll(a)).To(Equal([]byte("test-fixture")))
})

context("uri is overridden", func() {
context("uri is overridden HTTP", func() {
it.Before(func() {
dependencyCache.Mappings = map[string]string{
dependency.SHA256: fmt.Sprintf("%s/override-path", server.URL()),
Expand All @@ -243,6 +243,26 @@ func testDependencyCache(t *testing.T, context spec.G, it spec.S) {
})
})

context("uri is overridden FILE", func() {
it.Before(func() {
sourcePath, err := ioutil.TempDir("", "dependency-source-path")
Expect(err).NotTo(HaveOccurred())
sourceFile := filepath.Join(sourcePath, "source-file")
Expect(ioutil.WriteFile(sourceFile, []byte("test-fixture"), 0644)).ToNot(HaveOccurred())

dependencyCache.Mappings = map[string]string{
dependency.SHA256: fmt.Sprintf("file://%s", sourceFile),
}
})

it("downloads from override filesystem", func() {
a, err := dependencyCache.Artifact(dependency)
Expect(err).NotTo(HaveOccurred())

Expect(ioutil.ReadAll(a)).To(Equal([]byte("test-fixture")))
})
})

it("fails with invalid SHA256", func() {
server.AppendHandlers(ghttp.RespondWith(http.StatusOK, "invalid-fixture"))

Expand Down

0 comments on commit 0e35505

Please sign in to comment.