summaryrefslogtreecommitdiff
path: root/cmd/ls.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/ls.go')
-rw-r--r--cmd/ls.go168
1 files changed, 168 insertions, 0 deletions
diff --git a/cmd/ls.go b/cmd/ls.go
new file mode 100644
index 0000000..bcdbe66
--- /dev/null
+++ b/cmd/ls.go
@@ -0,0 +1,168 @@
+/*
+Copyright © 2025 NAME HERE <EMAIL ADDRESS>
+*/
+package cmd
+
+import (
+ "context"
+ "fmt"
+ "os"
+ "path/filepath"
+ "sync"
+
+ "github.com/scrotadamus/ghligh/document"
+ "github.com/spf13/cobra"
+)
+
+var recursive bool
+
+type resolver struct {
+ paths []string
+ recurse bool
+ ctx context.Context
+ ch chan<- string
+ wg sync.WaitGroup
+}
+
+func (r *resolver) resolve() {
+ for _, path := range r.paths {
+ r.wg.Add(1)
+ go r.resolvePath(path)
+ }
+
+ go func() {
+ r.wg.Wait()
+ close(r.ch)
+ }()
+}
+
+func (r *resolver) resolvePath(path string) {
+ defer r.wg.Done()
+ if err := r.ctx.Err(); err != nil {
+ return
+ }
+
+ entries, err := os.ReadDir(path)
+ if err != nil {
+ str, err := filepath.Abs(path)
+ if err != nil {
+ return
+ }
+
+ r.ch <- str
+ return
+ }
+
+ for _, entry := range entries {
+ info, err := entry.Info()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error retrieving info for %s: %v\n", entry.Name(), err)
+ continue
+ }
+
+ fullPath := filepath.Join(path, entry.Name())
+
+ if info.IsDir() {
+ if r.recurse {
+ if err := r.ctx.Err(); err != nil {
+ return
+ }
+ r.wg.Add(1)
+ go r.resolvePath(fullPath)
+ }
+ } else if info.Mode().IsRegular() {
+ r.ch <- fullPath
+ }
+ }
+}
+
+func lsArgs(args []string) []string {
+ if len(args) == 0 {
+ cwd, err := os.Getwd()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "%v\n", err)
+ os.Exit(1)
+ return nil
+ }
+ return []string{cwd}
+
+ }
+ return args
+}
+
+func checkFile(path string) bool {
+ doc, err := document.Open(path)
+ if err != nil {
+ return false
+ }
+ defer doc.Close()
+
+ return doc.HasHighlights()
+}
+
+// lsCmd represents the ls command
+var lsCmd = &cobra.Command{
+ Use: "ls",
+ Short: "show files with highlights or tagged with 'ls' [unix]",
+ Long: `
+ ghligh ls file1.pdf directory [-R] [-c]
+
+ will show every file inside directory that contains highlights or it is marked
+ ls with the ghligh tag add command
+
+ ghligh ls # show files in current dir
+ ghligh ls file1.pdf # if it outpus file1.pdf it means that file1.pdf contains highlights
+ ghligh ls -c file1.pdf # same as ghligh ls file1.pdf but exit status will not be if file1.pdf doesnt
+ contains highlights
+
+ ghligh ls -R # do it recursively, be careful with symlink dir cycles, as I am to lazy to
+ address that particular issue
+`,
+ Run: func(cmd *cobra.Command, args []string) {
+ files := lsArgs(args)
+ ch := make(chan string)
+ ctx := context.Background()
+
+ res := resolver{
+ paths: files,
+ recurse: recursive,
+ ctx: ctx,
+ ch: ch,
+ }
+
+ go res.resolve()
+
+ var wg sync.WaitGroup
+ var found bool
+ for file := range ch {
+ wg.Add(1)
+ go func(f string) {
+ defer wg.Done()
+ if checkFile(f) {
+ found = true
+ fmt.Printf("%s\n", f)
+ }
+ }(file)
+ }
+ wg.Wait()
+
+ check, err := cmd.Flags().GetBool("check")
+ if err != nil {
+ cmd.Help()
+ return
+ }
+ if check && !found {
+ os.Exit(1)
+ }
+
+ },
+}
+
+func init() {
+ rootCmd.AddCommand(lsCmd)
+
+ lsCmd.Flags().BoolVarP(&recursive, "recursive", "R", false, "List recursively")
+ lsCmd.Flags().BoolP("check", "c", false, "exit status is 1 if no file its found")
+ // order pdf by time of something (modification / creation) ???
+ //lsCmd.Flags().BoolP("time", "t", false, "ls by time")
+}