69 lines
1.5 KiB
Go
69 lines
1.5 KiB
Go
package backup
|
|
|
|
import (
|
|
"archive/tar"
|
|
"compress/gzip"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
// CreateTarGz creates a tar.gz archive of the specified directory
|
|
func CreateTarGz(sourceDir, outputFile string) error {
|
|
// Create the output file
|
|
file, err := os.Create(outputFile)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create output file: %w", err)
|
|
}
|
|
defer file.Close()
|
|
|
|
// Create gzip writer
|
|
gzWriter := gzip.NewWriter(file)
|
|
defer gzWriter.Close()
|
|
|
|
// Create tar writer
|
|
tarWriter := tar.NewWriter(gzWriter)
|
|
defer tarWriter.Close()
|
|
|
|
// Walk through the source directory
|
|
return filepath.Walk(sourceDir, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Create tar header
|
|
header, err := tar.FileInfoHeader(info, "")
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create tar header: %w", err)
|
|
}
|
|
|
|
// Update the name to be relative to the source directory
|
|
relPath, err := filepath.Rel(sourceDir, path)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get relative path: %w", err)
|
|
}
|
|
header.Name = relPath
|
|
|
|
// Write header
|
|
if err := tarWriter.WriteHeader(header); err != nil {
|
|
return fmt.Errorf("failed to write tar header: %w", err)
|
|
}
|
|
|
|
// If it's a file, write its content
|
|
if !info.IsDir() {
|
|
file, err := os.Open(path)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to open file: %w", err)
|
|
}
|
|
defer file.Close()
|
|
|
|
if _, err := io.Copy(tarWriter, file); err != nil {
|
|
return fmt.Errorf("failed to write file content: %w", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|