-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
fileloader.go
111 lines (96 loc) · 3.4 KB
/
fileloader.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package loader
import (
"fmt"
"os"
"path/filepath"
"github.com/kubernetes-sigs/kustomize/pkg/fs"
)
const currentDir = "."
// fileLoader loads files from a file system.
type fileLoader struct {
root string
fSys fs.FileSystem
}
// 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)
if err != nil {
return false
}
return filepath.IsAbs(fullFilePath)
}
// 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) {
// First, validate the parameters
if len(root) == 0 && len(location) == 0 {
return "", fmt.Errorf("unable to calculate full location: root and location empty")
}
// Special case current directory, expanding to full file path.
if location == currentDir {
currentDir, err := os.Getwd()
if err != nil {
return "", err
}
location = currentDir
}
// Assume the location is a full file path. If not, then join root with location.
fullLocation := location
if !filepath.IsAbs(location) {
fullLocation = filepath.Join(root, location)
}
return fullLocation, nil
}
// Load returns the bytes from reading a file at fullFilePath.
// Implements the Loader interface.
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)
}