X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=buildlog.go;h=f04efa41e2bf269251b2c56824eaa4d3e48e9581;hb=HEAD;hp=3403e4d750d051a191bfaba0ecd88f31b74c64f8;hpb=7492a39768035abafa55be738649a8dd035a89bd;p=goredo.git diff --git a/buildlog.go b/buildlog.go index 3403e4d..f04efa4 100644 --- a/buildlog.go +++ b/buildlog.go @@ -1,19 +1,17 @@ -/* -goredo -- djb's redo implementation on pure Go -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 -the Free Software Foundation, version 3 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ +// goredo -- djb's redo implementation on pure Go +// Copyright (C) 2020-2024 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 +// the Free Software Foundation, version 3 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . package main @@ -23,9 +21,9 @@ import ( "flag" "fmt" "io" + "io/fs" "os" "path" - "path/filepath" "sort" "strconv" "strings" @@ -38,8 +36,7 @@ import ( const HumanTimeFmt = "2006-01-02 15:04:05.000000000 Z07:00" type BuildLogJob struct { - dir string - tgt string + tgt *Tgt started time.Time exitCode int rec map[string][]string @@ -75,15 +72,16 @@ func init() { buildLogSeen = make(map[string]struct{}) } -func parseBuildLogRec(dir, tgt string) (map[string][]string, error) { - fd, err := os.Open(path.Join(dir, RedoDir, tgt+LogSuffix+DepSuffix)) +func parseBuildLogRec(tgt *Tgt) (map[string][]string, error) { + h, t := path.Split(tgt.a) + fd, err := os.Open(path.Join(h, RedoDir, t+LogRecSuffix)) if err != nil { - return nil, err + return nil, ErrLine(err) } r := recfile.NewReader(bufio.NewReader(fd)) rec, err := r.NextMapWithSlice() fd.Close() - return rec, err + return rec, ErrLine(err) } func depthPrefix(depth int) string { @@ -94,39 +92,35 @@ func depthPrefix(depth int) string { } func showBuildLogSub(sub *BuildLogJob, depth int) error { - abs, err := filepath.Abs(path.Join(sub.dir, sub.tgt)) - if err != nil { - return err - } - if _, ok := buildLogSeen[abs]; ok { + if _, ok := buildLogSeen[sub.tgt.rel]; ok { return nil } - buildLogSeen[abs] = struct{}{} + buildLogSeen[sub.tgt.rel] = struct{}{} dp := depthPrefix(depth) fmt.Printf( "%s%s%s\n", sub.rec["Started"][0], dp, - colourize(CRedo, "redo "+sub.tgt), + colourize(CRedo, "redo "+sub.tgt.rel), ) - if err := showBuildLog(sub.dir, sub.tgt, sub.rec, depth+1); err != nil { + if err := showBuildLog(sub.tgt, sub.rec, depth+1); err != nil { return err } durationSec, durationNsec, err := durationToInts(sub.rec["Duration"][0]) if err != nil { - return err + return ErrLine(err) } if sub.exitCode > 0 { fmt.Printf( "%s%s%s (code: %d) (%d.%ds)\n\n", sub.rec["Finished"][0], dp, - colourize(CErr, "err "+sub.tgt), + colourize(CErr, "err "+sub.tgt.rel), sub.exitCode, durationSec, durationNsec, ) } else { fmt.Printf( "%s%s%s (%d.%ds)\n\n", sub.rec["Finished"][0], dp, - colourize(CRedo, "done "+sub.tgt), + colourize(CRedo, "done "+sub.tgt.rel), durationSec, durationNsec, ) } @@ -144,7 +138,7 @@ func durationToInts(d string) (int64, int64, error) { func showBuildLogCmd(m map[string][]string, depth int) error { started, err := tai64n.Decode(m["Started"][0]) if err != nil { - return err + return ErrLine(err) } dp := depthPrefix(depth) fmt.Printf( @@ -156,11 +150,11 @@ func showBuildLogCmd(m map[string][]string, depth int) error { } finished, err := tai64n.Decode(m["Finished"][0]) if err != nil { - return err + return ErrLine(err) } durationSec, durationNsec, err := durationToInts(m["Duration"][0]) if err != nil { - return err + return ErrLine(err) } fmt.Printf( "%s%sStarted:\t%s\n%s%sFinished:\t%s\n%s%sDuration:\t%d.%ds\n\n", @@ -171,11 +165,10 @@ func showBuildLogCmd(m map[string][]string, depth int) error { return nil } -func showBuildLog(dir, tgt string, buildLogRec map[string][]string, depth int) error { +func showBuildLog(tgt *Tgt, buildLogRec map[string][]string, depth int) error { var err error - dirNormalized, tgtNormalized := cwdAndTgt(path.Join(dir, tgt)) if *flagBuildLogCommands || *flagBuildLogRecursive { - buildLogRec, err = parseBuildLogRec(dirNormalized, tgtNormalized) + buildLogRec, err = parseBuildLogRec(tgt) if err != nil { return err } @@ -185,9 +178,10 @@ func showBuildLog(dir, tgt string, buildLogRec map[string][]string, depth int) e return err } } - fd, err := os.Open(path.Join(dirNormalized, RedoDir, tgtNormalized+LogSuffix)) + tgtH, tgtT := path.Split(tgt.a) + fd, err := os.Open(path.Join(tgtH, RedoDir, tgtT+LogSuffix)) if err != nil { - return err + return ErrLine(err) } if !*flagBuildLogRecursive { w := bufio.NewWriter(os.Stdout) @@ -195,29 +189,20 @@ func showBuildLog(dir, tgt string, buildLogRec map[string][]string, depth int) e fd.Close() if err != nil { w.Flush() - return err + return ErrLine(err) } - return w.Flush() + return ErrLine(w.Flush()) } defer fd.Close() - fdDep, err := os.Open(path.Join(dirNormalized, RedoDir, tgtNormalized+DepSuffix)) - if err != nil { - return err - } - depInfo, err := depRead(fdDep) - fdDep.Close() - if err != nil { - return err - } - subs := make([]*BuildLogJob, 0, len(depInfo.ifchanges)) - for _, dep := range depInfo.ifchanges { - subDir, subTgt := cwdAndTgt(path.Join(dirNormalized, dep["Target"])) - if subDir == dirNormalized && subTgt == tgtNormalized { + subs := make([]*BuildLogJob, 0, len(buildLogRec["Ifchange"])) + for _, depPath := range buildLogRec["Ifchange"] { + dep := NewTgt(path.Join(tgtH, depPath)) + if dep.rel == tgt.rel { continue } - rec, err := parseBuildLogRec(subDir, subTgt) + rec, err := parseBuildLogRec(dep) if err != nil { - if os.IsNotExist(err) { + if errors.Is(err, fs.ErrNotExist) { continue } return err @@ -227,18 +212,17 @@ func showBuildLog(dir, tgt string, buildLogRec map[string][]string, depth int) e } started, err := tai64n.Decode(rec["Started"][0]) if err != nil { - return err + return ErrLine(err) } var exitCode int if len(rec["ExitCode"]) > 0 { exitCode, err = strconv.Atoi(rec["ExitCode"][0]) if err != nil { - return err + return ErrLine(err) } } subs = append(subs, &BuildLogJob{ - dir: dirNormalized, - tgt: dep["Target"], + tgt: dep, started: started, exitCode: exitCode, rec: rec, @@ -257,13 +241,13 @@ func showBuildLog(dir, tgt string, buildLogRec map[string][]string, depth int) e for { if !scanner.Scan() { if err = scanner.Err(); err != nil { - return err + return ErrLine(err) } break } text = scanner.Text() if text[0] != '@' { - return errors.New("unexpected non-TAI64Ned string") + return ErrLine(errors.New("unexpected non-TAI64Ned string")) } sep = strings.IndexByte(text, byte(' ')) if sep == -1 { @@ -271,7 +255,7 @@ func showBuildLog(dir, tgt string, buildLogRec map[string][]string, depth int) e } t, err = tai64n.Decode(text[1:sep]) if err != nil { - return err + return ErrLine(err) } for sub != nil && t.After(sub.started) { if err = showBuildLogSub(sub, depth); err != nil {