package main
import (
- "os"
"path"
"strings"
)
level int,
deps map[string]map[string]struct{},
includeSrc bool,
+ seen map[string]struct{},
) []string {
cwd, tgt := cwdAndTgt(path.Join(cwd, tgtOrig))
- depPath := path.Join(cwd, RedoDir, tgt+DepSuffix)
- fdDep, err := os.Open(depPath)
- if err != nil {
+ tgtFull := path.Join(cwd, tgt)
+ if _, ok := seen[tgtFull]; ok {
return nil
}
- depInfo, err := depRead(fdDep)
- fdDep.Close()
+ depPath := path.Join(cwd, RedoDir, tgt+DepSuffix)
+ depInfo, err := depRead(depPath)
if err != nil {
return nil
}
+ // DepInfoCache[depPath] = depInfo
+ seen[tgtFull] = struct{}{}
var alwayses []string
returnReady := false
tgtRel := cwdMustRel(cwd, tgt)
returnReady = true
}
}
- for _, m := range depInfo.ifchanges {
- dep := m["Target"]
- if dep == "" {
- return alwayses
- }
- if dep == tgt {
+ for _, dep := range depInfo.ifchanges {
+ if dep.tgt == tgt {
continue
}
- if !includeSrc && isSrc(cwd, dep) {
+ if !includeSrc && isSrc(cwd, dep.tgt) {
continue
}
if !returnReady {
- depRel := cwdMustRel(cwd, dep)
+ depRel := cwdMustRel(cwd, dep.tgt)
if m, ok := deps[depRel]; ok {
m[tgtRel] = struct{}{}
} else {
m[tgtRel] = struct{}{}
deps[depRel] = m
}
- alwayses = append(
- alwayses,
- collectDeps(cwd, dep, level+1, deps, includeSrc)...,
- )
+ alwayses = append(alwayses,
+ collectDeps(cwd, dep.tgt, level+1, deps, includeSrc, seen)...)
}
}
return alwayses
tracef(CDebug, "collecting deps")
seen := map[string]struct{}{}
deps := map[string]map[string]struct{}{}
+ collectDepsSeen := make(map[string]struct{})
for _, tgtInitial := range tgts {
- for _, tgt := range collectDeps(Cwd, tgtInitial, 0, deps, false) {
+ for _, tgt := range collectDeps(Cwd, tgtInitial, 0, deps, false, collectDepsSeen) {
if tgt != tgtInitial {
seen[tgt] = struct{}{}
}
if len(seen) == 0 {
return seen
}
+ collectDepsSeen = nil
levelOrig := Level
defer func() {
Level = 1
tracef(CDebug, "building %d alwayses: %v", len(seen), seen)
errs := make(chan error, len(seen))
+ ok := true
+ okChecker := make(chan struct{})
+ go func() {
+ for err := range errs {
+ ok = isOkRun(err) && ok
+ }
+ close(okChecker)
+ }()
for tgt := range seen {
if err := runScript(tgt, errs, false, false); err != nil {
tracef(CErr, "always run error: %s, skipping dependants", err)
+ Jobs.Wait()
+ close(errs)
return nil
}
}
- ok := true
- for i := 0; i < len(seen); i++ {
- ok = isOkRun(<-errs) && ok
- }
Jobs.Wait()
close(errs)
+ <-okChecker
if !ok {
tracef(CDebug, "alwayses failed, skipping dependants")
return nil
tracef(CDebug, "building %d dependant targets: %v", len(queue), queue)
errs = make(chan error, len(queue))
+ okChecker = make(chan struct{})
jobs := 0
queueSrc = []string{}
+ go func() {
+ for err := range errs {
+ ok = isOkRun(err) && ok
+ }
+ close(okChecker)
+ }()
for tgt := range queue {
ood, err := isOODWithTrace(Cwd, tgt, 0, seen)
if err != nil {
seen[tgt] = struct{}{}
jobs++
}
- for i := 0; i < jobs; i++ {
- ok = isOkRun(<-errs) && ok
- }
+ Jobs.Wait()
+ close(errs)
+ <-okChecker
if !ok {
tracef(CDebug, "dependants failed, skipping them")
return nil
}
- Jobs.Wait()
- close(errs)
if jobs == 0 {
return seen
}
if !IsTopRedo {
defer jsAcquire("ifchange exiting")
}
- defer Jobs.Wait()
seen := buildDependants(tgts)
if seen == nil {
+ Jobs.Wait()
return false, nil
}
oodTgtsClear()
tracef(CDebug, "building %d targets: %v", len(tgts), tgts)
- jobs := 0
- errs := make(chan error, len(tgts))
var ood bool
var err error
+ ok := true
+ okChecker := make(chan struct{})
+ errs := make(chan error, len(tgts))
+ go func() {
+ for err := range errs {
+ ok = isOkRun(err) && ok
+ }
+ close(okChecker)
+ }()
for _, tgt := range tgts {
if _, ok := seen[tgt]; ok {
tracef(CDebug, "%s was already build as a dependant", tgt)
if !forced {
ood, err = isOODWithTrace(Cwd, tgt, 0, seen)
if err != nil {
- return false, err
+ Jobs.Wait()
+ close(errs)
+ return false, ErrLine(err)
}
}
if !ood {
continue
}
if err = runScript(tgt, errs, forced, traced); err != nil {
- return false, err
+ Jobs.Wait()
+ close(errs)
+ return false, ErrLine(err)
}
- jobs++
- }
- ok := true
- for ; jobs > 0; jobs-- {
- ok = isOkRun(<-errs) && ok
}
+ Jobs.Wait()
+ close(errs)
+ <-okChecker
return ok, nil
}