zip folder with source and target


zip folder with source and target



I use the following code which zip some folder to a given path,the issue that im currently facing is that I need to zip some folder with content into specific target and not in the same directory



For example



Folder in path like
source



"/Users/i03434/go/src/zdf/BUILD"


"/Users/i03434/go/src/zdf/BUILD"



target



"/Users/i03434/go/src/zdf/app/info.zip"


"/Users/i03434/go/src/zdf/app/info.zip"



currently I try to add new path[2] which doesnt helps, any idea how to do it?



This is all the code


func zipit(params ...string) error {

zipfile, err := os.Create(params[1])
if err != nil {
return err
}
defer zipfile.Close()

archive := zip.NewWriter(zipfile)
defer archive.Close()

info, err := os.Stat(params[0])
if err != nil {
return err
}

var baseDir string
if info.IsDir(); len(params) > 2 {
baseDir = params[2]
} else {
baseDir = filepath.Base(params[0])
}

if baseDir != "" {
baseDir += "/"
}

filepath.Walk(params[0], func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

if info.IsDir() {
return nil
}

header, err := zip.FileInfoHeader(info)
if err != nil {
return err
}

if baseDir != "" {
header.Name = filepath.Join(strings.TrimPrefix(path, baseDir))
}

header.Method = zip.Deflate

writer, err := archive.CreateHeader(header)
if err != nil {
return err
}

file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(writer, file)
return err
})

return err
}



The logic of the zip is working as expected, zip should be according to the jar spec



This question has not received enough attention.



I need some e2e unit testing for this





When you say you need to zip some folder with content into specific target, do you mean that the base folder for the zipped files is taken from param[2], if it's available ?
– John S Perayil
2 days ago





@yes, but what i need some unit test for this mechanism
– shopia T
2 days ago





zipfile is an os.File interface, so it can be mocked to write an e2e test.
– John S Perayil
2 days ago


os.File




1 Answer
1



For Testing :



You can pass in a mocked zipFile (os.File) as an argument for function zipit() and compare it with expected data in a test.



Original Answer:



There are a few things to consider.



You need to use filepath.Dir instead of filepath.Base.
Base gives the last element of the path not the base directory.


filepath.Dir


filepath.Base



if info.IsDir(); len(params) > 2 { only checks the condition len(params) > 2, info.IsDir() is evaluated but not used anywhere.


if info.IsDir(); len(params) > 2 {


len(params) > 2


info.IsDir()



Refer : If with a short statement format in Go [1] [2]



It should be


if info.IsDir() {
if len(params) > 2 {
...
} else {
...
}
}



Changes :


var baseDir string
if info.IsDir(); len(params) > 2 {
baseDir = params[2]
} else {
baseDir = filepath.Base(params[0])
}



should be


var baseDir, newBaseDir string
if info.IsDir() {
baseDir = filepath.Dir(params[0])
if len(params) > 2 {
newBaseDir = params[2]
}
}



AND



header.Name = filepath.Join(strings.TrimPrefix(path, baseDir))
becomes
header.Name = filepath.Join(newBaseDir, strings.TrimPrefix(path, baseDir))


header.Name = filepath.Join(strings.TrimPrefix(path, baseDir))


header.Name = filepath.Join(newBaseDir, strings.TrimPrefix(path, baseDir))



Full Code :


func zipit(params ...string) error {

zipfile, err := os.Create(params[1])
if err != nil {
return err
}
defer zipfile.Close()

archive := zip.NewWriter(zipfile)
defer archive.Close()

info, err := os.Stat(params[0])
if err != nil {
return err
}

var baseDir, newBaseDir string
if info.IsDir() {
baseDir = filepath.Dir(params[0])
if len(params) > 2 {
newBaseDir = params[2]
}
}

if baseDir != "" {
baseDir += "/"
}

filepath.Walk(params[0], func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

if info.IsDir() {
return nil
}

header, err := zip.FileInfoHeader(info)
if err != nil {
return err
}

if baseDir != "" {
header.Name = filepath.Join(newBaseDir, strings.TrimPrefix(path, baseDir))
}

header.Method = zip.Deflate

writer, err := archive.CreateHeader(header)
if err != nil {
return err
}

file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(writer, file)
return err
})

return err
}





Thanks :), But as requested I need unit test, could you please provide it?
– shopia T
2 days ago







By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

List of Kim Possible characters

Audio Livestreaming with Python & Flask

NSwag: Generate C# Client from multiple Versions of an API