2 Commits
Author SHA1 Message Date
Yash-Handa eea000f606 Added time formate flag 2020-08-30 14:25:02 +05:30
Yash-Handa 6679b87c63 Added Recursion 2020-08-30 12:48:45 +05:30
3 changed files with 161 additions and 24 deletions
+18 -1
View File
@@ -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"
```
+37 -4
View File
@@ -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:
+106 -19
View File
@@ -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() {