github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/git/repo_tag_test.go (about) 1 // Copyright 2023 The GitBundle Inc. All rights reserved. 2 // Copyright 2017 The Gitea Authors. All rights reserved. 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file. 5 6 package git 7 8 import ( 9 "path/filepath" 10 "testing" 11 12 "github.com/gitbundle/modules/util" 13 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/require" 16 ) 17 18 func TestRepository_GetTags(t *testing.T) { 19 bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") 20 bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) 21 if err != nil { 22 assert.NoError(t, err) 23 return 24 } 25 defer bareRepo1.Close() 26 27 tags, total, err := bareRepo1.GetTagInfos(0, 0) 28 if err != nil { 29 assert.NoError(t, err) 30 return 31 } 32 assert.Len(t, tags, 1) 33 assert.Equal(t, len(tags), total) 34 assert.EqualValues(t, "test", tags[0].Name) 35 assert.EqualValues(t, "3ad28a9149a2864384548f3d17ed7f38014c9e8a", tags[0].ID.String()) 36 assert.EqualValues(t, "tag", tags[0].Type) 37 } 38 39 func TestRepository_GetTag(t *testing.T) { 40 bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") 41 42 clonedPath, err := cloneRepo(bareRepo1Path, "TestRepository_GetTag") 43 if err != nil { 44 assert.NoError(t, err) 45 return 46 } 47 defer util.RemoveAll(clonedPath) 48 49 bareRepo1, err := openRepositoryWithDefaultContext(clonedPath) 50 if err != nil { 51 assert.NoError(t, err) 52 return 53 } 54 defer bareRepo1.Close() 55 56 // LIGHTWEIGHT TAGS 57 lTagCommitID := "6fbd69e9823458e6c4a2fc5c0f6bc022b2f2acd1" 58 lTagName := "lightweightTag" 59 60 // Create the lightweight tag 61 err = bareRepo1.CreateTag(lTagName, lTagCommitID) 62 if err != nil { 63 assert.NoError(t, err, "Unable to create the lightweight tag: %s for ID: %s. Error: %v", lTagName, lTagCommitID, err) 64 return 65 } 66 67 // and try to get the Tag for lightweight tag 68 lTag, err := bareRepo1.GetTag(lTagName) 69 if err != nil { 70 assert.NoError(t, err) 71 return 72 } 73 if lTag == nil { 74 assert.NotNil(t, lTag) 75 assert.FailNow(t, "nil lTag: %s", lTagName) 76 return 77 } 78 assert.EqualValues(t, lTagName, lTag.Name) 79 assert.EqualValues(t, lTagCommitID, lTag.ID.String()) 80 assert.EqualValues(t, lTagCommitID, lTag.Object.String()) 81 assert.EqualValues(t, "commit", lTag.Type) 82 83 // ANNOTATED TAGS 84 aTagCommitID := "8006ff9adbf0cb94da7dad9e537e53817f9fa5c0" 85 aTagName := "annotatedTag" 86 aTagMessage := "my annotated message \n - test two line" 87 88 // Create the annotated tag 89 err = bareRepo1.CreateAnnotatedTag(aTagName, aTagMessage, aTagCommitID) 90 if err != nil { 91 assert.NoError(t, err, "Unable to create the annotated tag: %s for ID: %s. Error: %v", aTagName, aTagCommitID, err) 92 return 93 } 94 95 // Now try to get the tag for the annotated Tag 96 aTagID, err := bareRepo1.GetTagID(aTagName) 97 if err != nil { 98 assert.NoError(t, err) 99 return 100 } 101 102 aTag, err := bareRepo1.GetTag(aTagName) 103 if err != nil { 104 assert.NoError(t, err) 105 return 106 } 107 if aTag == nil { 108 assert.NotNil(t, aTag) 109 assert.FailNow(t, "nil aTag: %s", aTagName) 110 return 111 } 112 assert.EqualValues(t, aTagName, aTag.Name) 113 assert.EqualValues(t, aTagID, aTag.ID.String()) 114 assert.NotEqual(t, aTagID, aTag.Object.String()) 115 assert.EqualValues(t, aTagCommitID, aTag.Object.String()) 116 assert.EqualValues(t, "tag", aTag.Type) 117 118 // RELEASE TAGS 119 120 rTagCommitID := "8006ff9adbf0cb94da7dad9e537e53817f9fa5c0" 121 rTagName := "release/" + lTagName 122 123 err = bareRepo1.CreateTag(rTagName, rTagCommitID) 124 if err != nil { 125 assert.NoError(t, err, "Unable to create the tag: %s for ID: %s. Error: %v", rTagName, rTagCommitID, err) 126 return 127 } 128 129 rTagID, err := bareRepo1.GetTagID(rTagName) 130 if err != nil { 131 assert.NoError(t, err) 132 return 133 } 134 assert.EqualValues(t, rTagCommitID, rTagID) 135 136 oTagID, err := bareRepo1.GetTagID(lTagName) 137 if err != nil { 138 assert.NoError(t, err) 139 return 140 } 141 assert.EqualValues(t, lTagCommitID, oTagID) 142 } 143 144 func TestRepository_GetAnnotatedTag(t *testing.T) { 145 bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") 146 147 clonedPath, err := cloneRepo(bareRepo1Path, "TestRepository_GetAnnotatedTag") 148 if err != nil { 149 assert.NoError(t, err) 150 return 151 } 152 defer util.RemoveAll(clonedPath) 153 154 bareRepo1, err := openRepositoryWithDefaultContext(clonedPath) 155 if err != nil { 156 assert.NoError(t, err) 157 return 158 } 159 defer bareRepo1.Close() 160 161 lTagCommitID := "6fbd69e9823458e6c4a2fc5c0f6bc022b2f2acd1" 162 lTagName := "lightweightTag" 163 bareRepo1.CreateTag(lTagName, lTagCommitID) 164 165 aTagCommitID := "8006ff9adbf0cb94da7dad9e537e53817f9fa5c0" 166 aTagName := "annotatedTag" 167 aTagMessage := "my annotated message" 168 bareRepo1.CreateAnnotatedTag(aTagName, aTagMessage, aTagCommitID) 169 aTagID, _ := bareRepo1.GetTagID(aTagName) 170 171 // Try an annotated tag 172 tag, err := bareRepo1.GetAnnotatedTag(aTagID) 173 if err != nil { 174 assert.NoError(t, err) 175 return 176 } 177 assert.NotNil(t, tag) 178 assert.EqualValues(t, aTagName, tag.Name) 179 assert.EqualValues(t, aTagID, tag.ID.String()) 180 assert.EqualValues(t, "tag", tag.Type) 181 182 // Annotated tag's Commit ID should fail 183 tag2, err := bareRepo1.GetAnnotatedTag(aTagCommitID) 184 assert.Error(t, err) 185 assert.True(t, IsErrNotExist(err)) 186 assert.Nil(t, tag2) 187 188 // Annotated tag's name should fail 189 tag3, err := bareRepo1.GetAnnotatedTag(aTagName) 190 assert.Error(t, err) 191 assert.Errorf(t, err, "Length must be 40: %d", len(aTagName)) 192 assert.Nil(t, tag3) 193 194 // Lightweight Tag should fail 195 tag4, err := bareRepo1.GetAnnotatedTag(lTagCommitID) 196 assert.Error(t, err) 197 assert.True(t, IsErrNotExist(err)) 198 assert.Nil(t, tag4) 199 } 200 201 func TestRepository_parseTagRef(t *testing.T) { 202 tests := []struct { 203 name string 204 205 givenRef map[string]string 206 207 want *Tag 208 wantErr bool 209 expectedErr error 210 }{ 211 { 212 name: "lightweight tag", 213 214 givenRef: map[string]string{ 215 "objecttype": "commit", 216 "refname:short": "v1.9.1", 217 // object will be empty for lightweight tags 218 "object": "", 219 "objectname": "ab23e4b7f4cd0caafe0174c0e7ef6d651ba72889", 220 "creator": "Foo Bar <foo@bar.com> 1565789218 +0300", 221 "contents": `Add changelog of v1.9.1 (#7859) 222 223 * add changelog of v1.9.1 224 * Update CHANGELOG.md 225 `, 226 "contents:signature": "", 227 }, 228 229 want: &Tag{ 230 Name: "v1.9.1", 231 ID: MustIDFromString("ab23e4b7f4cd0caafe0174c0e7ef6d651ba72889"), 232 Object: MustIDFromString("ab23e4b7f4cd0caafe0174c0e7ef6d651ba72889"), 233 Type: "commit", 234 Tagger: parseAuthorLine(t, "Foo Bar <foo@bar.com> 1565789218 +0300"), 235 Message: "Add changelog of v1.9.1 (#7859)\n\n* add changelog of v1.9.1\n* Update CHANGELOG.md\n", 236 Signature: nil, 237 }, 238 }, 239 240 { 241 name: "annotated tag", 242 243 givenRef: map[string]string{ 244 "objecttype": "tag", 245 "refname:short": "v0.0.1", 246 // object will refer to commit hash for annotated tag 247 "object": "3325fd8a973321fd59455492976c042dde3fd1ca", 248 "objectname": "8c68a1f06fc59c655b7e3905b159d761e91c53c9", 249 "creator": "Foo Bar <foo@bar.com> 1565789218 +0300", 250 "contents": `Add changelog of v1.9.1 (#7859) 251 252 * add changelog of v1.9.1 253 * Update CHANGELOG.md 254 `, 255 "contents:signature": "", 256 }, 257 258 want: &Tag{ 259 Name: "v0.0.1", 260 ID: MustIDFromString("8c68a1f06fc59c655b7e3905b159d761e91c53c9"), 261 Object: MustIDFromString("3325fd8a973321fd59455492976c042dde3fd1ca"), 262 Type: "tag", 263 Tagger: parseAuthorLine(t, "Foo Bar <foo@bar.com> 1565789218 +0300"), 264 Message: "Add changelog of v1.9.1 (#7859)\n\n* add changelog of v1.9.1\n* Update CHANGELOG.md\n", 265 Signature: nil, 266 }, 267 }, 268 269 { 270 name: "annotated tag with signature", 271 272 givenRef: map[string]string{ 273 "objecttype": "tag", 274 "refname:short": "v0.0.1", 275 "object": "3325fd8a973321fd59455492976c042dde3fd1ca", 276 "objectname": "8c68a1f06fc59c655b7e3905b159d761e91c53c9", 277 "creator": "Foo Bar <foo@bar.com> 1565789218 +0300", 278 "contents": `Add changelog of v1.9.1 (#7859) 279 280 * add changelog of v1.9.1 281 * Update CHANGELOG.md 282 -----BEGIN PGP SIGNATURE----- 283 284 aBCGzBAABCgAdFiEEyWRwv/q1Q6IjSv+D4IPOwzt33PoFAmI8jbIACgkQ4IPOwzt3 285 3PoRuAv9FVSbPBXvzECubls9KQd7urwEvcfG20Uf79iBwifQJUv+egNQojrs6APT 286 T4CdIXeGRpwJZaGTUX9RWnoDO1SLXAWnc82CypWraNwrHq8Go2YeoVu0Iy3vb0EU 287 REdob/tXYZecMuP8AjhUR0XfdYaERYAvJ2dYsH/UkFrqDjM3V4kPXWG+R5DCaZiE 288 slB5U01i4Dwb/zm/ckzhUGEcOgcnpOKX8SnY5kYRVDY47dl/yJZ1u2XWir3mu60G 289 1geIitH7StBddHi/8rz+sJwTfcVaLjn2p59p/Dr9aGbk17GIaKq1j0pZA2lKT0Xt 290 f9jDqU+9vCxnKgjSDhrwN69LF2jT47ZFjEMGV/wFPOa1EBxVWpgQ/CfEolBlbUqx 291 yVpbxi/6AOK2lmG130e9jEZJcu+WeZUeq851WgKSEkf2d5f/JpwtSTEOlOedu6V6 292 kl845zu5oE2nKM4zMQ7XrYQn538I31ps+VGQ0H8R07WrZP8WKUWugL2cU8KmXFwg 293 qbHDASXl 294 =2yGi 295 -----END PGP SIGNATURE----- 296 297 `, 298 "contents:signature": `-----BEGIN PGP SIGNATURE----- 299 300 aBCGzBAABCgAdFiEEyWRwv/q1Q6IjSv+D4IPOwzt33PoFAmI8jbIACgkQ4IPOwzt3 301 3PoRuAv9FVSbPBXvzECubls9KQd7urwEvcfG20Uf79iBwifQJUv+egNQojrs6APT 302 T4CdIXeGRpwJZaGTUX9RWnoDO1SLXAWnc82CypWraNwrHq8Go2YeoVu0Iy3vb0EU 303 REdob/tXYZecMuP8AjhUR0XfdYaERYAvJ2dYsH/UkFrqDjM3V4kPXWG+R5DCaZiE 304 slB5U01i4Dwb/zm/ckzhUGEcOgcnpOKX8SnY5kYRVDY47dl/yJZ1u2XWir3mu60G 305 1geIitH7StBddHi/8rz+sJwTfcVaLjn2p59p/Dr9aGbk17GIaKq1j0pZA2lKT0Xt 306 f9jDqU+9vCxnKgjSDhrwN69LF2jT47ZFjEMGV/wFPOa1EBxVWpgQ/CfEolBlbUqx 307 yVpbxi/6AOK2lmG130e9jEZJcu+WeZUeq851WgKSEkf2d5f/JpwtSTEOlOedu6V6 308 kl845zu5oE2nKM4zMQ7XrYQn538I31ps+VGQ0H8R07WrZP8WKUWugL2cU8KmXFwg 309 qbHDASXl 310 =2yGi 311 -----END PGP SIGNATURE----- 312 313 `, 314 }, 315 316 want: &Tag{ 317 Name: "v0.0.1", 318 ID: MustIDFromString("8c68a1f06fc59c655b7e3905b159d761e91c53c9"), 319 Object: MustIDFromString("3325fd8a973321fd59455492976c042dde3fd1ca"), 320 Type: "tag", 321 Tagger: parseAuthorLine(t, "Foo Bar <foo@bar.com> 1565789218 +0300"), 322 Message: "Add changelog of v1.9.1 (#7859)\n\n* add changelog of v1.9.1\n* Update CHANGELOG.md", 323 Signature: &CommitGPGSignature{ 324 Signature: `-----BEGIN PGP SIGNATURE----- 325 326 aBCGzBAABCgAdFiEEyWRwv/q1Q6IjSv+D4IPOwzt33PoFAmI8jbIACgkQ4IPOwzt3 327 3PoRuAv9FVSbPBXvzECubls9KQd7urwEvcfG20Uf79iBwifQJUv+egNQojrs6APT 328 T4CdIXeGRpwJZaGTUX9RWnoDO1SLXAWnc82CypWraNwrHq8Go2YeoVu0Iy3vb0EU 329 REdob/tXYZecMuP8AjhUR0XfdYaERYAvJ2dYsH/UkFrqDjM3V4kPXWG+R5DCaZiE 330 slB5U01i4Dwb/zm/ckzhUGEcOgcnpOKX8SnY5kYRVDY47dl/yJZ1u2XWir3mu60G 331 1geIitH7StBddHi/8rz+sJwTfcVaLjn2p59p/Dr9aGbk17GIaKq1j0pZA2lKT0Xt 332 f9jDqU+9vCxnKgjSDhrwN69LF2jT47ZFjEMGV/wFPOa1EBxVWpgQ/CfEolBlbUqx 333 yVpbxi/6AOK2lmG130e9jEZJcu+WeZUeq851WgKSEkf2d5f/JpwtSTEOlOedu6V6 334 kl845zu5oE2nKM4zMQ7XrYQn538I31ps+VGQ0H8R07WrZP8WKUWugL2cU8KmXFwg 335 qbHDASXl 336 =2yGi 337 -----END PGP SIGNATURE----- 338 339 `, 340 Payload: `object 3325fd8a973321fd59455492976c042dde3fd1ca 341 type commit 342 tag v0.0.1 343 tagger Foo Bar <foo@bar.com> 1565789218 +0300 344 345 Add changelog of v1.9.1 (#7859) 346 347 * add changelog of v1.9.1 348 * Update CHANGELOG.md 349 `, 350 }, 351 }, 352 }, 353 } 354 355 for _, test := range tests { 356 tc := test // don't close over loop variable 357 t.Run(tc.name, func(t *testing.T) { 358 got, err := parseTagRef(tc.givenRef) 359 360 if tc.wantErr { 361 require.Error(t, err) 362 require.ErrorIs(t, err, tc.expectedErr) 363 } else { 364 require.NoError(t, err) 365 require.Equal(t, tc.want, got) 366 } 367 }) 368 } 369 } 370 371 func parseAuthorLine(t *testing.T, committer string) *Signature { 372 t.Helper() 373 374 sig, err := newSignatureFromCommitline([]byte(committer)) 375 if err != nil { 376 t.Fatalf("parse author line '%s': %v", committer, err) 377 } 378 379 return sig 380 }