123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- package localversion
- import (
- "errors"
- "os"
- "path/filepath"
- "sort"
- "strings"
- "imuslab.com/arozos/mod/filesystem"
- )
- /*
- localversion.go
- This is a local version management module for arozos files
- Author: tobychui
- */
- type FileSnapshot struct {
- HistoryID string
- Filename string
- ModTime int64
- OverwriteTime string
- Filesize int64
- Relpath string
- }
- type VersionList struct {
- CurrentFile string
- LatestModtime int64
- Versions []*FileSnapshot
- }
- func GetFileVersionData(realFilepath string) (*VersionList, error) {
- mtime, _ := filesystem.GetModTime(realFilepath)
- versionList := VersionList{
- CurrentFile: filepath.Base(realFilepath),
- LatestModtime: mtime,
- Versions: []*FileSnapshot{},
- }
- //Example folder structure: ./.localver/{date_time}/{file}
- expectedVersionFiles := filepath.Join(filepath.Dir(realFilepath), ".localver", "*", filepath.Base(realFilepath))
- versions, err := filepath.Glob(filepath.ToSlash(expectedVersionFiles))
- if err != nil {
- return &versionList, err
- }
- //Reverse the versions so latest version on top
- sort.Sort(sort.Reverse(sort.StringSlice(versions)))
- for _, version := range versions {
- historyID := filepath.Base(filepath.Dir(version))
- mtime, _ := filesystem.GetModTime(version)
- overwriteDisplayTime := strings.ReplaceAll(strings.Replace(strings.Replace(historyID, "-", "/", 2), "-", ":", 2), "_", " ")
- versionList.Versions = append(versionList.Versions, &FileSnapshot{
- HistoryID: historyID,
- Filename: filepath.Base(version),
- ModTime: mtime,
- OverwriteTime: overwriteDisplayTime,
- Filesize: filesystem.GetFileSize(version),
- Relpath: ".localver/" + historyID + "/" + filepath.Base(version),
- })
- }
- return &versionList, nil
- }
- func RestoreFileHistory(originalFilepath string, histroyID string) error {
- expectedVersionFile := filepath.Join(filepath.Dir(originalFilepath), ".localver", filepath.Base(histroyID), filepath.Base(originalFilepath))
- if !filesystem.FileExists(expectedVersionFile) {
- return errors.New("File version not exists")
- }
- //Restore it
- os.Rename(originalFilepath, originalFilepath+".backup")
- filesystem.BasicFileCopy(expectedVersionFile, originalFilepath)
- //Check if it has been restored correctly
- versionFileHash, _ := filesystem.GetFileMD5Sum(expectedVersionFile)
- copiedFileHash, _ := filesystem.GetFileMD5Sum(expectedVersionFile)
- if versionFileHash != copiedFileHash {
- //Rollback failed. Restore backup file
- os.Rename(originalFilepath+".backup", originalFilepath)
- return errors.New("Unable to restore file: file hash mismatch after restore")
- }
- //OK! Delete the backup file
- os.Remove(originalFilepath + ".backup")
- //Delete all history versions that is after the restored versions
- expectedVersionFiles := filepath.Join(filepath.Dir(originalFilepath), ".localver", "*", filepath.Base(originalFilepath))
- versions, err := filepath.Glob(filepath.ToSlash(expectedVersionFiles))
- if err != nil {
- return err
- }
- enableRemoval := false
- for _, version := range versions {
- if enableRemoval {
- //Remove this version as this is after the restored version
- os.Remove(version)
- } else {
- thisHistoryId := filepath.Base(filepath.Dir(version))
- if thisHistoryId == histroyID {
- //Match. Tag enable Removal
- enableRemoval = true
- //Remove this version
- os.Remove(version)
- }
- }
- }
- return nil
- }
- func RemoveFileHistory(originalFilepath string, histroyID string) error {
- return nil
- }
- func CreateFileSnapshot(realFilepath string) error {
- return nil
- }
|