X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=sources.go;h=3f375a6fe58f666c01a5b190a5c82ee149bf20d5;hb=e935c1db3ae2ff6d920ff37802774ba2e85629f0;hp=d53e0e32501b880be35e737cf377602cf9f3ed5e;hpb=10baafbc3ef7dd24ecdc18a008e59e5068c8eb39;p=goredo.git diff --git a/sources.go b/sources.go index d53e0e3..3f375a6 100644 --- a/sources.go +++ b/sources.go @@ -18,47 +18,54 @@ along with this program. If not, see . package main import ( - "log" "os" "path" ) -func sourcesWalker(tgts []string) ([]string, error) { - seen := make(map[string]struct{}, 1<<10) +func sourcesWalker( + tgts []string, + seen map[string]struct{}, + seenDeps map[string]struct{}, + srcs map[string]struct{}, +) error { for _, tgt := range tgts { tgtAbsPath := mustAbs(path.Join(Cwd, tgt)) cwd, f := path.Split(path.Join(Cwd, tgt)) - fdDep, err := os.Open(path.Join(cwd, RedoDir, f+DepSuffix)) + depPath := path.Join(cwd, RedoDir, f+DepSuffix) + if _, ok := seenDeps[depPath]; ok { + continue + } + seenDeps[depPath] = struct{}{} + fdDep, err := os.Open(depPath) if err != nil { if errors.Is(err, fs.ErrNotExist) { continue } - return nil, ErrLine(err) + return ErrLine(err) } depInfo, err := depRead(fdDep) fdDep.Close() if err != nil { - return nil, ErrLine(err) + return ErrLine(err) } for _, m := range depInfo.ifchanges { depTgt := m["Target"] depTgtAbsPath := mustAbs(path.Join(cwd, depTgt)) + if _, ok := seen[depTgtAbsPath]; ok { + continue + } + seen[depTgtAbsPath] = struct{}{} if isSrc(cwd, depTgt) { - seen[cwdMustRel(depTgtAbsPath)] = struct{}{} + srcs[cwdMustRel(depTgtAbsPath)] = struct{}{} } else if depTgtAbsPath != tgtAbsPath { - subSrcs, err := sourcesWalker([]string{cwdMustRel(depTgtAbsPath)}) - if err != nil { - log.Fatal(err) - } - for _, p := range subSrcs { - seen[p] = struct{}{} + if err := sourcesWalker( + []string{cwdMustRel(depTgtAbsPath)}, + seen, seenDeps, srcs, + ); err != nil { + return err } } } } - srcs := make([]string, 0, len(seen)) - for p := range seen { - srcs = append(srcs, p) - } - return srcs, nil + return nil }