(root string)
| 757 | } |
| 758 | |
| 759 | func gatherSymlinkOptions(root string) ([]symlinkOption, error) { |
| 760 | var options []symlinkOption |
| 761 | err := filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error { |
| 762 | if err != nil { |
| 763 | return err |
| 764 | } |
| 765 | if path == root { |
| 766 | return nil |
| 767 | } |
| 768 | if d.IsDir() && shouldSkipSymlinkDir(d.Name()) { |
| 769 | return filepath.SkipDir |
| 770 | } |
| 771 | |
| 772 | rel, err := filepath.Rel(root, path) |
| 773 | if err != nil { |
| 774 | return err |
| 775 | } |
| 776 | rel = filepath.Clean(rel) |
| 777 | display := filepath.ToSlash(rel) |
| 778 | opt := symlinkOption{ |
| 779 | Path: rel, |
| 780 | } |
| 781 | if d.IsDir() { |
| 782 | opt.Label = fmt.Sprintf("[D] %s/", display) |
| 783 | } else { |
| 784 | opt.Label = fmt.Sprintf("[F] %s", display) |
| 785 | } |
| 786 | options = append(options, opt) |
| 787 | if len(options) >= symlinkCandidateLimit { |
| 788 | return errSymlinkCandidateLimit |
| 789 | } |
| 790 | return nil |
| 791 | }) |
| 792 | if err != nil && !errors.Is(err, errSymlinkCandidateLimit) { |
| 793 | return nil, err |
| 794 | } |
| 795 | |
| 796 | sort.Slice(options, func(i, j int) bool { |
| 797 | return options[i].Label < options[j].Label |
| 798 | }) |
| 799 | return options, nil |
| 800 | } |
| 801 | |
| 802 | func shouldSkipSymlinkDir(name string) bool { |
| 803 | _, skip := symlinkSkipDirectories[name] |
no test coverage detected