Files
linuxkit/vendor/github.com/docker/infrakit/pkg/spi/metadata/path.go
Rolf Neugebauer 48845bcfd9 infrakit: Move the hyperkit instance plugin into the source directory
- The tools directory ideally should not contain source code
- Removes double vendoring of packagages
- Makes it easer to hook the build into the top-level Makefile

Eventually, the plugin should be moved to the infrakit repo.

Signed-off-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
2017-03-25 13:02:45 +01:00

103 lines
2.2 KiB
Go

package metadata
var (
// NullPath means no path
NullPath = Path([]string{})
)
// Path is used to identify a particle of metadata. The path can be strings separated by / as in a URL.
type Path []string
// Clean scrubs the path to remove any empty string or . or .. and collapse the path into a concise form.
// It's similar to path/filepath.Clean in the standard lib.
func (p Path) Clean() Path {
this := []string(p)
copy := []string{}
for _, v := range this {
switch v {
case "", ".":
case "..":
if len(copy) == 0 {
copy = append(copy, "..")
} else {
copy = copy[0 : len(copy)-1]
if len(copy) == 0 {
return NullPath
}
}
default:
copy = append(copy, v)
}
}
return Path(copy)
}
// Len returns the length of the path
func (p Path) Len() int {
return len([]string(p))
}
// Index returns the ith component in the path
func (p Path) Index(i int) *string {
if p.Len() <= i {
return nil
}
copy := []string(p)[i]
return &copy
}
// Shift returns a new path that's shifted i positions to the left -- ith child of the head at index=0
func (p Path) Shift(i int) Path {
len := p.Len() - i
if len <= 0 {
return Path([]string{})
}
new := make([]string, len)
copy(new, []string(p)[i:])
return Path(new)
}
// Dir returns the 'dir' of the path
func (p Path) Dir() Path {
pp := p.Clean()
if len(pp) > 1 {
return p[0 : len(pp)-1]
}
return Path([]string{"."})
}
// Base returns the base of the path
func (p Path) Base() string {
pp := p.Clean()
return pp[len(pp)-1]
}
// Join joins the input as a child of this path
func (p Path) Join(child string) Path {
return p.Sub(Path([]string{child}))
}
// Sub joins the child to the parent
func (p Path) Sub(child Path) Path {
pp := p.Clean()
return Path(append(pp, []string(child)...))
}
// Rel returns a new path that is a child of the input from this path.
// e.g. For a path a/b/c/d Rel(a/b/) returns c/d. NullPath is returned if
// the two are not relative to one another.
func (p Path) Rel(path Path) Path {
this := []string(p.Clean())
parent := []string(path.Clean())
if len(this) < len(parent) {
return NullPath
}
for i := 0; i < len(parent); i++ {
if parent[i] != this[i] {
return NullPath
}
}
return Path(this[len(parent):])
}