/*
-goredo -- redo implementation on pure Go
-Copyright (C) 2020 Sergey Matveev <stargrave@stargrave.org>
+goredo -- djb's redo implementation on pure Go
+Copyright (C) 2020-2021 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
cwd, tgtOrig string,
level int,
deps map[string]map[string]struct{},
+ includeSrc bool,
) []string {
cwd, tgt := cwdAndTgt(path.Join(cwd, tgtOrig))
depPath := path.Join(cwd, RedoDir, tgt+DepSuffix)
if dep == "" {
return alwayses
}
- if dep == tgt || isSrc(cwd, dep) {
+ if dep == tgt {
+ continue
+ }
+ if !includeSrc && isSrc(cwd, dep) {
continue
}
if !returnReady {
if m, ok := deps[depRel]; ok {
m[tgtRel] = struct{}{}
} else {
- m = make(map[string]struct{}, 0)
+ m = map[string]struct{}{}
m[tgtRel] = struct{}{}
deps[depRel] = m
}
- alwayses = append(alwayses, collectDeps(cwd, dep, level+1, deps)...)
+ alwayses = append(
+ alwayses,
+ collectDeps(cwd, dep, level+1, deps, includeSrc)...,
+ )
}
}
return alwayses
trace(CDebug, "collecting deps")
seen := map[string]struct{}{}
deps := map[string]map[string]struct{}{}
- for _, tgt := range tgts {
- for _, tgt := range collectDeps(Cwd, tgt, 0, deps) {
- seen[tgt] = struct{}{}
+ for _, tgtInitial := range tgts {
+ for _, tgt := range collectDeps(Cwd, tgtInitial, 0, deps, false) {
+ if tgt != tgtInitial {
+ seen[tgt] = struct{}{}
+ }
}
}
if len(seen) == 0 {
Level = 1
trace(CDebug, "building %d alwayses: %v", len(seen), seen)
errs := make(chan error, len(seen))
- for tgt, _ := range seen {
+ for tgt := range seen {
if err := runScript(tgt, errs, false); err != nil {
trace(CErr, "always run error: %s, skipping dependants", err)
return nil
}
ok := true
for i := 0; i < len(seen); i++ {
- ok = ok && isOkRun(<-errs)
+ ok = isOkRun(<-errs) && ok
}
Jobs.Wait()
close(errs)
if !ok {
- trace(CDebug, "alwayses failed, skipping depdendants")
+ trace(CDebug, "alwayses failed, skipping dependants")
return nil
}
queueSrc := make([]string, 0, len(seen))
- for tgt, _ := range seen {
+ for tgt := range seen {
queueSrc = append(queueSrc, tgt)
}
if len(queueSrc) == 0 {
trace(CDebug, "checking %d dependant targets: %v", len(queueSrc), queueSrc)
queue := []string{}
for _, tgt := range queueSrc {
- for dep, _ := range deps[tgt] {
+ for dep := range deps[tgt] {
queue = append(queue, dep)
}
}
jobs := 0
queueSrc = []string{}
for _, tgt := range queue {
- ood, err := isOOD(Cwd, tgt, 0, seen)
+ ood, err := isOODWithTrace(Cwd, tgt, 0, seen)
if err != nil {
trace(CErr, "dependant error: %s, skipping dependants", err)
return nil
jobs++
}
for i := 0; i < jobs; i++ {
- ok = ok && isOkRun(<-errs)
+ ok = isOkRun(<-errs) && ok
}
if !ok {
trace(CDebug, "dependants failed, skipping them")
func ifchange(tgts []string, forced, traced bool) (bool, error) {
jsInit()
- defer jsAcquire("ifchange exiting")
+ if !IsTopRedo {
+ defer jsAcquire("ifchange exiting")
+ }
defer Jobs.Wait()
seen := buildDependants(tgts)
+ oodTgtsClear()
trace(CDebug, "building %d targets: %v", len(tgts), tgts)
jobs := 0
errs := make(chan error, len(tgts))
var err error
for _, tgt := range tgts {
if _, ok := seen[tgt]; ok {
- trace(CDebug, "%s was already build as a dependenant", tgt)
+ trace(CDebug, "%s was already build as a dependant", tgt)
continue
}
ood = true
if !forced {
- ood, err = isOOD(Cwd, tgt, 0, seen)
+ ood, err = isOODWithTrace(Cwd, tgt, 0, seen)
if err != nil {
return false, err
}
}
ok := true
for ; jobs > 0; jobs-- {
- ok = ok && isOkRun(<-errs)
+ ok = isOkRun(<-errs) && ok
}
return ok, nil
}