github.com/PaulioRandall/go-cookies@v0.1.1/cookies/files.go (about) 1 package cookies 2 3 import ( 4 "fmt" 5 "io" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "strconv" 10 "strings" 11 ) 12 13 // WorkDirHistory is the working directory stack used by Pushd and Popd 14 // functions. 15 var WorkDirHistory = []string{} 16 17 // Pushd emulates pushd bash command. 18 func Pushd(dir string) error { 19 curr, e := os.Getwd() 20 if e != nil { 21 return e 22 } 23 if e = os.Chdir(dir); e != nil { 24 return e 25 } 26 WorkDirHistory = append(WorkDirHistory, curr) 27 return nil 28 } 29 30 // Popd emulates the popd bash command. 31 func Popd() error { 32 if len(WorkDirHistory) == 0 { 33 return nil 34 } 35 last := len(WorkDirHistory) - 1 36 dir := WorkDirHistory[last] 37 if e := os.Chdir(dir); e != nil { 38 return e 39 } 40 WorkDirHistory = WorkDirHistory[:last] 41 return nil 42 } 43 44 // FileExists returns true if the file exists, false if not, and an error if 45 // file existence could not be determined. 46 func FileExists(f string) (bool, error) { 47 _, e := os.Stat(f) 48 if os.IsNotExist(e) { 49 return false, nil 50 } 51 return true, e 52 } 53 54 // IsDir returns true if the file exists and is a directory. An error is 55 // returned if this could not be determined. 56 func IsDir(f string) (bool, error) { 57 stat, e := os.Stat(f) 58 if os.IsNotExist(e) { 59 return false, nil 60 } 61 if e != nil { 62 return false, e 63 } 64 return stat.Mode().IsDir(), nil 65 } 66 67 // IsRegFile returns true if the file exists and is a regular file. An error is 68 // returned if this could not be determined. 69 func IsRegFile(f string) (bool, error) { 70 stat, e := os.Stat(f) 71 if os.IsNotExist(e) { 72 return false, nil 73 } 74 if e != nil { 75 return false, e 76 } 77 return stat.Mode().IsRegular(), nil 78 } 79 80 // SameFile returns true if the two files 'a' and 'b' describe the same file 81 // as determined by os.SameFile. An error is returned if the file info could 82 // not be retreived for either file. 83 func SameFile(a, b string) (bool, error) { 84 aStat, e := os.Stat(a) 85 if e != nil { 86 return false, e 87 } 88 bStat, e := os.Stat(b) 89 if e != nil { 90 return false, e 91 } 92 return os.SameFile(aStat, bStat), nil 93 } 94 95 // CopyFile copies the single file 'src' to 'dst'. 96 func CopyFile(src, dst string, overwrite bool) error { 97 98 if ok, e := IsRegFile(src); e != nil || !ok { 99 return fmt.Errorf("Missing or not a regular file: %s", src) 100 } 101 102 if !overwrite { 103 ok, e := FileExists(dst) 104 if e != nil { 105 return e 106 } 107 if ok { 108 return fmt.Errorf("Destination already exists: %s", dst) 109 } 110 } 111 112 same, e := SameFile(src, dst) 113 if e == nil && same { 114 return fmt.Errorf("Destination is the same as source: %s == %s", dst, src) 115 } 116 117 return NoCheckCopyFile(src, dst) 118 } 119 120 // NoCheckCopyFile copies the single file 'src' to 'dst' and doesn't make any 121 // attempt to check the file paths before hand. 122 func NoCheckCopyFile(src, dst string) error { 123 124 srcFile, e := os.Open(src) 125 if e != nil { 126 return e 127 } 128 defer srcFile.Close() 129 130 dstFile, e := os.Create(dst) 131 if e != nil { 132 return e 133 } 134 defer dstFile.Close() 135 136 _, e = io.Copy(dstFile, srcFile) 137 if e != nil { 138 return e 139 } 140 141 return nil 142 } 143 144 // FileToQuote returns the bytes of the input file as as a quoted string so it 145 // may be embedded in source code. Use []byte(quotedString) to decode. 146 func FileToQuote(file string) (string, error) { 147 b, e := ioutil.ReadFile(file) 148 if e != nil { 149 return "", e 150 } 151 s := strconv.Quote(string(b)) 152 return s, nil 153 } 154 155 // CreateFiles creates the files and directories within 'files' with 'root' as 156 // the root directory. 'files' contains a set of relative file paths mapped to 157 // the their required content. If the file is a directory it must be suffixed 158 // with a '/' and the mapped data will be ignored. 159 func CreateFiles(root string, mode os.FileMode, files map[string][]byte) error { 160 161 createFile := func(f string, data []byte) error { 162 parent := filepath.Dir(f) 163 if e := os.MkdirAll(parent, mode); e != nil { // Create parents if missing 164 return e 165 } 166 return ioutil.WriteFile(f, data, mode) 167 } 168 169 createDir := func(d string) error { 170 if exists, e := FileExists(d); e != nil || exists { 171 return e 172 } 173 return os.MkdirAll(d, mode) 174 } 175 176 for p, data := range files { 177 f := filepath.Join(root, p) 178 179 if strings.HasSuffix(p, "/") { 180 if e := createDir(f); e != nil { 181 return e 182 } 183 continue 184 } 185 186 if e := createFile(f, data); e != nil { 187 return e 188 } 189 } 190 191 return nil 192 }