diff --git a/targz.go b/targz.go index d5c624b5..ebaaa366 100644 --- a/targz.go +++ b/targz.go @@ -76,17 +76,18 @@ func tarGzFile(tarWriter *tar.Writer, source string) error { return nil } - file, err := os.Open(path) - if err != nil { - return fmt.Errorf("%s: open: %v", path, err) + if header.Typeflag == tar.TypeReg { + file, err := os.Open(path) + if err != nil { + return fmt.Errorf("%s: open: %v", path, err) + } + defer file.Close() + + _, err = io.Copy(tarWriter, file) + if err != nil { + return fmt.Errorf("%s: copying contents: %v", path, err) + } } - defer file.Close() - - _, err = io.Copy(tarWriter, file) - if err != nil { - return fmt.Errorf("%s: copying contents: %v", path, err) - } - return nil }) } @@ -128,7 +129,9 @@ func untarGzFile(tr *tar.Reader, header *tar.Header, destination string) error { case tar.TypeDir: return mkdir(filepath.Join(destination, header.Name)) case tar.TypeReg: - return writeNewFile(filepath.Join(destination, header.Name), tr) + return writeNewFile(filepath.Join(destination, header.Name), tr, header.FileInfo().Mode()) + case tar.TypeSymlink: + return writeNewSymbolicLink(filepath.Join(destination, header.Name), header.Linkname) default: return fmt.Errorf("%s: unknown type flag: %c", header.Name, header.Typeflag) } diff --git a/zip.go b/zip.go index 27f80c99..e78c5203 100644 --- a/zip.go +++ b/zip.go @@ -8,6 +8,7 @@ import ( "os" "path" "path/filepath" + "runtime" "strings" ) @@ -84,15 +85,17 @@ func zipFile(w *zip.Writer, source string) error { return nil } - file, err := os.Open(fpath) - if err != nil { - return fmt.Errorf("%s: opening: %v", fpath, err) - } - defer file.Close() + if header.Mode().IsRegular() { + file, err := os.Open(fpath) + if err != nil { + return fmt.Errorf("%s: opening: %v", fpath, err) + } + defer file.Close() - _, err = io.Copy(writer, file) - if err != nil { - return fmt.Errorf("%s: copying contents: %v", fpath, err) + _, err = io.Copy(writer, file) + if err != nil { + return fmt.Errorf("%s: copying contents: %v", fpath, err) + } } return nil @@ -127,10 +130,10 @@ func unzipFile(zf *zip.File, destination string) error { } defer rc.Close() - return writeNewFile(filepath.Join(destination, zf.Name), rc) + return writeNewFile(filepath.Join(destination, zf.Name), rc, zf.FileInfo().Mode()) } -func writeNewFile(fpath string, in io.Reader) error { +func writeNewFile(fpath string, in io.Reader, fm os.FileMode) error { err := os.MkdirAll(path.Dir(fpath), 0755) if err != nil { return fmt.Errorf("%s: making directory for file: %v", fpath, err) @@ -142,6 +145,11 @@ func writeNewFile(fpath string, in io.Reader) error { } defer out.Close() + err = out.Chmod(fm) + if err != nil && runtime.GOOS != "windows" { + return fmt.Errorf("%s: changing file mode: %v", fpath, err) + } + _, err = io.Copy(out, in) if err != nil { return fmt.Errorf("%s: writing file: %v", fpath, err) @@ -149,6 +157,20 @@ func writeNewFile(fpath string, in io.Reader) error { return nil } +func writeNewSymbolicLink(fpath string, target string) error { + err := os.MkdirAll(path.Dir(fpath), 0755) + if err != nil { + return fmt.Errorf("%s: making directory for file: %v", fpath, err) + } + + err = os.Symlink(target, fpath) + if err != nil { + return fmt.Errorf("%s: making symbolic link for: %v", fpath, err) + } + + return nil +} + func mkdir(dirPath string) error { err := os.Mkdir(dirPath, 0755) if err != nil { diff --git a/zip_test.go b/zip_test.go index 927c8663..3a1aa862 100644 --- a/zip_test.go +++ b/zip_test.go @@ -65,17 +65,29 @@ func symmetricTest(t *testing.T, ext string, cf CompressFunc, dcf DecompressFunc return nil } + expectedFileInfo, err := os.Stat(origPath) + if err != nil { + t.Fatalf("%s: Error obtaining original file info: %v", fpath, err) + } expected, err := ioutil.ReadFile(origPath) if err != nil { t.Fatalf("%s: Couldn't open original file (%s) from disk: %v", fpath, origPath, err) } + actualFileInfo, err := os.Stat(fpath) + if err != nil { + t.Fatalf("%s: Error obtaining actual file info: %v", fpath, err) + } actual, err := ioutil.ReadFile(fpath) if err != nil { t.Fatalf("%s: Couldn't open new file from disk: %v", fpath, err) } + if actualFileInfo.Mode() != expectedFileInfo.Mode() { + t.Fatalf("%s: File mode differed between on disk and compressed", + expectedFileInfo.Mode().String()+" : "+actualFileInfo.Mode().String()) + } if !bytes.Equal(expected, actual) { t.Fatalf("%s: File contents differed between on disk and compressed", origPath) }