0
0
Fork 0
mirror of https://github.com/schollz/croc.git synced 2025-10-11 13:21:00 +02:00

minor zip fixes

Allows multiple zips.

Need to close file after zipping it.
This commit is contained in:
Zack Scholl 2018-10-24 06:42:27 -07:00
parent fea07cab6c
commit 0ca74b010e
2 changed files with 148 additions and 98 deletions

View file

@ -3,6 +3,7 @@ package zipper
import ( import (
"archive/zip" "archive/zip"
"compress/flate" "compress/flate"
"fmt"
"io" "io"
"os" "os"
"path" "path"
@ -77,28 +78,39 @@ func UnzipFile(src, dest string) (err error) {
return return
} }
// ZipFile will zip the folder // ZipFiles will zip all the files and the folders as if they were in the same directory
func ZipFile(fname string, compress bool) (writtenFilename string, err error) { func ZipFiles(fnames []string, compress bool) (writtenFilename string, err error) {
logger.SetLogLevel(DebugLevel) logger.SetLogLevel(DebugLevel)
log.Debugf("zipping %s with compression? %v", fname, compress) if len(fnames) == 0 {
err = fmt.Errorf("must provide files to zip")
// get absolute filename
fname, err = filepath.Abs(fname)
if err != nil {
log.Error(err)
return return
} }
// get path to file and the filename log.Debugf("zipping %s with compression? %v", fnames, compress)
fpath, fname := filepath.Split(fname) writtenFilename = fmt.Sprintf("%d_files.croc.zip", len(fnames))
err = makeZip(writtenFilename, fnames, compress)
return
}
writtenFilename = fname + ".croc.zip" // ZipFile will zip the folder
func ZipFile(fname string, compress bool) (writtenFilename string, err error) {
logger.SetLogLevel(DebugLevel)
// get path to file and the filename
_, filename := filepath.Split(fname)
writtenFilename = filename + ".croc.zip"
err = makeZip(writtenFilename, []string{fname}, compress)
return
}
func makeZip(writtenFilename string, fnames []string, compress bool) (err error) {
log.Debugf("creating file: %s", writtenFilename) log.Debugf("creating file: %s", writtenFilename)
f, err := os.Create(writtenFilename) f, err := os.Create(writtenFilename)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
return return
} }
defer f.Close()
zipWriter := zip.NewWriter(f) zipWriter := zip.NewWriter(f)
zipWriter.RegisterCompressor(zip.Deflate, func(out io.Writer) (io.WriteCloser, error) { zipWriter.RegisterCompressor(zip.Deflate, func(out io.Writer) (io.WriteCloser, error) {
@ -110,88 +122,108 @@ func ZipFile(fname string, compress bool) (writtenFilename string, err error) {
}) })
defer zipWriter.Close() defer zipWriter.Close()
// Get the file information for the target err = zipFiles(fnames, compress, zipWriter)
log.Debugf("checking %s", path.Join(fpath, fname)) if err == nil {
ftarget, err := os.Open(path.Join(fpath, fname)) log.Debugf("wrote zip file to %s", writtenFilename)
if err != nil {
log.Error(err)
return
}
defer ftarget.Close()
info, err := ftarget.Stat()
if err != nil {
log.Error(err)
return
}
// write header informaiton
header, err := zip.FileInfoHeader(info)
if err != nil {
log.Error(err)
return
}
var writer io.Writer
if info.IsDir() {
baseDir := path.Join(fpath, fname)
log.Debugf("walking base dir: %s", baseDir)
filepath.Walk(baseDir, func(curpath string, info os.FileInfo, err error) error {
if err != nil {
log.Error(err)
return err
}
header, err := zip.FileInfoHeader(info)
if err != nil {
log.Error(err)
return err
}
if baseDir != "" {
baseDir = filepath.Clean(baseDir)
header.Name = path.Join(fname, strings.TrimPrefix(curpath, baseDir))
}
log.Debug(header.Name)
if info.IsDir() {
header.Name += "/"
} else {
header.Method = zip.Deflate
}
header.Name = filepath.ToSlash(header.Name)
writer, err = zipWriter.CreateHeader(header)
if err != nil {
return err
}
if info.IsDir() {
return nil
}
file, err := os.Open(curpath)
if err != nil {
log.Error(err)
return err
}
defer file.Close()
_, err = io.Copy(writer, file)
return err
})
} else { } else {
writer, err = zipWriter.CreateHeader(header) log.Error(err)
if err != nil {
log.Error(err)
return
}
_, err = io.Copy(writer, ftarget)
if err != nil {
log.Error(err)
return
}
} }
log.Debugf("wrote zip file to %s", writtenFilename)
return return
} }
func zipFiles(fnames []string, compress bool, zipWriter *zip.Writer) (err error) {
for _, fname := range fnames {
// get absolute filename
absPath, err := filepath.Abs(filepath.Clean(fname))
if err != nil {
log.Error(err)
return err
}
// get path to file and the filename
fpath, fname := filepath.Split(absPath)
// Get the file information for the target
log.Debugf("checking %s", absPath)
ftarget, err := os.Open(absPath)
if err != nil {
log.Error(err)
return err
}
defer ftarget.Close()
info, err := ftarget.Stat()
if err != nil {
log.Error(err)
return err
}
// write header informaiton
header, err := zip.FileInfoHeader(info)
if err != nil {
log.Error(err)
return err
}
var writer io.Writer
if info.IsDir() {
baseDir := filepath.Clean(path.Join(fpath, fname))
log.Debugf("walking base dir: %s", baseDir)
filepath.Walk(baseDir, func(curpath string, info os.FileInfo, err error) error {
curpath = filepath.Clean(curpath)
if err != nil {
log.Error(err)
return err
}
header, err := zip.FileInfoHeader(info)
if err != nil {
log.Error(err)
return err
}
if baseDir != "" {
header.Name = path.Join(fname, strings.TrimPrefix(curpath, baseDir))
}
header.Name = filepath.Clean(filepath.ToSlash(header.Name))
log.Debug(header.Name)
if info.IsDir() {
header.Name += "/"
} else {
header.Method = zip.Deflate
}
writer, err = zipWriter.CreateHeader(header)
if err != nil {
return err
}
if info.IsDir() {
return nil
}
file, err := os.Open(curpath)
if err != nil {
log.Error(err)
return err
}
defer file.Close()
_, err = io.Copy(writer, file)
return err
})
} else {
writer, err = zipWriter.CreateHeader(header)
if err != nil {
log.Error(err)
return err
}
_, err = io.Copy(writer, ftarget)
if err != nil {
log.Error(err)
return err
}
}
}
return nil
}

