-/*
-goredo -- djb's redo implementation on pure Go
-Copyright (C) 2020-2023 Sergey Matveev <stargrave@stargrave.org>
-
-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 <http://www.gnu.org/licenses/>.
-*/
+// goredo -- djb's redo implementation on pure Go
+// Copyright (C) 2020-2024 Sergey Matveev <stargrave@stargrave.org>
+//
+// 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 <http://www.gnu.org/licenses/>.
package main
"io"
"os"
"path"
- "path/filepath"
"strings"
)
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 err
+ return ErrLine(err)
}
defer dir.Close()
for {
- fis, err := dir.Readdir(1 << 10)
+ entries, err := dir.ReadDir(1 << 10)
if err != nil {
if err == io.EOF {
break
}
- return err
+ return ErrLine(err)
}
- for _, fi := range fis {
- if !fi.IsDir() {
+ for _, entry := range entries {
+ if !entry.IsDir() {
continue
}
- pth := path.Join(root, fi.Name())
- if fi.Name() == RedoDir {
+ pth := path.Join(root, entry.Name())
+ if entry.Name() == RedoDir {
redoDir, err := os.Open(pth)
if err != nil {
- return err
+ return ErrLine(err)
}
- redoFis, err := redoDir.Readdir(0)
+ redoEntries, err := redoDir.ReadDir(0)
redoDir.Close()
if err != nil {
- return err
+ return ErrLine(err)
}
- for _, redoFi := range redoFis {
- name := redoFi.Name()
+ for _, redoEntry := range redoEntries {
+ name := redoEntry.Name()
if strings.HasSuffix(name, DepSuffix) {
name = cwdMustRel(root, name)
tgts[name[:len(name)-len(DepSuffix)]] = struct{}{}
}
func targetsWalker(tgts []string) ([]string, error) {
- tgtsMap := map[string]struct{}{}
+ tgtsMap := make(map[string]struct{})
for _, tgt := range tgts {
- if err := targetsCollect(tgt, tgtsMap); err != nil {
+ if err := targetsCollect(mustAbs(tgt), tgtsMap); err != nil {
return nil, err
}
}
}
func collectWholeDeps(
- tgts map[string]struct{},
- deps map[string]map[string]struct{},
- seen map[string]struct{},
+ tgts map[string]*Tgt,
+ deps map[string]map[string]*Tgt,
+ seen map[string]*Tgt,
) {
- for tgt := range tgts {
- seen[tgt] = struct{}{}
- collectWholeDeps(deps[tgt], deps, seen)
+ for _, tgt := range tgts {
+ if _, exists := seen[tgt.rel]; exists {
+ continue
+ }
+ seen[tgt.rel] = tgt
+ collectWholeDeps(deps[tgt.rel], deps, seen)
}
}