github.com/rakutentech/cli@v6.12.5-0.20151006231303-24468b65536e+incompatible/cf/app_files/app_files.go (about) 1 package app_files 2 3 import ( 4 "crypto/sha1" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 10 "github.com/cloudfoundry/cli/cf/models" 11 "github.com/cloudfoundry/gofileutils/fileutils" 12 ) 13 14 type AppFiles interface { 15 AppFilesInDir(dir string) (appFiles []models.AppFileFields, err error) 16 CopyFiles(appFiles []models.AppFileFields, fromDir, toDir string) (err error) 17 CountFiles(directory string) int64 18 WalkAppFiles(dir string, onEachFile func(string, string) error) (err error) 19 } 20 21 type ApplicationFiles struct{} 22 23 func (appfiles ApplicationFiles) AppFilesInDir(dir string) (appFiles []models.AppFileFields, err error) { 24 dir, err = filepath.Abs(dir) 25 if err != nil { 26 return 27 } 28 29 err = appfiles.WalkAppFiles(dir, func(fileName string, fullPath string) (err error) { 30 fileInfo, err := os.Lstat(fullPath) 31 if err != nil { 32 return 33 } 34 35 appFile := models.AppFileFields{ 36 Path: filepath.ToSlash(fileName), 37 Size: fileInfo.Size(), 38 } 39 40 if fileInfo.IsDir() { 41 appFile.Sha1 = "0" 42 appFile.Size = 0 43 } else { 44 hash := sha1.New() 45 err = fileutils.CopyPathToWriter(fullPath, hash) 46 if err != nil { 47 return 48 } 49 appFile.Sha1 = fmt.Sprintf("%x", hash.Sum(nil)) 50 } 51 52 appFiles = append(appFiles, appFile) 53 return 54 }) 55 return 56 } 57 58 func (appfiles ApplicationFiles) CopyFiles(appFiles []models.AppFileFields, fromDir, toDir string) (err error) { 59 if err != nil { 60 return 61 } 62 63 for _, file := range appFiles { 64 fromPath := filepath.Join(fromDir, file.Path) 65 toPath := filepath.Join(toDir, file.Path) 66 err = copyPathToPath(fromPath, toPath) 67 if err != nil { 68 return 69 } 70 } 71 return 72 } 73 74 func (appfiles ApplicationFiles) CountFiles(directory string) int64 { 75 var count int64 76 appfiles.WalkAppFiles(directory, func(_, _ string) error { 77 count++ 78 return nil 79 }) 80 return count 81 } 82 83 func (appfiles ApplicationFiles) WalkAppFiles(dir string, onEachFile func(string, string) error) (err error) { 84 cfIgnore := loadIgnoreFile(dir) 85 walkFunc := func(fullPath string, f os.FileInfo, inErr error) (err error) { 86 err = inErr 87 if err != nil { 88 return 89 } 90 91 if fullPath == dir { 92 return 93 } 94 95 if !f.Mode().IsRegular() && !f.IsDir() { 96 return 97 } 98 99 fileRelativePath, _ := filepath.Rel(dir, fullPath) 100 fileRelativeUnixPath := filepath.ToSlash(fileRelativePath) 101 102 if !cfIgnore.FileShouldBeIgnored(fileRelativeUnixPath) { 103 err = onEachFile(fileRelativePath, fullPath) 104 } 105 106 return 107 } 108 109 err = filepath.Walk(dir, walkFunc) 110 return 111 } 112 113 func copyPathToPath(fromPath, toPath string) (err error) { 114 srcFileInfo, err := os.Stat(fromPath) 115 if err != nil { 116 return 117 } 118 119 if srcFileInfo.IsDir() { 120 err = os.MkdirAll(toPath, srcFileInfo.Mode()) 121 if err != nil { 122 return 123 } 124 } else { 125 var dst *os.File 126 dst, err = fileutils.Create(toPath) 127 if err != nil { 128 return 129 } 130 defer dst.Close() 131 132 dst.Chmod(srcFileInfo.Mode()) 133 134 err = fileutils.CopyPathToWriter(fromPath, dst) 135 } 136 return err 137 } 138 139 func loadIgnoreFile(dir string) CfIgnore { 140 fileContents, err := ioutil.ReadFile(filepath.Join(dir, ".cfignore")) 141 if err == nil { 142 return NewCfIgnore(string(fileContents)) 143 } else { 144 return NewCfIgnore("") 145 } 146 }