X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=ifchange.go;h=4a43872c2cf35b4ec4a8ae0a97739f6b0de5bb1b;hb=b4eefdd675c9aef9ff8bd1089d031ee05733195b;hp=128d1afbef6eaea5fdd1681af86cb1339ec8f738;hpb=dd726a39166775b4d60f921f032b1b898e7d7001;p=goredo.git diff --git a/ifchange.go b/ifchange.go index 128d1af..4a43872 100644 --- a/ifchange.go +++ b/ifchange.go @@ -1,6 +1,6 @@ /* goredo -- djb's redo implementation on pure Go -Copyright (C) 2020-2021 Sergey Matveev +Copyright (C) 2020-2023 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 @@ -45,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 } @@ -87,7 +87,7 @@ 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 _, tgtInitial := range tgts { @@ -98,7 +98,7 @@ func buildDependants(tgts []string) map[string]struct{} { } } if len(seen) == 0 { - return nil + return seen } levelOrig := Level @@ -106,11 +106,11 @@ 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 } } @@ -121,7 +121,7 @@ func buildDependants(tgts []string) map[string]struct{} { Jobs.Wait() close(errs) if !ok { - trace(CDebug, "alwayses failed, skipping dependants") + tracef(CDebug, "alwayses failed, skipping dependants") return nil } @@ -134,28 +134,29 @@ func buildDependants(tgts []string) map[string]struct{} { } 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) @@ -166,7 +167,7 @@ RebuildDeps: ok = isOkRun(<-errs) && ok } if !ok { - trace(CDebug, "dependants failed, skipping them") + tracef(CDebug, "dependants failed, skipping them") return nil } Jobs.Wait() @@ -179,21 +180,35 @@ RebuildDeps: } 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 @@ -207,7 +222,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 {