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  }