file.go 2.1 KB

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