package Archive import ( "PackageManager/Variables" "archive/tar" "compress/gzip" "io" "os" "strings" ) func CreateArchive(files []string, target string) error { var ( outFile *os.File gzipWriter *gzip.Writer tarWriter *tar.Writer file string e error ) // Create output file outFile, e = os.Create(target) if e != nil { return e } defer outFile.Close() gzipWriter = gzip.NewWriter(outFile) defer gzipWriter.Close() tarWriter = tar.NewWriter(gzipWriter) defer tarWriter.Close() // Iterate over files and add them to the tar archive for _, file = range files { e = addToArchive(tarWriter, file) if e != nil { return e } } return nil } func addToArchive(tarWriter *tar.Writer, filename string) error { var ( file *os.File info os.FileInfo header *tar.Header e error ) // Open the file which will be written into the archive file, e = os.Open(filename) if e != nil { return e } defer file.Close() // Get FileInfo about our file providing file size, mode, etc. info, e = file.Stat() if e != nil { return e } // Create a tar Header from the FileInfo data header, e = tar.FileInfoHeader(info, info.Name()) if e != nil { return e } // Use full path as name (FileInfoHeader only takes the basename) // If we don't do this the directory strucuture would // not be preserved // https://golang.org/src/archive/tar/common.go?#L626 header.Name = strings.TrimPrefix( strings.TrimPrefix( filename, Variables.RootDir, ), "/", ) // Write file header to the tar archive e = tarWriter.WriteHeader(header) if e != nil { return e } // Copy file content to tar archive _, e = io.Copy(tarWriter, file) if e != nil { return e } return nil }