github.com/scottcagno/storage@v1.8.0/pkg/filesystem/ls.go (about)

     1  package filesystem
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"io/fs"
     7  	"os"
     8  	"path/filepath"
     9  	"sort"
    10  	"strings"
    11  )
    12  
    13  var showAll = flag.Bool("a", false, "flag to output all files")
    14  var showLong = flag.Bool("l", false, "flag to output long format")
    15  var sortModTime = flag.Bool("t", false, "flag to sort output by modification time")
    16  var sortSize = flag.Bool("s", false, "flag to sort output by size")
    17  
    18  func LSCli() {
    19  	// parse flags
    20  	flag.Parse()
    21  	// if no file was given, copy stdin to stdout
    22  	if flag.NArg() == 0 {
    23  		ls(".")
    24  		return
    25  	}
    26  	// otherwise, a file was given, so use that as input
    27  	ls(flag.Arg(0))
    28  }
    29  
    30  func LS(dir string) {
    31  	if dir == "" {
    32  		dir = "."
    33  	}
    34  	ls(dir)
    35  }
    36  
    37  const doNotSkip bool = false
    38  
    39  func ls(dir string) {
    40  	// skip function
    41  	skip := func(de fs.DirEntry) bool {
    42  		return doNotSkip
    43  	}
    44  	// setup listing
    45  	var listing []fs.DirEntry
    46  	// walk dir path
    47  	err := filepath.WalkDir(dir, func(path string, de fs.DirEntry, err error) error {
    48  		if err != nil {
    49  			fmt.Fprintf(os.Stderr, "prevent panic by handling failure accessing a path %q: %v\n", path, err)
    50  			return err
    51  		}
    52  		if skip(de) {
    53  			return fs.SkipDir
    54  		}
    55  		if canPrint(de) {
    56  			listing = append(listing, de)
    57  			//fmt.Fprintf(os.Stdout, "%s", fmtEntry(de))
    58  		}
    59  		return nil
    60  	})
    61  	// check for errors
    62  	if err != nil {
    63  		fmt.Fprintf(os.Stderr, "%s", err)
    64  	}
    65  	// finish
    66  	printListing(listing)
    67  	if !*showLong {
    68  		fmt.Println()
    69  	}
    70  }
    71  
    72  func canPrint(de fs.DirEntry) bool {
    73  	if *showAll {
    74  		return true
    75  	}
    76  	return !strings.HasPrefix(de.Name(), ".")
    77  }
    78  
    79  func fmtEntry(de fs.DirEntry) string {
    80  	if *showLong {
    81  		return fmt.Sprintf("%s\n", de.Name())
    82  	}
    83  	return fmt.Sprintf("%s  ", de.Name())
    84  }
    85  
    86  func printListing(listing []fs.DirEntry) {
    87  	if *sortSize {
    88  		By(size).Sort(listing)
    89  	}
    90  	if *sortModTime {
    91  		By(modtime).Sort(listing)
    92  	}
    93  	for _, de := range listing {
    94  		fmt.Fprintf(os.Stdout, "%s", fmtEntry(de))
    95  	}
    96  }
    97  
    98  var size = func(d1, d2 fs.DirEntry) bool {
    99  	d1i, err := d1.Info()
   100  	if err != nil {
   101  		fmt.Fprintf(os.Stderr, "%s", err)
   102  	}
   103  	d2i, err := d2.Info()
   104  	if err != nil {
   105  		fmt.Fprintf(os.Stderr, "%s", err)
   106  	}
   107  	return d1i.Size() > d2i.Size()
   108  }
   109  
   110  var modtime = func(d1, d2 fs.DirEntry) bool {
   111  	d1i, err := d1.Info()
   112  	if err != nil {
   113  		fmt.Fprintf(os.Stderr, "%s", err)
   114  	}
   115  	d2i, err := d2.Info()
   116  	if err != nil {
   117  		fmt.Fprintf(os.Stderr, "%s", err)
   118  	}
   119  	return d1i.ModTime().UnixNano() > d2i.ModTime().UnixNano()
   120  }
   121  
   122  type dirEntrySorter struct {
   123  	entries []fs.DirEntry
   124  	by      func(e1, e2 fs.DirEntry) bool
   125  }
   126  
   127  func (des *dirEntrySorter) Len() int {
   128  	return len(des.entries)
   129  }
   130  
   131  func (des *dirEntrySorter) Swap(i, j int) {
   132  	des.entries[i], des.entries[j] = des.entries[j], des.entries[i]
   133  }
   134  
   135  func (des *dirEntrySorter) Less(i, j int) bool {
   136  	return des.by(des.entries[i], des.entries[j])
   137  }
   138  
   139  type By func(e1, e2 fs.DirEntry) bool
   140  
   141  func (by By) Sort(entries []fs.DirEntry) {
   142  	des := &dirEntrySorter{
   143  		entries: entries,
   144  		by:      by,
   145  	}
   146  	sort.Sort(des)
   147  }