confirmeddir.go 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. Copyright 2018 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package fs
  14. import (
  15. "io/ioutil"
  16. "path/filepath"
  17. "strings"
  18. )
  19. // ConfirmedDir is a clean, absolute, delinkified path
  20. // that was confirmed to point to an existing directory.
  21. type ConfirmedDir string
  22. // NewTmpConfirmedDir returns a temporary dir, else error.
  23. // The directory is cleaned, no symlinks, etc. so its
  24. // returned as a ConfirmedDir.
  25. func NewTmpConfirmedDir() (ConfirmedDir, error) {
  26. n, err := ioutil.TempDir("", "kustomize-")
  27. if err != nil {
  28. return "", err
  29. }
  30. // In MacOs `ioutil.TempDir` creates a directory
  31. // with root in the `/var` folder, which is in turn a symlinked path
  32. // to `/private/var`.
  33. // Function `filepath.EvalSymlinks`is used to
  34. // resolve the real absolute path.
  35. deLinked, err := filepath.EvalSymlinks(n)
  36. return ConfirmedDir(deLinked), err
  37. }
  38. // HasPrefix returns true if the directory argument
  39. // is a prefix of self (d) from the point of view of
  40. // a file system.
  41. //
  42. // I.e., it's true if the argument equals or contains
  43. // self (d) in a file path sense.
  44. //
  45. // HasPrefix emulates the semantics of strings.HasPrefix
  46. // such that the following are true:
  47. //
  48. // strings.HasPrefix("foobar", "foobar")
  49. // strings.HasPrefix("foobar", "foo")
  50. // strings.HasPrefix("foobar", "")
  51. //
  52. // d := fSys.ConfirmDir("/foo/bar")
  53. // d.HasPrefix("/foo/bar")
  54. // d.HasPrefix("/foo")
  55. // d.HasPrefix("/")
  56. //
  57. // Not contacting a file system here to check for
  58. // actual path existence.
  59. //
  60. // This is tested on linux, but will have trouble
  61. // on other operating systems.
  62. // TODO(monopole) Refactor when #golang/go/18358 closes.
  63. // See also:
  64. // https://github.com/golang/go/issues/18358
  65. // https://github.com/golang/dep/issues/296
  66. // https://github.com/golang/dep/blob/master/internal/fs/fs.go#L33
  67. // https://codereview.appspot.com/5712045
  68. func (d ConfirmedDir) HasPrefix(path ConfirmedDir) bool {
  69. if path.String() == string(filepath.Separator) || path == d {
  70. return true
  71. }
  72. return strings.HasPrefix(
  73. string(d),
  74. string(path)+string(filepath.Separator))
  75. }
  76. func (d ConfirmedDir) Join(path string) string {
  77. return filepath.Join(string(d), path)
  78. }
  79. func (d ConfirmedDir) String() string {
  80. return string(d)
  81. }