github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/ls/fileinfo_plan9.go (about) 1 // Copyright 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 //go:build plan9 6 // +build plan9 7 8 package ls 9 10 import ( 11 "fmt" 12 "os" 13 "regexp" 14 "strconv" 15 "syscall" 16 "time" 17 18 humanize "github.com/dustin/go-humanize" 19 ) 20 21 // Matches characters which would interfere with ls's formatting. 22 var unprintableRe = regexp.MustCompile("[[:cntrl:]\n]") 23 24 // FileInfo holds file metadata. 25 // 26 // Since `os.FileInfo` is an interface, it is difficult to tweak some of its 27 // internal values. For example, replacing the starting directory with a dot. 28 // `extractImportantParts` populates our own struct which we can modify at will 29 // before printing. 30 type FileInfo struct { 31 Name string 32 Mode os.FileMode 33 UID string 34 Size int64 35 MTime time.Time 36 } 37 38 // FromOSFileInfo converts os.FileInfo to an ls.FileInfo. 39 func FromOSFileInfo(path string, fi os.FileInfo) FileInfo { 40 return FileInfo{ 41 Name: fi.Name(), 42 Mode: fi.Mode(), 43 // Plan 9 UIDs from the file system are strings. 44 UID: fi.Sys().(*syscall.Dir).Uid, 45 Size: fi.Size(), 46 MTime: fi.ModTime(), 47 } 48 } 49 50 // PrintableName returns a printable file name. 51 func (fi FileInfo) PrintableName() string { 52 return unprintableRe.ReplaceAllLiteralString(fi.Name, "?") 53 } 54 55 // Stringer provides a consistent way to format FileInfo. 56 type Stringer interface { 57 // FileString formats a FileInfo. 58 FileString(fi FileInfo) string 59 } 60 61 // NameStringer is a Stringer implementation that just prints the name. 62 type NameStringer struct{} 63 64 // FileString implements Stringer.FileString and just returns fi's name. 65 func (ns NameStringer) FileString(fi FileInfo) string { 66 return fi.PrintableName() 67 } 68 69 // QuotedStringer is a Stringer that returns the file name surrounded by qutoes 70 // with escaped control characters. 71 type QuotedStringer struct{} 72 73 // FileString returns the name surrounded by quotes with escaped control characters. 74 func (qs QuotedStringer) FileString(fi FileInfo) string { 75 return fmt.Sprintf("%#v", fi.Name) 76 } 77 78 // LongStringer is a Stringer that returns the file info formatted in `ls -l` 79 // long format. 80 type LongStringer struct { 81 Human bool 82 Name Stringer 83 } 84 85 // FileString implements Stringer.FileString. 86 func (ls LongStringer) FileString(fi FileInfo) string { 87 var size string 88 if ls.Human { 89 size = humanize.Bytes(uint64(fi.Size)) 90 } else { 91 size = strconv.FormatInt(fi.Size, 10) 92 } 93 // Ex: -rw-rw---- myuser 1256 Feb 6 09:31 recipes.txt 94 return fmt.Sprintf("%s\t%s\t%s\t%v\t%s", 95 fi.Mode.String(), 96 fi.UID, 97 size, 98 fi.MTime.Format("Jan _2 15:04"), 99 ls.Name.FileString(fi)) 100 }