X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=ood.go;fp=ood.go;h=dffaa4ef06b8ea1335e51636751a880d0191cbe7;hb=3f8ee87bd625a38b57a0a38e3c34bb26fe6e1b8e;hp=5dc543f56aa263d821b33dc03a4d8fa30d66ccf7;hpb=4655c362aed45a161e0bac3a6987347bb35c3eaa;p=goredo.git diff --git a/ood.go b/ood.go index 5dc543f..dffaa4e 100644 --- a/ood.go +++ b/ood.go @@ -27,7 +27,6 @@ import ( "io/fs" "log" "os" - "path" "strings" "golang.org/x/sys/unix" @@ -70,7 +69,7 @@ func FileExists(p string) bool { } type TgtError struct { - Tgt string + Tgt *Tgt Err error } @@ -80,183 +79,165 @@ func (e TgtError) Error() string { return fmt.Sprintf("%s: %s", e.Tgt, e.Err) } -func isSrc(cwd, tgt string) bool { - d, f := path.Split(path.Join(cwd, tgt)) - if !FileExists(path.Join(d, f)) { +func isSrc(tgt *Tgt) bool { + if !FileExists(tgt.a) { return false } - if FileExists(path.Join(d, f+".do")) { + if FileExists(tgt.a + ".do") { return false } - if FileExists(path.Join(d, RedoDir, f+DepSuffix)) { + if FileExists(tgt.Dep()) { return false } return true } -func isOODByBuildUUID(cwd, tgtOrig string) bool { - cwd, tgt := cwdAndTgt(path.Join(cwd, tgtOrig)) - depPath := path.Join(cwd, RedoDir, tgt+DepSuffix) - build, err := depReadBuild(depPath) +func isOODByBuildUUID(tgt *Tgt) bool { + build, err := depReadBuild(tgt.Dep()) return err != nil || build != BuildUUID } -func isOOD(cwd, tgtOrig string, level int, seen map[string]struct{}) (bool, error) { +func isOOD(tgt *Tgt, level int, seen map[string]*Tgt) (bool, error) { indent := strings.Repeat(". ", level) - tracef(CDebug, "ood: %s%s checking", indent, tgtOrig) - cwd, tgt := cwdAndTgt(path.Join(cwd, tgtOrig)) - ood, cached := OODCache[path.Join(cwd, tgt)] + tracef(CDebug, "ood: %s%s checking", indent, tgt) + ood, cached := OODCache[tgt.a] if cached { - tracef(CDebug, "ood: %s%s -> cached: %v", indent, tgtOrig, ood) + tracef(CDebug, "ood: %s%s -> cached: %v", indent, tgt, ood) return ood, nil } - depPath := path.Join(cwd, RedoDir, tgt+DepSuffix) - depInfo, err := depRead(depPath) + depInfo, err := depRead(tgt) if err != nil { if errors.Is(err, fs.ErrNotExist) { - if isSrc(cwd, tgt) { + if isSrc(tgt) { ood = false - tracef(CDebug, "ood: %s%s -> is source", indent, tgtOrig) + tracef(CDebug, "ood: %s%s -> is source", indent, tgt) } else { ood = true - tracef(CDebug, "ood: %s%s -> no dep: %s", indent, tgtOrig, depPath) + tracef(CDebug, "ood: %s%s -> no dep: %s", indent, tgt, tgt.Dep()) } - OODCache[path.Join(cwd, tgt)] = ood + OODCache[tgt.a] = ood return ood, nil } if err != nil { - return true, TgtError{tgtOrig, ErrLine(err)} + return true, TgtError{tgt, ErrLine(err)} } } if depInfo.build == BuildUUID { - tracef(CDebug, "ood: %s%s -> already built", indent, tgtOrig) - OODCache[path.Join(cwd, tgt)] = false + tracef(CDebug, "ood: %s%s -> already built", indent, tgt) + OODCache[tgt.a] = false return false, nil } - if !FileExists(path.Join(cwd, tgt)) { - tracef(CDebug, "ood: %s%s -> non-existent", indent, tgtOrig) - OODCache[path.Join(cwd, tgt)] = true + if !FileExists(tgt.a) { + tracef(CDebug, "ood: %s%s -> non-existent", indent, tgt) + OODCache[tgt.a] = true return true, nil } for _, dep := range depInfo.ifcreates { - if FileExists(path.Join(cwd, dep)) { - tracef(CDebug, "ood: %s%s -> %s created", indent, tgtOrig, dep) + if FileExists(dep.a) { + tracef(CDebug, "ood: %s%s -> %s created", indent, tgt, dep) ood = true goto Done } } for _, dep := range depInfo.ifchanges { - tracef(CDebug, "ood: %s%s -> %s: checking", indent, tgtOrig, dep.tgt) - ood, cached = OODCache[path.Join(cwd, dep.tgt)] + tracef(CDebug, "ood: %s%s -> %s: checking", indent, tgt, dep.tgt) + ood, cached = OODCache[dep.tgt.a] if cached { - tracef(CDebug, "ood: %s%s -> %s: cached: %v", indent, tgtOrig, dep.tgt, ood) + tracef(CDebug, "ood: %s%s -> %s: cached: %v", indent, tgt, dep.tgt, ood) if ood { goto Done } continue } - inode, err := inodeFromFileByPath(path.Join(cwd, dep.tgt)) + inode, err := inodeFromFileByPath(dep.tgt.a) if err != nil { if errors.Is(err, fs.ErrNotExist) { - tracef(CDebug, "ood: %s%s -> %s: not exists", indent, tgtOrig, dep.tgt) + tracef(CDebug, "ood: %s%s -> %s: not exists", indent, tgt, dep.tgt) ood = true - OODCache[path.Join(cwd, dep.tgt)] = ood + OODCache[dep.tgt.a] = ood goto Done } - return ood, TgtError{tgtOrig, ErrLine(err)} + return ood, TgtError{tgt, ErrLine(err)} } if inode.Size != dep.inode.Size { - tracef(CDebug, "ood: %s%s -> %s: size differs", indent, tgtOrig, dep.tgt) + tracef(CDebug, "ood: %s%s -> %s: size differs", indent, tgt, dep.tgt) ood = true - OODCache[path.Join(cwd, dep.tgt)] = ood + OODCache[dep.tgt.a] = ood goto Done } if InodeTrust != InodeTrustNone && inode.Equals(dep.inode) { - tracef(CDebug, "ood: %s%s -> %s: same inode", indent, tgtOrig, dep.tgt) + tracef(CDebug, "ood: %s%s -> %s: same inode", indent, tgt, dep.tgt) } else { - tracef(CDebug, "ood: %s%s -> %s: inode differs", indent, tgtOrig, dep.tgt) - fd, err := os.Open(path.Join(cwd, dep.tgt)) + tracef(CDebug, "ood: %s%s -> %s: inode differs", indent, tgt, dep.tgt) + fd, err := os.Open(dep.tgt.a) if err != nil { - return ood, TgtError{tgtOrig, ErrLine(err)} + return ood, TgtError{tgt, ErrLine(err)} } hsh, err := fileHash(fd) fd.Close() if err != nil { - return ood, TgtError{tgtOrig, ErrLine(err)} + return ood, TgtError{tgt, ErrLine(err)} } if !bytes.Equal(dep.hash, hsh) { - tracef(CDebug, "ood: %s%s -> %s: hash differs", indent, tgtOrig, dep.tgt) + tracef(CDebug, "ood: %s%s -> %s: hash differs", indent, tgt, dep.tgt) ood = true - OODCache[path.Join(cwd, dep.tgt)] = ood + OODCache[dep.tgt.a] = ood goto Done } - tracef(CDebug, "ood: %s%s -> %s: same hash", indent, tgtOrig, dep.tgt) + tracef(CDebug, "ood: %s%s -> %s: same hash", indent, tgt, dep.tgt) } - if dep.tgt == tgt { - tracef(CDebug, "ood: %s%s -> %s: same target", indent, tgtOrig, dep.tgt) + if dep.tgt.a == tgt.a { + tracef(CDebug, "ood: %s%s -> %s: same target", indent, tgt, dep.tgt) continue } - if isSrc(cwd, dep.tgt) { - tracef(CDebug, "ood: %s%s -> %s: is source", indent, tgtOrig, dep.tgt) - OODCache[path.Join(cwd, dep.tgt)] = false + if isSrc(dep.tgt) { + tracef(CDebug, "ood: %s%s -> %s: is source", indent, tgt, dep.tgt) + OODCache[dep.tgt.a] = false continue } - if _, ok := seen[cwdMustRel(cwd, dep.tgt)]; ok { - tracef(CDebug, "ood: %s%s -> %s: was always built", indent, tgtOrig, dep.tgt) - OODCache[path.Join(cwd, dep.tgt)] = false + if _, ok := seen[dep.tgt.a]; ok { + tracef(CDebug, "ood: %s%s -> %s: was always built", indent, tgt, dep.tgt) + OODCache[dep.tgt.a] = false continue } - depOOD, err := isOODWithTrace(cwd, dep.tgt, level+1, seen) + depOOD, err := isOODWithTrace(dep.tgt, level+1, seen) if err != nil { - return ood, TgtError{tgtOrig, err} + return ood, TgtError{tgt, err} } if depOOD { - tracef(CDebug, "ood: %s%s -> %s: ood", indent, tgtOrig, dep.tgt) + tracef(CDebug, "ood: %s%s -> %s: ood", indent, tgt, dep.tgt) ood = true goto Done } - tracef(CDebug, "ood: %s%s -> %s: !ood", indent, tgtOrig, dep.tgt) + tracef(CDebug, "ood: %s%s -> %s: !ood", indent, tgt, dep.tgt) } Done: - tracef(CDebug, "ood: %s%s: %v", indent, tgtOrig, ood) - OODCache[path.Join(cwd, tgt)] = ood + tracef(CDebug, "ood: %s%s: %v", indent, tgt, ood) + OODCache[tgt.a] = ood return ood, nil } -func isOODWithTrace( - cwd, tgtOrig string, - level int, - seen map[string]struct{}, -) (bool, error) { - p := mustAbs(path.Join(cwd, tgtOrig)) - _, ood := OODTgts[p] +func isOODWithTrace(tgt *Tgt, level int, seen map[string]*Tgt) (bool, error) { + _, ood := OODTgts[tgt.a] var err error if ood { - if !isOODByBuildUUID(cwd, tgtOrig) { - tracef( - CDebug, - "ood: %s%s -> already built", - strings.Repeat(". ", level), tgtOrig, - ) + if !isOODByBuildUUID(tgt) { + tracef(CDebug, "ood: %s%s -> already built", strings.Repeat(". ", level), tgt) return false, nil } - tracef( - CDebug, - "ood: %s%s true, external decision", - strings.Repeat(". ", level), tgtOrig, - ) + tracef(CDebug, "ood: %s%s true, external decision", strings.Repeat(". ", level), tgt) goto RecordOODTgt } - ood, err = isOOD(cwd, tgtOrig, level, seen) + ood, err = isOOD(tgt, level, seen) if !ood { return ood, err } @@ -271,7 +252,7 @@ RecordOODTgt: if _, err = FdOODTgts.Seek(0, io.SeekEnd); err != nil { log.Fatal(err) } - if _, err := FdOODTgts.WriteString(p + "\x00"); err != nil { + if _, err := FdOODTgts.WriteString(tgt.a + "\x00"); err != nil { log.Fatal(err) } flock.Type = unix.F_UNLCK