Merge pull request #6740 from tiborvass/untar_allow_overwrite

Allow overwrite in archive.Untar
This commit is contained in:
Michael Crosby 2014-06-27 14:15:47 -07:00
commit e5d3aa2765
2 changed files with 12 additions and 6 deletions

View File

@ -383,7 +383,8 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
// identity (uncompressed), gzip, bzip2, xz. // identity (uncompressed), gzip, bzip2, xz.
// If `dest` does not exist, it is created unless there are multiple entries in `archive`. // If `dest` does not exist, it is created unless there are multiple entries in `archive`.
// In the latter case, an error is returned. // In the latter case, an error is returned.
// An other error is returned if `dest` exists but is not a directory, to prevent overwriting. // If `dest` is an existing file, it gets overwritten.
// If `dest` is an existing directory, its files get merged (with overwrite for conflicting files).
func Untar(archive io.Reader, dest string, options *TarOptions) error { func Untar(archive io.Reader, dest string, options *TarOptions) error {
if archive == nil { if archive == nil {
return fmt.Errorf("Empty archive") return fmt.Errorf("Empty archive")
@ -399,7 +400,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error {
var ( var (
dirs []*tar.Header dirs []*tar.Header
destNotExist bool create bool
multipleEntries bool multipleEntries bool
) )
@ -408,9 +409,10 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error {
return err return err
} }
// destination does not exist, so it is assumed it has to be created. // destination does not exist, so it is assumed it has to be created.
destNotExist = true create = true
} else if !fi.IsDir() { } else if !fi.IsDir() {
return fmt.Errorf("Trying to untar to `%s`: exists but not a directory", dest) // destination exists and is not a directory, so it will be overwritten.
create = true
} }
// Iterate through the files in the archive. // Iterate through the files in the archive.
@ -425,7 +427,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error {
} }
// Return an error if destination needs to be created and there is more than 1 entry in the tar stream. // Return an error if destination needs to be created and there is more than 1 entry in the tar stream.
if destNotExist && multipleEntries { if create && multipleEntries {
return fmt.Errorf("Trying to untar an archive with multiple entries to an inexistant target `%s`: did you mean `%s` instead?", dest, filepath.Dir(dest)) return fmt.Errorf("Trying to untar an archive with multiple entries to an inexistant target `%s`: did you mean `%s` instead?", dest, filepath.Dir(dest))
} }
@ -445,7 +447,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error {
} }
var path string var path string
if destNotExist { if create {
path = dest // we are renaming hdr.Name to dest path = dest // we are renaming hdr.Name to dest
} else { } else {
path = filepath.Join(dest, hdr.Name) path = filepath.Join(dest, hdr.Name)
@ -465,6 +467,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error {
} }
} }
} }
if err := createTarFile(path, dest, hdr, tr, options == nil || !options.NoLchown); err != nil { if err := createTarFile(path, dest, hdr, tr, options == nil || !options.NoLchown); err != nil {
return err return err
} }

View File

@ -176,6 +176,9 @@ func TestTarUntarFile(t *testing.T) {
if err := ioutil.WriteFile(path.Join(origin, "before", "file"), []byte("hello world"), 0700); err != nil { if err := ioutil.WriteFile(path.Join(origin, "before", "file"), []byte("hello world"), 0700); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err := ioutil.WriteFile(path.Join(origin, "after", "file2"), []byte("please overwrite me"), 0700); err != nil {
t.Fatal(err)
}
tar, err := TarWithOptions(path.Join(origin, "before"), &TarOptions{Compression: Uncompressed, Includes: []string{"file"}}) tar, err := TarWithOptions(path.Join(origin, "before"), &TarOptions{Compression: Uncompressed, Includes: []string{"file"}})
if err != nil { if err != nil {