From: Sergey Matveev Date: Wed, 17 Nov 2021 10:54:13 +0000 (+0300) Subject: Linting X-Git-Tag: v1.20.0~3 X-Git-Url: http://www.git.cypherpunks.ru/?p=goredo.git;a=commitdiff_plain;h=d8abe40c66df8d79a025524c0d230959cacf9465 Linting --- diff --git a/dep.go b/dep.go index e1c2aae..bf5e758 100644 --- a/dep.go +++ b/dep.go @@ -35,9 +35,11 @@ import ( var ( DirPrefix string DepCwd string + + ErrBadRecFormat = errors.New("invalid format of .rec") ) -func recfileWrite(fdDep *os.File, fields ...recfile.Field) error { +func recfileWrite(fdDep io.StringWriter, fields ...recfile.Field) error { w := recfile.NewWriter(fdDep) if _, err := w.RecordStart(); err != nil { return err @@ -49,7 +51,7 @@ func recfileWrite(fdDep *os.File, fields ...recfile.Field) error { } func ifcreate(fdDep *os.File, tgt string) error { - trace(CDebug, "ifcreate: %s <- %s", fdDep.Name(), tgt) + tracef(CDebug, "ifcreate: %s <- %s", fdDep.Name(), tgt) return recfileWrite( fdDep, recfile.Field{Name: "Type", Value: DepTypeIfcreate}, @@ -58,17 +60,17 @@ func ifcreate(fdDep *os.File, tgt string) error { } func always(fdDep *os.File) error { - trace(CDebug, "always: %s", fdDep.Name()) + tracef(CDebug, "always: %s", fdDep.Name()) return recfileWrite(fdDep, recfile.Field{Name: "Type", Value: DepTypeAlways}) } func stamp(fdDep, src *os.File) error { var hsh string - hsh, err := fileHash(os.Stdin) + hsh, err := fileHash(src) if err != nil { return err } - trace(CDebug, "stamp: %s <- %s", fdDep.Name(), hsh) + tracef(CDebug, "stamp: %s <- %s", fdDep.Name(), hsh) return recfileWrite( fdDep, recfile.Field{Name: "Type", Value: DepTypeStamp}, @@ -85,7 +87,7 @@ func fileHash(fd *os.File) (string, error) { } func writeDep(fdDep *os.File, cwd, tgt string) error { - trace(CDebug, "ifchange: %s <- %s", fdDep.Name(), tgt) + tracef(CDebug, "ifchange: %s <- %s", fdDep.Name(), tgt) fd, err := os.Open(path.Join(cwd, tgt)) if err != nil { return err @@ -115,9 +117,9 @@ func writeDep(fdDep *os.File, cwd, tgt string) error { return recfileWrite(fdDep, fields...) } -func writeDeps(fdDep *os.File, tgts []string) (err error) { +func writeDeps(fdDep *os.File, tgts []string) error { if fdDep == nil { - trace(CDebug, "no opened fdDep: %s", tgts) + tracef(CDebug, "no opened fdDep: %s", tgts) return nil } for _, tgt := range tgts { @@ -137,7 +139,7 @@ func writeDeps(fdDep *os.File, tgts []string) (err error) { if _, errStat := os.Stat(tgt); errStat == nil { err = writeDep(fdDep, tgtDir, tgtRel) } else { - trace(CDebug, "ifchange: %s <- %s (non-existing)", fdDep.Name(), tgtRel) + tracef(CDebug, "ifchange: %s <- %s (non-existing)", fdDep.Name(), tgtRel) fields := []recfile.Field{ {Name: "Type", Value: DepTypeIfchange}, {Name: "Target", Value: tgtRel}, @@ -146,8 +148,11 @@ func writeDeps(fdDep *os.File, tgts []string) (err error) { fields = append(fields, inodeDummy.RecfileFields()...) err = recfileWrite(fdDep, fields...) } + if err != nil { + return err + } } - return + return nil } type DepInfo struct { @@ -158,22 +163,22 @@ type DepInfo struct { ifchanges []map[string]string } -func depRead(fdDep *os.File) (*DepInfo, error) { +func depRead(fdDep io.Reader) (*DepInfo, error) { r := recfile.NewReader(fdDep) m, err := r.NextMap() if err != nil { return nil, err } depInfo := DepInfo{} - if b := m["Build"]; b == "" { + b := m["Build"] + if b == "" { return nil, errors.New(".rec missing Build:") - } else { - depInfo.build = b } + depInfo.build = b for { m, err := r.NextMap() if err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { break } return nil, err @@ -184,7 +189,7 @@ func depRead(fdDep *os.File) (*DepInfo, error) { case DepTypeIfcreate: dep := m["Target"] if dep == "" { - return nil, errors.New("invalid format of .rec") + return nil, ErrBadRecFormat } depInfo.ifcreates = append(depInfo.ifcreates, dep) case DepTypeIfchange: @@ -193,11 +198,11 @@ func depRead(fdDep *os.File) (*DepInfo, error) { case DepTypeStamp: hsh := m["Hash"] if hsh == "" { - return nil, errors.New("invalid format of .rec") + return nil, ErrBadRecFormat } depInfo.stamp = hsh default: - return nil, errors.New("invalid format of .rec") + return nil, ErrBadRecFormat } } return &depInfo, nil diff --git a/dot.go b/dot.go index 39c9019..050b350 100644 --- a/dot.go +++ b/dot.go @@ -20,6 +20,7 @@ along with this program. If not, see . package main import ( + "errors" "fmt" "io" "os" @@ -46,7 +47,7 @@ func dotWalker(data map[DotNodes]bool, tgtOrig string) (map[DotNodes]bool, error for { m, err := r.NextMap() if err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { break } return nil, err diff --git a/ifchange.go b/ifchange.go index 128d1af..43cfdb3 100644 --- a/ifchange.go +++ b/ifchange.go @@ -45,13 +45,13 @@ func collectDeps( tgtRel := cwdMustRel(cwd, tgt) if depInfo.always { if depInfo.build == BuildUUID { - trace( + tracef( CDebug, "ood: %s%s always, but already build", strings.Repeat(". ", level), tgtOrig, ) returnReady = true } else { - trace(CDebug, "ood: %s%s always", strings.Repeat(". ", level), tgtOrig) + tracef(CDebug, "ood: %s%s always", strings.Repeat(". ", level), tgtOrig) alwayses = append(alwayses, tgtRel) returnReady = true } @@ -87,7 +87,7 @@ func collectDeps( func buildDependants(tgts []string) map[string]struct{} { defer Jobs.Wait() - trace(CDebug, "collecting deps") + tracef(CDebug, "collecting deps") seen := map[string]struct{}{} deps := map[string]map[string]struct{}{} for _, tgtInitial := range tgts { @@ -106,11 +106,11 @@ func buildDependants(tgts []string) map[string]struct{} { Level = levelOrig }() Level = 1 - trace(CDebug, "building %d alwayses: %v", len(seen), seen) + tracef(CDebug, "building %d alwayses: %v", len(seen), seen) errs := make(chan error, len(seen)) for tgt := range seen { if err := runScript(tgt, errs, false); err != nil { - trace(CErr, "always run error: %s, skipping dependants", err) + tracef(CErr, "always run error: %s, skipping dependants", err) return nil } } @@ -121,7 +121,7 @@ func buildDependants(tgts []string) map[string]struct{} { Jobs.Wait() close(errs) if !ok { - trace(CDebug, "alwayses failed, skipping dependants") + tracef(CDebug, "alwayses failed, skipping dependants") return nil } @@ -134,28 +134,28 @@ func buildDependants(tgts []string) map[string]struct{} { } RebuildDeps: - trace(CDebug, "checking %d dependant targets: %v", len(queueSrc), queueSrc) + tracef(CDebug, "checking %d dependant targets: %v", len(queueSrc), queueSrc) queue := []string{} for _, tgt := range queueSrc { for dep := range deps[tgt] { queue = append(queue, dep) } } - trace(CDebug, "building %d dependant targets: %v", len(queue), queue) + tracef(CDebug, "building %d dependant targets: %v", len(queue), queue) errs = make(chan error, len(queue)) jobs := 0 queueSrc = []string{} for _, tgt := range queue { ood, err := isOODWithTrace(Cwd, tgt, 0, seen) if err != nil { - trace(CErr, "dependant error: %s, skipping dependants", err) + tracef(CErr, "dependant error: %s, skipping dependants", err) return nil } if !ood { continue } if err := runScript(tgt, errs, false); err != nil { - trace(CErr, "dependant error: %s, skipping dependants", err) + tracef(CErr, "dependant error: %s, skipping dependants", err) return nil } queueSrc = append(queueSrc, tgt) @@ -166,7 +166,7 @@ RebuildDeps: ok = isOkRun(<-errs) && ok } if !ok { - trace(CDebug, "dependants failed, skipping them") + tracef(CDebug, "dependants failed, skipping them") return nil } Jobs.Wait() @@ -186,14 +186,14 @@ func ifchange(tgts []string, forced, traced bool) (bool, error) { defer Jobs.Wait() seen := buildDependants(tgts) oodTgtsClear() - trace(CDebug, "building %d targets: %v", len(tgts), tgts) + tracef(CDebug, "building %d targets: %v", len(tgts), tgts) jobs := 0 errs := make(chan error, len(tgts)) var ood bool var err error for _, tgt := range tgts { if _, ok := seen[tgt]; ok { - trace(CDebug, "%s was already build as a dependant", tgt) + tracef(CDebug, "%s was already build as a dependant", tgt) continue } ood = true @@ -207,7 +207,7 @@ func ifchange(tgts []string, forced, traced bool) (bool, error) { continue } if isSrc(Cwd, tgt) { - trace(CDebug, "%s is source, not redoing", tgt) + tracef(CDebug, "%s is source, not redoing", tgt) continue } if err = runScript(tgt, errs, traced); err != nil { diff --git a/inode.go b/inode.go index 45c3acb..8ec6b9e 100644 --- a/inode.go +++ b/inode.go @@ -30,7 +30,7 @@ import ( const EnvInodeNoTrust = "REDO_INODE_NO_TRUST" -var InodeTrust bool = false +var InodeTrust = false type Inode struct { Size int64 diff --git a/js.go b/js.go index 1f2ec39..82f15d2 100644 --- a/js.go +++ b/js.go @@ -82,11 +82,12 @@ func init() { func jsStart(jobsEnv string) { jobs := uint64(1) var err error - if *flagJobs == 0 { + switch { + case *flagJobs == 0: jobs = 0 - } else if *flagJobs > 0 { + case *flagJobs > 0: jobs = uint64(*flagJobs) - } else if jobsEnv != "" { + case jobsEnv != "": jobs, err = strconv.ParseUint(jobsEnv, 10, 64) if err != nil { log.Fatalln("can not parse", EnvJobs, err) @@ -100,7 +101,7 @@ func jsStart(jobsEnv string) { if err != nil { log.Fatalln(err) } - trace(CJS, "initial fill with %d", jobs) + tracef(CJS, "initial fill with %d", jobs) jsTokens[BMakeGoodToken] = int(jobs) for ; jobs > 0; jobs-- { jsReleaseNoLock(BMakeGoodToken) @@ -180,7 +181,7 @@ func jsRelease(ctx string, token byte) { if JSW == nil { return } - trace(CJS, "release from %s", ctx) + tracef(CJS, "release from %s", ctx) jsTokensM.Lock() jsTokens[token]-- jsReleaseNoLock(token) @@ -201,7 +202,7 @@ func jsAcquire(ctx string) byte { if JSR == nil { return BMakeGoodToken } - trace(CJS, "acquire for %s", ctx) + tracef(CJS, "acquire for %s", ctx) token := []byte{0} if n, err := JSR.Read(token); err != nil || n != 1 { log.Fatalln("can not read JSR:", err) @@ -209,6 +210,6 @@ func jsAcquire(ctx string) byte { jsTokensM.Lock() jsTokens[token[0]]++ jsTokensM.Unlock() - trace(CJS, "acquired for %s", ctx) + tracef(CJS, "acquired for %s", ctx) return token[0] } diff --git a/log.go b/log.go index 3064a7a..c9f9119 100644 --- a/log.go +++ b/log.go @@ -59,7 +59,7 @@ var ( CWarn string CJS string CReset string - CNone string = "NONE" + CNone = "NONE" flagDebug = flag.Bool("d", false, fmt.Sprintf("enable debug logging (%s=1)", EnvDebug)) flagNoProgress *bool @@ -108,7 +108,7 @@ func erasedStatus(s, end string) string { return s + KeyEraseLine + end } -func trace(level, format string, args ...interface{}) { +func tracef(level, format string, args ...interface{}) { var p string if MyPid != 0 { p = fmt.Sprintf("[%d] ", MyPid) diff --git a/main.go b/main.go index c3b1be7..9f11581 100644 --- a/main.go +++ b/main.go @@ -21,6 +21,7 @@ import ( "bufio" "bytes" "crypto/rand" + "errors" "flag" "fmt" "io" @@ -62,8 +63,8 @@ var ( IsTopRedo bool // is it the top redo instance ) -func mustSetenv(key, value string) { - if err := os.Setenv(key, value); err != nil { +func mustSetenv(key string) { + if err := os.Setenv(key, "1"); err != nil { panic(err) } } @@ -154,28 +155,28 @@ func main() { DepCwd = os.Getenv(EnvDepCwd) if flagStderrKeep != nil && *flagStderrKeep { - mustSetenv(EnvStderrKeep, "1") + mustSetenv(EnvStderrKeep) } if flagStderrSilent != nil && *flagStderrSilent { - mustSetenv(EnvStderrSilent, "1") + mustSetenv(EnvStderrSilent) } if flagNoProgress != nil && *flagNoProgress { - mustSetenv(EnvNoProgress, "1") + mustSetenv(EnvNoProgress) } if flagDebug != nil && *flagDebug { - mustSetenv(EnvDebug, "1") + mustSetenv(EnvDebug) } if flagLogWait != nil && *flagLogWait { - mustSetenv(EnvLogWait, "1") + mustSetenv(EnvLogWait) } if flagLogLock != nil && *flagLogLock { - mustSetenv(EnvLogLock, "1") + mustSetenv(EnvLogLock) } if flagLogPid != nil && *flagLogPid { - mustSetenv(EnvLogPid, "1") + mustSetenv(EnvLogPid) } if flagLogJS != nil && *flagLogJS { - mustSetenv(EnvLogJS, "1") + mustSetenv(EnvLogJS) } StderrKeep = os.Getenv(EnvStderrKeep) == "1" StderrSilent = os.Getenv(EnvStderrSilent) == "1" @@ -189,7 +190,7 @@ func main() { } var traced bool if flagTraceAll != nil && *flagTraceAll { - mustSetenv(EnvTrace, "1") + mustSetenv(EnvTrace) } if os.Getenv(EnvTrace) == "1" { TracedAll = true @@ -227,7 +228,9 @@ func main() { if err != nil { log.Fatalln(err) } - unix.Flock(int(fdLock.Fd()), unix.LOCK_UN) + if err = unix.Flock(int(fdLock.Fd()), unix.LOCK_UN); err != nil { + log.Fatalln(err) + } OODTgts = map[string]struct{}{} for _, tgtRaw := range bytes.Split(tgtsRaw, []byte{0}) { t := string(tgtRaw) @@ -235,7 +238,7 @@ func main() { continue } OODTgts[t] = struct{}{} - trace(CDebug, "ood: known to be: %s", t) + tracef(CDebug, "ood: known to be: %s", t) } } @@ -284,23 +287,23 @@ func main() { } } - killed := make(chan os.Signal, 0) + killed := make(chan os.Signal, 1) signal.Notify(killed, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM) go func() { <-killed - trace(CDebug, "[%s] killed", BuildUUID) + tracef(CDebug, "[%s] killed", BuildUUID) jsReleaseAll() RunningProcsM.Lock() for pid, proc := range RunningProcs { - trace(CDebug, "[%s] killing child %d", BuildUUID, pid) - proc.Signal(syscall.SIGTERM) + tracef(CDebug, "[%s] killing child %d", BuildUUID, pid) + _ = proc.Signal(syscall.SIGTERM) } os.Exit(1) }() ok := true err = nil - trace( + tracef( CDebug, "[%s] run: %s %s cwd:%s dirprefix:%s", BuildUUID, cmdName, tgts, Cwd, DirPrefix, ) @@ -386,7 +389,7 @@ CmdSwitch: for { m, err := r.NextMap() if err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { break } break CmdSwitch @@ -487,6 +490,6 @@ CmdSwitch: if !ok || err != nil { rc = 1 } - trace(CDebug, "[%s] finished: %s %s", BuildUUID, cmdName, tgts) + tracef(CDebug, "[%s] finished: %s %s", BuildUUID, cmdName, tgts) os.Exit(rc) } diff --git a/ood.go b/ood.go index c455a3b..fdb0d84 100644 --- a/ood.go +++ b/ood.go @@ -48,14 +48,14 @@ var ( FdOODTgtsLock *os.File ) -type TgtErr struct { +type TgtError struct { Tgt string Err error } -func (e TgtErr) Unwrap() error { return e.Err } +func (e TgtError) Unwrap() error { return e.Err } -func (e TgtErr) Error() string { +func (e TgtError) Error() string { return fmt.Sprintf("%s: %s", e.Tgt, e.Err) } @@ -107,33 +107,33 @@ func isOODByBuildUUID(cwd, tgtOrig string) bool { func isOOD(cwd, tgtOrig string, level int, seen map[string]struct{}) (bool, error) { indent := strings.Repeat(". ", level) - trace(CDebug, "ood: %s%s checking", indent, tgtOrig) + tracef(CDebug, "ood: %s%s checking", indent, tgtOrig) cwd, tgt := cwdAndTgt(path.Join(cwd, tgtOrig)) depPath := path.Join(cwd, RedoDir, tgt+DepSuffix) fdDep, err := os.Open(depPath) if err != nil { - trace(CDebug, "ood: %s%s -> no dep: %s", indent, tgtOrig, depPath) + tracef(CDebug, "ood: %s%s -> no dep: %s", indent, tgtOrig, depPath) return true, nil } depInfo, err := depRead(fdDep) fdDep.Close() if err != nil { - return true, TgtErr{tgtOrig, err} + return true, TgtError{tgtOrig, err} } if depInfo.build == BuildUUID { - trace(CDebug, "ood: %s%s -> already built", indent, tgtOrig) + tracef(CDebug, "ood: %s%s -> already built", indent, tgtOrig) return false, nil } if _, err := os.Stat(path.Join(cwd, tgt)); err != nil && os.IsNotExist(err) { - trace(CDebug, "ood: %s%s -> non-existent", indent, tgtOrig) + tracef(CDebug, "ood: %s%s -> non-existent", indent, tgtOrig) return true, nil } ood := false for _, dep := range depInfo.ifcreates { if _, err := os.Stat(path.Join(cwd, dep)); err == nil { - trace(CDebug, "ood: %s%s -> %s created", indent, tgtOrig, dep) + tracef(CDebug, "ood: %s%s -> %s created", indent, tgtOrig, dep) ood = true goto Done } @@ -142,80 +142,80 @@ func isOOD(cwd, tgtOrig string, level int, seen map[string]struct{}) (bool, erro for _, m := range depInfo.ifchanges { dep := m["Target"] if dep == "" { - return ood, TgtErr{tgtOrig, errors.New("invalid format of .rec: missing Target")} + return ood, TgtError{tgtOrig, errors.New("invalid format of .rec: missing Target")} } theirInode, err := inodeFromRec(m) if err != nil { - return ood, TgtErr{tgtOrig, fmt.Errorf("invalid format of .rec: %w", err)} + return ood, TgtError{tgtOrig, fmt.Errorf("invalid format of .rec: %w", err)} } theirHsh := m["Hash"] - trace(CDebug, "ood: %s%s -> %s: checking", indent, tgtOrig, dep) + tracef(CDebug, "ood: %s%s -> %s: checking", indent, tgtOrig, dep) fd, err := os.Open(path.Join(cwd, dep)) if err != nil { if os.IsNotExist(err) { - trace(CDebug, "ood: %s%s -> %s: not exists", indent, tgtOrig, dep) + tracef(CDebug, "ood: %s%s -> %s: not exists", indent, tgtOrig, dep) ood = true goto Done } - return ood, TgtErr{tgtOrig, err} + return ood, TgtError{tgtOrig, err} } defer fd.Close() inode, err := inodeFromFile(fd) if err != nil { - return ood, TgtErr{tgtOrig, err} + return ood, TgtError{tgtOrig, err} } if inode.Size != theirInode.Size { - trace(CDebug, "ood: %s%s -> %s: size differs", indent, tgtOrig, dep) + tracef(CDebug, "ood: %s%s -> %s: size differs", indent, tgtOrig, dep) ood = true goto Done } if InodeTrust && inode.Equals(theirInode) { - trace(CDebug, "ood: %s%s -> %s: same inode", indent, tgtOrig, dep) + tracef(CDebug, "ood: %s%s -> %s: same inode", indent, tgtOrig, dep) } else { - trace(CDebug, "ood: %s%s -> %s: inode differs", indent, tgtOrig, dep) + tracef(CDebug, "ood: %s%s -> %s: inode differs", indent, tgtOrig, dep) hsh, err := fileHash(fd) if err != nil { - return ood, TgtErr{tgtOrig, err} + return ood, TgtError{tgtOrig, err} } if theirHsh != hsh { - trace(CDebug, "ood: %s%s -> %s: hash differs", indent, tgtOrig, dep) + tracef(CDebug, "ood: %s%s -> %s: hash differs", indent, tgtOrig, dep) ood = true goto Done } - trace(CDebug, "ood: %s%s -> %s: same hash", indent, tgtOrig, dep) + tracef(CDebug, "ood: %s%s -> %s: same hash", indent, tgtOrig, dep) } fd.Close() // optimization not to hold it for long if dep == tgt { - trace(CDebug, "ood: %s%s -> %s: same target", indent, tgtOrig, dep) + tracef(CDebug, "ood: %s%s -> %s: same target", indent, tgtOrig, dep) continue } if isSrc(cwd, dep) { - trace(CDebug, "ood: %s%s -> %s: is source", indent, tgtOrig, dep) + tracef(CDebug, "ood: %s%s -> %s: is source", indent, tgtOrig, dep) continue } if _, ok := seen[cwdMustRel(cwd, dep)]; ok { - trace(CDebug, "ood: %s%s -> %s: was always built", indent, tgtOrig, dep) + tracef(CDebug, "ood: %s%s -> %s: was always built", indent, tgtOrig, dep) continue } depOod, err := isOODWithTrace(cwd, dep, level+1, seen) if err != nil { - return ood, TgtErr{tgtOrig, err} + return ood, TgtError{tgtOrig, err} } if depOod { - trace(CDebug, "ood: %s%s -> %s: ood", indent, tgtOrig, dep) + tracef(CDebug, "ood: %s%s -> %s: ood", indent, tgtOrig, dep) ood = true goto Done } - trace(CDebug, "ood: %s%s -> %s: !ood", indent, tgtOrig, dep) + tracef(CDebug, "ood: %s%s -> %s: !ood", indent, tgtOrig, dep) } Done: - trace(CDebug, "ood: %s%s: %v", indent, tgtOrig, ood) + tracef(CDebug, "ood: %s%s: %v", indent, tgtOrig, ood) return ood, nil } @@ -231,14 +231,14 @@ func isOODWithTrace( _, ood := OODTgts[p] if ood { if !isOODByBuildUUID(cwd, tgtOrig) { - trace( + tracef( CDebug, "ood: %s%s -> already built", strings.Repeat(". ", level), tgtOrig, ) return false, nil } - trace( + tracef( CDebug, "ood: %s%s true, external decision", strings.Repeat(". ", level), tgtOrig, @@ -259,16 +259,21 @@ RecordOODTgt: if _, err := FdOODTgts.WriteString(p + "\x00"); err != nil { log.Fatalln(err) } - unix.Flock(int(FdOODTgtsLock.Fd()), unix.LOCK_UN) + if err = unix.Flock(int(FdOODTgtsLock.Fd()), unix.LOCK_UN); err != nil { + log.Fatalln(err) + } return true, nil } func oodTgtsClear() { - if err := unix.Flock(int(FdOODTgtsLock.Fd()), unix.LOCK_EX); err != nil { + var err error + if err = unix.Flock(int(FdOODTgtsLock.Fd()), unix.LOCK_EX); err != nil { + log.Fatalln(err) + } + if err = FdOODTgts.Truncate(0); err != nil { log.Fatalln(err) } - if err := FdOODTgts.Truncate(0); err != nil { + if err = unix.Flock(int(FdOODTgtsLock.Fd()), unix.LOCK_UN); err != nil { log.Fatalln(err) } - unix.Flock(int(FdOODTgtsLock.Fd()), unix.LOCK_UN) } diff --git a/run.go b/run.go index 0178d72..ea14641 100644 --- a/run.go +++ b/run.go @@ -61,9 +61,9 @@ const ( ) var ( - NoSync bool = false - StderrKeep bool = false - StderrSilent bool = false + NoSync = false + StderrKeep = false + StderrSilent = false StderrPrefix string Jobs sync.WaitGroup @@ -76,6 +76,8 @@ var ( RunningProcs = map[int]*os.Process{} RunningProcsM sync.Mutex + + Err1WasTouched = errors.New("$1 was explicitly touched") ) func init() { @@ -92,7 +94,7 @@ func init() { fmt.Sprintf("silent, do not print job's stderr (%s=1)", EnvStderrSilent)) } -type RunErr struct { +type RunError struct { Tgt string DoFile string Started *time.Time @@ -100,7 +102,7 @@ type RunErr struct { Err error } -func (e *RunErr) Name() string { +func (e *RunError) Name() string { var name string if e.DoFile == "" { name = e.Tgt @@ -113,7 +115,7 @@ func (e *RunErr) Name() string { return fmt.Sprintf("%s (%.3fs)", name, e.Finished.Sub(*e.Started).Seconds()) } -func (e RunErr) Error() string { +func (e RunError) Error() string { return fmt.Sprintf("%s: %s", e.Name(), e.Err) } @@ -138,7 +140,7 @@ func isModified(cwd, redoDir, tgt string) (bool, *Inode, error) { for { m, err := r.NextMap() if err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { break } return false, nil, err @@ -184,7 +186,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { cwd, tgt := cwdAndTgt(tgtOrig) redoDir := path.Join(cwd, RedoDir) if err := mkdirs(redoDir); err != nil { - return TgtErr{tgtOrig, err} + return TgtError{tgtOrig, err} } // Acquire lock @@ -194,34 +196,42 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { os.FileMode(0666), ) if err != nil { - return TgtErr{tgtOrig, err} + return TgtError{tgtOrig, err} } lockRelease := func() { - trace(CLock, "LOCK_UN: %s", fdLock.Name()) - unix.Flock(int(fdLock.Fd()), unix.LOCK_UN) + tracef(CLock, "LOCK_UN: %s", fdLock.Name()) + if err := unix.Flock(int(fdLock.Fd()), unix.LOCK_UN); err != nil { + log.Fatalln(err) + } fdLock.Close() } - trace(CLock, "LOCK_NB: %s", fdLock.Name()) + tracef(CLock, "LOCK_NB: %s", fdLock.Name()) // Waiting for job completion, already taken by someone else if err = unix.Flock(int(fdLock.Fd()), unix.LOCK_EX|unix.LOCK_NB); err != nil { if uintptr(err.(syscall.Errno)) != uintptr(unix.EWOULDBLOCK) { fdLock.Close() - return TgtErr{tgtOrig, err} + return TgtError{tgtOrig, err} } Jobs.Add(1) - trace(CDebug, "waiting: %s", tgtOrig) + tracef(CDebug, "waiting: %s", tgtOrig) if FdStatus != nil { - FdStatus.Write([]byte{StatusWait}) + if _, err = FdStatus.Write([]byte{StatusWait}); err != nil { + log.Fatalln(err) + } } go func() { defer Jobs.Done() - trace(CLock, "LOCK_EX: %s", fdLock.Name()) - unix.Flock(int(fdLock.Fd()), unix.LOCK_EX) + tracef(CLock, "LOCK_EX: %s", fdLock.Name()) + if err := unix.Flock(int(fdLock.Fd()), unix.LOCK_EX); err != nil { + log.Fatalln(err) + } lockRelease() - trace(CDebug, "waiting done: %s", tgtOrig) + tracef(CDebug, "waiting done: %s", tgtOrig) if FdStatus != nil { - FdStatus.Write([]byte{StatusWaited}) + if _, err = FdStatus.Write([]byte{StatusWaited}); err != nil { + log.Fatalln(err) + } } var depInfo *DepInfo fdDep, err := os.Open(path.Join(redoDir, tgt+DepSuffix)) @@ -241,7 +251,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { } Finish: if err != nil { - err = TgtErr{tgtOrig, err} + err = TgtError{tgtOrig, err} } errs <- err }() @@ -252,10 +262,10 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { modified, inodePrev, err := isModified(cwd, redoDir, tgt) if err != nil { lockRelease() - return TgtErr{tgtOrig, err} + return TgtError{tgtOrig, err} } if modified { - trace(CWarn, "%s externally modified: not redoing", tgtOrig) + tracef(CWarn, "%s externally modified: not redoing", tgtOrig) lockRelease() go func() { errs <- nil @@ -267,7 +277,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { fdDep, err := tempfile(redoDir, tgt+DepSuffix) if err != nil { lockRelease() - return TgtErr{tgtOrig, err} + return TgtError{tgtOrig, err} } fdDepPath := fdDep.Name() cleanup := func() { @@ -279,18 +289,18 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { recfile.Field{Name: "Build", Value: BuildUUID}, ); err != nil { cleanup() - return TgtErr{tgtOrig, err} + return TgtError{tgtOrig, err} } // Find .do doFile, upLevels, err := findDo(fdDep, cwd, tgt) if err != nil { cleanup() - return TgtErr{tgtOrig, err} + return TgtError{tgtOrig, err} } if doFile == "" { cleanup() - return TgtErr{tgtOrig, errors.New("no .do found")} + return TgtError{tgtOrig, errors.New("no .do found")} } // Determine basename and DIRPREFIX @@ -306,7 +316,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { cwd = path.Clean(cwd) doFilePath := path.Join(cwd, doFile) basename := tgt - runErr := RunErr{Tgt: tgtOrig} + runErr := RunError{Tgt: tgtOrig} if strings.HasPrefix(doFile, "default.") { basename = tgt[:len(tgt)-(len(doFile)-len("default.")-len(".do"))-1] runErr.DoFile = doFileRelPath @@ -314,10 +324,10 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { if err = writeDep(fdDep, cwdOrig, doFileRelPath); err != nil { cleanup() - return TgtErr{tgtOrig, err} + return TgtError{tgtOrig, err} } fdDep.Close() - trace(CWait, "%s", runErr.Name()) + tracef(CWait, "%s", runErr.Name()) // Prepare command line var cmdName string @@ -339,7 +349,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { fdStdout, err := tempfile(cwdOrig, tgt) if err != nil { cleanup() - return TgtErr{tgtOrig, err} + return TgtError{tgtOrig, err} } stdoutPath := fdStdout.Name() fdStdout.Close() @@ -393,14 +403,14 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { ) if err != nil { cleanup() - return TgtErr{tgtOrig, err} + return TgtError{tgtOrig, err} } } shCtx := fmt.Sprintf( "sh: %s: %s %s cwd:%s dirprefix:%s", tgtOrig, cmdName, args, cwd, dirPrefix, ) - trace(CDebug, "%s", shCtx) + tracef(CDebug, "%s", shCtx) Jobs.Add(1) go func() { @@ -421,7 +431,9 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { } if FdStatus != nil { - FdStatus.Write([]byte{StatusRun}) + if _, err = FdStatus.Write([]byte{StatusRun}); err != nil { + log.Fatalln(err) + } } var finished time.Time @@ -532,7 +544,9 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { os.Remove(tmpPath) os.Remove(fdLock.Name()) if FdStatus != nil { - FdStatus.Write([]byte{StatusDone}) + if _, err = FdStatus.Write([]byte{StatusDone}); err != nil { + log.Fatalln(err) + } } Jobs.Done() }() @@ -553,9 +567,9 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { RunningProcs[cmd.Process.Pid] = cmd.Process RunningProcsM.Unlock() pid := fmt.Sprintf("[%d]", cmd.Process.Pid) - trace(CDebug, "%s runs %s", tgtOrig, pid) + tracef(CDebug, "%s runs %s", tgtOrig, pid) - stderrTerm := make(chan struct{}, 0) + stderrTerm := make(chan struct{}) go func() { scanner := bufio.NewScanner(stderr) var line string @@ -577,9 +591,9 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { continue } if MyPid == 0 { - trace(CNone, "%s", line) + tracef(CNone, "%s", line) } else { - trace(CNone, "%s %s", pid, line) + tracef(CNone, "%s %s", pid, line) } } close(stderrTerm) @@ -602,25 +616,24 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { // Was $1 touched? if fd, err := os.Open(path.Join(cwdOrig, tgt)); err == nil { - errTouched := errors.New("$1 was explicitly touched") + errTouched := Err1WasTouched if inodePrev == nil { fd.Close() runErr.Err = errTouched errs <- runErr return - } else { - inode, err := inodeFromFile(fd) - fd.Close() - if err != nil { - runErr.Err = err - errs <- runErr - return - } - if !inode.Equals(inodePrev) { - runErr.Err = errTouched - errs <- runErr - return - } + } + inode, err := inodeFromFile(fd) + fd.Close() + if err != nil { + runErr.Err = err + errs <- runErr + return + } + if !inode.Equals(inodePrev) { + runErr.Err = errTouched + errs <- runErr + return } } @@ -629,7 +642,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { inode, err := inodeFromFile(fd) fd.Close() if err == nil && !inode.Equals(inodePrev) { - runErr.Err = errors.New("$1 was explicitly touched") + runErr.Err = Err1WasTouched errs <- runErr return } @@ -729,10 +742,11 @@ func isOkRun(err error) bool { if err == nil { return true } - if err, ok := err.(RunErr); ok && err.Err == nil { - trace(CRedo, "%s", err.Name()) + var runErr RunError + if errors.As(err, &runErr) && runErr.Err == nil { + tracef(CRedo, "%s", runErr.Name()) return true } - trace(CErr, "%s", err) + tracef(CErr, "%s", err) return false } diff --git a/sources.go b/sources.go index 1fd4c9d..ebfbcb9 100644 --- a/sources.go +++ b/sources.go @@ -40,6 +40,9 @@ func sourcesWalker(tgts []string) ([]string, error) { return nil, err } depInfo, err := depRead(fdDep) + if err != nil { + return nil, err + } fdDep.Close() for _, m := range depInfo.ifchanges { depTgt := m["Target"]