View file

@ -2,6 +2,7 @@ package zipper
import ( import (
"os" "os"
"path"
"testing" "testing"
log "github.com/cihub/seelog" log "github.com/cihub/seelog"
@ -12,18 +13,35 @@ import (
func TestZip(t *testing.T) { func TestZip(t *testing.T) {
defer log.Flush() defer log.Flush()
DebugLevel = "debug" DebugLevel = "debug"
writtenFilename, err := ZipFile("../croc", true) writtenFilename1, err := ZipFile("../croc", true)
assert.Nil(t, err) assert.Nil(t, err)
defer os.Remove(writtenFilename) err = UnzipFile(writtenFilename1, ".")
err = UnzipFile(writtenFilename, ".")
assert.Nil(t, err) assert.Nil(t, err)
assert.True(t, utils.Exists("croc")) assert.True(t, utils.Exists("croc"))
writtenFilename, err = ZipFile("../../README.md", false) writtenFilename2, err := ZipFile("../../README.md", false)
assert.Nil(t, err) assert.Nil(t, err)
defer os.Remove(writtenFilename) err = UnzipFile(writtenFilename2, ".")
err = UnzipFile(writtenFilename, ".")
assert.Nil(t, err) assert.Nil(t, err)
assert.True(t, utils.Exists("README.md")) assert.True(t, utils.Exists("README.md"))
os.Remove("README.md")
os.RemoveAll("croc")
os.Remove(writtenFilename1)
os.Remove(writtenFilename2)
}
func TestZipFiles(t *testing.T) {
defer log.Flush()
DebugLevel = "debug"
writtenFilename, err := ZipFiles([]string{"../../LICENSE", "../win/Makefile", "../utils"}, true)
assert.Nil(t, err)
err = UnzipFile(writtenFilename, "zipfilestest")
assert.Nil(t, err)
assert.True(t, utils.Exists("zipfilestest/LICENSE"))
assert.True(t, utils.Exists("zipfilestest/Makefile"))
assert.True(t, utils.Exists("zipfilestest/utils/exists.go"))
os.RemoveAll("zipfilestest")
err = os.Remove(path.Join(".", writtenFilename))
assert.Nil(t, err)
} }