|
4 | 4 | "context" |
5 | 5 | "errors" |
6 | 6 | "fmt" |
| 7 | + "io" |
7 | 8 | "io/ioutil" |
8 | 9 | "os" |
9 | 10 | "path/filepath" |
@@ -317,11 +318,43 @@ func (c *Client) get(ctx context.Context, req *Request, g Getter) (*GetResult, * |
317 | 318 | return nil, &getError{true, err} |
318 | 319 | } |
319 | 320 |
|
320 | | - err = copyDir(ctx, req.realDst, subDir, false, req.DisableSymlinks, req.umask()) |
321 | | - if err != nil { |
322 | | - return nil, &getError{false, err} |
| 321 | + if stat, err := os.Stat(subDir); err != nil { |
| 322 | + return nil, &getError{false, fmt.Errorf("failed to stat '%s': %w", subDir, err)} |
| 323 | + } else if stat.IsDir() { |
| 324 | + err = copyDir(ctx, req.realDst, subDir, false, req.DisableSymlinks, req.umask()) |
| 325 | + if err != nil { |
| 326 | + return nil, &getError{false, err} |
| 327 | + } |
| 328 | + return &GetResult{req.realDst}, nil |
| 329 | + } else { |
| 330 | + src, err := os.Open(subDir) |
| 331 | + if err != nil { |
| 332 | + return nil, &getError{false, fmt.Errorf("failed to open local source file at '%s': %w", subDir, err)} |
| 333 | + } |
| 334 | + //goland:noinspection GoUnhandledErrorResult |
| 335 | + defer src.Close() |
| 336 | + |
| 337 | + target := filepath.Join(req.realDst, filepath.Base(subDir)) |
| 338 | + dst, err := os.Create(target) |
| 339 | + if err != nil { |
| 340 | + return nil, &getError{false, fmt.Errorf("failed to open local target file at '%s': %w", target, err)} |
| 341 | + } |
| 342 | + //goland:noinspection GoUnhandledErrorResult |
| 343 | + defer dst.Close() |
| 344 | + |
| 345 | + buf := make([]byte, 1024*20) // 20k buffer should usually suffice for 99% of files |
| 346 | + for { |
| 347 | + n, err := src.Read(buf) |
| 348 | + if err != nil && err != io.EOF { |
| 349 | + return nil, &getError{false, fmt.Errorf("failed to read local source file at '%s': %w", subDir, err)} |
| 350 | + } else if n == 0 { |
| 351 | + break |
| 352 | + } else if _, err := dst.Write(buf[:n]); err != nil { |
| 353 | + return nil, &getError{false, fmt.Errorf("failed to write to local source file at '%s': %w", target, err)} |
| 354 | + } |
| 355 | + } |
| 356 | + return &GetResult{target}, nil |
323 | 357 | } |
324 | | - return &GetResult{req.realDst}, nil |
325 | 358 | } |
326 | 359 |
|
327 | 360 | return &GetResult{req.Dst}, nil |
|
0 commit comments