@@ -18,63 +18,210 @@ package libgit2
18
18
19
19
import (
20
20
"context"
21
- "crypto/sha256"
22
- "encoding/hex"
23
- "io"
21
+ "errors"
22
+ "fmt"
24
23
"os"
25
- "path"
26
24
"testing"
25
+ "time"
27
26
28
27
git2go "github.com/libgit2/git2go/v31"
28
+ . "github.com/onsi/gomega"
29
29
30
30
"github.com/fluxcd/source-controller/pkg/git"
31
31
)
32
32
33
33
func TestCheckoutTagSemVer_Checkout (t * testing.T ) {
34
- certCallback := func (cert * git2go.Certificate , valid bool , hostname string ) git2go.ErrorCode {
35
- return git2go .ErrorCodeOK
34
+ g := NewWithT (t )
35
+ now := time .Now ()
36
+
37
+ tags := []struct {
38
+ tag string
39
+ simple bool
40
+ commitTime time.Time
41
+ tagTime time.Time
42
+ }{
43
+ {
44
+ tag : "v0.0.1" ,
45
+ simple : true ,
46
+ commitTime : now ,
47
+ },
48
+ {
49
+ tag : "v0.1.0+build-1" ,
50
+ simple : false ,
51
+ commitTime : now .Add (1 * time .Minute ),
52
+ tagTime : now .Add (1 * time .Hour ), // This should be ignored during TS comparisons
53
+ },
54
+ {
55
+ tag : "v0.1.0+build-2" ,
56
+ simple : true ,
57
+ commitTime : now .Add (2 * time .Minute ),
58
+ },
59
+ {
60
+ tag : "0.2.0" ,
61
+ simple : false ,
62
+ commitTime : now ,
63
+ tagTime : now ,
64
+ },
65
+ }
66
+ tests := []struct {
67
+ name string
68
+ constraint string
69
+ expectError error
70
+ expectTag string
71
+ }{
72
+ {
73
+ name : "Orders semver" ,
74
+ constraint : ">0.1.0" ,
75
+ expectTag : "0.2.0" ,
76
+ },
77
+ {
78
+ name : "Orders by SemVer and timestamp" ,
79
+ constraint : "<0.2.0" ,
80
+ expectTag : "v0.1.0+build-2" ,
81
+ },
82
+ {
83
+ name : "Errors without match" ,
84
+ constraint : ">=1.0.0" ,
85
+ expectError : errors .New ("no match found for semver: >=1.0.0" ),
86
+ },
87
+ }
88
+
89
+ repo , err := initBareRepo ()
90
+ if err != nil {
91
+ t .Fatal (err )
92
+ }
93
+ defer repo .Free ()
94
+ defer os .RemoveAll (repo .Path ())
95
+
96
+ for _ , tt := range tags {
97
+ cId , err := commit (repo , "tag.txt" , tt .tag , tt .commitTime )
98
+ if err != nil {
99
+ t .Fatal (err )
100
+ }
101
+ _ , err = tag (repo , cId , tt .simple , tt .tag , tt .tagTime )
102
+ if err != nil {
103
+ t .Fatal (err )
104
+ }
105
+ }
106
+
107
+ c , err := repo .Tags .List ()
108
+ g .Expect (err ).ToNot (HaveOccurred ())
109
+ g .Expect (c ).To (HaveLen (len (tags )))
110
+
111
+ for _ , tt := range tests {
112
+ t .Run (tt .name , func (t * testing.T ) {
113
+ semVer := CheckoutSemVer {
114
+ semVer : tt .constraint ,
115
+ }
116
+ tmpDir , _ := os .MkdirTemp ("" , "test" )
117
+ defer os .RemoveAll (tmpDir )
118
+
119
+ _ , ref , err := semVer .Checkout (context .TODO (), tmpDir , repo .Path (), & git.Auth {})
120
+ if tt .expectError != nil {
121
+ g .Expect (err ).To (Equal (tt .expectError ))
122
+ g .Expect (ref ).To (BeEmpty ())
123
+ return
124
+ }
125
+ g .Expect (err ).ToNot (HaveOccurred ())
126
+ g .Expect (ref ).To (HavePrefix (tt .expectTag + "/" ))
127
+ })
128
+ }
129
+ }
130
+
131
+ func initBareRepo () (* git2go.Repository , error ) {
132
+ tmpDir , err := os .MkdirTemp ("" , "git2go-" )
133
+ if err != nil {
134
+ return nil , err
135
+ }
136
+ repo , err := git2go .InitRepository (tmpDir , false )
137
+ if err != nil {
138
+ _ = os .RemoveAll (tmpDir )
139
+ return nil , err
140
+ }
141
+ return repo , nil
142
+ }
143
+
144
+ func headCommit (repo * git2go.Repository ) (* git2go.Commit , error ) {
145
+ head , err := repo .Head ()
146
+ if err != nil {
147
+ return nil , err
36
148
}
37
- auth := & git.Auth {CertCallback : certCallback }
149
+ defer head .Free ()
150
+
151
+ commit , err := repo .LookupCommit (head .Target ())
152
+ if err != nil {
153
+ return nil , err
154
+ }
155
+
156
+ return commit , nil
157
+ }
38
158
39
- tag := CheckoutTag {
40
- tag : "v1.7.0" ,
159
+ func commit (repo * git2go.Repository , path , content string , time time.Time ) (* git2go.Oid , error ) {
160
+ var parentC []* git2go.Commit
161
+ head , err := headCommit (repo )
162
+ if err == nil {
163
+ defer head .Free ()
164
+ parentC = append (parentC , head )
41
165
}
42
- tmpDir , _ := os .MkdirTemp ("" , "test" )
43
- defer os .RemoveAll (tmpDir )
44
166
45
- cTag , _ , err := tag . Checkout ( context . TODO (), tmpDir , "https://github.com/projectcontour/contour" , auth )
167
+ index , err := repo . Index ( )
46
168
if err != nil {
47
- t . Error ( err )
169
+ return nil , err
48
170
}
171
+ defer index .Free ()
49
172
50
- // Ensure the correct files are checked out on disk
51
- f , err := os .Open (path .Join (tmpDir , "README.md" ))
173
+ blobOID , err := repo .CreateBlobFromBuffer ([]byte (content ))
52
174
if err != nil {
53
- t .Error (err )
175
+ return nil , err
176
+ }
177
+
178
+ entry := & git2go.IndexEntry {
179
+ Mode : git2go .FilemodeBlob ,
180
+ Id : blobOID ,
181
+ Path : path ,
182
+ }
183
+
184
+ if err := index .Add (entry ); err != nil {
185
+ return nil , err
54
186
}
55
- defer f .Close ()
56
- h := sha256 .New ()
57
- if _ , err := io .Copy (h , f ); err != nil {
58
- t .Error (err )
187
+ if err := index .Write (); err != nil {
188
+ return nil , err
59
189
}
60
- const expectedHash = "2bd1707542a11f987ee24698dcc095a9f57639f401133ef6a29da97bf8f3f302"
61
- fileHash := hex .EncodeToString (h .Sum (nil ))
62
- if fileHash != expectedHash {
63
- t .Errorf ("expected files not checked out. Expected hash %s, got %s" , expectedHash , fileHash )
190
+
191
+ newTreeOID , err := index .WriteTree ()
192
+ if err != nil {
193
+ return nil , err
194
+ }
195
+
196
+ tree , err := repo .LookupTree (newTreeOID )
197
+ if err != nil {
198
+ return nil , err
64
199
}
200
+ defer tree .Free ()
65
201
66
- semVer := CheckoutSemVer {
67
- semVer : ">=1.0.0 <=1.7.0" ,
202
+ commit , err := repo .CreateCommit ("HEAD" , signature (time ), signature (time ), "Committing " + path , tree , parentC ... )
203
+ if err != nil {
204
+ return nil , err
68
205
}
69
- tmpDir2 , _ := os .MkdirTemp ("" , "test" )
70
- defer os .RemoveAll (tmpDir2 )
71
206
72
- cSemVer , _ , err := semVer .Checkout (context .TODO (), tmpDir2 , "https://github.com/projectcontour/contour" , auth )
207
+ return commit , nil
208
+ }
209
+
210
+ func tag (repo * git2go.Repository , cId * git2go.Oid , simple bool , tag string , time time.Time ) (* git2go.Oid , error ) {
211
+ commit , err := repo .LookupCommit (cId )
73
212
if err != nil {
74
- t . Error ( err )
213
+ return nil , err
75
214
}
215
+ if simple {
216
+ return repo .Tags .CreateLightweight (tag , commit , false )
217
+ }
218
+ return repo .Tags .Create (tag , commit , signature (time ), fmt .Sprintf ("Annotated tag for %s" , tag ))
219
+ }
76
220
77
- if cTag .Hash () != cSemVer .Hash () {
78
- t .Errorf ("expected semver hash %s, got %s" , cTag .Hash (), cSemVer .Hash ())
221
+ func signature (time time.Time ) * git2go.Signature {
222
+ return & git2go.Signature {
223
+ Name : "Jane Doe" ,
224
+ Email : "author@example.com" ,
225
+ When : time ,
79
226
}
80
227
}
0 commit comments