]> Cypherpunks.ru repositories - goredo.git/commitdiff
Recursively search for all sources. Ability to narrow results
authorSergey Matveev <stargrave@stargrave.org>
Mon, 21 Jun 2021 12:56:07 +0000 (15:56 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Mon, 21 Jun 2021 13:35:24 +0000 (16:35 +0300)
doc/cmds.texi
doc/news.texi
main.go
sources.go
targets.go
usage.go

index d0e93c3de7338514f5b4b7c857191b4504a38bee..578d182ce65f43015cf5d292cc522d965269a614 100644 (file)
 
 @item redo-log
     Display @url{http://cr.yp.to/libtai/tai64.html, TAI64N} timestamped
-    last @command{stderr} of the target.
+    last @command{stderr} of the target, captured before.
 
 @item redo-targets, redo-sources, redo-ood
-    List known targets, sources and out-of-date targets.
+    List known targets, sources and out-of-date targets. You can limit
+    results by specifying explicit targets you are interested in.
+    @command{redo-sources} shows all recursive source files given
+    targets depend on.
 
 @item redo-stamp
     Record stamp dependency. Nothing more, dummy. Read about
index 36f6aa948c965390bdd87841e8bbe956e9c409e8..c2674ae4ffed7bb3b75d07e5e63c95a898e0db9b 100644 (file)
@@ -1,6 +1,20 @@
 @node News
 @unnumbered News
 
+@anchor{Release 1.5.0}
+@section Release 1.5.0
+@itemize
+@item
+    @command{redo-ood}, @command{redo-sources} and
+    @command{redo-targets} can optionally take list of targets to apply
+    the command on, to narrow the result.
+@item
+    @command{redo-sources} mistakenly missed @file{.do} files in the output.
+@item
+    @command{redo-sources} now recursively searches for all source
+    files, not the "first" depth level ones.
+@end itemize
+
 @anchor{Release 1.4.1}
 @section Release 1.4.1
 @itemize
diff --git a/main.go b/main.go
index f6668c2425aeb614dc7103a1f71a709f81700689..092d38957ce4cd50bbef6cacaa8db5d88c45c65b 100644 (file)
--- a/main.go
+++ b/main.go
@@ -226,6 +226,7 @@ func main() {
 
        tgts := flag.Args()
        BuildUUID = os.Getenv(EnvBuildUUID)
+       tgtsWasEmpty := len(tgts) == 0
        if BuildUUID == "" {
                raw := new([16]byte)
                if _, err = io.ReadFull(rand.Reader, raw[:]); err != nil {
@@ -236,7 +237,7 @@ func main() {
                        "%x-%x-%x-%x-%x",
                        raw[0:4], raw[4:6], raw[6:8], raw[8:10], raw[10:],
                )
-               if len(tgts) == 0 {
+               if tgtsWasEmpty {
                        tgts = []string{"all"}
                }
        }
@@ -359,13 +360,24 @@ CmdSwitch:
                        fmt.Println(rel)
                }
        case "redo-targets":
-               tgts, err = targetsWalker(Cwd)
+               if tgtsWasEmpty {
+                       tgts = []string{Cwd}
+               }
+               tgts, err = targetsWalker(tgts)
+               if err != nil {
+                       break
+               }
                sort.Strings(tgts)
                for _, tgt := range tgts {
                        fmt.Println(tgt)
                }
        case "redo-ood":
-               tgts, err = targetsWalker(Cwd)
+               if tgtsWasEmpty {
+                       tgts, err = targetsWalker([]string{Cwd})
+                       if err != nil {
+                               break
+                       }
+               }
                sort.Strings(tgts)
                var ood bool
                for _, tgt := range tgts {
@@ -378,10 +390,18 @@ CmdSwitch:
                        }
                }
        case "redo-sources":
-               tgts, err = sourcesWalker()
+               if tgtsWasEmpty {
+                       tgts, err = targetsWalker([]string{Cwd})
+                       if err != nil {
+                               break
+                       }
+               }
                sort.Strings(tgts)
-               for _, tgt := range tgts {
-                       fmt.Println(tgt)
+               var srcs []string
+               srcs, err = sourcesWalker(tgts)
+               sort.Strings(srcs)
+               for _, src := range srcs {
+                       fmt.Println(src)
                }
        default:
                log.Fatalln("unknown command", cmdName)
index e321c43b96ef5591596658162a373adc950b8885..0d361900527ca0aa1710e2daa7c96e8478075871 100644 (file)
@@ -21,17 +21,16 @@ import (
        "os"
        "path"
        "path/filepath"
-       "strings"
 )
 
-func sourcesWalker() ([]string, error) {
-       tgts, err := targetsWalker(Cwd)
-       if err != nil {
-               return nil, err
-       }
-       srcs := make(map[string]struct{}, 1<<10)
+func sourcesWalker(tgts []string) ([]string, error) {
+       seen := make(map[string]struct{}, 1<<10)
        for _, tgt := range tgts {
-               cwd, f := path.Split(tgt)
+               tgtAbsPath, err := filepath.Abs(path.Join(Cwd, tgt))
+               if err != nil {
+                       panic(err)
+               }
+               cwd, f := path.Split(path.Join(Cwd, tgt))
                fdDep, err := os.Open(path.Join(cwd, RedoDir, f+DepSuffix))
                if err != nil {
                        return nil, err
@@ -39,19 +38,27 @@ func sourcesWalker() ([]string, error) {
                depInfo, err := depRead(fdDep)
                fdDep.Close()
                for _, m := range depInfo.ifchanges {
-                       tgt = m["Target"]
-                       if !strings.HasSuffix(tgt, ".do") && isSrc(cwd, tgt) {
-                               pth, err := filepath.Abs(path.Join(cwd, tgt))
+                       depTgt := m["Target"]
+                       depTgtAbsPath, err := filepath.Abs(path.Join(cwd, depTgt))
+                       if err != nil {
+                               panic(err)
+                       }
+                       if isSrc(cwd, depTgt) {
+                               seen[cwdMustRel(depTgtAbsPath)] = struct{}{}
+                       } else if depTgtAbsPath != tgtAbsPath {
+                               subSrcs, err := sourcesWalker([]string{cwdMustRel(depTgtAbsPath)})
                                if err != nil {
                                        panic(err)
                                }
-                               srcs[cwdMustRel(pth)] = struct{}{}
+                               for _, p := range subSrcs {
+                                       seen[p] = struct{}{}
+                               }
                        }
                }
        }
-       tgts = make([]string, 0, len(srcs))
-       for tgt := range srcs {
-               tgts = append(tgts, tgt)
+       srcs := make([]string, 0, len(seen))
+       for p := range seen {
+               srcs = append(srcs, p)
        }
-       return tgts, nil
+       return srcs, nil
 }
index 602fd942abbf16b1741df0c946167f06aa703877..bc8edfd6d0b00669f1d48a8491034ddef151bda0 100644 (file)
@@ -25,24 +25,23 @@ import (
        "strings"
 )
 
-func targetsWalker(root string) ([]string, error) {
+func targetsCollect(root string, tgts map[string]struct{}) error {
        root, err := filepath.Abs(root)
        if err != nil {
                panic(err)
        }
        dir, err := os.Open(root)
        if err != nil {
-               return nil, err
+               return err
        }
        defer dir.Close()
-       tgts := make([]string, 0, 1<<10)
        for {
                fis, err := dir.Readdir(1 << 10)
                if err != nil {
                        if err == io.EOF {
                                break
                        }
-                       return tgts, err
+                       return err
                }
                for _, fi := range fis {
                        if !fi.IsDir() {
@@ -52,28 +51,40 @@ func targetsWalker(root string) ([]string, error) {
                        if fi.Name() == RedoDir {
                                redoDir, err := os.Open(pth)
                                if err != nil {
-                                       return tgts, err
+                                       return err
                                }
                                redoFis, err := redoDir.Readdir(0)
                                if err != nil {
-                                       return tgts, err
+                                       return err
                                }
                                for _, redoFi := range redoFis {
                                        name := redoFi.Name()
                                        if strings.HasSuffix(name, DepSuffix) {
                                                name = cwdMustRel(root, name)
-                                               tgts = append(tgts, name[:len(name)-len(DepSuffix)])
+                                               tgts[name[:len(name)-len(DepSuffix)]] = struct{}{}
                                        }
                                }
                                redoDir.Close()
                        } else {
-                               subTgts, err := targetsWalker(pth)
-                               tgts = append(tgts, subTgts...)
-                               if err != nil {
-                                       return tgts, err
+                               if err = targetsCollect(pth, tgts); err != nil {
+                                       return err
                                }
                        }
                }
        }
-       return tgts, dir.Close()
+       return dir.Close()
+}
+
+func targetsWalker(tgts []string) ([]string, error) {
+       tgtsMap := make(map[string]struct{}, 0)
+       for _, tgt := range tgts {
+               if err := targetsCollect(tgt, tgtsMap); err != nil {
+                       return nil, err
+               }
+       }
+       tgts = make([]string, 0, len(tgtsMap))
+       for tgt := range tgtsMap {
+               tgts = append(tgts, tgt)
+       }
+       return tgts, nil
 }
index 81e954dad5599880ec4b10ff0c6e853ffdeb23a8..670da2abdecfe7dd5b7f9d7a7bc811d2cc09f252 100644 (file)
--- a/usage.go
+++ b/usage.go
@@ -24,7 +24,7 @@ import (
 )
 
 const (
-       Version  = "1.4.1"
+       Version  = "1.5.0"
        Warranty = `Copyright (C) 2020-2021 Sergey Matveev
 
 This program is free software: you can redistribute it and/or modify
@@ -46,7 +46,8 @@ func usage(cmd string) {
        case "redo":
                d = `Usage: redo [options] [target ...]
 
-Forcefully and *sequentially* build specified targets.`
+Forcefully and *sequentially* build specified targets.
+If no targets specified, then use "all" one.`
        case "redo-ifchange":
                d = `Usage: redo-ifchange target [...]
 
@@ -87,15 +88,15 @@ anyway.`
 Display .do search paths for specified target. Exits successfully
 if the last .do in output if the found existing one.`
        case "redo-targets":
-               d = `Usage: redo-targets
+               d = `Usage: redo-targets [target ...]
 
 List all currently known targets.`
        case "redo-sources":
-               d = `Usage: redo-sources
+               d = `Usage: redo-sources [target ...]
 
 List all currently known source files.`
        case "redo-ood":
-               d = `Usage: redo-ood
+               d = `Usage: redo-ood [target ...]
 
 List all currently known out-of-date targets.`
        default:
@@ -103,7 +104,8 @@ List all currently known out-of-date targets.`
 
 goredo expects to be called through the symbolic link to it.
 Available commands: redo, redo-always, redo-cleanup, redo-dot,
-redo-ifchange, redo-ifcreate, redo-log, redo-stamp, redo-whichdo.`
+redo-ifchange, redo-ifcreate, redo-log, redo-ood, redo-sources,
+redo-stamp, redo-targets, redo-whichdo.`
        }
        fmt.Fprintf(os.Stderr, "%s\n\nCommon options:\n", d)
        flag.PrintDefaults()