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:
parent
fea07cab6c
commit
0ca74b010e
2 changed files with 148 additions and 98 deletions
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue