1 // Copyright 2019 The Kubernetes Authors. 2 // SPDX-License-Identifier: Apache-2.0 3 4 package filesys 5 6 import ( 7 "os" 8 "path/filepath" 9 "strings" 10 ) 11 12 // ConfirmedDir is a clean, absolute, delinkified path 13 // that was confirmed to point to an existing directory. 14 type ConfirmedDir string 15 16 // NewTmpConfirmedDir returns a temporary dir, else error. 17 // The directory is cleaned, no symlinks, etc. so it's 18 // returned as a ConfirmedDir. 19 func NewTmpConfirmedDir() (ConfirmedDir, error) { 20 n, err := os.MkdirTemp("", "kustomize-") 21 if err != nil { 22 return "", err 23 } 24 25 // In MacOs `os.MkdirTemp` creates a directory 26 // with root in the `/var` folder, which is in turn 27 // a symlinked path to `/private/var`. 28 // Function `filepath.EvalSymlinks`is used to 29 // resolve the real absolute path. 30 deLinked, err := filepath.EvalSymlinks(n) 31 return ConfirmedDir(deLinked), err 32 } 33 34 // HasPrefix returns true if the directory argument 35 // is a prefix of self (d) from the point of view of 36 // a file system. 37 // 38 // I.e., it's true if the argument equals or contains 39 // self (d) in a file path sense. 40 // 41 // HasPrefix emulates the semantics of strings.HasPrefix 42 // such that the following are true: 43 // 44 // strings.HasPrefix("foobar", "foobar") 45 // strings.HasPrefix("foobar", "foo") 46 // strings.HasPrefix("foobar", "") 47 // 48 // d := fSys.ConfirmDir("/foo/bar") 49 // d.HasPrefix("/foo/bar") 50 // d.HasPrefix("/foo") 51 // d.HasPrefix("/") 52 // 53 // Not contacting a file system here to check for 54 // actual path existence. 55 // 56 // This is tested on linux, but will have trouble 57 // on other operating systems. 58 // TODO(monopole) Refactor when #golang/go/18358 closes. 59 // See also: 60 // https://github.com/golang/go/issues/18358 61 // https://github.com/golang/dep/issues/296 62 // https://github.com/golang/dep/blob/master/internal/fs/fs.go#L33 63 // https://codereview.appspot.com/5712045 64 func (d ConfirmedDir) HasPrefix(path ConfirmedDir) bool { 65 if path.String() == string(filepath.Separator) || path == d { 66 return true 67 } 68 return strings.HasPrefix( 69 string(d), 70 string(path)+string(filepath.Separator)) 71 } 72 73 func (d ConfirmedDir) Join(path string) string { 74 return filepath.Join(string(d), path) 75 } 76 77 func (d ConfirmedDir) String() string { 78 return string(d) 79 } 80