53 lines
2.0 KiB
Go
53 lines
2.0 KiB
Go
|
package workdir
|
||
|
|
||
|
import (
|
||
|
"path/filepath"
|
||
|
)
|
||
|
|
||
|
// NormalizePath attempts to transform the given path so that it's relative
|
||
|
// to the working directory, which is our preferred way to present and store
|
||
|
// paths to files and directories within a configuration so that they can
|
||
|
// be portable to operations in other working directories.
|
||
|
//
|
||
|
// It isn't always possible to produce a relative path. For example, on Windows
|
||
|
// the given path might be on a different volume (e.g. drive letter or network
|
||
|
// share) than the working directory.
|
||
|
//
|
||
|
// Note that the result will be relative to the main directory of the receiver,
|
||
|
// which should always be the actual process working directory in normal code,
|
||
|
// but might be some other temporary working directory when in test code.
|
||
|
// If you need to access the file or directory that the result refers to with
|
||
|
// functions that aren't aware of our base directory, you can use something
|
||
|
// like the following, which again should be needed only in test code which
|
||
|
// might need to inspect the filesystem in order to make assertions:
|
||
|
//
|
||
|
// filepath.Join(d.RootModuleDir(), normalizePathResult)
|
||
|
//
|
||
|
// The above is suitable only for situations where the given path is known
|
||
|
// to be beneath the working directory, which is the typical situation for
|
||
|
// temporary working directories created for automated tests.
|
||
|
func (d *Dir) NormalizePath(given string) string {
|
||
|
// We need an absolute version of d.mainDir in order for our "Rel"
|
||
|
// result to be reliable.
|
||
|
absMain, err := filepath.Abs(d.mainDir)
|
||
|
if err != nil {
|
||
|
// Weird, but okay...
|
||
|
return filepath.Clean(given)
|
||
|
}
|
||
|
|
||
|
if !filepath.IsAbs(given) {
|
||
|
given = filepath.Join(absMain, given)
|
||
|
}
|
||
|
|
||
|
ret, err := filepath.Rel(absMain, given)
|
||
|
if err != nil {
|
||
|
// It's not always possible to find a relative path. For example,
|
||
|
// the given path might be on an entirely separate volume
|
||
|
// (e.g. drive letter or network share) on a Windows system, which
|
||
|
// always requires an absolute path.
|
||
|
return filepath.Clean(given)
|
||
|
}
|
||
|
|
||
|
return ret
|
||
|
}
|