@@ -22,9 +22,6 @@ import (
2222 "io/ioutil"
2323 "os"
2424
25- "github.com/blang/semver"
26- "github.com/go-git/go-git/v5"
27- "github.com/go-git/go-git/v5/plumbing"
2825 "github.com/go-git/go-git/v5/plumbing/object"
2926 "github.com/go-git/go-git/v5/plumbing/transport"
3027 "github.com/go-logr/logr"
@@ -122,36 +119,18 @@ func (r *GitRepositoryReconciler) SetupWithManagerAndOptions(mgr ctrl.Manager, o
122119}
123120
124121func (r * GitRepositoryReconciler ) sync (ctx context.Context , repository sourcev1.GitRepository ) (sourcev1.GitRepository , error ) {
125- // set defaults: master branch, no tags fetching, max two commits
126- branch := "master"
127- revision := ""
128- tagMode := git .NoTags
129- depth := 2
130-
131- // determine ref
132- refName := plumbing .NewBranchReferenceName (branch )
133-
134- if repository .Spec .Reference != nil {
135- if repository .Spec .Reference .Branch != "" {
136- branch = repository .Spec .Reference .Branch
137- refName = plumbing .NewBranchReferenceName (branch )
138- }
139- if repository .Spec .Reference .Commit != "" {
140- depth = 0
141- } else {
142- if repository .Spec .Reference .Tag != "" {
143- refName = plumbing .NewTagReferenceName (repository .Spec .Reference .Tag )
144- }
145- if repository .Spec .Reference .SemVer != "" {
146- tagMode = git .AllTags
147- }
148- }
122+ // create tmp dir for the Git clone
123+ tmpGit , err := ioutil .TempDir ("" , repository .Name )
124+ if err != nil {
125+ err = fmt .Errorf ("tmp dir error: %w" , err )
126+ return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .StorageOperationFailedReason , err .Error ()), err
149127 }
128+ defer os .RemoveAll (tmpGit )
150129
151130 // determine auth method
152- strategy := intgit .AuthSecretStrategyForURL (repository .Spec .URL )
153131 var auth transport.AuthMethod
154- if repository .Spec .SecretRef != nil {
132+ authStrategy := intgit .AuthSecretStrategyForURL (repository .Spec .URL )
133+ if repository .Spec .SecretRef != nil && authStrategy != nil {
155134 name := types.NamespacedName {
156135 Namespace : repository .GetNamespace (),
157136 Name : repository .Spec .SecretRef .Name ,
@@ -164,124 +143,16 @@ func (r *GitRepositoryReconciler) sync(ctx context.Context, repository sourcev1.
164143 return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .AuthenticationFailedReason , err .Error ()), err
165144 }
166145
167- auth , err = strategy .Method (secret )
146+ auth , err = authStrategy .Method (secret )
168147 if err != nil {
169148 err = fmt .Errorf ("auth error: %w" , err )
170149 return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .AuthenticationFailedReason , err .Error ()), err
171150 }
172151 }
173152
174- // create tmp dir for the Git clone
175- tmpGit , err := ioutil .TempDir ("" , repository .Name )
176- if err != nil {
177- err = fmt .Errorf ("tmp dir error: %w" , err )
178- return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .StorageOperationFailedReason , err .Error ()), err
179- }
180- defer os .RemoveAll (tmpGit )
181-
182- // clone to tmp
183- gitCtx , cancel := context .WithTimeout (ctx , repository .GetTimeout ())
184- repo , err := git .PlainCloneContext (gitCtx , tmpGit , false , & git.CloneOptions {
185- URL : repository .Spec .URL ,
186- Auth : auth ,
187- RemoteName : "origin" ,
188- ReferenceName : refName ,
189- SingleBranch : true ,
190- NoCheckout : false ,
191- Depth : depth ,
192- RecurseSubmodules : 0 ,
193- Progress : nil ,
194- Tags : tagMode ,
195- })
196- cancel ()
197- if err != nil {
198- err = fmt .Errorf ("git clone error: %w" , err )
199- return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .GitOperationFailedReason , err .Error ()), err
200- }
201-
202- // checkout commit or tag
203- if repository .Spec .Reference != nil {
204- if commit := repository .Spec .Reference .Commit ; commit != "" {
205- w , err := repo .Worktree ()
206- if err != nil {
207- err = fmt .Errorf ("git worktree error: %w" , err )
208- return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .GitOperationFailedReason , err .Error ()), err
209- }
210-
211- err = w .Checkout (& git.CheckoutOptions {
212- Hash : plumbing .NewHash (commit ),
213- Force : true ,
214- })
215- if err != nil {
216- err = fmt .Errorf ("git checkout '%s' for '%s' error: %w" , commit , branch , err )
217- return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .GitOperationFailedReason , err .Error ()), err
218- }
219- } else if exp := repository .Spec .Reference .SemVer ; exp != "" {
220- rng , err := semver .ParseRange (exp )
221- if err != nil {
222- err = fmt .Errorf ("semver parse range error: %w" , err )
223- return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .GitOperationFailedReason , err .Error ()), err
224- }
225-
226- repoTags , err := repo .Tags ()
227- if err != nil {
228- err = fmt .Errorf ("git list tags error: %w" , err )
229- return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .GitOperationFailedReason , err .Error ()), err
230- }
231-
232- tags := make (map [string ]string )
233- _ = repoTags .ForEach (func (t * plumbing.Reference ) error {
234- tags [t .Name ().Short ()] = t .Strings ()[1 ]
235- return nil
236- })
237-
238- svTags := make (map [string ]string )
239- var svers []semver.Version
240- for tag , _ := range tags {
241- v , _ := semver .ParseTolerant (tag )
242- if rng (v ) {
243- svers = append (svers , v )
244- svTags [v .String ()] = tag
245- }
246- }
247-
248- if len (svers ) > 0 {
249- semver .Sort (svers )
250- v := svers [len (svers )- 1 ]
251- t := svTags [v .String ()]
252- commit := tags [t ]
253- revision = fmt .Sprintf ("%s/%s" , t , commit )
254-
255- w , err := repo .Worktree ()
256- if err != nil {
257- err = fmt .Errorf ("git worktree error: %w" , err )
258- return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .GitOperationFailedReason , err .Error ()), err
259- }
260-
261- err = w .Checkout (& git.CheckoutOptions {
262- Hash : plumbing .NewHash (commit ),
263- })
264- if err != nil {
265- err = fmt .Errorf ("git checkout error: %w" , err )
266- return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .GitOperationFailedReason , err .Error ()), err
267- }
268- } else {
269- err = fmt .Errorf ("no match found for semver: %s" , repository .Spec .Reference .SemVer )
270- return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .GitOperationFailedReason , err .Error ()), err
271- }
272- }
273- }
274-
275- // read commit hash
276- ref , err := repo .Head ()
153+ checkoutStrategy := intgit .CheckoutStrategyForRef (repository .Spec .Reference )
154+ commit , revision , err := checkoutStrategy .Checkout (ctx , tmpGit , repository .Spec .URL , auth )
277155 if err != nil {
278- err = fmt .Errorf ("git resolve HEAD error: %w" , err )
279- return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .GitOperationFailedReason , err .Error ()), err
280- }
281-
282- commit , err := repo .CommitObject (ref .Hash ())
283- if err != nil {
284- err = fmt .Errorf ("git resolve HEAD error: %w" , err )
285156 return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .GitOperationFailedReason , err .Error ()), err
286157 }
287158
@@ -296,15 +167,8 @@ func (r *GitRepositoryReconciler) sync(ctx context.Context, repository sourcev1.
296167 }
297168 }
298169
299- if revision == "" {
300- revision = fmt .Sprintf ("%s/%s" , branch , ref .Hash ().String ())
301- if repository .Spec .Reference != nil && repository .Spec .Reference .Tag != "" {
302- revision = fmt .Sprintf ("%s/%s" , repository .Spec .Reference .Tag , ref .Hash ().String ())
303- }
304- }
305-
306170 artifact := r .Storage .ArtifactFor (repository .Kind , repository .ObjectMeta .GetObjectMeta (),
307- fmt .Sprintf ("%s.tar.gz" , ref .Hash () .String ()), revision )
171+ fmt .Sprintf ("%s.tar.gz" , commit .Hash .String ()), revision )
308172
309173 // create artifact dir
310174 err = r .Storage .MkdirAll (artifact )
0 commit comments