X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=run.go;h=40fad74af0f20f98dc517020faca88c86df57359;hb=14398260feaf14dac68b9bdb1c810ccba7d1e768;hp=6a38d5abdf7b735e15beb7023ae43d459cf3e2d3;hpb=a001f12e6aaf4ea0b068028a95c188af1f7925e9;p=goredo.git diff --git a/run.go b/run.go index 6a38d5a..40fad74 100644 --- a/run.go +++ b/run.go @@ -1,6 +1,6 @@ /* goredo -- redo implementation on pure Go -Copyright (C) 2020 Sergey Matveev +Copyright (C) 2020-2021 Sergey Matveev This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,7 +21,6 @@ package main import ( "bufio" - "encoding/hex" "errors" "flag" "fmt" @@ -29,13 +28,14 @@ import ( "os" "os/exec" "path" - "strconv" + "path/filepath" "strings" "sync" "syscall" "time" "go.cypherpunks.ru/recfile" + "go.cypherpunks.ru/tai64n" "golang.org/x/sys/unix" ) @@ -63,7 +63,8 @@ var ( StderrPrefix string Jobs sync.WaitGroup - flagTrace = flag.Bool("x", false, fmt.Sprintf("trace current target (sh -x) (set %s=1 for all others)", EnvTrace)) + flagTrace = flag.Bool("x", false, "trace (sh -x) current targets") + flagTraceAll = flag.Bool("xx", false, fmt.Sprintf("trace (sh -x) all targets (%s=1)", EnvTrace)) flagStderrKeep = flag.Bool("logs", false, fmt.Sprintf("keep job's stderr (%s=1)", EnvStderrKeep)) flagStderrSilent = flag.Bool("silent", false, fmt.Sprintf("do not print job's stderr (%s=1)", EnvStderrSilent)) ) @@ -102,16 +103,6 @@ func mkdirs(pth string) error { return os.MkdirAll(pth, os.FileMode(0777)) } -func tempsuffix() string { - return strconv.FormatInt((time.Now().UnixNano()+int64(os.Getpid()))&0xFFFFFFFF, 16) -} - -func tempfile(dir, prefix string) (*os.File, error) { - // It respects umask, unlike ioutil.TempFile - name := path.Join(dir, TmpPrefix+prefix+"."+tempsuffix()) - return os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, os.FileMode(0666)) -} - func isModified(cwd, redoDir, tgt string) (bool, string, error) { fdDep, err := os.Open(path.Join(redoDir, tgt+DepSuffix)) if err != nil { @@ -316,13 +307,22 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { } // Temporary file for stdout - fdStdout, err := tempfile(cwd, tgt) + fdStdout, err := tempfile(cwdOrig, tgt) if err != nil { cleanup() return TgtErr{tgtOrig, err} } tmpPath := fdStdout.Name() + ".3" // and for $3 - args = append(args, tgt, basename, path.Base(tmpPath)) + tmpPathRel, err := filepath.Rel(cwd, tmpPath) + if err != nil { + panic(err) + } + args = append( + args, + path.Join(dirPrefix, tgt), + path.Join(dirPrefix, basename), + tmpPathRel, + ) cmd := exec.Command(cmdName, args...) cmd.Dir = cwd @@ -420,7 +420,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { go func() { scanner := bufio.NewScanner(stderr) var line string - ts := new(TAI64N) + ts := new(tai64n.TAI64N) for scanner.Scan() { line = scanner.Text() if strings.HasPrefix(line, childStderrPrefix) { @@ -429,9 +429,9 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { continue } if fdStderr != nil { - tai64nNow(ts) + tai64n.FromTime(time.Now(), ts) LogMutex.Lock() - fmt.Fprintf(fdStderr, "@%s %s\n", hex.EncodeToString(ts[:]), line) + fmt.Fprintf(fdStderr, "%s %s\n", ts.Encode(), line) LogMutex.Unlock() } if StderrSilent { @@ -458,14 +458,16 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { } // 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 + if tsPrev != "" { + if fd, err := os.Open(path.Join(cwdOrig, tgt)); err == nil { + ts, err := fileCtime(fd) fd.Close() - return + if err == nil && ts != tsPrev { + runErr.Err = errors.New("$1 was explicitly touched") + errs <- runErr + fd.Close() + return + } } } @@ -505,6 +507,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { // Do we need to ifcreate it, of ifchange with renaming? if fd == nil { + os.Remove(path.Join(cwdOrig, tgt)) err = ifcreate(fdDep, tgt) if err != nil { goto Finish