fakefs.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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. "fmt"
  16. "path/filepath"
  17. "sort"
  18. "strings"
  19. "sigs.k8s.io/kustomize/pkg/constants"
  20. )
  21. var _ FileSystem = &fakeFs{}
  22. // fakeFs implements FileSystem using a fake in-memory filesystem.
  23. type fakeFs struct {
  24. m map[string]*FakeFile
  25. }
  26. // MakeFakeFS returns an instance of fakeFs with no files in it.
  27. func MakeFakeFS() *fakeFs {
  28. result := &fakeFs{m: map[string]*FakeFile{}}
  29. result.Mkdir("/")
  30. return result
  31. }
  32. // kustomizationContent is used in tests.
  33. const kustomizationContent = `apiVersion: kustomize.config.k8s.io/v1beta1
  34. kind: Kustomization
  35. namePrefix: some-prefix
  36. nameSuffix: some-suffix
  37. # Labels to add to all objects and selectors.
  38. # These labels would also be used to form the selector for apply --prune
  39. # Named differently than “labels” to avoid confusion with metadata for this object
  40. commonLabels:
  41. app: helloworld
  42. commonAnnotations:
  43. note: This is an example annotation
  44. resources: []
  45. #- service.yaml
  46. #- ../some-dir/
  47. # There could also be configmaps in Base, which would make these overlays
  48. configMapGenerator: []
  49. # There could be secrets in Base, if just using a fork/rebase workflow
  50. secretGenerator: []
  51. `
  52. // Create assures a fake file appears in the in-memory file system.
  53. func (fs *fakeFs) Create(name string) (File, error) {
  54. f := &FakeFile{}
  55. f.open = true
  56. fs.m[name] = f
  57. return fs.m[name], nil
  58. }
  59. // Mkdir assures a fake directory appears in the in-memory file system.
  60. func (fs *fakeFs) Mkdir(name string) error {
  61. fs.m[name] = makeDir(name)
  62. return nil
  63. }
  64. // MkdirAll delegates to Mkdir
  65. func (fs *fakeFs) MkdirAll(name string) error {
  66. return fs.Mkdir(name)
  67. }
  68. // RemoveAll presumably does rm -r on a path.
  69. // There's no error.
  70. func (fs *fakeFs) RemoveAll(name string) error {
  71. var toRemove []string
  72. for k := range fs.m {
  73. if strings.HasPrefix(k, name) {
  74. toRemove = append(toRemove, k)
  75. }
  76. }
  77. for _, k := range toRemove {
  78. delete(fs.m, k)
  79. }
  80. return nil
  81. }
  82. // Open returns a fake file in the open state.
  83. func (fs *fakeFs) Open(name string) (File, error) {
  84. if _, found := fs.m[name]; !found {
  85. return nil, fmt.Errorf("file %q cannot be opened", name)
  86. }
  87. return fs.m[name], nil
  88. }
  89. // CleanedAbs cannot fail.
  90. func (fs *fakeFs) CleanedAbs(path string) (ConfirmedDir, string, error) {
  91. if fs.IsDir(path) {
  92. return ConfirmedDir(path), "", nil
  93. }
  94. d := filepath.Dir(path)
  95. if d == path {
  96. return ConfirmedDir(d), "", nil
  97. }
  98. return ConfirmedDir(d), filepath.Base(path), nil
  99. }
  100. // Exists returns true if file is known.
  101. func (fs *fakeFs) Exists(name string) bool {
  102. _, found := fs.m[name]
  103. return found
  104. }
  105. // Glob returns the list of matching files
  106. func (fs *fakeFs) Glob(pattern string) ([]string, error) {
  107. var result []string
  108. for p := range fs.m {
  109. if fs.pathMatch(p, pattern) {
  110. result = append(result, p)
  111. }
  112. }
  113. sort.Strings(result)
  114. return result, nil
  115. }
  116. // IsDir returns true if the file exists and is a directory.
  117. func (fs *fakeFs) IsDir(name string) bool {
  118. f, found := fs.m[name]
  119. if found && f.dir {
  120. return true
  121. }
  122. if !strings.HasSuffix(name, "/") {
  123. name = name + "/"
  124. }
  125. for k := range fs.m {
  126. if strings.HasPrefix(k, name) {
  127. return true
  128. }
  129. }
  130. return false
  131. }
  132. // ReadFile always returns an empty bytes and error depending on content of m.
  133. func (fs *fakeFs) ReadFile(name string) ([]byte, error) {
  134. if ff, found := fs.m[name]; found {
  135. return ff.content, nil
  136. }
  137. return nil, fmt.Errorf("cannot read file %q", name)
  138. }
  139. func (fs *fakeFs) ReadTestKustomization() ([]byte, error) {
  140. return fs.ReadFile(constants.KustomizationFileNames[0])
  141. }
  142. // WriteFile always succeeds and does nothing.
  143. func (fs *fakeFs) WriteFile(name string, c []byte) error {
  144. ff := &FakeFile{}
  145. ff.Write(c)
  146. fs.m[name] = ff
  147. return nil
  148. }
  149. // WriteTestKustomization writes a standard test file.
  150. func (fs *fakeFs) WriteTestKustomization() {
  151. fs.WriteTestKustomizationWith([]byte(kustomizationContent))
  152. }
  153. // WriteTestKustomizationWith writes a standard test file.
  154. func (fs *fakeFs) WriteTestKustomizationWith(bytes []byte) {
  155. fs.WriteFile(constants.KustomizationFileNames[0], bytes)
  156. }
  157. func (fs *fakeFs) pathMatch(path, pattern string) bool {
  158. match, _ := filepath.Match(pattern, path)
  159. return match
  160. }