X-Git-Url: http://www.git.cypherpunks.ru/?p=goredo.git;a=blobdiff_plain;f=ifchange.go;h=43cfdb3e387e12474aec2034b719a8046ab6e6be;hp=f0e877ef22c78da9f88f583b57d23bd244fe261d;hb=d8abe40c66df8d79a025524c0d230959cacf9465;hpb=573c4cabcbb8e4bf6a90d0f19a440af92b9cef6d diff --git a/ifchange.go b/ifchange.go index f0e877e..43cfdb3 100644 --- a/ifchange.go +++ b/ifchange.go @@ -1,6 +1,6 @@ /* -goredo -- redo implementation on pure Go -Copyright (C) 2020 Sergey Matveev +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 @@ -27,6 +27,7 @@ func collectDeps( 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) @@ -44,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 } @@ -60,7 +61,10 @@ func collectDeps( if dep == "" { return alwayses } - if dep == tgt || isSrc(cwd, dep) { + if dep == tgt { + continue + } + if !includeSrc && isSrc(cwd, dep) { continue } if !returnReady { @@ -68,11 +72,14 @@ func collectDeps( 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 @@ -80,12 +87,14 @@ 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 _, 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 { @@ -97,22 +106,22 @@ 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 } } 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") + tracef(CDebug, "alwayses failed, skipping dependants") return nil } @@ -125,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 := isOOD(Cwd, tgt, 0, seen) + 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) @@ -154,10 +163,10 @@ RebuildDeps: jobs++ } for i := 0; i < jobs; i++ { - ok = ok && isOkRun(<-errs) + ok = isOkRun(<-errs) && ok } if !ok { - trace(CDebug, "dependants failed, skipping them") + tracef(CDebug, "dependants failed, skipping them") return nil } Jobs.Wait() @@ -171,22 +180,25 @@ RebuildDeps: 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) - trace(CDebug, "building %d targets: %v", len(tgts), tgts) + oodTgtsClear() + 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 dependenant", tgt) + tracef(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 } @@ -195,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 { @@ -205,7 +217,7 @@ func ifchange(tgts []string, forced, traced bool) (bool, error) { } ok := true for ; jobs > 0; jobs-- { - ok = ok && isOkRun(<-errs) + ok = isOkRun(<-errs) && ok } return ok, nil }