github.com/docker/libcompose@v0.4.1-0.20210616120443-2a046c0bdbf2/lookup/file.go (about) 1 package lookup 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path" 7 "path/filepath" 8 "strings" 9 10 "github.com/sirupsen/logrus" 11 ) 12 13 // relativePath returns the proper relative path for the given file path. If 14 // the relativeTo string equals "-", then it means that it's from the stdin, 15 // and the returned path will be the current working directory. Otherwise, if 16 // file is really an absolute path, then it will be returned without any 17 // changes. Otherwise, the returned path will be a combination of relativeTo 18 // and file. 19 func relativePath(file, relativeTo string) string { 20 // stdin: return the current working directory if possible. 21 if relativeTo == "-" { 22 if cwd, err := os.Getwd(); err == nil { 23 return filepath.Join(cwd, file) 24 } 25 } 26 27 // If the given file is already an absolute path, just return it. 28 // Otherwise, the returned path will be relative to the given relativeTo 29 // path. 30 if filepath.IsAbs(file) { 31 return file 32 } 33 34 abs, err := filepath.Abs(filepath.Join(path.Dir(relativeTo), file)) 35 if err != nil { 36 logrus.Errorf("Failed to get absolute directory: %s", err) 37 return file 38 } 39 return abs 40 } 41 42 // FileResourceLookup is a "bare" structure that implements the project.ResourceLookup interface 43 type FileResourceLookup struct { 44 } 45 46 // Lookup returns the content and the actual filename of the file that is "built" using the 47 // specified file and relativeTo string. file and relativeTo are supposed to be file path. 48 // If file starts with a slash ('/'), it tries to load it, otherwise it will build a 49 // filename using the folder part of relativeTo joined with file. 50 func (f *FileResourceLookup) Lookup(file, relativeTo string) ([]byte, string, error) { 51 file = relativePath(file, relativeTo) 52 logrus.Debugf("Reading file %s", file) 53 bytes, err := ioutil.ReadFile(file) 54 return bytes, file, err 55 } 56 57 // ResolvePath returns the path to be used for the given path volume. This 58 // function already takes care of relative paths. 59 func (f *FileResourceLookup) ResolvePath(path, relativeTo string) string { 60 vs := strings.SplitN(path, ":", 2) 61 if len(vs) != 2 || filepath.IsAbs(vs[0]) { 62 return path 63 } 64 vs[0] = relativePath(vs[0], relativeTo) 65 return strings.Join(vs, ":") 66 }