package main import ( "path" "path/filepath" ) var TgtCache = make(map[string]*Tgt) 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...)) } type Tgt struct { // a/h/t resemble zsh'es :a, :h, :t modifiers a string // absolute path h string // head of the path, directory t string // tail of the path, only name rel string // relative to Cwd dep string // path to dependency file } func NewTgt(tgt string) *Tgt { a := mustAbs(tgt) if TgtCache != nil { if t := TgtCache[a]; t != nil { return t } } t := Tgt{a: a} t.h, t.t = path.Split(t.a) if len(t.h) > 1 { t.h = t.h[:len(t.h)-1] } t.rel = mustRel(Cwd, t.a) if TgtCache != nil { TgtCache[a] = &t } return &t } func (tgt *Tgt) String() string { return tgt.rel } func (tgt *Tgt) Dep() string { if tgt.dep == "" { tgt.dep = path.Join(tgt.h, RedoDir, tgt.t+DepSuffix) } return tgt.dep } func (tgt *Tgt) RelTo(cwd string) string { return mustRel(cwd, tgt.a) }