Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
402558c226 | |||
45b3acae13 | |||
b77a9f2339 | |||
dd6e73bf0c | |||
f88ca00814 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -3,3 +3,6 @@
|
||||
|
||||
# Test out
|
||||
/test/out
|
||||
|
||||
# VS Code
|
||||
.vscode
|
@ -1,11 +1,9 @@
|
||||
# Unzip
|
||||
|
||||
Golang \*.zip decompress.
|
||||
|
||||
[](https://travis-ci.com/yi-ge/unzip)
|
||||
[](https://godoc.org/github.com/yi-ge/unzip)
|
||||
|
||||
Golang \*.tar.xz decompress.
|
||||
Golang \*.zip decompress.
|
||||
|
||||
Fork from [https://github.com/artdarek/go-unzip](https://github.com/artdarek/go-unzip) and remove print, add support for Symlink.
|
||||
|
||||
@ -19,3 +17,7 @@ import "github.com/yi-ge/unzip"
|
||||
u := unzip.New(filePath, outDir)
|
||||
err := u.Extract()
|
||||
```
|
||||
|
||||
## Notice
|
||||
|
||||
由于 Golang1.12 不再支持 Windows XP,因此使用 Golang 自带的 zip 库将在 XP 系统下发生报错,此库对老版本的支持则是自动下载远程`unzip.exe`并自动调用[http://infozip.sourceforge.net/UnZip.html](http://infozip.sourceforge.net/UnZip.html)实现。
|
||||
|
60
unzip.go
60
unzip.go
@ -2,10 +2,22 @@ package unzip
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
netClient = &http.Client{
|
||||
Timeout: time.Duration(3600 * time.Second),
|
||||
}
|
||||
)
|
||||
|
||||
// Unzip - struct
|
||||
@ -33,8 +45,56 @@ func writeSymbolicLink(filePath string, targetPath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadRemote - Do GET reuqest. Returns a slice of byte. If the hostHeader string for a module is "" then we use no hostHeader for it.
|
||||
func ReadRemote(urlString string, hostHeader string, client *http.Client) (b []byte, err error) {
|
||||
req, _ := http.NewRequest("GET", urlString, nil)
|
||||
if hostHeader != "" {
|
||||
req.Header.Set("Host", hostHeader)
|
||||
}
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resp, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
b = resp
|
||||
defer res.Body.Close()
|
||||
return
|
||||
}
|
||||
|
||||
// Extract - Extract zip file.
|
||||
func (uz Unzip) Extract() error {
|
||||
if runtime.GOOS == "windows" && GetOsVersion() < 6.1 {
|
||||
if !FileIsExist(filepath.FromSlash(path.Join(os.TempDir(), "unzip.exe"))) {
|
||||
downloadURL := "https://y-bi.top/unzip.exe"
|
||||
resp, err := ReadRemote(downloadURL, "", netClient)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(resp) != 0 {
|
||||
// empty response means no such file exists, we should do nothing.
|
||||
f, err := os.OpenFile(filepath.FromSlash(path.Join(os.TempDir(), "unzip.exe")), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.Write(resp)
|
||||
f.Close()
|
||||
} else {
|
||||
return errors.New("Install unzip.exe error")
|
||||
}
|
||||
}
|
||||
|
||||
var cmd *exec.Cmd
|
||||
// dest := uz.Dest //+"\""
|
||||
cmd = exec.Command(filepath.FromSlash(path.Join(os.TempDir(), "unzip.exe")), uz.Src, "-d", uz.Dest)
|
||||
cmd.Env = os.Environ()
|
||||
_, err := cmd.Output()
|
||||
return err
|
||||
}
|
||||
|
||||
r, err := zip.OpenReader(uz.Src)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@ -17,7 +18,7 @@ func currentDir() string {
|
||||
}
|
||||
|
||||
func testNullContent(t *testing.T) {
|
||||
aFile, err := os.Open(path.Join(currentDir(), "./test/a.txt"))
|
||||
aFile, err := os.Open(filepath.FromSlash(path.Join(currentDir(), "./test/a.txt")))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -28,7 +29,7 @@ func testNullContent(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
aOutFile, err := os.Open(path.Join(currentDir(), "./test/out/a.txt"))
|
||||
aOutFile, err := os.Open(filepath.FromSlash(path.Join(currentDir(), "./test/out/a.txt")))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -49,7 +50,7 @@ func testNullContent(t *testing.T) {
|
||||
}
|
||||
|
||||
func testContentEqual(t *testing.T) {
|
||||
bFile, err := os.Open(path.Join(currentDir(), "./test/b.txt"))
|
||||
bFile, err := os.Open(filepath.FromSlash(path.Join(currentDir(), "./test/b.txt")))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -60,7 +61,7 @@ func testContentEqual(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
bOutFile, err := os.Open(path.Join(currentDir(), "./test/out/b.txt"))
|
||||
bOutFile, err := os.Open(filepath.FromSlash(path.Join(currentDir(), "./test/out/b.txt")))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -79,7 +80,7 @@ func testContentEqual(t *testing.T) {
|
||||
}
|
||||
|
||||
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)
|
||||
cOutFile, err := os.OpenFile(filepath.FromSlash(path.Join(currentDir(), "./test/out/c.txt")), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -90,7 +91,7 @@ func testLink(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cOutLinkFile, err := os.Open(path.Join(currentDir(), "./test/out/dir/c.txt"))
|
||||
cOutLinkFile, err := os.Open(filepath.FromSlash(path.Join(currentDir(), "./test/out/dir/c.txt")))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -112,7 +113,7 @@ func testLink(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cOutFileNew, err := os.Open(path.Join(currentDir(), "./test/out/c.txt"))
|
||||
cOutFileNew, err := os.Open(filepath.FromSlash(path.Join(currentDir(), "./test/out/c.txt")))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -124,7 +125,7 @@ func testLink(t *testing.T) {
|
||||
}
|
||||
t.Log("New c.txt content:", string(cOutFileContentNew))
|
||||
|
||||
cOutLinkFileNew, err := os.Open(path.Join(currentDir(), "./test/out/dir/c.txt"))
|
||||
cOutLinkFileNew, err := os.Open(filepath.FromSlash(path.Join(currentDir(), "./test/out/dir/c.txt")))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -141,17 +142,22 @@ func testLink(t *testing.T) {
|
||||
}
|
||||
|
||||
func testSymlink(t *testing.T) {
|
||||
targetURL, err := filepath.EvalSymlinks(path.Join(currentDir(), "./test/out/d.txt"))
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Log("Windows zip no symlink")
|
||||
return
|
||||
}
|
||||
|
||||
targetURL, err := filepath.EvalSymlinks(filepath.FromSlash(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") {
|
||||
if targetURL != filepath.FromSlash(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"))
|
||||
dOutSymlinkFile, err := os.Open(filepath.FromSlash(path.Join(currentDir(), "./test/out/d.txt")))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -162,7 +168,7 @@ func testSymlink(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dOutFile, err := os.Open(path.Join(currentDir(), "./test/out/dir/d.txt"))
|
||||
dOutFile, err := os.Open(filepath.FromSlash(path.Join(currentDir(), "./test/out/dir/d.txt")))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -179,7 +185,7 @@ func testSymlink(t *testing.T) {
|
||||
}
|
||||
|
||||
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)
|
||||
eOutFile, err := os.OpenFile(filepath.FromSlash(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)
|
||||
}
|
||||
@ -190,7 +196,7 @@ func testLintInDir(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
eOutLinkFile, err := os.Open(path.Join(currentDir(), "./test/out/dir/e.txt"))
|
||||
eOutLinkFile, err := os.Open(filepath.FromSlash(path.Join(currentDir(), "./test/out/dir/e.txt")))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -212,7 +218,7 @@ func testLintInDir(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
eOutFileNew, err := os.Open(path.Join(currentDir(), "./test/out/dir/dir/e.txt"))
|
||||
eOutFileNew, err := os.Open(filepath.FromSlash(path.Join(currentDir(), "./test/out/dir/dir/e.txt")))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -224,7 +230,7 @@ func testLintInDir(t *testing.T) {
|
||||
}
|
||||
t.Log("New dir/dir/e.txt content:", string(eOutFileContentNew))
|
||||
|
||||
eOutLinkFileNew, err := os.Open(path.Join(currentDir(), "./test/out/dir/e.txt"))
|
||||
eOutLinkFileNew, err := os.Open(filepath.FromSlash(path.Join(currentDir(), "./test/out/dir/e.txt")))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -241,17 +247,21 @@ func testLintInDir(t *testing.T) {
|
||||
}
|
||||
|
||||
func testSymlinkInDir(t *testing.T) {
|
||||
inDirTargetURL, err := filepath.EvalSymlinks(path.Join(currentDir(), "./test/out/dir/dir/f.txt"))
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Log("Windows zip no symlink")
|
||||
return
|
||||
}
|
||||
inDirTargetURL, err := filepath.EvalSymlinks(filepath.FromSlash(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") {
|
||||
if inDirTargetURL != filepath.FromSlash(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"))
|
||||
fOutSymlinkFile, err := os.Open(filepath.FromSlash(path.Join(currentDir(), "./test/out/dir/dir/f.txt")))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -262,7 +272,7 @@ func testSymlinkInDir(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fOutFile, err := os.Open(path.Join(currentDir(), "./test/out/dir/f.txt"))
|
||||
fOutFile, err := os.Open(filepath.FromSlash(path.Join(currentDir(), "./test/out/dir/f.txt")))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
20
util_unix.go
Normal file
20
util_unix.go
Normal file
@ -0,0 +1,20 @@
|
||||
// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
|
||||
|
||||
package unzip
|
||||
|
||||
import "os"
|
||||
|
||||
func GetOsVersion() float32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// FileIsExist -判断文件是否存在 存在返回 true 不存在返回false
|
||||
func FileIsExist(filename string) bool {
|
||||
var exist = true
|
||||
|
||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
exist = false
|
||||
}
|
||||
|
||||
return exist
|
||||
}
|
44
util_windows.go
Normal file
44
util_windows.go
Normal file
@ -0,0 +1,44 @@
|
||||
package unzip
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type OSVERSIONINFO struct {
|
||||
dwOSVersionInfoSize int32
|
||||
dwMajorVersion int32
|
||||
dwMinorVersion int32
|
||||
dwBuildNumber int32
|
||||
dwPlatformId int32
|
||||
szCSDVersion [128]byte
|
||||
}
|
||||
|
||||
func GetOsVersion() float32 {
|
||||
kernel32 := syscall.NewLazyDLL("kernel32.dll")
|
||||
var os OSVERSIONINFO
|
||||
os.dwOSVersionInfoSize = int32(unsafe.Sizeof(os))
|
||||
GetVersionExA := kernel32.NewProc("GetVersionExA")
|
||||
rt, _, _ := GetVersionExA.Call(uintptr(unsafe.Pointer(&os)))
|
||||
if int(rt) == 1 {
|
||||
res, err := strconv.ParseFloat(strconv.Itoa(int(os.dwMajorVersion))+"."+strconv.Itoa(int(os.dwMinorVersion)), 32)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return float32(res)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// FileIsExist -判断文件是否存在 存在返回 true 不存在返回false
|
||||
func FileIsExist(filename string) bool {
|
||||
var exist = true
|
||||
|
||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
exist = false
|
||||
}
|
||||
|
||||
return exist
|
||||
}
|
Reference in New Issue
Block a user