gopkg.in/hugelgupf/u-root.v9@v9.0.0-20180831063832-3f6f1057f09b/cmds/ls/ls.go (about) 1 // Copyright 2013-2017 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Ls prints the contents of a directory. 6 // 7 // Synopsis: 8 // ls [OPTIONS] [DIRS]... 9 // 10 // Options: 11 // -l: long form 12 // -Q: quoted 13 // -R: equivalent to findutil's find 14 // 15 // Bugs: 16 // With the `-R` flag, directories are only ever printed once. 17 package main 18 19 import ( 20 "fmt" 21 "io" 22 "log" 23 "os" 24 "path/filepath" 25 "text/tabwriter" 26 27 flag "github.com/spf13/pflag" 28 ) 29 30 var ( 31 all = flag.BoolP("all", "a", false, "show hidden files") 32 human = flag.BoolP("human-readable", "h", false, "human readable sizes") 33 long = flag.BoolP("long", "l", false, "long form") 34 quoted = flag.BoolP("quote-name", "Q", false, "quoted") 35 recurse = flag.BoolP("recursive", "R", false, "equivalent to findutil's find") 36 ) 37 38 func stringer(fi fileInfo) fmt.Stringer { 39 var s fmt.Stringer = fi 40 if *quoted { 41 s = quotedStringer{fileInfo: fi} 42 } 43 if *long { 44 s = longStringer{ 45 fileInfo: fi, 46 comp: s, 47 human: *human, 48 } 49 } 50 return s 51 } 52 53 func listName(d string, w io.Writer, prefix bool) error { 54 return filepath.Walk(d, func(path string, osfi os.FileInfo, err error) error { 55 // Soft error. Useful when a permissions are insufficient to 56 // stat one of the files. 57 if err != nil { 58 log.Printf("%s: %v\n", path, err) 59 return nil 60 } 61 62 fi := extractImportantParts(path, osfi) 63 64 if *recurse { 65 // Mimic find command 66 fi.name = path 67 } else if path == d { 68 // Starting directory is a dot when non-recursive 69 if osfi.IsDir() { 70 fi.name = "." 71 if prefix { 72 fmt.Printf("%q\n", d) 73 } 74 } 75 } 76 77 // Hide .files unless -a was given 78 if *all || fi.name[0] != '.' { 79 // Print the file in the proper format. 80 fmt.Fprintln(w, stringer(fi)) 81 } 82 83 // Skip directories when non-recursive. 84 if path != d && fi.mode.IsDir() && !*recurse { 85 return filepath.SkipDir 86 } 87 return nil 88 }) 89 } 90 91 func main() { 92 flag.Parse() 93 94 // Write output in tabular form. 95 w := new(tabwriter.Writer) 96 w.Init(os.Stdout, 0, 0, 1, ' ', 0) 97 defer w.Flush() 98 99 // Array of names to list. 100 names := flag.Args() 101 if len(names) == 0 { 102 names = []string{"."} 103 } 104 105 // Is a name a directory? If so, list it in its own section. 106 prefix := len(names) > 1 107 for _, d := range names { 108 if err := listName(d, w, prefix); err != nil { 109 log.Printf("error while listing %#v: %v", d, err) 110 } 111 w.Flush() 112 } 113 }