Skip to content

Commit

Permalink
Fix HTTP getter subdir paths to work properly
Browse files Browse the repository at this point in the history
The tests were actually turning `foo//bar` into `foo/bar` so we have
_never_ tested subdir access with HTTP. Turns out, it never worked!
There was a bug that caused it to never work. This fixes that bug, adds
more tests, and verifies globbing works, too.
  • Loading branch information
mitchellh committed Sep 2, 2017
1 parent ed2b33b commit dd54fc3
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 12 deletions.
12 changes: 2 additions & 10 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,19 +305,11 @@ func (c *Client) Get() error {
return err
}

// Subdir matching supports globs. This allows matching unknown
// subdirectory structures but where we know the general path.
// For example, for archives that have a root folder containing
// all the items, you can download it with the getter URL of:
// 'path//*'.
matches, err := filepath.Glob(filepath.Join(dst, subDir))
// Process any globs
subDir, err := SubdirGlob(dst, subDir)
if err != nil {
return err
}
if len(matches) > 1 {
return fmt.Errorf("subdir %q matches multiple paths", subDir)
}
subDir = matches[0]

return copyDir(realDst, subDir, false)
}
Expand Down
12 changes: 10 additions & 2 deletions get_http.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ func (g *HttpGetter) Get(dst string, u *url.URL) error {
}

func (g *HttpGetter) GetFile(dst string, u *url.URL) error {

if g.Netrc {
// Add auth from netrc if we can
if err := addAuthFromNetrc(u); err != nil {
Expand Down Expand Up @@ -140,13 +139,22 @@ func (g *HttpGetter) getSubdir(dst, source, subDir string) error {
}
defer os.RemoveAll(td)

// We have to create a subdirectory that doesn't exist for the file
// getter to work.
td = filepath.Join(td, "data")

// Download that into the given directory
if err := Get(td, source); err != nil {
return err
}

// Process any globbing
sourcePath, err := SubdirGlob(td, subDir)
if err != nil {
return err
}

// Make sure the subdir path actually exists
sourcePath := filepath.Join(td, subDir)
if _, err := os.Stat(sourcePath); err != nil {
return fmt.Errorf(
"Error downloading %s: %s", source, err)
Expand Down
29 changes: 29 additions & 0 deletions get_http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,30 @@ func TestHttpGetter_metaSubdir(t *testing.T) {
}
}

func TestHttpGetter_metaSubdirGlob(t *testing.T) {
ln := testHttpServer(t)
defer ln.Close()

g := new(HttpGetter)
dst := tempDir(t)

var u url.URL
u.Scheme = "http"
u.Host = ln.Addr().String()
u.Path = "/meta-subdir-glob"

// Get it!
if err := g.Get(dst, &u); err != nil {
t.Fatalf("err: %s", err)
}

// Verify the main file exists
mainPath := filepath.Join(dst, "sub.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}

func TestHttpGetter_none(t *testing.T) {
ln := testHttpServer(t)
defer ln.Close()
Expand Down Expand Up @@ -194,6 +218,7 @@ func testHttpServer(t *testing.T) net.Listener {
mux.HandleFunc("/meta", testHttpHandlerMeta)
mux.HandleFunc("/meta-auth", testHttpHandlerMetaAuth)
mux.HandleFunc("/meta-subdir", testHttpHandlerMetaSubdir)
mux.HandleFunc("/meta-subdir-glob", testHttpHandlerMetaSubdirGlob)

var server http.Server
server.Handler = mux
Expand Down Expand Up @@ -234,6 +259,10 @@ func testHttpHandlerMetaSubdir(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(fmt.Sprintf(testHttpMetaStr, testModuleURL("basic//subdir").String())))
}

func testHttpHandlerMetaSubdirGlob(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(fmt.Sprintf(testHttpMetaStr, testModuleURL("basic//sub*").String())))
}

func testHttpHandlerNone(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(testHttpNoneStr))
}
Expand Down
5 changes: 5 additions & 0 deletions module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,15 @@ func testModule(n string) string {
}

func testModuleURL(n string) *url.URL {
n, subDir := SourceDirSubdir(n)
u, err := urlhelper.Parse(testModule(n))
if err != nil {
panic(err)
}
if subDir != "" {
u.Path += "//" + subDir
u.RawPath = u.Path
}

return u
}
Expand Down
21 changes: 21 additions & 0 deletions source.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package getter

import (
"fmt"
"path/filepath"
"strings"
)

Expand Down Expand Up @@ -34,3 +36,22 @@ func SourceDirSubdir(src string) (string, string) {

return src, subdir
}

// SubdirGlob returns the actual subdir with globbing processed.
//
// dst should be a destination directory that is already populated (the
// download is complete) and subDir should be the set subDir. If subDir
// is an empty string, this returns an empty string.
//
// The returned path is the full absolute path.
func SubdirGlob(dst, subDir string) (string, error) {
matches, err := filepath.Glob(filepath.Join(dst, subDir))
if err != nil {
return "", err
}
if len(matches) > 1 {
return "", fmt.Errorf("subdir %q matches multiple paths", subDir)
}

return matches[0], nil
}

0 comments on commit dd54fc3

Please sign in to comment.