diff --git a/README.md b/README.md index 01bcd33..e91e1fb 100644 --- a/README.md +++ b/README.md @@ -1,58 +1,2 @@ # backuper - -## Usage - -### Incremental backup - -```sh -backuper i -``` - -### Full backup - -```sh -backuper f -``` - -### Search files in backup - -```sh -backuper s -``` - -### Recover files from backup - -```sh -backuper r -``` - -Examples: - -```sh -# Recover Go files relevant as of 01.01.2023 to /home/user/go directory -backuper r config.conf "*.go" "01.01.2023" "/home/user/go" -``` - -### Test backup for errors - -```sh -backuper t -``` - -## Basic config example - -Backup config files from `/etc` and sqlite files from `/var`: - -```toml -FileName = "backup" - -[[Patterns]] -Path = "/etc" -FileNamePatternList = ["*.conf", "*.toml", "*.ini", "*.yaml"] -Recursive = true - -[[Patterns]] -Path = "/var" -FileNamePatternList = ["*.sqlite"] -Recursive = true -``` + diff --git a/backuper.go b/backuper.go index 30c8960..e162dc8 100644 --- a/backuper.go +++ b/backuper.go @@ -46,8 +46,6 @@ func (b *Config) fileList(fileNames chan FileInfo) { if b.StopOnAnyError { return fmt.Errorf("get file info error: %v", err) } - - return nil } file := FileInfo{ diff --git a/go.mod b/go.mod index c3f3191..dc75287 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( github.com/BurntSushi/toml v1.2.1 - github.com/klauspost/compress v1.16.4 + github.com/klauspost/compress v1.16.3 github.com/stretchr/testify v1.8.2 github.com/tidwall/match v1.1.1 ) diff --git a/go.sum b/go.sum index e54a948..cc9c001 100644 --- a/go.sum +++ b/go.sum @@ -3,8 +3,8 @@ github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= -github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= +github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/index.go b/index.go index f613319..9ce9947 100644 --- a/index.go +++ b/index.go @@ -62,8 +62,7 @@ func (index Index) Save(fileName string) error { enc, err := zstd.NewWriter(f, zstd.WithEncoderLevel(zstd.SpeedBestCompression)) if err != nil { - f.Close() - os.Remove(fileName) + f.Close() // TODO: удалить частичный файл? return err } @@ -83,8 +82,7 @@ func (index Index) Save(fileName string) error { err := csvWriter.Write([]string{fileName, historyItem.ArchiveFileName, strconv.Itoa(int(historyItem.ModificationTime.Unix()))}) if err != nil { enc.Close() - f.Close() - os.Remove(fileName) + f.Close() // TODO: удалить частичный файл? return err } } @@ -93,15 +91,13 @@ func (index Index) Save(fileName string) error { csvWriter.Flush() if err := csvWriter.Error(); err != nil { enc.Close() - f.Close() - os.Remove(fileName) + f.Close() // TODO: удалить частичный файл? return err } err = enc.Close() if err != nil { - f.Close() - os.Remove(fileName) + f.Close() // TODO: удалить частичный файл? return err } diff --git a/main.go b/main.go index 0b1f8ca..2b9a74f 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "log" "os" "path/filepath" + "time" ) func init() { @@ -55,9 +56,25 @@ func main() { log.Fatalln(err) } - t, err := parseTime(os.Args[4]) - if err != nil { - config.fatalln(err) + var t time.Time + switch len(os.Args[4]) { + case len("02.01.2006"): + t, err = time.Parse("02.01.2006 15:04", os.Args[4]) + if err != nil { + config.fatalln("time parse error:", err) + } + case len("02.01.2006 15:04"): + t, err = time.Parse("02.01.2006 15:04", os.Args[4]) + if err != nil { + config.fatalln("time parse error:", err) + } + case len("02.01.2006 15:04:05"): + t, err = time.Parse("02.01.2006 15:04:05", os.Args[4]) + if err != nil { + config.fatalln("time parse error:", err) + } + default: + config.fatalln(`wrong time format, must be ["DD.MM.YYYY", "DD.MM.YYYY hh:mm", "DD.MM.YYYY hh:mm:ss"]`) } plan, err := config.extractionPlan(os.Args[3], t) diff --git a/utils.go b/utils.go index 7ec8a8c..f0ef4d8 100644 --- a/utils.go +++ b/utils.go @@ -1,11 +1,9 @@ package main import ( - "errors" "fmt" "path/filepath" "strings" - "time" "github.com/tidwall/match" ) @@ -34,7 +32,7 @@ func sizeToApproxHuman(s int64) string { return fmt.Sprintf("%d B", s) } -// clean убирает невозможные комбинации символов из пути +// clean убирает невозможнын комбинации символов из пути func clean(s string) string { s = strings.ReplaceAll(s, ":", "") s = strings.ReplaceAll(s, `\\`, `\`) @@ -73,16 +71,3 @@ func isFilePathMatchPatterns(patterns []string, fileName string) bool { return false } - -func parseTime(s string) (time.Time, error) { - switch len(s) { - case len("02.01.2006"): - return time.ParseInLocation("02.01.2006", s, time.Local) - case len("02.01.2006 15:04"): - return time.ParseInLocation("02.01.2006 15:04", s, time.Local) - case len("02.01.2006 15:04:05"): - return time.ParseInLocation("02.01.2006 15:04:05", s, time.Local) - } - - return time.Time{}, errors.New("unknown time format") -} diff --git a/utils_test.go b/utils_test.go index 3769cd4..6bad3fc 100644 --- a/utils_test.go +++ b/utils_test.go @@ -2,7 +2,6 @@ package main import ( "testing" - "time" "github.com/stretchr/testify/assert" ) @@ -11,21 +10,3 @@ func TestSizeToApproxHuman(t *testing.T) { assert.Equal(t, "1.0 KiB", sizeToApproxHuman(1024)) assert.Equal(t, "1.1 KiB", sizeToApproxHuman(1126)) } - -func TestParseTime(t *testing.T) { - tests := []struct { - input string - expected time.Time - }{ - {"02.01.2006", time.Date(2006, 01, 02, 0, 0, 0, 0, time.Local)}, - {"02.01.2006 15:04", time.Date(2006, 01, 02, 15, 4, 0, 0, time.Local)}, - {"02.01.2006 15:04:05", time.Date(2006, 01, 02, 15, 4, 5, 0, time.Local)}, - } - - for _, test := range tests { - got, err := parseTime(test.input) - assert.NoError(t, err) - - assert.Equal(t, test.expected, got) - } -}