file.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package gannex
  2. import (
  3. "os"
  4. "path/filepath"
  5. "strings"
  6. "io"
  7. "fmt"
  8. "regexp"
  9. )
  10. var (
  11. secPar = regexp.MustCompile(`(\.\.)`)
  12. aFPattern = regexp.MustCompile(`[\\\/]annex[\\\/](.+)`)
  13. )
  14. type AFile struct {
  15. Filepath string
  16. OFilename string
  17. Info os.FileInfo
  18. }
  19. type AnnexFileNotFound struct {
  20. error
  21. }
  22. func NewAFile(annexpath, repopath, Ofilename string, APFileC []byte) (*AFile, error) {
  23. nAF := &AFile{OFilename: Ofilename}
  24. matches := aFPattern.FindStringSubmatch(string(APFileC))
  25. if matches != nil && len(matches) > 1 {
  26. filepath := strings.Replace(matches[1], "\\", "/", 0)
  27. filepath = fmt.Sprintf("%s/annex/%s", repopath, filepath)
  28. if !secPar.MatchString(filepath) {
  29. info, err := os.Stat(filepath)
  30. if err == nil {
  31. nAF.Filepath = filepath
  32. nAF.Info = info
  33. return nAF, nil
  34. }
  35. }
  36. }
  37. pathParts := strings.SplitAfter(string(APFileC), string(os.PathSeparator))
  38. filename := strings.TrimSpace(pathParts[len(pathParts)-1])
  39. // lets find the annex file
  40. filepath.Walk(filepath.Join(annexpath, repopath), func(path string, info os.FileInfo, err error) error {
  41. if err != nil {
  42. return filepath.SkipDir
  43. }
  44. if info.IsDir() {
  45. return nil
  46. } else if info.Name() == filename {
  47. nAF.Filepath = path
  48. nAF.Info = info
  49. return io.EOF
  50. }
  51. return nil
  52. })
  53. if nAF.Filepath != "" {
  54. return nAF, nil
  55. } else {
  56. return nil, AnnexFileNotFound{error: fmt.Errorf("Could not find File: %s anywhere below: %s", filename,
  57. filepath.Join(annexpath, repopath))}
  58. }
  59. }
  60. func (af *AFile) Open() (*os.File, error) {
  61. fp, err := os.Open(af.Filepath)
  62. if err != nil {
  63. return nil, err
  64. }
  65. return fp, nil
  66. }