Gai Lazar
Gai Lazar

Reputation: 31

How to zip symlinks in Golang using "archive/zip" package?

I need to zip/unzip folder that contains symlinks in a way that the structure will be saved and symlinks will be written as symlinks.

Is there a way doing this using Golang package "archive/zip"? or any other alternative way?

I tried to use this code, but 'io.Copy()' copies the target file content and we "lose" the symlink.

archive, err := os.Create("archive.zip")
if err != nil {
    panic(err)
}
defer archive.Close()
zipWriter := zip.NewWriter(archive)
localPath := "../testdata/sym"
file, err := os.Open(localPath)
defer file.Close()
if err != nil {
    panic(err)
}
w1 , err:= zipWriter.Create("w1")
if _, err = io.Copy(w1, file); err !=nil{
    panic(err)
}
zipWriter.Close()

Upvotes: 2

Views: 1163

Answers (1)

Gai Lazar
Gai Lazar

Reputation: 31

I used this PR : https://github.com/mholt/archiver/pull/92 and wrote symlink's target to writer.

I tested it on Linux and Windows.

archive, err := os.Create("archive.zip")
if err != nil {
    panic(err)
}
defer archive.Close()
zipWriter := zip.NewWriter(archive)
defer zipWriter.Close()
localPath := "../testdata/sym"
symlinksTarget = "../a/b.in"
file, err := os.Open(localPath)
defer file.Close()
if err != nil {
    panic(err)
}
info, err := os.Lstat(file.Name())
if err != nil {
    panic(err)
}
header, err := zip.FileInfoHeader(info)
if err != nil {
    panic(err)
}
header.Method = zip.Deflate
writer, err := zipWriter.CreateHeader(header)
if err != nil {
    panic(err)
}

// Write symlink's target to writer - file's body for symlinks is the symlink target.
_, err = writer.Write([]byte(filepath.ToSlash(symlinksTarget)))
if err != nil {
    panic(err)
}
    

Upvotes: 1

Related Questions