Merge pull request #16023 from hashicorp/jbardin/update-go-getter

update go-getter
This commit is contained in:
James Bardin 2017-09-05 18:11:39 -04:00 committed by GitHub
commit 19f9d1c93a
7 changed files with 107 additions and 6 deletions

View File

@ -119,6 +119,37 @@ The protocol-specific options are documented below the URL format
section. But because they are part of the URL, we point it out here so
you know they exist.
### Subdirectories
If you want to download only a specific subdirectory from a downloaded
directory, you can specify a subdirectory after a double-slash `//`.
go-getter will first download the URL specified _before_ the double-slash
(as if you didn't specify a double-slash), but will then copy the
path after the double slash into the target directory.
For example, if you're downloading this GitHub repository, but you only
want to download the `test-fixtures` directory, you can do the following:
```
https://github.com/hashicorp/go-getter.git//test-fixtures
```
If you downloaded this to the `/tmp` directory, then the file
`/tmp/archive.gz` would exist. Notice that this file is in the `test-fixtures`
directory in this repository, but because we specified a subdirectory,
go-getter automatically copied only that directory contents.
Subdirectory paths may contain may also use filesystem glob patterns.
The path must match _exactly one_ entry or go-getter will return an error.
This is useful if you're not sure the exact directory name but it follows
a predictable naming structure.
For example, the following URL would also work:
```
https://github.com/hashicorp/go-getter.git//test-*
```
### Checksumming
For file downloads of any protocol, go-getter can automatically verify

View File

@ -305,7 +305,13 @@ func (c *Client) Get() error {
return err
}
return copyDir(realDst, filepath.Join(dst, subDir), false)
// Process any globs
subDir, err := SubdirGlob(dst, subDir)
if err != nil {
return err
}
return copyDir(realDst, subDir, false)
}
return nil

View File

@ -27,6 +27,11 @@ func untar(input io.Reader, dst, src string, dir bool) error {
return err
}
if hdr.Typeflag == tar.TypeXGlobalHeader || hdr.Typeflag == tar.TypeXHeader {
// don't unpack extended headers as files
continue
}
path := dst
if dir {
path = filepath.Join(path, hdr.Name)
@ -81,3 +86,27 @@ func untar(input io.Reader, dst, src string, dir bool) error {
}
}
}
// tarDecompressor is an implementation of Decompressor that can
// unpack tar files.
type tarDecompressor struct{}
func (d *tarDecompressor) Decompress(dst, src string, dir bool) error {
// If we're going into a directory we should make that first
mkdir := dst
if !dir {
mkdir = filepath.Dir(dst)
}
if err := os.MkdirAll(mkdir, 0755); err != nil {
return err
}
// File first
f, err := os.Open(src)
if err != nil {
return err
}
defer f.Close()
return untar(f, dst, src, dir)
}

View File

@ -72,12 +72,18 @@ func Detect(src string, pwd string, ds []Detector) (string, error) {
subDir = detectSubdir
}
}
if subDir != "" {
u, err := url.Parse(result)
if err != nil {
return "", fmt.Errorf("Error parsing URL: %s", err)
}
u.Path += "//" + subDir
// a subdir may contain wildcards, but in order to support them we
// have to ensure the path isn't escaped.
u.RawPath = u.Path
result = u.String()
}

View File

@ -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 {
@ -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)

View File

@ -1,6 +1,8 @@
package getter
import (
"fmt"
"path/filepath"
"strings"
)
@ -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
}

6
vendor/vendor.json vendored
View File

@ -1369,10 +1369,10 @@
"revisionTime": "2017-02-11T01:34:15Z"
},
{
"checksumSHA1": "Glhu9BTy826XCLfMw7rexQ5mKeY=",
"checksumSHA1": "cw5fzHNCbc3zVjNRnP1pm5tt5rk=",
"path": "github.com/hashicorp/go-getter",
"revision": "6aae8e4e2dee8131187c6a54b52664796e5a02b0",
"revisionTime": "2017-07-13T01:23:01Z"
"revision": "ee320eed76420de7fa4395de568552c63fe9115e",
"revisionTime": "2017-09-05T20:45:58Z"
},
{
"checksumSHA1": "9J+kDr29yDrwsdu2ULzewmqGjpA=",