github.com/henvic/wedeploycli@v1.7.6-0.20200319005353-3630f582f284/deployment/transport/gogit/gogit.go (about) 1 package gogit 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "path/filepath" 8 "time" 9 10 "github.com/hashicorp/errwrap" 11 "github.com/henvic/wedeploycli/deployment/internal/groupuid" 12 "github.com/henvic/wedeploycli/deployment/transport" 13 "github.com/henvic/wedeploycli/services" 14 "github.com/henvic/wedeploycli/verbose" 15 git "gopkg.in/src-d/go-git.v4" 16 gitconfig "gopkg.in/src-d/go-git.v4/config" 17 "gopkg.in/src-d/go-git.v4/plumbing" 18 "gopkg.in/src-d/go-git.v4/plumbing/object" 19 gotransport "gopkg.in/src-d/go-git.v4/plumbing/transport" 20 "gopkg.in/src-d/go-git.v4/plumbing/transport/http" 21 ) 22 23 // Transport using go-git. 24 type Transport struct { 25 ctx context.Context 26 settings transport.Settings 27 28 repository *git.Repository 29 worktree *git.Worktree 30 31 start time.Time 32 end time.Time 33 } 34 35 // Stage files. 36 func (t *Transport) Stage(s services.ServiceInfoList) (err error) { 37 verbose.Debug("Staging files") 38 39 for _, s := range s { 40 if _, err = t.worktree.Add(filepath.Base(s.Location)); err != nil { 41 return err 42 } 43 } 44 45 return nil 46 } 47 48 // Commit adds all files and commits 49 func (t *Transport) Commit(message string) (commit string, err error) { 50 verbose.Debug("Committing changes.") 51 52 var hash plumbing.Hash 53 54 hash, err = t.worktree.Commit(message, &git.CommitOptions{ 55 Author: &object.Signature{ 56 Name: "Liferay Cloud user", 57 Email: "user@deployment", 58 When: time.Now(), 59 }, 60 }) 61 62 if err != nil { 63 return "", errwrap.Wrapf("can't commit: {{err}}", err) 64 } 65 66 commit = hash.String() 67 68 verbose.Debug("commit", commit) 69 return commit, nil 70 } 71 72 // Push deployment to the Liferay Cloud remote 73 func (t *Transport) Push() (groupUID string, err error) { 74 verbose.Debug("Started uploading deployment package to the infrastructure") 75 76 t.start = time.Now() 77 defer func() { 78 t.end = time.Now() 79 }() 80 81 buf := &bytes.Buffer{} 82 83 o := &git.PushOptions{ 84 RemoteName: t.getGitRemote(), 85 RefSpecs: []gitconfig.RefSpec{ 86 "+refs/heads/master:refs/heads/master", 87 }, 88 Auth: &http.BasicAuth{ 89 Username: t.settings.ConfigContext.Token(), 90 }, 91 Progress: buf, 92 } 93 94 err = t.repository.PushContext(t.ctx, o) 95 96 switch { 97 case err == gotransport.ErrAuthenticationRequired: 98 return "", errwrap.Wrapf("Invalid credentials", err) 99 case err != nil: 100 return "", err 101 } 102 103 return groupuid.Extract(buf.String()) 104 } 105 106 // UploadDuration for deployment (only correct after it finishes) 107 func (t *Transport) UploadDuration() time.Duration { 108 return t.end.Sub(t.start) 109 } 110 111 // Setup as a git repo 112 func (t *Transport) Setup(ctx context.Context, settings transport.Settings) error { 113 t.ctx = ctx 114 t.settings = settings 115 return nil 116 } 117 118 // Init repository 119 func (t *Transport) Init() (err error) { 120 if t.repository, err = git.PlainInit(t.settings.WorkDir, false); err != nil { 121 return errwrap.Wrapf("cannot create repository: {{err}}", err) 122 } 123 124 if t.worktree, err = t.repository.Worktree(); err != nil { 125 return errwrap.Wrapf("cannot create worktree: {{err}}", err) 126 } 127 128 return nil 129 } 130 131 func (t *Transport) getGitRemote() string { 132 var remote = t.settings.ConfigContext.Remote() 133 134 // always add a "wedeploy-" prefix to all deployment remote endpoints, but "lcp" 135 if remote != "lcp" { 136 remote = "lcp" + "-" + remote 137 } 138 139 return remote 140 } 141 142 // ProcessIgnored gets what file should be ignored. 143 func (t *Transport) ProcessIgnored() (map[string]struct{}, error) { 144 i := ignoreChecker{ 145 path: t.settings.Path, 146 } 147 148 return i.Process() 149 } 150 151 // AddRemote on project 152 func (t *Transport) AddRemote() (err error) { 153 var gitServer = fmt.Sprintf("https://git.%v/%v.git", 154 t.settings.ConfigContext.InfrastructureDomain(), 155 t.settings.ProjectID) 156 157 _, err = t.repository.CreateRemote(&gitconfig.RemoteConfig{ 158 Name: t.getGitRemote(), 159 URLs: []string{gitServer}, 160 }) 161 162 return err 163 } 164 165 // UserAgent of the transport layer. 166 func (t *Transport) UserAgent() string { 167 return "go-git v4" 168 }