Skip to content

Instantly share code, notes, and snippets.

@SijmenHuizenga
Created April 8, 2020 22:57
Show Gist options
  • Save SijmenHuizenga/f22f96b89a37f3ab56e9d135e1f91de7 to your computer and use it in GitHub Desktop.
Save SijmenHuizenga/f22f96b89a37f3ab56e9d135e1f91de7 to your computer and use it in GitHub Desktop.
Zip a directory in Golang with error handling, ignoring symlinks and file checking
func zipDirectory(zipfilename string) error {
outFile, err := os.Create(zipfilename)
if err != nil {
return err
}
w := zip.NewWriter(outFile)
if err := addFilesToZip(w, zipfilename, ""); err != nil {
_ = outFile.Close()
return err
}
if err := w.Close(); err != nil {
_ = outFile.Close()
return errors.New("Warning: closing zipfile writer failed: " + err.Error())
}
if err := outFile.Close(); err != nil {
return errors.New("Warning: closing zipfile failed: " + err.Error())
}
return nil
}
func addFilesToZip(w *zip.Writer, basePath, baseInZip string) error {
files, err := ioutil.ReadDir(basePath)
if err != nil {
return err
}
for _, file := range files {
fullfilepath := filepath.Join(basePath, file.Name())
if _, err := os.Stat(fullfilepath); os.IsNotExist(err) {
// ensure the file exists. For example a symlink pointing to a non-existing location might be listed but not actually exist
continue
}
if file.Mode() & os.ModeSymlink != 0 {
// ignore symlinks alltogether
continue
}
if file.IsDir() {
if err := addFilesToZip(w, fullfilepath, filepath.Join(baseInZip, file.Name())); err != nil {
return err
}
} else if file.Mode().IsRegular() {
dat, err := ioutil.ReadFile(fullfilepath)
if err != nil {
return err
}
f, err := w.Create(filepath.Join(baseInZip, file.Name()))
if err != nil {
return err
}
_, err = f.Write(dat)
if err != nil {
return err
}
} else {
// we ignore non-regular files because they are scary
}
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment