1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
//go:build testtools
// +build testtools
package main
import (
"fmt"
"os"
"path/filepath"
)
func canonicalize(path string) (string, error) {
left := path
right := ""
for {
canon, err := filepath.EvalSymlinks(left)
if err != nil && !os.IsNotExist(err) {
return "", err
}
if err == nil {
if right == "" {
return canon, nil
}
return filepath.Join(canon, right), nil
}
// One component of our path is missing. Let's walk up a level
// and canonicalize that and then append the remaining piece.
full := filepath.Join(left, right)
if right == "" {
full = left
}
newleft := filepath.Clean(fmt.Sprintf("%s%c..", left, os.PathSeparator))
newright, err := filepath.Rel(newleft, full)
if err != nil {
return "", err
}
left = newleft
right = newright
}
}
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "Usage: %s PATH\n", os.Args[0])
os.Exit(2)
}
path, err := filepath.Abs(os.Args[1])
if err != nil {
fmt.Fprintf(os.Stderr, "Error creating absolute path: %v", err)
os.Exit(3)
}
fullpath, err := canonicalize(path)
if err != nil {
fmt.Fprintf(os.Stderr, "Error canonicalizing: %v", err)
os.Exit(4)
}
fmt.Println(fullpath)
}
|