mirror of
https://github.com/Yash-Handa/logo-ls.git
synced 2026-08-28 02:24:49 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eea000f606 | ||
|
|
6679b87c63 |
@@ -1,5 +1,5 @@
|
||||
```txt
|
||||
Usage: logo-ls [-1?aAdgGhlorSstUvVX] [files ...]
|
||||
Usage: logo-ls [-1?aAdgGhloRrSstUvVX] [-T value] [files ...]
|
||||
-1 list one file per line.
|
||||
-? display this help and exit
|
||||
-a, --all do not ignore entries starting with .
|
||||
@@ -11,12 +11,29 @@ Usage: logo-ls [-1?aAdgGhlorSstUvVX] [files ...]
|
||||
with -l and -s, print sizes like 1K 234M 2G etc.
|
||||
-l use a long listing format
|
||||
-o like -l, but do not list group information
|
||||
-R, --recursive list subdirectories recursively
|
||||
-r, --reverse reverse order while sorting
|
||||
-S sort by file size, largest first
|
||||
-s, --size print the allocated size of each file, in blocks
|
||||
-t sort by modification time, newest first
|
||||
-T, --time-style=value
|
||||
time/date format with -l; see time-style below [Stamp]
|
||||
-U do not sort; list entries in directory order
|
||||
-v natural sort of (version) numbers within text
|
||||
-V, --version output version information and exit
|
||||
-X sort alphabetically by entry extension
|
||||
|
||||
Possible value for --time-style (-T)
|
||||
ANSIC "Mon Jan _2 15:04:05 2006"
|
||||
UnixDate "Mon Jan _2 15:04:05 MST 2006"
|
||||
RubyDate "Mon Jan 02 15:04:05 -0700 2006"
|
||||
RFC822 "02 Jan 06 15:04 MST"
|
||||
RFC822Z "02 Jan 06 15:04 -0700"
|
||||
RFC850 "Monday, 02-Jan-06 15:04:05 MST"
|
||||
RFC1123 "Mon, 02 Jan 2006 15:04:05 MST"
|
||||
RFC1123Z "Mon, 02 Jan 2006 15:04:05 -0700"
|
||||
RFC3339 "2006-01-02T15:04:05Z07:00"
|
||||
Kitchen "3:04PM"
|
||||
Stamp "Mon Jan _2 15:04:05" [Default]
|
||||
StampMilli "Jan _2 15:04:05.000"
|
||||
```
|
||||
|
||||
@@ -4,6 +4,8 @@ package main
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
@@ -28,8 +30,8 @@ type file struct {
|
||||
type dir struct {
|
||||
info *file
|
||||
parent *file
|
||||
files []*file // all child files and dirs
|
||||
dirs []*file // for recursion contain only child dirs
|
||||
files []*file // all child files and dirs
|
||||
dirs []string // for recursion contain only child dirs
|
||||
less func(int, int) bool
|
||||
}
|
||||
|
||||
@@ -94,7 +96,7 @@ func newDir(d *os.File) (*dir, error) {
|
||||
}
|
||||
t.files = append(t.files, f)
|
||||
if v.IsDir() {
|
||||
t.dirs = append(t.dirs, f)
|
||||
t.dirs = append(t.dirs, name+"/")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,6 +164,37 @@ func newDir_ArgFiles(files []os.FileInfo) *dir {
|
||||
return t
|
||||
}
|
||||
|
||||
func newDirs_Recussion(d *os.File) {
|
||||
dd, err := newDir(d)
|
||||
d.Close()
|
||||
if err != nil {
|
||||
log.Printf("partial access to %q: %v\n", d.Name(), err)
|
||||
_ = set_osExitCode(code_Minor)
|
||||
}
|
||||
// print the info of the files of the directory
|
||||
io.Copy(os.Stdout, dd.print())
|
||||
if len(dd.dirs) == 0 {
|
||||
return
|
||||
}
|
||||
// at this point dd.print has sorted the children files
|
||||
// but not using it instead printing children in directory order
|
||||
temp := make([]string, len(dd.dirs))
|
||||
for i, v := range dd.dirs {
|
||||
temp[i] = filepath.Join(d.Name(), v)
|
||||
}
|
||||
for _, v := range temp {
|
||||
fmt.Printf("\n%s:\n", v)
|
||||
f, err := os.Open(v)
|
||||
if err != nil {
|
||||
log.Printf("cannot access %q: %v\n", v, err)
|
||||
f.Close()
|
||||
_ = set_osExitCode(code_Minor)
|
||||
continue
|
||||
}
|
||||
newDirs_Recussion(f)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *dir) print() *bytes.Buffer {
|
||||
// take care of printing, extending symbolic links in long forms
|
||||
|
||||
@@ -183,7 +216,7 @@ func (d *dir) print() *bytes.Buffer {
|
||||
if flagVector&flag_s > 0 {
|
||||
fmt.Fprintf(w, "%s\t", getSizeInFormate(v.blocks*512))
|
||||
}
|
||||
fmt.Fprintf(w, fmtStr, v.mode, v.owner, v.group, getSizeInFormate(v.size), v.modTime.Format(time.Stamp), v.name+v.ext+v.indicator)
|
||||
fmt.Fprintf(w, fmtStr, v.mode, v.owner, v.group, getSizeInFormate(v.size), v.modTime.Format(timeFormate), v.name+v.ext+v.indicator)
|
||||
}
|
||||
w.Flush()
|
||||
case flagVector&flag_1 > 0:
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/pborman/getopt/v2"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
@@ -20,6 +21,7 @@ const (
|
||||
flag_alpha // sort in alphabetic order (default)
|
||||
flag_A
|
||||
flag_h
|
||||
flag_R
|
||||
flag_r
|
||||
flag_S
|
||||
flag_t
|
||||
@@ -40,6 +42,29 @@ var flagVector uint
|
||||
// terminal width for formatting
|
||||
var terminalWidth int
|
||||
|
||||
// time formate
|
||||
var timeFormate string
|
||||
|
||||
const (
|
||||
code_OK int = iota
|
||||
code_Minor
|
||||
code_Serious
|
||||
)
|
||||
|
||||
// os exit code (do not update manually)
|
||||
var osExitCode int = code_OK
|
||||
|
||||
// only use set_osExitCode to update the value of osExitCode
|
||||
func set_osExitCode(c int) int {
|
||||
switch {
|
||||
case c == code_Serious:
|
||||
osExitCode = code_Serious
|
||||
case c == code_Minor && osExitCode != code_Serious:
|
||||
osExitCode = code_Minor
|
||||
}
|
||||
return osExitCode
|
||||
}
|
||||
|
||||
func main() {
|
||||
// content flags
|
||||
f_a := getopt.BoolLong("all", 'a', "do not ignore entries starting with .")
|
||||
@@ -63,6 +88,8 @@ func main() {
|
||||
f_t := getopt.Bool('t', "sort by modification time, newest first")
|
||||
|
||||
f_r := getopt.BoolLong("reverse", 'r', "reverse order while sorting")
|
||||
f_R := getopt.BoolLong("recursive", 'R', "list subdirectories recursively")
|
||||
f_T := getopt.EnumLong("time-style", 'T', []string{"Stamp", "StampMilli", "Kitchen", "ANSIC", "UnixDate", "RubyDate", "RFC1123", "RFC1123Z", "RFC3339", "RFC822", "RFC822Z", "RFC850"}, "Stamp", "time/date format with -l; see time-style below")
|
||||
|
||||
f_help := getopt.Bool('?', "display this help and exit")
|
||||
f_V := getopt.BoolLong("version", 'V', "output version information and exit")
|
||||
@@ -72,19 +99,32 @@ func main() {
|
||||
if err != nil {
|
||||
// code to handle error
|
||||
log.Printf("%v\nTry 'logo-ls -?' for more information.", err)
|
||||
os.Exit(2)
|
||||
os.Exit(set_osExitCode(code_Serious))
|
||||
}
|
||||
|
||||
// if f_help is provided print help and exit(0)
|
||||
if *f_help {
|
||||
getopt.PrintUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
fmt.Println("\nPossible value for --time-style (-T)")
|
||||
fmt.Printf("%-11s %-32q\n", "ANSIC", "Mon Jan _2 15:04:05 2006")
|
||||
fmt.Printf("%-11s %-32q\n", "UnixDate", "Mon Jan _2 15:04:05 MST 2006")
|
||||
fmt.Printf("%-11s %-32q\n", "RubyDate", "Mon Jan 02 15:04:05 -0700 2006")
|
||||
fmt.Printf("%-11s %-32q\n", "RFC822", "02 Jan 06 15:04 MST")
|
||||
fmt.Printf("%-11s %-32q\n", "RFC822Z", "02 Jan 06 15:04 -0700")
|
||||
fmt.Printf("%-11s %-32q\n", "RFC850", "Monday, 02-Jan-06 15:04:05 MST")
|
||||
fmt.Printf("%-11s %-32q\n", "RFC1123", "Mon, 02 Jan 2006 15:04:05 MST")
|
||||
fmt.Printf("%-11s %-32q\n", "RFC1123Z", "Mon, 02 Jan 2006 15:04:05 -0700")
|
||||
fmt.Printf("%-11s %-32q\n", "RFC3339", "2006-01-02T15:04:05Z07:00")
|
||||
fmt.Printf("%-11s %-32q\n", "Kitchen", "3:04PM")
|
||||
fmt.Printf("%-11s %-32q [Default]\n", "Stamp", "Mon Jan _2 15:04:05")
|
||||
fmt.Printf("%-11s %-32q\n", "StampMilli", "Jan _2 15:04:05.000")
|
||||
os.Exit(osExitCode)
|
||||
}
|
||||
|
||||
// if f_V is provided version will be printed and exit(0)
|
||||
if *f_V {
|
||||
fmt.Printf("logo-ls %s\nCopyright (c) 2020 Yash Handa\nLicense MIT <https://opensource.org/licenses/MIT>.\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law.\n", "v0.0.0")
|
||||
os.Exit(0)
|
||||
fmt.Printf("logo-ls %s\nCopyright (c) 2020 Yash Handa\nLicense MIT <https://opensource.org/licenses/MIT>.\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law.\n", "v1.1.0")
|
||||
os.Exit(osExitCode)
|
||||
}
|
||||
|
||||
// set one of -A and -a priority -A > -a
|
||||
@@ -116,6 +156,11 @@ func main() {
|
||||
flagVector |= flag_r
|
||||
}
|
||||
|
||||
// set recursion (-R) flag
|
||||
if *f_R {
|
||||
flagVector |= flag_R
|
||||
}
|
||||
|
||||
// set -1 flag
|
||||
if *f_1 {
|
||||
flagVector |= flag_1
|
||||
@@ -131,6 +176,36 @@ func main() {
|
||||
flagVector |= flag_G
|
||||
}
|
||||
|
||||
// set time formate
|
||||
switch *f_T {
|
||||
case "Stamp":
|
||||
timeFormate = time.Stamp
|
||||
case "StampMilli":
|
||||
timeFormate = time.StampMilli
|
||||
case "Kitchen":
|
||||
timeFormate = time.Kitchen
|
||||
case "ANSIC":
|
||||
timeFormate = time.ANSIC
|
||||
case "UnixDate":
|
||||
timeFormate = time.UnixDate
|
||||
case "RubyDate":
|
||||
timeFormate = time.RubyDate
|
||||
case "RFC1123":
|
||||
timeFormate = time.RFC1123
|
||||
case "RFC1123Z":
|
||||
timeFormate = time.RFC1123Z
|
||||
case "RFC3339":
|
||||
timeFormate = time.RFC3339
|
||||
case "RFC822":
|
||||
timeFormate = time.RFC822
|
||||
case "RFC822Z":
|
||||
timeFormate = time.RFC822Z
|
||||
case "RFC850":
|
||||
timeFormate = time.RFC850
|
||||
default:
|
||||
timeFormate = time.Stamp
|
||||
}
|
||||
|
||||
// set -h flag
|
||||
if *f_h {
|
||||
flagVector |= flag_h
|
||||
@@ -179,14 +254,14 @@ func main() {
|
||||
if err != nil {
|
||||
log.Printf("cannot access %q: %v\n", v, err)
|
||||
d.Close()
|
||||
defer os.Exit(2)
|
||||
_ = set_osExitCode(code_Serious)
|
||||
continue
|
||||
}
|
||||
ds, err := d.Stat()
|
||||
if err != nil {
|
||||
log.Printf("cannot access %q: %v\n", v, err)
|
||||
d.Close()
|
||||
defer os.Exit(2)
|
||||
_ = set_osExitCode(code_Serious)
|
||||
continue
|
||||
}
|
||||
if ds.IsDir() {
|
||||
@@ -203,24 +278,36 @@ func main() {
|
||||
}
|
||||
|
||||
// process and display all the dirs in arg
|
||||
pName := len(dirs) > 1
|
||||
for i, v := range args.dirs {
|
||||
if pName {
|
||||
if flagVector&flag_R > 0 {
|
||||
// use recursive func
|
||||
for i, v := range args.dirs {
|
||||
if i > 0 {
|
||||
fmt.Println()
|
||||
}
|
||||
fmt.Printf("%s:\n", v.Name())
|
||||
newDirs_Recussion(v)
|
||||
}
|
||||
d, err := newDir(v)
|
||||
v.Close()
|
||||
if err != nil {
|
||||
log.Printf("partial access to %q: %v\n", v.Name(), err)
|
||||
defer os.Exit(2)
|
||||
}
|
||||
// print the info of the files of the directory
|
||||
io.Copy(os.Stdout, d.print())
|
||||
if i < len(args.dirs)-1 {
|
||||
fmt.Println()
|
||||
} else {
|
||||
pName := len(dirs) > 1
|
||||
for i, v := range args.dirs {
|
||||
if pName {
|
||||
fmt.Printf("%s:\n", v.Name())
|
||||
}
|
||||
d, err := newDir(v)
|
||||
v.Close()
|
||||
if err != nil {
|
||||
log.Printf("partial access to %q: %v\n", v.Name(), err)
|
||||
_ = set_osExitCode(code_Serious)
|
||||
}
|
||||
// print the info of the files of the directory
|
||||
io.Copy(os.Stdout, d.print())
|
||||
if i < len(args.dirs)-1 {
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
os.Exit(osExitCode)
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
Reference in New Issue
Block a user