(ctx context.Context, srcPath, dstPath string)
| 564 | } |
| 565 | |
| 566 | func copyDecompressEntry(ctx context.Context, srcPath, dstPath string) (retErr error) { |
| 567 | if err := ctx.Err(); err != nil { |
| 568 | return err |
| 569 | } |
| 570 | info, err := os.Lstat(srcPath) |
| 571 | if err != nil { |
| 572 | return err |
| 573 | } |
| 574 | |
| 575 | if info.Mode()&os.ModeSymlink != 0 { |
| 576 | if err := os.RemoveAll(dstPath); err != nil { |
| 577 | return err |
| 578 | } |
| 579 | if err := os.MkdirAll(filepath.Dir(dstPath), constant.DirPerm); err != nil { |
| 580 | return err |
| 581 | } |
| 582 | target, err := os.Readlink(srcPath) |
| 583 | if err != nil { |
| 584 | return err |
| 585 | } |
| 586 | if err := os.Symlink(target, dstPath); err != nil { |
| 587 | return err |
| 588 | } |
| 589 | return applyDecompressOwnership(srcPath, dstPath) |
| 590 | } |
| 591 | |
| 592 | if info.IsDir() { |
| 593 | dstInfo, err := os.Lstat(dstPath) |
| 594 | keepExistingDir := err == nil && dstInfo.IsDir() && dstInfo.Mode()&os.ModeSymlink == 0 |
| 595 | if err != nil && !os.IsNotExist(err) { |
| 596 | return err |
| 597 | } |
| 598 | if !keepExistingDir { |
| 599 | if err := os.RemoveAll(dstPath); err != nil { |
| 600 | return err |
| 601 | } |
| 602 | if err := os.MkdirAll(dstPath, info.Mode().Perm()); err != nil { |
| 603 | return err |
| 604 | } |
| 605 | if err := applyDecompressOwnership(srcPath, dstPath); err != nil { |
| 606 | return err |
| 607 | } |
| 608 | } |
| 609 | entries, err := os.ReadDir(srcPath) |
| 610 | if err != nil { |
| 611 | return err |
| 612 | } |
| 613 | for _, entry := range entries { |
| 614 | if err := copyDecompressEntry(ctx, filepath.Join(srcPath, entry.Name()), filepath.Join(dstPath, entry.Name())); err != nil { |
| 615 | return err |
| 616 | } |
| 617 | } |
| 618 | if keepExistingDir { |
| 619 | return nil |
| 620 | } |
| 621 | return os.Chtimes(dstPath, info.ModTime(), info.ModTime()) |
| 622 | } |
| 623 |
no test coverage detected