]> Cypherpunks.ru repositories - goredo.git/blobdiff - main.go
Refactor target paths, less CPU, less memory, more clarity
[goredo.git] / main.go
diff --git a/main.go b/main.go
index 39c6d118a0d941ce0a6f113ca378ef55298e39e8..bba64d02112bdd42c1904fe580344f153996db48 100644 (file)
--- a/main.go
+++ b/main.go
@@ -29,7 +29,6 @@ import (
        "os"
        "os/signal"
        "path"
-       "path/filepath"
        "runtime"
        "sort"
        "strconv"
@@ -45,17 +44,17 @@ const (
        CmdNameRedoAffects  = "redo-affects"
        CmdNameRedoAlways   = "redo-always"
        CmdNameRedoCleanup  = "redo-cleanup"
+       CmdNameRedoDepFix   = "redo-depfix"
        CmdNameRedoDot      = "redo-dot"
        CmdNameRedoIfchange = "redo-ifchange"
        CmdNameRedoIfcreate = "redo-ifcreate"
+       CmdNameRedoInode    = "redo-inode"
        CmdNameRedoLog      = "redo-log"
        CmdNameRedoOOD      = "redo-ood"
        CmdNameRedoSources  = "redo-sources"
        CmdNameRedoStamp    = "redo-stamp"
        CmdNameRedoTargets  = "redo-targets"
        CmdNameRedoWhichdo  = "redo-whichdo"
-       CmdNameRedoDepFix   = "redo-depfix"
-       CmdNameRedoInode    = "redo-inode"
 )
 
 var (
@@ -252,7 +251,7 @@ func main() {
                if err = unix.FcntlFlock(fdLock.Fd(), unix.F_SETLK, &flock); err != nil {
                        log.Fatal(err)
                }
-               OODTgts = map[string]struct{}{}
+               OODTgts = make(map[string]struct{})
                for _, tgtRaw := range bytes.Split(tgtsRaw, []byte{0}) {
                        t := string(tgtRaw)
                        if t == "" {
@@ -279,7 +278,10 @@ func main() {
                fdDep = mustParseFd(v, EnvDepFd)
        }
 
-       tgts := flag.Args()
+       tgts := make([]*Tgt, 0, len(flag.Args()))
+       for _, arg := range flag.Args() {
+               tgts = append(tgts, NewTgt(arg))
+       }
        BuildUUID = os.Getenv(EnvBuildUUID)
        tgtsWasEmpty := len(tgts) == 0
        if BuildUUID == "" {
@@ -294,7 +296,7 @@ func main() {
                        raw[0:4], raw[4:6], raw[6:8], raw[8:10], raw[10:],
                )
                if tgtsWasEmpty {
-                       tgts = []string{"all"}
+                       tgts = append(tgts, NewTgt("all"))
                }
        }
 
@@ -302,12 +304,6 @@ func main() {
                statusInit()
        }
 
-       for i, tgt := range tgts {
-               if path.IsAbs(tgt) {
-                       tgts[i] = cwdMustRel(tgt)
-               }
-       }
-
        killed := make(chan os.Signal, 1)
        signal.Notify(killed, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
        go func() {
@@ -333,7 +329,7 @@ CmdSwitch:
        switch cmdName {
        case CmdNameRedo:
                for _, tgt := range tgts {
-                       ok, err = ifchange([]string{tgt}, true, traced)
+                       ok, err = ifchange([]*Tgt{tgt}, true, traced)
                        if err != nil || !ok {
                                break
                        }
@@ -348,15 +344,7 @@ CmdSwitch:
                        log.Fatalln("no", EnvDepFd)
                }
                for _, tgt := range tgts {
-                       tgtRel, err := filepath.Rel(
-                               path.Join(Cwd, DirPrefix),
-                               path.Join(Cwd, tgt),
-                       )
-                       if err != nil {
-                               err = ErrLine(err)
-                               break
-                       }
-                       err = ifcreate(fdDep, tgtRel)
+                       err = ifcreate(fdDep, tgt.RelTo(path.Join(Cwd, DirPrefix)))
                        if err != nil {
                                break
                        }
@@ -368,7 +356,7 @@ CmdSwitch:
                err = always(fdDep)
        case CmdNameRedoCleanup:
                for _, what := range tgts {
-                       err = cleanupWalker(Cwd, what)
+                       err = cleanupWalker(Cwd, what.t)
                        if err != nil {
                                break
                        }
@@ -384,8 +372,7 @@ CmdSwitch:
                if len(tgts) != 1 {
                        log.Fatal("single target expected")
                }
-               d, t := cwdAndTgt(tgts[0])
-               err = showBuildLog(d, t, nil, 0)
+               err = showBuildLog(tgts[0], nil, 0)
        case CmdNameRedoWhichdo:
                if len(tgts) != 1 {
                        log.Fatal("single target expected")
@@ -400,8 +387,8 @@ CmdSwitch:
                        err = ErrLine(err)
                        break
                }
-               cwd, tgt := cwdAndTgt(tgts[0])
-               doFile, upLevels, err := findDo(fdTmp, cwd, tgt)
+               tgt := tgts[0]
+               doFile, upLevels, err := findDo(fdTmp, tgt.h, tgt.t)
                if err != nil {
                        err = ErrLine(err)
                        break
@@ -421,13 +408,13 @@ CmdSwitch:
                                err = ErrLine(err)
                                break CmdSwitch
                        }
-                       fmt.Println(cwdMustRel(cwd, m["Target"]))
+                       fmt.Println(cwdMustRel(tgt.h, m["Target"]))
                }
                if doFile == "" {
                        ok = false
                } else {
                        p := make([]string, 0, upLevels+2)
-                       p = append(p, cwd)
+                       p = append(p, tgt.h)
                        for i := 0; i < upLevels; i++ {
                                p = append(p, "..")
                        }
@@ -436,55 +423,66 @@ CmdSwitch:
                        fmt.Println(rel)
                }
        case CmdNameRedoTargets:
+               raws := make([]string, 0, len(tgts))
+               for _, tgt := range tgts {
+                       raws = append(raws, tgt.String())
+               }
                if tgtsWasEmpty {
-                       tgts = []string{Cwd}
+                       raws = []string{Cwd}
                }
-               tgts, err = targetsWalker(tgts)
+               raws, err = targetsWalker(raws)
                if err != nil {
                        err = ErrLine(err)
                        break
                }
-               sort.Strings(tgts)
-               for _, tgt := range tgts {
+               sort.Strings(raws)
+               for _, tgt := range raws {
                        fmt.Println(tgt)
                }
        case CmdNameRedoAffects:
                if tgtsWasEmpty {
                        log.Fatal("no targets specified")
                }
-               var tgtsKnown []string
-               tgtsKnown, err = targetsWalker([]string{Cwd})
-               if err != nil {
-                       err = ErrLine(err)
-                       break
-               }
-               deps := map[string]map[string]struct{}{}
-               for _, tgt := range tgtsKnown {
-                       collectDeps(Cwd, tgt, 0, deps, true, map[string]struct{}{})
-               }
-               seen := map[string]struct{}{}
-               for _, tgt := range tgts {
-                       collectWholeDeps(deps[tgt], deps, seen)
-               }
-               tgts := make([]string, 0, len(seen))
-               for dep := range seen {
-                       tgts = append(tgts, dep)
+               var res []string
+               {
+                       var tgtsKnown []string
+                       tgtsKnown, err = targetsWalker([]string{Cwd})
+                       if err != nil {
+                               err = ErrLine(err)
+                               break
+                       }
+                       deps := make(map[string]map[string]*Tgt)
+                       for _, tgt := range tgtsKnown {
+                               collectDeps(NewTgt(tgt), 0, deps, true, make(map[string]struct{}))
+                       }
+                       seen := make(map[string]*Tgt)
+                       for _, tgt := range tgts {
+                               collectWholeDeps(deps[tgt.a], deps, seen)
+                       }
+                       res = make([]string, 0, len(seen))
+                       for _, dep := range seen {
+                               res = append(res, dep.String())
+                       }
                }
-               sort.Strings(tgts)
-               for _, dep := range tgts {
+               sort.Strings(res)
+               for _, dep := range res {
                        fmt.Println(dep)
                }
        case CmdNameRedoOOD:
+               raws := make([]string, 0, len(tgts))
+               for _, tgt := range tgts {
+                       raws = append(raws, tgt.String())
+               }
                if tgtsWasEmpty {
-                       tgts, err = targetsWalker([]string{Cwd})
+                       raws, err = targetsWalker([]string{Cwd})
                        if err != nil {
                                break
                        }
                }
-               sort.Strings(tgts)
+               sort.Strings(raws)
                var ood bool
-               for _, tgt := range tgts {
-                       ood, err = isOOD(Cwd, tgt, 0, nil)
+               for _, tgt := range raws {
+                       ood, err = isOOD(NewTgt(tgt), 0, nil)
                        if err != nil {
                                err = ErrLine(err)
                                break
@@ -494,27 +492,34 @@ CmdSwitch:
                        }
                }
        case CmdNameRedoSources:
-               if tgtsWasEmpty {
-                       tgts, err = targetsWalker([]string{Cwd})
-                       if err != nil {
-                               err = ErrLine(err)
-                               break
+               srcs := make(map[string]*Tgt)
+               {
+                       raws := make([]string, 0, len(tgts))
+                       for _, tgt := range tgts {
+                               raws = append(raws, tgt.String())
+                       }
+                       if tgtsWasEmpty {
+                               raws, err = targetsWalker([]string{Cwd})
+                               if err != nil {
+                                       err = ErrLine(err)
+                                       break
+                               }
+                       }
+                       sort.Strings(raws)
+                       tgts = tgts[:0]
+                       for _, raw := range raws {
+                               tgts = append(tgts, NewTgt(raw))
                        }
+                       seen := make(map[string]struct{})
+                       seenDeps := make(map[string]struct{})
+                       err = ErrLine(sourcesWalker(tgts, seen, seenDeps, srcs))
                }
-               sort.Strings(tgts)
-               seen := make(map[string]struct{})
-               seenDeps := make(map[string]struct{})
-               srcs := make(map[string]struct{})
-               err = ErrLine(sourcesWalker(tgts, seen, seenDeps, srcs))
-               seen = nil
-               seenDeps = nil
                if err != nil {
                        break
                }
-               seenDeps = nil
                res := make([]string, 0, len(srcs))
-               for p := range srcs {
-                       res = append(res, p)
+               for _, tgt := range srcs {
+                       res = append(res, tgt.String())
                }
                srcs = nil
                sort.Strings(res)
@@ -526,13 +531,13 @@ CmdSwitch:
        case CmdNameRedoInode:
                var inode *Inode
                for _, tgt := range tgts {
-                       inode, err = inodeFromFileByPath(tgt)
+                       inode, err = inodeFromFileByPath(tgt.a)
                        if err != nil {
                                err = ErrLine(err)
                                break
                        }
                        err = recfileWrite(os.Stdout, append(
-                               []recfile.Field{{Name: "Target", Value: tgt}},
+                               []recfile.Field{{Name: "Target", Value: tgt.String()}},
                                inode.RecfileFields()...)...)
                        if err != nil {
                                err = ErrLine(err)