X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=targets.go;h=0545483752bda04c4ac1347cb16421ee46215c98;hb=bf96757828d2ae663f5f54147c0e229f74fc9357;hp=602fd942abbf16b1741df0c946167f06aa703877;hpb=609842c96d2bb25c509f3d2949fe26f60ec03a5f;p=goredo.git diff --git a/targets.go b/targets.go index 602fd94..0545483 100644 --- a/targets.go +++ b/targets.go @@ -25,24 +25,23 @@ import ( "strings" ) -func targetsWalker(root string) ([]string, error) { +func targetsCollect(root string, tgts map[string]struct{}) error { root, err := filepath.Abs(root) if err != nil { panic(err) } dir, err := os.Open(root) if err != nil { - return nil, err + return err } defer dir.Close() - tgts := make([]string, 0, 1<<10) for { fis, err := dir.Readdir(1 << 10) if err != nil { if err == io.EOF { break } - return tgts, err + return err } for _, fi := range fis { if !fi.IsDir() { @@ -52,28 +51,51 @@ func targetsWalker(root string) ([]string, error) { if fi.Name() == RedoDir { redoDir, err := os.Open(pth) if err != nil { - return tgts, err + return err } redoFis, err := redoDir.Readdir(0) if err != nil { - return tgts, err + return err } for _, redoFi := range redoFis { name := redoFi.Name() if strings.HasSuffix(name, DepSuffix) { name = cwdMustRel(root, name) - tgts = append(tgts, name[:len(name)-len(DepSuffix)]) + tgts[name[:len(name)-len(DepSuffix)]] = struct{}{} } } redoDir.Close() } else { - subTgts, err := targetsWalker(pth) - tgts = append(tgts, subTgts...) - if err != nil { - return tgts, err + if err = targetsCollect(pth, tgts); err != nil { + return err } } } } - return tgts, dir.Close() + return dir.Close() +} + +func targetsWalker(tgts []string) ([]string, error) { + tgtsMap := map[string]struct{}{} + for _, tgt := range tgts { + if err := targetsCollect(tgt, tgtsMap); err != nil { + return nil, err + } + } + tgts = make([]string, 0, len(tgtsMap)) + for tgt := range tgtsMap { + tgts = append(tgts, tgt) + } + return tgts, nil +} + +func collectWholeDeps( + tgts map[string]struct{}, + deps map[string]map[string]struct{}, + seen map[string]struct{}, +) { + for tgt := range tgts { + seen[tgt] = struct{}{} + collectWholeDeps(deps[tgt], deps, seen) + } }