// 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 ( "path" "path/filepath" "sync" ) var ( TgtCache = make(map[string]*Tgt) TgtCacheM sync.RWMutex ) func mustAbs(pth string) string { pth, err := filepath.Abs(pth) if err != nil { panic(err) } return pth } func mustRel(basepath, targpath string) string { pth, err := filepath.Rel(basepath, targpath) if err != nil { panic(err) } return pth } func cwdMustRel(paths ...string) string { return mustRel(Cwd, path.Join(paths...)) } func pathSplit(a string) (h, t string) { h, t = path.Split(a) if len(h) > 1 { h = h[:len(h)-1] } return } type Tgt struct { a string // absolute path rel string // relative to Cwd dep string // path to dependency file } func NewTgt(tgt string) *Tgt { a := mustAbs(tgt) TgtCacheM.RLock() cached := TgtCache[a] TgtCacheM.RUnlock() if cached != nil { return cached } h, t := pathSplit(a) res := Tgt{ a: a, rel: mustRel(Cwd, a), dep: path.Join(h, RedoDir, t+DepSuffix), } TgtCacheM.Lock() TgtCache[a] = &res TgtCacheM.Unlock() return &res } func (tgt *Tgt) String() string { return tgt.rel } func (tgt *Tgt) RelTo(cwd string) string { return mustRel(cwd, tgt.a) }