/*
goredo -- djb's redo implementation on pure Go
-Copyright (C) 2020-2021 Sergey Matveev <stargrave@stargrave.org>
+Copyright (C) 2020-2023 Sergey Matveev <stargrave@stargrave.org>
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
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
}
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 {
}
}
if len(seen) == 0 {
- return nil
+ return seen
}
levelOrig := Level
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
}
}
Jobs.Wait()
close(errs)
if !ok {
- trace(CDebug, "alwayses failed, skipping dependants")
+ tracef(CDebug, "alwayses failed, skipping dependants")
return nil
}
}
RebuildDeps:
- trace(CDebug, "checking %d dependant targets: %v", len(queueSrc), queueSrc)
- queue := []string{}
+ tracef(CDebug, "checking %d dependant targets: %v", len(queueSrc), queueSrc)
+ queue := map[string]struct{}{}
for _, tgt := range queueSrc {
for dep := range deps[tgt] {
- queue = append(queue, dep)
+ queue[dep] = struct{}{}
}
}
- 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 {
+ 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)
ok = isOkRun(<-errs) && ok
}
if !ok {
- trace(CDebug, "dependants failed, skipping them")
+ tracef(CDebug, "dependants failed, skipping them")
return nil
}
Jobs.Wait()
}
func ifchange(tgts []string, forced, traced bool) (bool, error) {
+ // only unique elements
+ m := make(map[string]struct{})
+ for _, t := range tgts {
+ m[t] = struct{}{}
+ }
+ tgts = tgts[:0]
+ for t := range m {
+ tgts = append(tgts, t)
+ }
+ m = nil
+
jsInit()
if !IsTopRedo {
defer jsAcquire("ifchange exiting")
}
defer Jobs.Wait()
seen := buildDependants(tgts)
+ if seen == nil {
+ return false, nil
+ }
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
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 {