diff options
Diffstat (limited to 'archive/archive.go')
-rw-r--r-- | archive/archive.go | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/archive/archive.go b/archive/archive.go index 1982218b46..2ba62f5363 100644 --- a/archive/archive.go +++ b/archive/archive.go @@ -27,6 +27,7 @@ type ( Compression int TarOptions struct { Includes []string + Excludes []string Compression Compression NoLchown bool } @@ -43,6 +44,16 @@ const ( Xz ) +func IsArchive(header []byte) bool { + compression := DetectCompression(header) + if compression != Uncompressed { + return true + } + r := tar.NewReader(bytes.NewBuffer(header)) + _, err := r.Next() + return err == nil +} + func DetectCompression(source []byte) Compression { for compression, m := range map[Compression][]byte{ Bzip2: {0x42, 0x5A, 0x68}, @@ -276,7 +287,7 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L // Tar creates an archive from the directory at `path`, and returns it as a // stream of bytes. func Tar(path string, compression Compression) (io.ReadCloser, error) { - return TarFilter(path, &TarOptions{Compression: compression}) + return TarWithOptions(path, &TarOptions{Compression: compression}) } func escapeName(name string) string { @@ -295,12 +306,9 @@ func escapeName(name string) string { return string(escaped) } -// TarFilter creates an archive from the directory at `srcPath` with `options`, and returns it as a -// stream of bytes. -// -// Files are included according to `options.Includes`, default to including all files. -// Stream is compressed according to `options.Compression', default to Uncompressed. -func TarFilter(srcPath string, options *TarOptions) (io.ReadCloser, error) { +// TarWithOptions creates an archive from the directory at `path`, only including files whose relative +// paths are included in `options.Includes` (if non-nil) or not in `options.Excludes`. +func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) { pipeReader, pipeWriter := io.Pipe() compressWriter, err := CompressStream(pipeWriter, options.Compression) @@ -332,6 +340,21 @@ func TarFilter(srcPath string, options *TarOptions) (io.ReadCloser, error) { return nil } + for _, exclude := range options.Excludes { + matched, err := filepath.Match(exclude, relFilePath) + if err != nil { + utils.Errorf("Error matching: %s (pattern: %s)", relFilePath, exclude) + return err + } + if matched { + utils.Debugf("Skipping excluded path: %s", relFilePath) + if f.IsDir() { + return filepath.SkipDir + } + return nil + } + } + if err := addTarFile(filePath, relFilePath, tw); err != nil { utils.Debugf("Can't add file %s to tar: %s\n", srcPath, err) } @@ -443,7 +466,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { // TarUntar aborts and returns the error. func TarUntar(src string, dst string) error { utils.Debugf("TarUntar(%s %s)", src, dst) - archive, err := TarFilter(src, &TarOptions{Compression: Uncompressed}) + archive, err := TarWithOptions(src, &TarOptions{Compression: Uncompressed}) if err != nil { return err } |