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