|
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