forked from cloudfoundry/cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
push.go
117 lines (100 loc) · 3.48 KB
/
push.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package actors
import (
"os"
"path/filepath"
"github.com/cloudfoundry/cli/cf/api/application_bits"
"github.com/cloudfoundry/cli/cf/api/resources"
"github.com/cloudfoundry/cli/cf/app_files"
"github.com/cloudfoundry/cli/cf/errors"
"github.com/cloudfoundry/cli/cf/models"
"github.com/cloudfoundry/gofileutils/fileutils"
)
type PushActor interface {
UploadApp(appGuid string, zipFile *os.File, presentFiles []resources.AppFileResource) error
GatherFiles(appDir string, uploadDir string) ([]resources.AppFileResource, error)
}
type PushActorImpl struct {
appBitsRepo application_bits.ApplicationBitsRepository
appfiles app_files.AppFiles
zipper app_files.Zipper
}
func NewPushActor(appBitsRepo application_bits.ApplicationBitsRepository, zipper app_files.Zipper, appfiles app_files.AppFiles) PushActor {
return PushActorImpl{
appBitsRepo: appBitsRepo,
appfiles: appfiles,
zipper: zipper,
}
}
func (actor PushActorImpl) GatherFiles(appDir string, uploadDir string) (presentFiles []resources.AppFileResource, apiErr error) {
if actor.zipper.IsZipFile(appDir) {
fileutils.TempDir("unzipped-app", func(tmpDir string, err error) {
err = actor.zipper.Unzip(appDir, tmpDir)
if err != nil {
presentFiles = nil
apiErr = err
return
}
presentFiles, apiErr = actor.copyUploadableFiles(tmpDir, uploadDir)
})
} else {
presentFiles, apiErr = actor.copyUploadableFiles(appDir, uploadDir)
}
return presentFiles, apiErr
}
func (actor PushActorImpl) UploadApp(appGuid string, zipFile *os.File, presentFiles []resources.AppFileResource) error {
return actor.appBitsRepo.UploadBits(appGuid, zipFile, presentFiles)
}
func (actor PushActorImpl) copyUploadableFiles(appDir string, uploadDir string) (presentFiles []resources.AppFileResource, err error) {
// Find which files need to be uploaded
allAppFiles, err := actor.appfiles.AppFilesInDir(appDir)
if err != nil {
return
}
appFilesToUpload, presentFiles, apiErr := actor.getFilesToUpload(allAppFiles)
if apiErr != nil {
err = errors.New(apiErr.Error())
return
}
// Copy files into a temporary directory and return it
err = actor.appfiles.CopyFiles(appFilesToUpload, appDir, uploadDir)
if err != nil {
return
}
// copy cfignore if present
fileutils.CopyPathToPath(filepath.Join(appDir, ".cfignore"), filepath.Join(uploadDir, ".cfignore")) //error handling?
return
}
func (actor PushActorImpl) getFilesToUpload(allAppFiles []models.AppFileFields) (appFilesToUpload []models.AppFileFields, presentFiles []resources.AppFileResource, apiErr error) {
appFilesRequest := []resources.AppFileResource{}
for _, file := range allAppFiles {
appFilesRequest = append(appFilesRequest, resources.AppFileResource{
Path: file.Path,
Sha1: file.Sha1,
Size: file.Size,
})
}
presentFiles, apiErr = actor.appBitsRepo.GetApplicationFiles(appFilesRequest)
if apiErr != nil {
return nil, nil, apiErr
}
appFilesToUpload = make([]models.AppFileFields, len(allAppFiles))
copy(appFilesToUpload, allAppFiles)
for _, file := range presentFiles {
appFile := models.AppFileFields{
Path: file.Path,
Sha1: file.Sha1,
Size: file.Size,
}
appFilesToUpload = actor.deleteAppFile(appFilesToUpload, appFile)
}
return
}
func (actor PushActorImpl) deleteAppFile(appFiles []models.AppFileFields, targetFile models.AppFileFields) []models.AppFileFields {
for i, file := range appFiles {
if file.Path == targetFile.Path {
appFiles[i] = appFiles[len(appFiles)-1]
return appFiles[:len(appFiles)-1]
}
}
return appFiles
}