X-Git-Url: http://www.git.cypherpunks.ru/?p=goredo.git;a=blobdiff_plain;f=run.go;h=366240557fff22680d401ae11b3d7de2ddb3ed01;hp=ba841522835e50dad65a5523ff5fe6c4d545ad8c;hb=3c87984511180d7bf865574123195588ea8c044c;hpb=c1b88a9301143b14fc3ef2a9b6bd9ac2ecf070f3 diff --git a/run.go b/run.go index ba84152..3662405 100644 --- a/run.go +++ b/run.go @@ -128,24 +128,26 @@ func mkdirs(pth string) error { return os.MkdirAll(pth, os.FileMode(0777)) } -func isModified(cwd, redoDir, tgt string) (bool, *Inode, error) { +func isModified(cwd, redoDir, tgt string) (bool, *Inode, string, error) { fdDep, err := os.Open(path.Join(redoDir, tgt+DepSuffix)) if err != nil { if os.IsNotExist(err) { - return false, nil, nil + return false, nil, "", nil } - return false, nil, err + return false, nil, "", err } defer fdDep.Close() r := recfile.NewReader(fdDep) + var modified bool var ourInode *Inode + var hshPrev string for { m, err := r.NextMap() if err != nil { if errors.Is(err, io.EOF) { break } - return false, nil, err + return false, nil, "", err } if m["Type"] != DepTypeIfchange || m["Target"] != tgt { continue @@ -153,25 +155,24 @@ func isModified(cwd, redoDir, tgt string) (bool, *Inode, error) { fd, err := os.Open(path.Join(cwd, tgt)) if err != nil { if os.IsNotExist(err) { - return false, nil, nil + return false, nil, "", nil } - return false, nil, err + return false, nil, "", err } ourInode, err = inodeFromFile(fd) fd.Close() if err != nil { - return false, nil, err + return false, nil, "", err } theirInode, err := inodeFromRec(m) if err != nil { - return false, nil, err - } - if !ourInode.Equals(theirInode) { - return true, ourInode, nil + return false, nil, "", err } + hshPrev = m["Hash"] + modified = !ourInode.Equals(theirInode) break } - return false, ourInode, nil + return modified, ourInode, hshPrev, nil } func syncDir(dir string) error { @@ -269,7 +270,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { } // Check if target is not modified externally - modified, inodePrev, err := isModified(cwd, redoDir, tgt) + modified, inodePrev, hshPrev, err := isModified(cwd, redoDir, tgt) if err != nil { lockRelease() return TgtError{tgtOrig, err} @@ -335,7 +336,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { runErr.DoFile = doFileRelPath } - if err = depWrite(fdDep, cwdOrig, doFileRelPath); err != nil { + if err = depWrite(fdDep, cwdOrig, doFileRelPath, ""); err != nil { cleanup() return TgtError{tgtOrig, err} } @@ -703,6 +704,39 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { goto Finish } } else { + var hsh string + if hshPrev != "" { + _, err = fd.Seek(0, io.SeekStart) + if err != nil { + goto Finish + } + hsh, err = fileHash(fd) + if err != nil { + goto Finish + } + if hsh == hshPrev { + tracef(CDebug, "%s has same hash, not renaming", tgtOrig) + err = os.Remove(fd.Name()) + if err != nil { + goto Finish + } + err = os.Chtimes(path.Join(cwdOrig, tgt), finished, finished) + if err != nil { + goto Finish + } + if !NoSync { + err = syncDir(cwdOrig) + if err != nil { + goto Finish + } + } + err = depWrite(fdDep, cwdOrig, tgt, hshPrev) + if err != nil { + goto Finish + } + goto RecCommit + } + } if !NoSync { err = fd.Sync() if err != nil { @@ -719,12 +753,13 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { goto Finish } } - err = depWrite(fdDep, cwdOrig, tgt) + err = depWrite(fdDep, cwdOrig, tgt, hsh) if err != nil { goto Finish } } + RecCommit: // Commit .rec if !NoSync { err = fdDep.Sync()