github.com/jgrancell/metasync@v0.0.0-20220105143315-c43793d9d9c1/app/candidate.go (about) 1 package app 2 3 import ( 4 "bytes" 5 "io/fs" 6 "io/ioutil" 7 "os" 8 9 diff "github.com/sergi/go-diff/diffmatchpatch" 10 ) 11 12 type SyncCandidate struct { 13 Diff string 14 Name string 15 SourceContents []byte 16 SourceFile string 17 TargetContents []byte 18 TargetFile string 19 TargetMode fs.FileMode 20 } 21 22 func (c *SyncCandidate) TargetExists() bool { 23 _, err := os.Stat(c.TargetFile) 24 if err != nil { 25 if os.IsNotExist(err) { 26 return false 27 } 28 } 29 return true 30 } 31 32 func (c *SyncCandidate) GetWriteMode(path string) error { 33 file, err := os.Stat(path) 34 if err != nil { 35 return err 36 } 37 38 c.TargetMode = file.Mode() 39 return nil 40 } 41 42 func (c *SyncCandidate) RequiresSync() (bool, error) { 43 var err error 44 if c.SourceContents, err = c.LoadContents(c.SourceFile); err != nil { 45 return false, err 46 } 47 48 if c.TargetExists() { 49 // Getting the file mode for the target file 50 if err := c.GetWriteMode(c.TargetFile); err != nil { 51 return false, err 52 } 53 54 c.TargetContents, err = c.LoadContents(c.TargetFile) 55 if err != nil { 56 return false, err 57 } 58 59 check := diff.New() 60 diffs := check.DiffMain(string(c.TargetContents), string(c.SourceContents), false) 61 c.Diff = check.DiffPrettyText(diffs) 62 63 if bytes.Equal(c.SourceContents, c.TargetContents) { 64 return false, nil 65 } 66 } 67 if err := c.GetWriteMode(c.SourceFile); err != nil { 68 return false, err 69 } 70 return true, nil 71 } 72 73 func (c *SyncCandidate) LoadContents(file string) ([]byte, error) { 74 contents, err := ioutil.ReadFile(file) 75 if err != nil { 76 return nil, err 77 } 78 return contents, nil 79 } 80 81 func (c *SyncCandidate) Sync() error { 82 return os.WriteFile(c.TargetFile, c.SourceContents, c.TargetMode) 83 }