179 lines
2.8 KiB
Go
179 lines
2.8 KiB
Go
package ls
|
|
import(
|
|
"os"
|
|
"fmt"
|
|
"strings"
|
|
"regexp"
|
|
"path"
|
|
"surdeus.su/core/cli/mtool"
|
|
)
|
|
|
|
var(
|
|
listHidden bool
|
|
args []string
|
|
)
|
|
|
|
var slashRegexp = regexp.MustCompile("/+")
|
|
|
|
func IsDir(p string) (bool, error) {
|
|
finfo, e := os.Stat(p)
|
|
if e != nil {
|
|
return false, e
|
|
}
|
|
return finfo.IsDir(), e
|
|
}
|
|
|
|
func ReadDir(p string) ([]os.FileInfo, error) {
|
|
f, e := os.Open(p)
|
|
if e != nil {
|
|
return nil, e
|
|
}
|
|
l, e := f.Readdir(-1)
|
|
if e != nil {
|
|
return nil, e
|
|
}
|
|
f.Close()
|
|
|
|
return l, nil
|
|
}
|
|
|
|
func
|
|
Stat(p string) (os.FileInfo, error) {
|
|
f, e := os.Open(p)
|
|
if e != nil {
|
|
return nil, e
|
|
}
|
|
s, e := f.Stat()
|
|
f.Close()
|
|
return s, nil
|
|
}
|
|
|
|
func findString(slice []string, val string) (int, bool) {
|
|
for i, v := range slice {
|
|
if v == val {
|
|
return i, true
|
|
}
|
|
}
|
|
return -1, false
|
|
}
|
|
|
|
func
|
|
isHidden(p string) bool {
|
|
if path.Base(p)[0] == '.' {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func shouldList(p string) bool {
|
|
if _, found := findString(args, p) ; found {
|
|
return true
|
|
}
|
|
if !listHidden && isHidden(p) {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func
|
|
deleteExceedSlashes(p string) string {
|
|
p = slashRegexp.ReplaceAllString(p, "/")
|
|
if p != "/" { // Do not trim if it is root dir.
|
|
p = strings.TrimRight(p, "/")
|
|
}
|
|
return p
|
|
}
|
|
|
|
func
|
|
ls(p string, fold int) error {
|
|
if !shouldList(p) {
|
|
return nil
|
|
}
|
|
|
|
p = deleteExceedSlashes(p)
|
|
|
|
isDir, e := IsDir(p)
|
|
if e != nil {
|
|
return e
|
|
}
|
|
|
|
|
|
if !isDir {
|
|
fmt.Println(p)
|
|
return nil
|
|
}
|
|
|
|
if fold>0 {
|
|
/* It's a directory and it can be ls-ed. */
|
|
l, e := ReadDir(p)
|
|
if e!=nil {
|
|
return e
|
|
}
|
|
for _, f := range l {
|
|
s := p+"/"+f.Name()
|
|
if b, _ := IsDir(s) ; b && fold!=1 {
|
|
fmt.Println(s)
|
|
}
|
|
ls(s, fold-1)
|
|
}
|
|
} else {
|
|
/* It's finish directory. Fold==0 or fold<0. */
|
|
fmt.Println(p)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func Run(flagSet *mtool.Flags) {
|
|
var foldLvl int
|
|
var rFlag bool
|
|
flagSet.BoolVar(&rFlag, "R", false, "set the '-r' flags value to the max depth (overrides the '-r')")
|
|
flagSet.IntVar(&foldLvl, "r", 1, "list recursively with choosing deepness, can't be negative or zero.")
|
|
flagSet.BoolVar(&listHidden, "a", false, "list hidden files.")
|
|
flagSet.Parse()
|
|
args = flagSet.Args()
|
|
|
|
if rFlag {
|
|
foldLvl = 9999999
|
|
}
|
|
if foldLvl<0 {
|
|
flagSet.Usage()
|
|
os.Exit(1)
|
|
}
|
|
|
|
if foldLvl==0 && len(args)==0 {
|
|
flagSet.Usage()
|
|
os.Exit(1)
|
|
}
|
|
|
|
if len(args) == 0 {
|
|
foldLvl -= 1
|
|
if l, e := ReadDir(".") ; e != nil {
|
|
fmt.Fprintf(os.Stderr, "%s.\n", e)
|
|
} else {
|
|
for _, f := range l {
|
|
if !shouldList(f.Name()) {
|
|
continue
|
|
}
|
|
isDir, _ := IsDir(f.Name())
|
|
|
|
fmt.Println(f.Name())
|
|
if isDir && foldLvl>0 {
|
|
e := ls(f.Name(), foldLvl)
|
|
if e!=nil {
|
|
fmt.Fprintf(os.Stderr,
|
|
"%s\n", e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
for _, p := range args {
|
|
e := ls(p, foldLvl)
|
|
if e != nil {
|
|
fmt.Fprintf(os.Stderr, "%s\n", e)
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|