]> Cypherpunks.ru repositories - goredo.git/blobdiff - run.go
Removed hashless mode, small bugfixes, tai64nlocal
[goredo.git] / run.go
diff --git a/run.go b/run.go
index eb67304fea4de6fe8798c7e28823fdfbe71b6f9b..0f7277bfd34313daf56c01e3b60ab4dee272f922 100644 (file)
--- a/run.go
+++ b/run.go
@@ -31,6 +31,7 @@ import (
        "path"
        "strconv"
        "strings"
+       "sync"
        "syscall"
        "time"
 
@@ -47,7 +48,6 @@ const (
        EnvStderrKeep   = "REDO_LOGS"
        EnvStderrSilent = "REDO_SILENT"
        EnvNoSync       = "REDO_NO_SYNC"
-       EnvStampPrev    = "REDO_STAMP_PREV"
 
        RedoDir    = ".redo"
        LockSuffix = ".lock"
@@ -62,7 +62,7 @@ var (
        StderrKeep   bool = false
        StderrSilent bool = false
        StderrPrefix string
-       StampPrev    string
+       Jobs         sync.WaitGroup
 
        flagTrace        = flag.Bool("x", false, "trace current target (sh -x) (set REDO_TRACE=1 for others too)")
        flagStderrKeep   = flag.Bool("logs", false, "keep job's stderr (REDO_LOGS=1)")
@@ -113,23 +113,24 @@ func tempfile(dir, prefix string) (*os.File, error) {
        return os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, os.FileMode(0666))
 }
 
-func isModified(cwd, redoDir, tgt string) (bool, error) {
+func isModified(cwd, redoDir, tgt string) (bool, string, error) {
        fdDep, err := os.Open(path.Join(redoDir, tgt+DepSuffix))
        if err != nil {
                if os.IsNotExist(err) {
-                       return false, nil
+                       return false, "", nil
                }
-               return false, err
+               return false, "", err
        }
        defer fdDep.Close()
        r := recfile.NewReader(fdDep)
+       var ourTs string
        for {
                m, err := r.NextMap()
                if err != nil {
                        if err == io.EOF {
                                break
                        }
-                       return false, err
+                       return false, "", err
                }
                if m["Target"] != tgt {
                        continue
@@ -137,21 +138,21 @@ func isModified(cwd, redoDir, tgt string) (bool, error) {
                fd, err := os.Open(path.Join(cwd, tgt))
                if err != nil {
                        if os.IsNotExist(err) {
-                               return false, nil
+                               return false, "", nil
                        }
-                       return false, err
+                       return false, "", err
                }
                defer fd.Close()
-               ourTs, err := fileCtime(fd)
+               ourTs, err = fileCtime(fd)
                if err != nil {
-                       return false, err
+                       return false, "", err
                }
                if ourTs != m["Ctime"] {
-                       return true, nil
+                       return true, ourTs, nil
                }
                break
        }
-       return false, nil
+       return false, ourTs, nil
 }
 
 func syncDir(dir string) error {
@@ -164,7 +165,7 @@ func syncDir(dir string) error {
        return err
 }
 
-func runScript(tgtOrig string, errs chan error, stampPrev string) error {
+func runScript(tgtOrig string, errs chan error) error {
        cwd, tgt := cwdAndTgt(tgtOrig)
        redoDir := path.Join(cwd, RedoDir)
        if err := mkdirs(redoDir); err != nil {
@@ -227,7 +228,7 @@ func runScript(tgtOrig string, errs chan error, stampPrev string) error {
        }
 
        // Check if target is not modified externally
-       modified, err := isModified(cwd, redoDir, tgt)
+       modified, tsPrev, err := isModified(cwd, redoDir, tgt)
        if err != nil {
                lockRelease()
                return TgtErr{tgtOrig, err}
@@ -235,8 +236,10 @@ func runScript(tgtOrig string, errs chan error, stampPrev string) error {
        if modified {
                trace(CWarn, "%s externally modified: not redoing", tgtOrig)
                lockRelease()
-               errs <- nil
-               return TgtErr{tgtOrig, err}
+               go func() {
+                       errs <- nil
+               }()
+               return nil
        }
 
        // Start preparing .dep
@@ -347,10 +350,6 @@ func runScript(tgtOrig string, errs chan error, stampPrev string) error {
        cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", EnvDirPrefix, dirPrefix))
        cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", EnvBuildUUID, BuildUUID))
 
-       if stampPrev != "" {
-               cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", EnvStampPrev, stampPrev))
-       }
-
        childStderrPrefix := tempsuffix()
        cmd.Env = append(cmd.Env, fmt.Sprintf(
                "%s=%s", EnvStderrPrefix, childStderrPrefix,
@@ -366,7 +365,9 @@ func runScript(tgtOrig string, errs chan error, stampPrev string) error {
        } else {
                cmd.ExtraFiles = append(cmd.ExtraFiles, JSR)
                cmd.ExtraFiles = append(cmd.ExtraFiles, JSW)
-               cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%d,%d", EnvJSFd, 3+fdNum+0, 3+fdNum+1))
+               cmd.Env = append(cmd.Env, fmt.Sprintf(
+                       "%s=%d,%d", EnvJSFd, 3+fdNum+0, 3+fdNum+1,
+               ))
                fdNum += 2
        }
 
@@ -458,6 +459,18 @@ func runScript(tgtOrig string, errs chan error, stampPrev string) error {
                        return
                }
 
+               // Was $1 touched?
+               if fd, err := os.Open(path.Join(cwdOrig, tgt)); err == nil {
+                       ts, err := fileCtime(fd)
+                       fd.Close()
+                       if err == nil && ts != tsPrev {
+                               runErr.Err = errors.New("$1 was explicitly touched")
+                               errs <- runErr
+                               fd.Close()
+                               return
+                       }
+               }
+
                // Does it produce both stdout and tmp?
                fiStdout, err := os.Stat(fdStdout.Name())
                if err != nil {
@@ -544,3 +557,15 @@ func runScript(tgtOrig string, errs chan error, stampPrev string) error {
        }()
        return nil
 }
+
+func isOkRun(err error) bool {
+       if err == nil {
+               return true
+       }
+       if err, ok := err.(RunErr); ok && err.Err == nil {
+               trace(CRedo, "%s", err.Name())
+               return true
+       }
+       trace(CErr, "%s", err)
+       return false
+}