X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=sources.go;h=6a925e24dc6c2b4318da1bf73e7f7afa25a87dd6;hb=a9455044065855ae42d95d939ed0027f7a895b83;hp=659df3a51d9ff76e352dcbc104b62e7d01a8be6b;hpb=9d1ca78917c32c17686d7ea2ef01c6ebcc0f63d8;p=goredo.git diff --git a/sources.go b/sources.go index 659df3a..6a925e2 100644 --- a/sources.go +++ b/sources.go @@ -1,64 +1,59 @@ -/* -goredo -- djb's redo implementation on pure Go -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 -the Free Software Foundation, version 3 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ +// goredo -- djb's redo implementation on pure Go +// Copyright (C) 2020-2024 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 +// the Free Software Foundation, version 3 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . package main import ( - "log" - "os" - "path" + "errors" + "io/fs" ) -func sourcesWalker(tgts []string) ([]string, error) { - seen := make(map[string]struct{}, 1<<10) +func sourcesWalker( + tgts []*Tgt, + seen map[string]struct{}, + seenDeps map[string]struct{}, + srcs map[string]*Tgt, +) 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)) + if _, ok := seenDeps[tgt.rel]; ok { + continue + } + seenDeps[tgt.rel] = struct{}{} + dep, err := depRead(tgt) if err != nil { - if os.IsNotExist(err) { + if errors.Is(err, fs.ErrNotExist) { continue } - return nil, 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 isSrc(cwd, depTgt) { - seen[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{}{} + for _, ifchange := range dep.ifchanges { + if _, ok := seen[ifchange.tgt.rel]; ok { + continue + } + seen[ifchange.tgt.rel] = struct{}{} + if isSrc(ifchange.tgt) { + srcs[ifchange.tgt.rel] = ifchange.tgt + } else if ifchange.tgt.rel != tgt.rel { + if err := sourcesWalker( + []*Tgt{ifchange.tgt}, + 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 }