writeToOutput writes file content to a local path and returns the final destination. A symlink target is refused, a directory target receives the file under its remote basename, and missing parent directories are created. Existing files are only overwritten when clobber is true.
(file *repoFile, output string, clobber bool)
| 254 | // A symlink target is refused, a directory target receives the file under its remote basename, |
| 255 | // and missing parent directories are created. Existing files are only overwritten when clobber is true. |
| 256 | func writeToOutput(file *repoFile, output string, clobber bool) (string, error) { |
| 257 | dest := output |
| 258 | |
| 259 | // A trailing separator signals the user intends dest to be a directory even if it does not exist yet. |
| 260 | asDir := strings.HasSuffix(dest, "/") || strings.HasSuffix(dest, string(os.PathSeparator)) |
| 261 | |
| 262 | if lr, err := lstatF(dest); err == nil { |
| 263 | if lr.isSymlink { |
| 264 | return "", fmt.Errorf("output path is a symlink") |
| 265 | } |
| 266 | if lr.isDir { |
| 267 | asDir = true |
| 268 | } |
| 269 | } else if !os.IsNotExist(err) { |
| 270 | return "", err |
| 271 | } |
| 272 | |
| 273 | if asDir { |
| 274 | dest = filepath.Join(dest, file.Name) |
| 275 | } |
| 276 | |
| 277 | if lr, err := lstatF(dest); err == nil { |
| 278 | if lr.isSymlink { |
| 279 | return "", fmt.Errorf("output path is a symlink") |
| 280 | } |
| 281 | if !clobber { |
| 282 | return "", fmt.Errorf("output path already exists: %q (use --clobber to overwrite)", dest) |
| 283 | } |
| 284 | } else if !os.IsNotExist(err) { |
| 285 | return "", err |
| 286 | } |
| 287 | |
| 288 | if dir := filepath.Dir(dest); dir != "" && dir != "." { |
| 289 | if err := mkdirAllF(dir, 0755); err != nil { |
| 290 | return "", err |
| 291 | } |
| 292 | } |
| 293 | |
| 294 | if err := writeFileF(dest, file.Content, 0644); err != nil { |
| 295 | return "", err |
| 296 | } |
| 297 | |
| 298 | return dest, nil |
| 299 | } |
| 300 | |
| 301 | // binaryContentType reports whether content appears to be binary and, if so, returns |
| 302 | // its detected MIME type. Textual content returns ("", false). |