/*
-goredo -- redo implementation on pure Go
-Copyright (C) 2020 Sergey Matveev <stargrave@stargrave.org>
+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
package main
import (
- "os"
+ "io"
"path"
- "path/filepath"
"strings"
)
var TopDir string
-func existsDo(fdDep *os.File, cwd, pth string) (bool, error) {
- if _, err := os.Stat(path.Join(cwd, pth)); err == nil {
+func existsDo(w io.Writer, fdDepName, cwd, pth string) (bool, error) {
+ if FileExists(path.Join(cwd, pth)) {
return true, nil
}
- return false, ifcreate(fdDep, pth)
+ return false, ifcreate(w, fdDepName, pth)
}
-func findDo(fdDep *os.File, cwd, tgt string) (string, int, error) {
+func findDo(w io.Writer, fdDepName, cwd, tgt string) (string, int, error) {
doFile := tgt + ".do"
- exists, err := existsDo(fdDep, cwd, doFile)
+ exists, err := existsDo(w, fdDepName, cwd, doFile)
if err != nil {
return "", 0, err
}
if exists {
return doFile, 0, nil
}
+ doFileOrig := doFile
levels := []string{}
extsOrig := strings.Split(tgt, ".")[1:]
dirAbsPrev := ""
doFile = strings.Join(append(
[]string{"default"}, append(exts, "do")...,
), ".")
- pth := path.Join(updir, doFile)
- exists, err = existsDo(fdDep, cwd, pth)
+ if len(levels) > 0 || (doFile != doFileOrig && doFile != tgt) {
+ exists, err = existsDo(w, fdDepName, cwd, path.Join(updir, doFile))
+ if err != nil {
+ return "", 0, err
+ }
+ if exists {
+ return doFile, len(levels), nil
+ }
+ }
+ exts = exts[1:]
+ }
+ doFile = "default.do"
+ if len(levels) > 0 || (doFile != doFileOrig && doFile != tgt) {
+ exists, err = existsDo(w, fdDepName, cwd, path.Join(updir, doFile))
if err != nil {
return "", 0, err
}
if exists {
return doFile, len(levels), nil
}
- exts = exts[1:]
- }
- doFile = "default.do"
- pth := path.Join(updir, doFile)
- exists, err = existsDo(fdDep, cwd, pth)
- if err != nil {
- return "", 0, err
- }
- if exists {
- return pth, len(levels), nil
}
levels = append(levels, "..")
- dirAbs, err := filepath.Abs(updir)
+ dirAbs := mustAbs(path.Join(cwd, updir))
if err != nil {
panic(err)
}
if dirAbs == TopDir {
break
}
- if _, err = os.Stat(path.Join(dirAbs, RedoDir, TopFile)); err == nil {
+ if FileExists(path.Join(dirAbs, RedoDir, TopFile)) {
break
}
if dirAbs == dirAbsPrev {