|
| 1 | +package filepath |
| 2 | + |
| 3 | +import ( |
| 4 | + "errors" |
| 5 | + "regexp" |
| 6 | + "strings" |
| 7 | +) |
| 8 | + |
| 9 | +var windowsAbs = regexp.MustCompile(`^[a-zA-Z]:\\.*$`) |
| 10 | + |
| 11 | +// Abs is a version of path/filepath's Abs with an explicit operating |
| 12 | +// system and current working directory. |
| 13 | +func Abs(os, path, cwd string) (_ string, err error) { |
| 14 | + if os == "windows" { |
| 15 | + return "", errors.New("Abs() does not support windows yet") |
| 16 | + } |
| 17 | + if IsAbs(os, path) { |
| 18 | + return Clean(os, path), nil |
| 19 | + } |
| 20 | + return Clean(os, Join(os, cwd, path)), nil |
| 21 | +} |
| 22 | + |
| 23 | +// IsAbs is a version of path/filepath's IsAbs with an explicit |
| 24 | +// operating system. |
| 25 | +func IsAbs(os, path string) bool { |
| 26 | + if os == "windows" { |
| 27 | + // FIXME: copy hideous logic from Go's |
| 28 | + // src/path/filepath/path_windows.go into somewhere where we can |
| 29 | + // put 3-clause BSD licensed code. |
| 30 | + return windowsAbs.MatchString(path) |
| 31 | + } |
| 32 | + sep := Separator(os) |
| 33 | + |
| 34 | + // POSIX has [1]: |
| 35 | + // |
| 36 | + // > If a pathname begins with two successive <slash> characters, |
| 37 | + // > the first component following the leading <slash> characters |
| 38 | + // > may be interpreted in an implementation-defined manner, |
| 39 | + // > although more than two leading <slash> characters shall be |
| 40 | + // > treated as a single <slash> character. |
| 41 | + // |
| 42 | + // And Boost treats // as non-absolute [2], but Linux [3,4], Python |
| 43 | + // [5] and Go [6] all treat // as absolute. |
| 44 | + // |
| 45 | + // [1]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13 |
| 46 | + // [2]: https://github.com/boostorg/filesystem/blob/boost-1.64.0/test/path_test.cpp#L861 |
| 47 | + // [3]: http://man7.org/linux/man-pages/man7/path_resolution.7.html |
| 48 | + // [4]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/path-lookup.md?h=v4.12#n41 |
| 49 | + // [5]: https://github.com/python/cpython/blob/v3.6.1/Lib/posixpath.py#L64-L66 |
| 50 | + // [6]: https://go.googlesource.com/go/+/go1.8.3/src/path/path.go#199 |
| 51 | + return strings.HasPrefix(path, string(sep)) |
| 52 | +} |
0 commit comments