|
- package repo
-
- import (
- "archive/zip"
- "io"
- "io/fs"
- "io/ioutil"
- "os"
- "path/filepath"
- "regexp"
- )
-
- var NamePattern = regexp.MustCompile(`^[A-Za-z0-9-_\\.]{1,100}$`)
-
- var GrampusNamePattern = regexp.MustCompile(`^[A-Za-z][\w|\-|\\.]{0,49}$`)
-
- // Zip compresses the specified files or dirs to zip archive.
- // If a path is a dir don't need to specify the trailing path separator.
- // For example calling Zip("archive.zip", "dir", "csv/baz.csv") will get archive.zip and the content of which is
- // baz.csv
- // dir
- // ├── bar.txt
- // └── foo.txt
- // Note that if a file is a symbolic link it will be skipped.
- func Zip(zipPath string, paths string) error {
- // Create zip file and it's parent dir.
- if err := os.MkdirAll(filepath.Dir(zipPath), os.ModePerm); err != nil {
- return err
- }
- archive, err := os.Create(zipPath)
- if err != nil {
- return err
- }
- defer archive.Close()
-
- // New zip writer.
- zipWriter := zip.NewWriter(archive)
- defer zipWriter.Close()
-
- files, err := ioutil.ReadDir(paths)
- if err != nil {
- return err
- }
- // Traverse the file or directory.
- for _, file := range files {
- // Remove the trailing path separator if path is a directory.
- rootPath := filepath.Join(paths, file.Name())
-
- // Visit all the files or directories in the tree.
- err = filepath.Walk(rootPath, walkFunc(rootPath, zipWriter))
- if err != nil {
- return err
- }
- }
- return nil
- }
-
- func walkFunc(rootPath string, zipWriter *zip.Writer) filepath.WalkFunc {
- return func(path string, info fs.FileInfo, err error) error {
- if err != nil {
- return err
- }
-
- // If a file is a symbolic link it will be skipped.
- if info.Mode()&os.ModeSymlink != 0 {
- return nil
- }
-
- // Create a local file header.
- header, err := zip.FileInfoHeader(info)
- if err != nil {
- return err
- }
-
- // Set compression method.
- header.Method = zip.Deflate
-
- // Set relative path of a file as the header name.
- header.Name, err = filepath.Rel(filepath.Dir(rootPath), path)
- if err != nil {
- return err
- }
- if info.IsDir() {
- header.Name += string(os.PathSeparator)
- }
-
- // Create writer for the file header and save content of the file.
- headerWriter, err := zipWriter.CreateHeader(header)
- if err != nil {
- return err
- }
- if info.IsDir() {
- return nil
- }
- f, err := os.Open(path)
- if err != nil {
- return err
- }
- defer f.Close()
- _, err = io.Copy(headerWriter, f)
- return err
- }
- }
|