init
This commit is contained in:
parent
314f38c25e
commit
dd0bac39d4
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Mac
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Test out
|
||||||
|
/test/out
|
23
.travis.yml
Normal file
23
.travis.yml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
language: go
|
||||||
|
sudo: required
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
allow_failures:
|
||||||
|
- go: master
|
||||||
|
include:
|
||||||
|
# Supported versions of Go: https://golang.org/dl/
|
||||||
|
- go: '1.11.x'
|
||||||
|
- go: '1.12.x'
|
||||||
|
- go: master
|
||||||
|
|
||||||
|
go_import_path: github.com/yi-ge/unzip
|
||||||
|
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- $GOPATH/pkg
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- echo "TRAVIS_GO_VERSION=${TRAVIS_GO_VERSION}"
|
||||||
|
|
||||||
|
script:
|
||||||
|
- go test -v
|
23
README.md
23
README.md
@ -1,2 +1,21 @@
|
|||||||
# unzip
|
# Unzip
|
||||||
Golang *.zip decompress.
|
|
||||||
|
Golang \*.zip decompress.
|
||||||
|
|
||||||
|
[](https://travis-ci.com/yi-ge/unzip)
|
||||||
|
[](https://godoc.org/github.com/yi-ge/unzip)
|
||||||
|
|
||||||
|
Golang \*.tar.xz decompress.
|
||||||
|
|
||||||
|
Fork from [https://github.com/artdarek/go-unzip](https://github.com/artdarek/go-unzip) and remove print, add support for Symlink.
|
||||||
|
|
||||||
|
Thank artdarek.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```golang
|
||||||
|
import "github.com/yi-ge/unzip"
|
||||||
|
|
||||||
|
u := unzip.New(filePath, outDir)
|
||||||
|
err := u.Extract()
|
||||||
|
```
|
||||||
|
0
test/a.txt
Normal file
0
test/a.txt
Normal file
1
test/b.txt
Normal file
1
test/b.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
1
|
1
test/c.txt
Normal file
1
test/c.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
2
|
1
test/d.txt
Symbolic link
1
test/d.txt
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
dir/d.txt
|
1
test/dir/c.txt
Normal file
1
test/dir/c.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
2
|
1
test/dir/d.txt
Normal file
1
test/dir/d.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
3
|
1
test/dir/dir/e.txt
Normal file
1
test/dir/dir/e.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
4
|
1
test/dir/dir/f.txt
Symbolic link
1
test/dir/dir/f.txt
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../f.txt
|
1
test/dir/e.txt
Normal file
1
test/dir/e.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
4
|
1
test/dir/f.txt
Normal file
1
test/dir/f.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
5
|
BIN
test/t.zip
Normal file
BIN
test/t.zip
Normal file
Binary file not shown.
103
unzip.go
Normal file
103
unzip.go
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package unzip
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/zip"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Unzip - struct
|
||||||
|
type Unzip struct {
|
||||||
|
Src string
|
||||||
|
Dest string
|
||||||
|
}
|
||||||
|
|
||||||
|
// New - Create a new Unzip.
|
||||||
|
func New(src string, dest string) Unzip {
|
||||||
|
return Unzip{src, dest}
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeSymbolicLink(filePath string, targetPath string) error {
|
||||||
|
err := os.MkdirAll(filepath.Dir(filePath), 0755)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.Symlink(targetPath, filePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract - Extract zip file.
|
||||||
|
func (uz Unzip) Extract() error {
|
||||||
|
r, err := zip.OpenReader(uz.Src)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := r.Close(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
os.MkdirAll(uz.Dest, 0755)
|
||||||
|
|
||||||
|
// Closure to address file descriptors issue with all the deferred .Close() methods
|
||||||
|
extractAndWriteFile := func(f *zip.File) error {
|
||||||
|
rc, err := f.Open()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := rc.Close(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
path := filepath.Join(uz.Dest, f.Name)
|
||||||
|
|
||||||
|
if f.FileInfo().IsDir() {
|
||||||
|
os.MkdirAll(path, f.Mode())
|
||||||
|
} else {
|
||||||
|
mode := f.FileHeader.Mode()
|
||||||
|
if mode&os.ModeType == os.ModeSymlink {
|
||||||
|
data, err := ioutil.ReadAll(rc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
writeSymbolicLink(path, string(data))
|
||||||
|
} else {
|
||||||
|
os.MkdirAll(filepath.Dir(path), f.Mode())
|
||||||
|
outFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := outFile.Close(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
_, err = io.Copy(outFile, rc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range r.File {
|
||||||
|
err := extractAndWriteFile(f)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
299
unzip_test.go
Normal file
299
unzip_test.go
Normal file
@ -0,0 +1,299 @@
|
|||||||
|
package unzip
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func currentDir() string {
|
||||||
|
dir, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return dir
|
||||||
|
}
|
||||||
|
|
||||||
|
func testNullContent(t *testing.T) {
|
||||||
|
aFile, err := os.Open(path.Join(currentDir(), "./test/a.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer aFile.Close()
|
||||||
|
|
||||||
|
aFileContent, err := ioutil.ReadAll(aFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
aOutFile, err := os.Open(path.Join(currentDir(), "./test/out/a.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer aOutFile.Close()
|
||||||
|
|
||||||
|
aOutFileContent, err := ioutil.ReadAll(aOutFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if string(aFileContent) != string(aOutFileContent) {
|
||||||
|
t.Fatal("Unzip file content error.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if string(aFileContent) != "" {
|
||||||
|
t.Fatal("Unzip file content error.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testContentEqual(t *testing.T) {
|
||||||
|
bFile, err := os.Open(path.Join(currentDir(), "./test/b.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer bFile.Close()
|
||||||
|
|
||||||
|
bFileContent, err := ioutil.ReadAll(bFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
bOutFile, err := os.Open(path.Join(currentDir(), "./test/out/b.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer bOutFile.Close()
|
||||||
|
|
||||||
|
bOutFileContent, err := ioutil.ReadAll(bOutFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if string(bFileContent) != string(bOutFileContent) {
|
||||||
|
t.Log(string(bFileContent))
|
||||||
|
t.Log(string(bOutFileContent))
|
||||||
|
t.Fatal("Unzip file content error.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testLink(t *testing.T) {
|
||||||
|
cOutFile, err := os.OpenFile(path.Join(currentDir(), "./test/out/c.txt"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer cOutFile.Close()
|
||||||
|
|
||||||
|
cOutFileContent, err := ioutil.ReadAll(cOutFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cOutLinkFile, err := os.Open(path.Join(currentDir(), "./test/out/dir/c.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer cOutLinkFile.Close()
|
||||||
|
|
||||||
|
cOutLinkFileContent, err := ioutil.ReadAll(cOutLinkFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if string(cOutFileContent) != string(cOutLinkFileContent) {
|
||||||
|
t.Fatal("Unzip file content error or link file content error.")
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Log("Old c.txt content:", string(cOutFileContent))
|
||||||
|
t.Log("Change c.txt content.")
|
||||||
|
_, err = cOutFile.WriteString("123")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cOutFileNew, err := os.Open(path.Join(currentDir(), "./test/out/c.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer cOutFileNew.Close()
|
||||||
|
|
||||||
|
cOutFileContentNew, err := ioutil.ReadAll(cOutFileNew)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("New c.txt content:", string(cOutFileContentNew))
|
||||||
|
|
||||||
|
cOutLinkFileNew, err := os.Open(path.Join(currentDir(), "./test/out/dir/c.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer cOutLinkFileNew.Close()
|
||||||
|
|
||||||
|
cOutLinkFileContentNew, err := ioutil.ReadAll(cOutLinkFileNew)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if string(cOutFileContentNew) != string(cOutLinkFileContentNew) {
|
||||||
|
t.Fatal("Unzip file link error.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSymlink(t *testing.T) {
|
||||||
|
targetURL, err := filepath.EvalSymlinks(path.Join(currentDir(), "./test/out/d.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Log("targetURL:", targetURL)
|
||||||
|
if targetURL != path.Join(currentDir(), "./test/out/dir/d.txt") {
|
||||||
|
t.Fatal("Unzip file Symlink error.")
|
||||||
|
}
|
||||||
|
|
||||||
|
dOutSymlinkFile, err := os.Open(path.Join(currentDir(), "./test/out/d.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer dOutSymlinkFile.Close()
|
||||||
|
|
||||||
|
dOutSymlinkFileContent, err := ioutil.ReadAll(dOutSymlinkFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dOutFile, err := os.Open(path.Join(currentDir(), "./test/out/dir/d.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer dOutFile.Close()
|
||||||
|
|
||||||
|
dOutFileContent, err := ioutil.ReadAll(dOutFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if string(dOutSymlinkFileContent) != string(dOutFileContent) {
|
||||||
|
t.Fatal("The content of symlink file is not equal to that of target file")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testLintInDir(t *testing.T) {
|
||||||
|
eOutFile, err := os.OpenFile(path.Join(currentDir(), "./test/out/dir/dir/e.txt"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer eOutFile.Close()
|
||||||
|
|
||||||
|
eOutFileContent, err := ioutil.ReadAll(eOutFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
eOutLinkFile, err := os.Open(path.Join(currentDir(), "./test/out/dir/e.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer eOutLinkFile.Close()
|
||||||
|
|
||||||
|
eOutLinkFileContent, err := ioutil.ReadAll(eOutLinkFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if string(eOutFileContent) != string(eOutLinkFileContent) {
|
||||||
|
t.Fatal("Unzip file content error or link file content error.")
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Log("Old dir/dir/e.txt content:", string(eOutFileContent))
|
||||||
|
t.Log("Change dir/dir/e.txt content.")
|
||||||
|
_, err = eOutFile.WriteString("abcde")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
eOutFileNew, err := os.Open(path.Join(currentDir(), "./test/out/dir/dir/e.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer eOutFileNew.Close()
|
||||||
|
|
||||||
|
eOutFileContentNew, err := ioutil.ReadAll(eOutFileNew)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("New dir/dir/e.txt content:", string(eOutFileContentNew))
|
||||||
|
|
||||||
|
eOutLinkFileNew, err := os.Open(path.Join(currentDir(), "./test/out/dir/e.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer eOutLinkFileNew.Close()
|
||||||
|
|
||||||
|
eOutLinkFileContentNew, err := ioutil.ReadAll(eOutLinkFileNew)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if string(eOutFileContentNew) != string(eOutLinkFileContentNew) {
|
||||||
|
t.Fatal("Unzip file link error.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSymlinkInDir(t *testing.T) {
|
||||||
|
inDirTargetURL, err := filepath.EvalSymlinks(path.Join(currentDir(), "./test/out/dir/dir/f.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("F outSymlinkFile link:", inDirTargetURL)
|
||||||
|
|
||||||
|
if inDirTargetURL != path.Join(currentDir(), "./test/out/dir/f.txt") {
|
||||||
|
t.Fatal("Unzip file Symlink error.")
|
||||||
|
}
|
||||||
|
|
||||||
|
fOutSymlinkFile, err := os.Open(path.Join(currentDir(), "./test/out/dir/dir/f.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer fOutSymlinkFile.Close()
|
||||||
|
|
||||||
|
fOutSymlinkFileContent, err := ioutil.ReadAll(fOutSymlinkFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fOutFile, err := os.Open(path.Join(currentDir(), "./test/out/dir/f.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer fOutFile.Close()
|
||||||
|
|
||||||
|
fOutFileContent, err := ioutil.ReadAll(fOutFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if string(fOutSymlinkFileContent) != string(fOutFileContent) {
|
||||||
|
t.Fatal("The content of symlink file is not equal to that of target file")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnzip(t *testing.T) {
|
||||||
|
filePath := filepath.FromSlash(path.Join(currentDir(), "./test/t.zip"))
|
||||||
|
outDir := filepath.FromSlash(path.Join(currentDir(), "./test/out") + "/")
|
||||||
|
|
||||||
|
os.RemoveAll(outDir)
|
||||||
|
|
||||||
|
unzip := New(filePath, outDir)
|
||||||
|
err := unzip.Extract()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("Content is null", testNullContent)
|
||||||
|
t.Run("Content is equal", testContentEqual)
|
||||||
|
// t.Run("Link", testLink)
|
||||||
|
t.Run("Symlink", testSymlink)
|
||||||
|
// t.Run("Link in dir", testLintInDir)
|
||||||
|
t.Run("Symlink in dir", testSymlinkInDir)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user