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