github.com/grzegorz-zur/bm@v0.0.0-20240312214136-6fc133e3e2c0/io.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 ) 9 10 // Open opens a file. 11 func Open(path string) (file File, err error) { 12 path = filepath.Clean(path) 13 file = File{ 14 Path: path, 15 history: &History{}, 16 } 17 _, err = file.Read(false) 18 if err != nil { 19 return file, fmt.Errorf("error opening file %s: %w", path, err) 20 } 21 return file, nil 22 } 23 24 // Read loads thie file. 25 func (file *File) Read(force bool) (read bool, err error) { 26 stat, err := os.Stat(file.Path) 27 if os.IsNotExist(err) { 28 err = ioutil.WriteFile(file.Path, []byte{}, os.ModePerm) 29 if err != nil { 30 return false, fmt.Errorf("error creating file %s info: %w", file.Path, err) 31 } 32 stat, err = os.Stat(file.Path) 33 } 34 if err != nil { 35 return false, fmt.Errorf("error checking file %s info: %w", file.Path, err) 36 } 37 changed := file.time != stat.ModTime() 38 if !changed && !force { 39 return false, nil 40 } 41 data, err := ioutil.ReadFile(file.Path) 42 if err != nil { 43 return false, fmt.Errorf("error reading file %s: %w", file.Path, err) 44 } 45 file.content = string(data) 46 stat, err = os.Stat(file.Path) 47 if err != nil { 48 return true, fmt.Errorf("error checking file %s info: %w", file.Path, err) 49 } 50 file.changed = false 51 file.time = stat.ModTime() 52 file.Archive() 53 if file.location > len(file.content) { 54 file.location = len(file.content) 55 } 56 if file.mark > len(file.content) { 57 file.mark = len(file.content) 58 } 59 return true, nil 60 } 61 62 // Write writes file contents. 63 func (file *File) Write() (wrote bool, err error) { 64 stat, err := os.Stat(file.Path) 65 if err != nil && !os.IsNotExist(err) { 66 return false, fmt.Errorf("error checking file %s info: %w", file.Path, err) 67 } 68 exists := stat != nil 69 changed := true 70 if exists { 71 changed = file.time != stat.ModTime() 72 } 73 if !file.changed && !changed { 74 return false, nil 75 } 76 data := []byte(file.content) 77 err = ioutil.WriteFile(file.Path, data, os.ModePerm) 78 if err != nil { 79 return false, fmt.Errorf("error writing file %s: %w", file.Path, err) 80 } 81 stat, err = os.Stat(file.Path) 82 if err != nil { 83 return true, fmt.Errorf("error checking file %s info: %w", file.Path, err) 84 } 85 file.changed = false 86 file.time = stat.ModTime() 87 return true, nil 88 }