diff --git a/pkg/commands/build.go b/pkg/commands/build.go index 5aae233d0..a270053c4 100644 --- a/pkg/commands/build.go +++ b/pkg/commands/build.go @@ -70,7 +70,7 @@ func (o *buildOptions) Validate(args []string) error { // RunBuild runs build command. func (o *buildOptions) RunBuild(out io.Writer, fSys fs.FileSystem) error { - l := loader.NewLoader(loader.NewFileLoader(fSys)) + l := loader.NewFileLoader(fSys) absPath, err := filepath.Abs(o.kustomizationPath) if err != nil { diff --git a/pkg/commands/configmap.go b/pkg/commands/configmap.go index 588764c69..c7b4de365 100644 --- a/pkg/commands/configmap.go +++ b/pkg/commands/configmap.go @@ -65,7 +65,7 @@ func newCmdAddConfigMap(fSys fs.FileSystem) *cobra.Command { err = addConfigMap( kustomization, flagsAndArgs, configmapandsecret.NewConfigMapFactory( - fSys, loader.NewLoader(loader.NewFileLoader(fSys)))) + fSys, loader.NewFileLoader(fSys))) if err != nil { return err } diff --git a/pkg/commands/diff.go b/pkg/commands/diff.go index 533ced4ec..b7f372ae8 100644 --- a/pkg/commands/diff.go +++ b/pkg/commands/diff.go @@ -68,7 +68,7 @@ func (o *diffOptions) Validate(args []string) error { // RunDiff gets the differences between Application.MakeCustomizedResMap() and Application.MakeUncustomizedResMap(). func (o *diffOptions) RunDiff(out, errOut io.Writer, fSys fs.FileSystem) error { - l := loader.NewLoader(loader.NewFileLoader(fSys)) + l := loader.NewFileLoader(fSys) absPath, err := filepath.Abs(o.kustomizationPath) if err != nil { diff --git a/pkg/configmapandsecret/configmapfactory_test.go b/pkg/configmapandsecret/configmapfactory_test.go index 3ef82ec88..54d3f8af8 100644 --- a/pkg/configmapandsecret/configmapfactory_test.go +++ b/pkg/configmapandsecret/configmapfactory_test.go @@ -136,8 +136,7 @@ func TestConstructConfigMap(t *testing.T) { // TODO: all tests should use a FakeFs fSys := fs.MakeRealFS() - f := NewConfigMapFactory(fSys, - loader.NewLoader(loader.NewFileLoader(fSys))) + f := NewConfigMapFactory(fSys, loader.NewFileLoader(fSys)) for _, tc := range testCases { cm, err := f.MakeConfigMap(&tc.input) if err != nil { diff --git a/pkg/internal/loadertest/fakeloader.go b/pkg/internal/loadertest/fakeloader.go index 93bc79f6b..4cdce780a 100644 --- a/pkg/internal/loadertest/fakeloader.go +++ b/pkg/internal/loadertest/fakeloader.go @@ -34,7 +34,7 @@ type FakeLoader struct { func NewFakeLoader(initialDir string) FakeLoader { // Create fake filesystem and inject it into initial Loader. fakefs := fs.MakeFakeFS() - rootLoader := loader.NewLoader(loader.NewFileLoader(fakefs)) + rootLoader := loader.NewFileLoader(fakefs) ldr, _ := rootLoader.New(initialDir) return FakeLoader{fs: fakefs, delegate: ldr} } diff --git a/pkg/loader/fileloader.go b/pkg/loader/fileloader.go index 3b675733b..6b047dadd 100644 --- a/pkg/loader/fileloader.go +++ b/pkg/loader/fileloader.go @@ -26,32 +26,59 @@ import ( const currentDir = "." -// FileLoader loads files from a file system. -type FileLoader struct { - fs fs.FileSystem +// fileLoader loads files from a file system. +type fileLoader struct { + root string + fSys fs.FileSystem } -// NewFileLoader returns a new FileLoader. -func NewFileLoader(fs fs.FileSystem) *FileLoader { - return &FileLoader{fs: fs} +// NewFileLoader returns a new fileLoader. +func NewFileLoader(fSys fs.FileSystem) *fileLoader { + return newFileLoaderAtRoot("", fSys) +} + +// newFileLoaderAtRoot returns a new fileLoader with given root. +func newFileLoaderAtRoot(root string, fs fs.FileSystem) *fileLoader { + return &fileLoader{root: root, fSys: fs} +} + +// Root returns the root location for this Loader. +func (l *fileLoader) Root() string { + return l.root +} + +// Returns a new Loader rooted at newRoot. "newRoot" MUST be +// a directory (not a file). The directory can have a trailing +// slash or not. +// Example: "/home/seans/project" or "/home/seans/project/" +// NOT "/home/seans/project/file.yaml". +func (l *fileLoader) New(newRoot string) (Loader, error) { + if !l.IsAbsPath(l.root, newRoot) { + return nil, fmt.Errorf("Not abs path: l.root='%s', loc='%s'\n", l.root, newRoot) + } + root, err := l.fullLocation(l.root, newRoot) + if err != nil { + return nil, err + } + return newFileLoaderAtRoot(root, l.fSys), nil } // IsAbsPath return true if the location calculated with the root // and location params a full file path. -func (l *FileLoader) IsAbsPath(root string, location string) bool { - fullFilePath, err := l.FullLocation(root, location) +func (l *fileLoader) IsAbsPath(root string, location string) bool { + fullFilePath, err := l.fullLocation(root, location) if err != nil { return false } return filepath.IsAbs(fullFilePath) } -// FullLocation returns some notion of a full path. +// fullLocation returns some notion of a full path. // If location is a full file path, then ignore root. If location is relative, then // join the root path with the location path. Either root or location can be empty, // but not both. Special case for ".": Expands to current working directory. // Example: "/home/seans/project", "subdir/bar" -> "/home/seans/project/subdir/bar". -func (l *FileLoader) FullLocation(root string, location string) (string, error) { +func (l *fileLoader) fullLocation(root string, location string) (string, error) { // First, validate the parameters if len(root) == 0 && len(location) == 0 { return "", fmt.Errorf("unable to calculate full location: root and location empty") @@ -74,12 +101,21 @@ func (l *FileLoader) FullLocation(root string, location string) (string, error) // Load returns the bytes from reading a file at fullFilePath. // Implements the Loader interface. -func (l *FileLoader) Load(p string) ([]byte, error) { - return l.fs.ReadFile(p) +func (l *fileLoader) Load(location string) ([]byte, error) { + fullLocation, err := l.fullLocation(l.root, location) + if err != nil { + fmt.Printf("Trouble in fulllocation: %v\n", err) + return nil, err + } + return l.fSys.ReadFile(fullLocation) } // GlobLoad returns the map from path to bytes from reading a glob path. // Implements the Loader interface. -func (l *FileLoader) GlobLoad(p string) (map[string][]byte, error) { - return l.fs.ReadFiles(p) +func (l *fileLoader) GlobLoad(location string) (map[string][]byte, error) { + fullLocation, err := l.fullLocation(l.root, location) + if err != nil { + return nil, err + } + return l.fSys.ReadFiles(fullLocation) } diff --git a/pkg/loader/loader_test.go b/pkg/loader/fileloader_test.go similarity index 95% rename from pkg/loader/loader_test.go rename to pkg/loader/fileloader_test.go index 7cd499cea..7d8ffe41d 100644 --- a/pkg/loader/loader_test.go +++ b/pkg/loader/fileloader_test.go @@ -24,10 +24,6 @@ import ( "github.com/kubernetes-sigs/kustomize/pkg/fs" ) -func initializeRootLoader(fakefs fs.FileSystem) Loader { - return NewLoader(NewFileLoader(fakefs)) -} - func TestLoader_Root(t *testing.T) { // Initialize the fake file system and the root loader. @@ -35,7 +31,7 @@ func TestLoader_Root(t *testing.T) { fakefs.WriteFile("/home/seans/project/file.yaml", []byte("Unused")) fakefs.WriteFile("/home/seans/project/subdir/file.yaml", []byte("Unused")) fakefs.WriteFile("/home/seans/project2/file.yaml", []byte("Unused")) - rootLoader := initializeRootLoader(fakefs) + rootLoader := NewFileLoader(fakefs) _, err := rootLoader.New("") if err == nil { @@ -89,7 +85,7 @@ func TestLoader_Load(t *testing.T) { fakefs.WriteFile("/home/seans/project/file.yaml", []byte("This is a yaml file")) fakefs.WriteFile("/home/seans/project/subdir/file.yaml", []byte("Subdirectory file content")) fakefs.WriteFile("/home/seans/project2/file.yaml", []byte("This is another yaml file")) - rootLoader := initializeRootLoader(fakefs) + rootLoader := NewFileLoader(fakefs) loader, err := rootLoader.New("/home/seans/project") if err != nil { diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index 54c3bf74b..545f6988b 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -17,8 +17,6 @@ limitations under the License. // Package loader has a data loading interface and various implementations. package loader -import "fmt" - // Loader interface exposes methods to read bytes. type Loader interface { // Root returns the root location for this Loader. @@ -30,60 +28,3 @@ type Loader interface { // GlobLoad returns the bytes read from a glob path or an error. GlobLoad(location string) (map[string][]byte, error) } - -// Private implementation of Loader interface. -type loaderImpl struct { - root string - fLoader *FileLoader -} - -const emptyRoot = "" - -// NewLoader initializes the first loader with the supported fLoader. -func NewLoader(fl *FileLoader) Loader { - return &loaderImpl{root: emptyRoot, fLoader: fl} -} - -// Root returns the root location for this Loader. -func (l *loaderImpl) Root() string { - return l.root -} - -// Returns a new Loader rooted at newRoot. "newRoot" MUST be -// a directory (not a file). The directory can have a trailing -// slash or not. -// Example: "/home/seans/project" or "/home/seans/project/" -// NOT "/home/seans/project/file.yaml". -func (l *loaderImpl) New(newRoot string) (Loader, error) { - if !l.fLoader.IsAbsPath(l.root, newRoot) { - return nil, fmt.Errorf("Not abs path: l.root='%s', loc='%s'\n", l.root, newRoot) - } - root, err := l.fLoader.FullLocation(l.root, newRoot) - if err != nil { - return nil, err - } - return &loaderImpl{root: root, fLoader: l.fLoader}, nil -} - -// Load returns all the bytes read from location or an error. -// "location" can be an absolute path, or if relative, full location is -// calculated from the Root(). -func (l *loaderImpl) Load(location string) ([]byte, error) { - fullLocation, err := l.fLoader.FullLocation(l.root, location) - if err != nil { - fmt.Printf("Trouble in fulllocation: %v\n", err) - return nil, err - } - return l.fLoader.Load(fullLocation) -} - -// GlobLoad returns a map from path to bytes read from the location or an error. -// "location" can be an absolute path, or if relative, full location is -// calculated from the Root(). -func (l *loaderImpl) GlobLoad(location string) (map[string][]byte, error) { - fullLocation, err := l.fLoader.FullLocation(l.root, location) - if err != nil { - return nil, err - } - return l.fLoader.GlobLoad(fullLocation) -}