pkg.re/essentialkaos/ek.v11@v12.41.0+incompatible/fsutil/helpers.go (about) 1 //go:build !windows 2 // +build !windows 3 4 package fsutil 5 6 // ////////////////////////////////////////////////////////////////////////////////// // 7 // // 8 // Copyright (c) 2022 ESSENTIAL KAOS // 9 // Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> // 10 // // 11 // ////////////////////////////////////////////////////////////////////////////////// // 12 13 import ( 14 "bufio" 15 "errors" 16 "io" 17 "os" 18 "path" 19 ) 20 21 // ////////////////////////////////////////////////////////////////////////////////// // 22 23 var _disableCopyFileChecks bool // Flag for testing purposes only 24 var _disableMoveFileChecks bool // Flag for testing purposes only 25 var _disableCopyDirChecks bool // Flag for testing purposes only 26 27 // ////////////////////////////////////////////////////////////////////////////////// // 28 29 // CopyFile copies file using bufio 30 func CopyFile(from, to string, perms ...os.FileMode) error { 31 var targetExist = IsExist(to) 32 33 if !_disableCopyFileChecks { 34 dir := path.Dir(to) 35 36 switch { 37 case from == "": 38 return errors.New("Source file can't be blank") 39 case to == "": 40 return errors.New("Target file can't be blank") 41 42 case !IsExist(from): 43 return errors.New("File " + from + " does not exists") 44 case !IsRegular(from): 45 return errors.New("File " + from + " is not a regular file") 46 case !IsReadable(from): 47 return errors.New("File " + from + " is not readable") 48 49 case !targetExist && !IsExist(dir): 50 return errors.New("Directory " + dir + " does not exists") 51 case !targetExist && !IsWritable(dir): 52 return errors.New("Directory " + dir + " is not writable") 53 54 case targetExist && !IsWritable(to): 55 return errors.New("Target file " + to + " is not writable") 56 case targetExist && !IsRegular(to): 57 return errors.New("Target is not a file") 58 } 59 } 60 61 return copyFile(from, to, perms) 62 } 63 64 // MoveFile moves file 65 func MoveFile(from, to string, perms ...os.FileMode) error { 66 if !_disableMoveFileChecks { 67 targetExist := IsExist(to) 68 dir := path.Dir(to) 69 70 switch { 71 case from == "": 72 return errors.New("Source file can't be blank") 73 case to == "": 74 return errors.New("Target file can't be blank") 75 76 case !IsExist(from): 77 return errors.New("File " + from + " does not exists") 78 case !IsRegular(from): 79 return errors.New("File " + from + " is not a regular file") 80 case !IsReadable(from): 81 return errors.New("File " + from + " is not readable") 82 83 case !targetExist && !IsExist(dir): 84 return errors.New("Directory " + dir + " does not exists") 85 case !targetExist && !IsWritable(dir): 86 return errors.New("Directory " + dir + " is not writable") 87 } 88 } 89 90 return moveFile(from, to, perms) 91 } 92 93 // CopyDir copies directory content recursively to target directory 94 func CopyDir(from, to string) error { 95 if !_disableCopyDirChecks { 96 switch { 97 case from == "": 98 return errors.New("Source directory can't be blank") 99 case to == "": 100 return errors.New("Target directory can't be blank") 101 102 case !IsExist(from): 103 return errors.New("Directory " + from + " does not exists") 104 case !IsDir(from): 105 return errors.New("Target " + from + " is not a directory") 106 case !IsReadable(from): 107 return errors.New("Directory " + from + " is not readable") 108 case IsExist(to) && !IsDir(to): 109 return errors.New("Target " + to + " is not a directory") 110 case IsExist(to) && !IsWritable(to): 111 return errors.New("Directory " + to + " is not writable") 112 } 113 } 114 115 if !IsExist(to) { 116 err := os.Mkdir(to, GetMode(from)) 117 118 if err != nil { 119 return err 120 } 121 } 122 123 return copyDir(from, to) 124 } 125 126 // TouchFile creates empty file 127 func TouchFile(path string, perm os.FileMode) error { 128 fd, err := os.OpenFile(path, os.O_CREATE, perm) 129 130 if err != nil { 131 return err 132 } 133 134 return fd.Close() 135 } 136 137 // ////////////////////////////////////////////////////////////////////////////////// // 138 139 func copyFile(from, to string, perms []os.FileMode) error { 140 var targetExist bool 141 var perm os.FileMode 142 143 if IsExist(to) { 144 targetExist = true 145 } 146 147 if len(perms) == 0 { 148 perm = GetMode(from) 149 } else { 150 perm = perms[0] 151 } 152 153 ffd, err := os.OpenFile(from, os.O_RDONLY, 0) 154 155 if err != nil { 156 return err 157 } 158 159 defer ffd.Close() 160 161 tfd, err := os.OpenFile(to, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, perm) 162 163 if err != nil { 164 return err 165 } 166 167 defer tfd.Close() 168 169 reader := bufio.NewReader(ffd) 170 171 _, err = io.Copy(tfd, reader) 172 173 if err != nil { 174 return err 175 } 176 177 if targetExist { 178 return os.Chmod(to, perm) 179 } 180 181 return nil 182 } 183 184 func moveFile(from, to string, perms []os.FileMode) error { 185 err := os.Rename(from, to) 186 187 if err != nil { 188 return err 189 } 190 191 if len(perms) == 0 { 192 return nil 193 } 194 195 return os.Chmod(to, perms[0]) 196 } 197 198 func copyDir(from, to string) error { 199 var err error 200 201 for _, target := range List(from, false) { 202 fp := from + "/" + target 203 tp := to + "/" + target 204 205 if IsDir(fp) { 206 err = os.Mkdir(tp, GetMode(fp)) 207 208 if err != nil { 209 return err 210 } 211 212 err = copyDir(fp, tp) 213 214 if err != nil { 215 return err 216 } 217 } else { 218 err = CopyFile(fp, tp) 219 220 if err != nil { 221 return err 222 } 223 } 224 } 225 226 return nil 227 }