github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/tag/git_commit_test.go (about) 1 //go:build !windows 2 // +build !windows 3 4 /* 5 Copyright 2019 The Skaffold Authors 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 */ 19 20 package tag 21 22 import ( 23 "context" 24 "io/ioutil" 25 "os" 26 "path/filepath" 27 "strings" 28 "testing" 29 "time" 30 31 git "github.com/go-git/go-git/v5" 32 "github.com/go-git/go-git/v5/plumbing" 33 "github.com/go-git/go-git/v5/plumbing/object" 34 35 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" 36 "github.com/GoogleContainerTools/skaffold/testutil" 37 ) 38 39 // These tests do not run on windows 40 // See: https://github.com/src-d/go-git/issues/378 41 func TestGitCommit_GenerateTag(t *testing.T) { 42 tests := []struct { 43 description string 44 variantTags string 45 variantCommitSha string 46 variantAbbrevCommitSha string 47 variantTreeSha string 48 variantAbbrevTreeSha string 49 variantBranches string 50 createGitRepo func(string) 51 subDir string 52 shouldErr bool 53 ignoreChanges bool 54 }{ 55 { 56 description: "clean worktree without tag", 57 variantTags: "eefe1b9", 58 variantCommitSha: "eefe1b9c44eb0aa87199c9a079f2d48d8eb8baed", 59 variantAbbrevCommitSha: "eefe1b9", 60 variantTreeSha: "3bed02ca656e336307e4eb4d80080d7221cba62c", 61 variantAbbrevTreeSha: "3bed02c", 62 variantBranches: "master", 63 createGitRepo: func(dir string) { 64 gitInit(t, dir). 65 write("source.go", "code"). 66 add("source.go"). 67 commit("initial") 68 }, 69 }, 70 { 71 description: "clean worktree with tag containing a slash", 72 variantTags: "v_2", 73 variantCommitSha: "aea33bcc86b5af8c8570ff45d8a643202d63c808", 74 variantAbbrevCommitSha: "aea33bc", 75 variantTreeSha: "bc69d50cda6897a6f2054e64b9059f038dc6fb0e", 76 variantAbbrevTreeSha: "bc69d50", 77 variantBranches: "master", 78 createGitRepo: func(dir string) { 79 gitInit(t, dir). 80 write("source.go", "code"). 81 add("source.go"). 82 commit("initial"). 83 tag("v/1"). 84 write("other.go", "other"). 85 add("other.go"). 86 commit("second commit"). 87 tag("v/2") 88 }, 89 }, 90 { 91 description: "clean worktree with a branch", 92 variantTags: "589c4dc", 93 variantCommitSha: "589c4dcf52df66d058c705db39f871dceacf6471", 94 variantAbbrevCommitSha: "589c4dc", 95 variantTreeSha: "3bed02ca656e336307e4eb4d80080d7221cba62c", 96 variantAbbrevTreeSha: "3bed02c", 97 variantBranches: "branch", 98 createGitRepo: func(dir string) { 99 gitInit(t, dir). 100 write("source.go", "code"). 101 add("source.go"). 102 commit("initial"). 103 branch("branch"). 104 commit("second") 105 }, 106 }, 107 { 108 description: "clean worktree with a branch containing a slash", 109 variantTags: "eefe1b9", 110 variantCommitSha: "eefe1b9c44eb0aa87199c9a079f2d48d8eb8baed", 111 variantAbbrevCommitSha: "eefe1b9", 112 variantTreeSha: "3bed02ca656e336307e4eb4d80080d7221cba62c", 113 variantAbbrevTreeSha: "3bed02c", 114 variantBranches: "branch_withslash", 115 createGitRepo: func(dir string) { 116 gitInit(t, dir). 117 write("source.go", "code"). 118 add("source.go"). 119 commit("initial"). 120 branch("branch/withslash") 121 }, 122 }, 123 { 124 description: "dirty worktree with tag containing a slash", 125 variantTags: "v_2-dirty", 126 variantCommitSha: "aea33bcc86b5af8c8570ff45d8a643202d63c808-dirty", 127 variantAbbrevCommitSha: "aea33bc-dirty", 128 variantTreeSha: "bc69d50cda6897a6f2054e64b9059f038dc6fb0e-dirty", 129 variantAbbrevTreeSha: "bc69d50-dirty", 130 variantBranches: "master-dirty", 131 createGitRepo: func(dir string) { 132 gitInit(t, dir). 133 write("source.go", "code"). 134 add("source.go"). 135 commit("initial"). 136 tag("v/1"). 137 write("other.go", "other"). 138 add("other.go"). 139 commit("second commit"). 140 tag("v/2"). 141 write("other.go", "updated code") 142 }, 143 }, 144 { 145 description: "dirty worktree with ignore changes flag", 146 variantTags: "v_2", 147 variantCommitSha: "aea33bcc86b5af8c8570ff45d8a643202d63c808", 148 variantAbbrevCommitSha: "aea33bc", 149 variantTreeSha: "bc69d50cda6897a6f2054e64b9059f038dc6fb0e", 150 variantAbbrevTreeSha: "bc69d50", 151 variantBranches: "master", 152 createGitRepo: func(dir string) { 153 gitInit(t, dir). 154 write("source.go", "code"). 155 add("source.go"). 156 commit("initial"). 157 tag("v/1"). 158 write("other.go", "other"). 159 add("other.go"). 160 commit("second commit"). 161 tag("v/2"). 162 write("other.go", "updated code") 163 }, 164 ignoreChanges: true, 165 }, 166 { 167 description: "clean worktree with tags", 168 variantTags: "v2", 169 variantCommitSha: "aea33bcc86b5af8c8570ff45d8a643202d63c808", 170 variantAbbrevCommitSha: "aea33bc", 171 variantTreeSha: "bc69d50cda6897a6f2054e64b9059f038dc6fb0e", 172 variantAbbrevTreeSha: "bc69d50", 173 variantBranches: "master", 174 createGitRepo: func(dir string) { 175 gitInit(t, dir). 176 write("source.go", "code"). 177 add("source.go"). 178 commit("initial"). 179 tag("v1"). 180 write("other.go", "other"). 181 add("other.go"). 182 commit("second commit"). 183 tag("v2") 184 }, 185 }, 186 { 187 description: "clean worktree with ignore changes flag", 188 variantTags: "v2", 189 variantCommitSha: "aea33bcc86b5af8c8570ff45d8a643202d63c808", 190 variantAbbrevCommitSha: "aea33bc", 191 variantTreeSha: "bc69d50cda6897a6f2054e64b9059f038dc6fb0e", 192 variantAbbrevTreeSha: "bc69d50", 193 variantBranches: "master", 194 createGitRepo: func(dir string) { 195 gitInit(t, dir). 196 write("source.go", "code"). 197 add("source.go"). 198 commit("initial"). 199 tag("v1"). 200 write("other.go", "other"). 201 add("other.go"). 202 commit("second commit"). 203 tag("v2") 204 }, 205 ignoreChanges: true, 206 }, 207 { 208 description: "treeSha only considers current tree content", 209 variantTags: "v1", 210 variantCommitSha: "b2f7a7d62794237ac293eb07c6bcae3736b96231", 211 variantAbbrevCommitSha: "b2f7a7d", 212 variantTreeSha: "3bed02ca656e336307e4eb4d80080d7221cba62c", 213 variantAbbrevTreeSha: "3bed02c", 214 variantBranches: "master", 215 createGitRepo: func(dir string) { 216 gitInit(t, dir). 217 write("source.go", "other code"). 218 add("source.go"). 219 commit("initial"). 220 write("source.go", "code"). 221 add("source.go"). 222 commit("updated code"). 223 tag("v1") 224 }, 225 }, 226 { 227 description: "dirty worktree without tag", 228 variantTags: "eefe1b9-dirty", 229 variantCommitSha: "eefe1b9c44eb0aa87199c9a079f2d48d8eb8baed-dirty", 230 variantAbbrevCommitSha: "eefe1b9-dirty", 231 variantTreeSha: "3bed02ca656e336307e4eb4d80080d7221cba62c-dirty", 232 variantAbbrevTreeSha: "3bed02c-dirty", 233 variantBranches: "master-dirty", 234 createGitRepo: func(dir string) { 235 gitInit(t, dir). 236 write("source.go", "code"). 237 add("source.go"). 238 commit("initial"). 239 write("source.go", "updated code") 240 }, 241 }, 242 { 243 description: "dirty worktree with tag", 244 variantTags: "v1-dirty", 245 variantCommitSha: "eefe1b9c44eb0aa87199c9a079f2d48d8eb8baed-dirty", 246 variantAbbrevCommitSha: "eefe1b9-dirty", 247 variantTreeSha: "3bed02ca656e336307e4eb4d80080d7221cba62c-dirty", 248 variantAbbrevTreeSha: "3bed02c-dirty", 249 variantBranches: "master-dirty", 250 createGitRepo: func(dir string) { 251 gitInit(t, dir). 252 write("source.go", "code"). 253 add("source.go"). 254 commit("initial"). 255 tag("v1"). 256 write("source.go", "updated code") 257 }, 258 }, 259 { 260 description: "untracked", 261 variantTags: "eefe1b9-dirty", 262 variantCommitSha: "eefe1b9c44eb0aa87199c9a079f2d48d8eb8baed-dirty", 263 variantAbbrevCommitSha: "eefe1b9-dirty", 264 variantTreeSha: "3bed02ca656e336307e4eb4d80080d7221cba62c-dirty", 265 variantAbbrevTreeSha: "3bed02c-dirty", 266 variantBranches: "master-dirty", 267 createGitRepo: func(dir string) { 268 gitInit(t, dir). 269 write("source.go", "code"). 270 add("source.go"). 271 commit("initial"). 272 write("new.go", "new code") 273 }, 274 }, 275 { 276 description: "tag plus one commit", 277 variantTags: "v1-1-g3cec6b9", 278 variantCommitSha: "3cec6b950895704a8a69b610a199b242a3bd370f", 279 variantAbbrevCommitSha: "3cec6b9", 280 variantTreeSha: "81eea360f7f81bc5c187498a8d6c4337e0361374", 281 variantAbbrevTreeSha: "81eea36", 282 variantBranches: "master", 283 createGitRepo: func(dir string) { 284 gitInit(t, dir). 285 write("source.go", "code"). 286 add("source.go"). 287 commit("initial"). 288 tag("v1"). 289 write("source.go", "updated code"). 290 add("source.go"). 291 commit("changes") 292 }, 293 }, 294 { 295 description: "deleted file", 296 variantTags: "279d53f-dirty", 297 variantCommitSha: "279d53fcc3ae34503aec382a49a41f6db6de9a66-dirty", 298 variantAbbrevCommitSha: "279d53f-dirty", 299 variantTreeSha: "039c20a072ceb72fb72d5883315df91659bb8ae4-dirty", 300 variantAbbrevTreeSha: "039c20a-dirty", 301 variantBranches: "master-dirty", 302 createGitRepo: func(dir string) { 303 gitInit(t, dir). 304 write("source1.go", "code1"). 305 write("source2.go", "code2"). 306 add("source1.go", "source2.go"). 307 commit("initial"). 308 delete("source1.go") 309 }, 310 }, 311 { 312 description: "rename", 313 variantTags: "eefe1b9-dirty", 314 variantCommitSha: "eefe1b9c44eb0aa87199c9a079f2d48d8eb8baed-dirty", 315 variantAbbrevCommitSha: "eefe1b9-dirty", 316 variantTreeSha: "3bed02ca656e336307e4eb4d80080d7221cba62c-dirty", 317 variantAbbrevTreeSha: "3bed02c-dirty", 318 variantBranches: "master-dirty", 319 createGitRepo: func(dir string) { 320 gitInit(t, dir). 321 write("source.go", "code"). 322 add("source.go"). 323 commit("initial"). 324 rename("source.go", "source2.go") 325 }, 326 }, 327 { 328 description: "clean artifact1 in tagged repo", 329 variantTags: "v1", 330 variantCommitSha: "b610928dc27484cc56990bc77622aab0dbd67131", 331 variantAbbrevCommitSha: "b610928", 332 variantTreeSha: "3bed02ca656e336307e4eb4d80080d7221cba62c", 333 variantAbbrevTreeSha: "3bed02c", 334 variantBranches: "master", 335 createGitRepo: func(dir string) { 336 gitInit(t, dir). 337 mkdir("artifact1").write("artifact1/source.go", "code"). 338 mkdir("artifact2").write("artifact2/source.go", "other code"). 339 add("artifact1/source.go", "artifact2/source.go"). 340 commit("initial").tag("v1") 341 }, 342 subDir: "artifact1/", 343 }, 344 { 345 description: "clean artifact2 in tagged repo", 346 variantTags: "v1", 347 variantCommitSha: "b610928dc27484cc56990bc77622aab0dbd67131", 348 variantAbbrevCommitSha: "b610928", 349 variantTreeSha: "36651c832d8bf5ca1e84c6dc23bb8678fa51cf3e", 350 variantAbbrevTreeSha: "36651c8", 351 variantBranches: "master", 352 createGitRepo: func(dir string) { 353 gitInit(t, dir). 354 mkdir("artifact1").write("artifact1/source.go", "code"). 355 mkdir("artifact2").write("artifact2/source.go", "other code"). 356 add("artifact1/source.go", "artifact2/source.go"). 357 commit("initial").tag("v1") 358 }, 359 subDir: "artifact2", 360 }, 361 { 362 description: "clean artifact in dirty repo", 363 variantTags: "v1", 364 variantCommitSha: "b610928dc27484cc56990bc77622aab0dbd67131", 365 variantAbbrevCommitSha: "b610928", 366 variantTreeSha: "3bed02ca656e336307e4eb4d80080d7221cba62c", 367 variantAbbrevTreeSha: "3bed02c", 368 variantBranches: "master", 369 createGitRepo: func(dir string) { 370 gitInit(t, dir). 371 mkdir("artifact1").write("artifact1/source.go", "code"). 372 mkdir("artifact2").write("artifact2/source.go", "other code"). 373 add("artifact1/source.go", "artifact2/source.go"). 374 commit("initial").tag("v1"). 375 write("artifact2/source.go", "updated code") 376 }, 377 subDir: "artifact1", 378 }, 379 { 380 description: "updated artifact in dirty repo", 381 variantTags: "v1-dirty", 382 variantCommitSha: "b610928dc27484cc56990bc77622aab0dbd67131-dirty", 383 variantAbbrevCommitSha: "b610928-dirty", 384 variantTreeSha: "36651c832d8bf5ca1e84c6dc23bb8678fa51cf3e-dirty", 385 variantAbbrevTreeSha: "36651c8-dirty", 386 variantBranches: "master-dirty", 387 createGitRepo: func(dir string) { 388 gitInit(t, dir). 389 mkdir("artifact1").write("artifact1/source.go", "code"). 390 mkdir("artifact2").write("artifact2/source.go", "other code"). 391 add("artifact1/source.go", "artifact2/source.go"). 392 commit("initial").tag("v1"). 393 write("artifact2/source.go", "updated code") 394 }, 395 subDir: "artifact2", 396 }, 397 { 398 description: "additional commit in other artifact", 399 variantTags: "0d16f59", 400 variantCommitSha: "0d16f59900bd63dd39425d6085d3f1333b66804f", 401 variantAbbrevCommitSha: "0d16f59", 402 variantTreeSha: "3bed02ca656e336307e4eb4d80080d7221cba62c", 403 variantAbbrevTreeSha: "3bed02c", 404 variantBranches: "master", 405 createGitRepo: func(dir string) { 406 gitInit(t, dir). 407 mkdir("artifact1").write("artifact1/source.go", "code"). 408 mkdir("artifact2").write("artifact2/source.go", "other code"). 409 add("artifact1/source.go", "artifact2/source.go"). 410 commit("initial"). 411 write("artifact2/source.go", "updated code"). 412 add("artifact2/source.go"). 413 commit("update artifact2") 414 }, 415 subDir: "artifact1", 416 }, 417 { 418 description: "non git repo", 419 createGitRepo: func(dir string) { 420 ioutil.WriteFile(filepath.Join(dir, "source.go"), []byte("code"), os.ModePerm) 421 }, 422 shouldErr: true, 423 }, 424 { 425 description: "git repo with no commit", 426 variantBranches: "master", 427 createGitRepo: func(dir string) { 428 gitInit(t, dir) 429 }, 430 shouldErr: true, 431 }, 432 } 433 434 for _, test := range tests { 435 test := test 436 testutil.Run(t, test.description, func(t *testutil.T) { 437 t.Parallel() 438 439 tmpDir := t.NewTempDir() 440 test.createGitRepo(tmpDir.Root()) 441 442 image := latest.Artifact{ 443 ImageName: "test", 444 Workspace: tmpDir.Path(test.subDir), 445 } 446 447 for variant, expectedTag := range map[string]string{ 448 "Tags": test.variantTags, 449 "CommitSha": test.variantCommitSha, 450 "AbbrevCommitSha": test.variantAbbrevCommitSha, 451 "TreeSha": test.variantTreeSha, 452 "AbbrevTreeSha": test.variantAbbrevTreeSha, 453 "Branches": test.variantBranches, 454 } { 455 tagger, err := NewGitCommit("", variant, test.ignoreChanges) 456 t.CheckNoError(err) 457 458 tag, err := tagger.GenerateTag(context.Background(), image) 459 460 // If we explicitly expect a tag for a variant, it should not err 461 shouldErr := test.shouldErr && expectedTag == "" 462 t.CheckErrorAndDeepEqual(shouldErr, err, expectedTag, tag) 463 } 464 }) 465 } 466 } 467 468 func TestGitCommit_GenerateFullyQualifiedImageName(t *testing.T) { 469 tests := []struct { 470 description string 471 variantTags string 472 variantCommitSha string 473 variantAbbrevCommitSha string 474 variantTreeSha string 475 variantAbbrevTreeSha string 476 variantBranches string 477 createGitRepo func(string) 478 subDir string 479 shouldErr bool 480 }{ 481 { 482 description: "clean worktree without tag", 483 variantTags: "test:eefe1b9", 484 variantCommitSha: "test:eefe1b9c44eb0aa87199c9a079f2d48d8eb8baed", 485 variantAbbrevCommitSha: "test:eefe1b9", 486 variantTreeSha: "test:3bed02ca656e336307e4eb4d80080d7221cba62c", 487 variantAbbrevTreeSha: "test:3bed02c", 488 variantBranches: "test:master", 489 createGitRepo: func(dir string) { 490 gitInit(t, dir). 491 write("source.go", "code"). 492 add("source.go"). 493 commit("initial") 494 }, 495 }, 496 { 497 description: "non git repo", 498 createGitRepo: func(dir string) { 499 ioutil.WriteFile(filepath.Join(dir, "source.go"), []byte("code"), os.ModePerm) 500 }, 501 shouldErr: true, 502 }, 503 } 504 for _, test := range tests { 505 test := test 506 testutil.Run(t, test.description, func(t *testutil.T) { 507 tmpDir := t.NewTempDir() 508 test.createGitRepo(tmpDir.Root()) 509 image := latest.Artifact{ 510 ImageName: "test", 511 Workspace: tmpDir.Path(test.subDir), 512 } 513 514 for variant, expectedTag := range map[string]string{ 515 "Tags": test.variantTags, 516 "CommitSha": test.variantCommitSha, 517 "AbbrevCommitSha": test.variantAbbrevCommitSha, 518 "TreeSha": test.variantTreeSha, 519 "AbbrevTreeSha": test.variantAbbrevTreeSha, 520 "Branches": test.variantBranches, 521 } { 522 tagger, err := NewGitCommit("", variant, false) 523 t.CheckNoError(err) 524 525 tag, err := GenerateFullyQualifiedImageName(context.Background(), tagger, image) 526 527 t.CheckErrorAndDeepEqual(test.shouldErr, err, expectedTag, tag) 528 } 529 }) 530 } 531 } 532 533 func TestGitCommit_CustomTemplate(t *testing.T) { 534 gitCommitExample, _ := NewGitCommit("", "CommitSha", false) 535 tests := []struct { 536 description string 537 template string 538 customMap map[string]Tagger 539 expected string 540 createGitRepo func(string) 541 subDir string 542 }{ 543 { 544 description: "gitCommit component", 545 template: "{{.FOO}}", 546 customMap: map[string]Tagger{"FOO": gitCommitExample}, 547 expected: "eefe1b9c44eb0aa87199c9a079f2d48d8eb8baed", 548 createGitRepo: func(dir string) { 549 gitInit(t, dir). 550 write("source.go", "code"). 551 add("source.go"). 552 commit("initial") 553 }, 554 }, 555 { 556 description: "gitCommit default component", 557 template: "{{.GIT}}", 558 expected: "eefe1b9", 559 createGitRepo: func(dir string) { 560 gitInit(t, dir). 561 write("source.go", "code"). 562 add("source.go"). 563 commit("initial") 564 }, 565 }, 566 } 567 for _, test := range tests { 568 test := test 569 testutil.Run(t, test.description, func(t *testutil.T) { 570 tmpDir := t.NewTempDir() 571 test.createGitRepo(tmpDir.Root()) 572 image := latest.Artifact{ 573 ImageName: "test", 574 Workspace: tmpDir.Path(test.subDir), 575 } 576 577 c, err := NewCustomTemplateTagger(test.template, test.customMap) 578 579 t.CheckNoError(err) 580 581 tag, err := c.GenerateTag(context.Background(), image) 582 583 t.CheckNoError(err) 584 t.CheckDeepEqual(test.expected, tag) 585 }) 586 } 587 } 588 589 func TestGitCommitSubDirectory(t *testing.T) { 590 testutil.Run(t, "", func(t *testutil.T) { 591 tmpDir := t.NewTempDir() 592 gitInit(t.T, tmpDir.Root()).mkdir("sub/sub").commit("initial") 593 image := latest.Artifact{ 594 ImageName: "test", 595 Workspace: tmpDir.Path("sub/sub"), 596 } 597 598 tagger, err := NewGitCommit("", "Tags", false) 599 t.CheckNoError(err) 600 tag, err := tagger.GenerateTag(context.Background(), image) 601 t.CheckNoError(err) 602 t.CheckDeepEqual("a7b32a6", tag) 603 604 tagger, err = NewGitCommit("", "CommitSha", false) 605 t.CheckNoError(err) 606 tag, err = tagger.GenerateTag(context.Background(), image) 607 t.CheckNoError(err) 608 t.CheckDeepEqual("a7b32a69335a6daa51bd89cc1bf30bd31df228ba", tag) 609 610 tagger, err = NewGitCommit("", "AbbrevCommitSha", false) 611 t.CheckNoError(err) 612 tag, err = tagger.GenerateTag(context.Background(), image) 613 t.CheckNoError(err) 614 t.CheckDeepEqual("a7b32a6", tag) 615 616 tagger, err = NewGitCommit("", "TreeSha", false) 617 t.CheckNoError(err) 618 _, err = tagger.GenerateTag(context.Background(), image) 619 t.CheckErrorAndDeepEqual(true, err, "a7b32a6", tag) 620 621 tagger, err = NewGitCommit("", "AbbrevTreeSha", false) 622 t.CheckNoError(err) 623 _, err = tagger.GenerateTag(context.Background(), image) 624 t.CheckErrorAndDeepEqual(true, err, "a7b32a6", tag) 625 }) 626 } 627 628 func TestPrefix(t *testing.T) { 629 testutil.Run(t, "", func(t *testutil.T) { 630 tmpDir := t.NewTempDir() 631 gitInit(t.T, tmpDir.Root()).commit("initial") 632 image := latest.Artifact{ 633 ImageName: "test", 634 Workspace: tmpDir.Path("."), 635 } 636 637 tagger, err := NewGitCommit("tag-", "Tags", false) 638 t.CheckNoError(err) 639 tag, err := tagger.GenerateTag(context.Background(), image) 640 t.CheckNoError(err) 641 t.CheckDeepEqual("tag-a7b32a6", tag) 642 643 tagger, err = NewGitCommit("commit-", "CommitSha", false) 644 t.CheckNoError(err) 645 tag, err = tagger.GenerateTag(context.Background(), image) 646 t.CheckNoError(err) 647 t.CheckDeepEqual("commit-a7b32a69335a6daa51bd89cc1bf30bd31df228ba", tag) 648 }) 649 } 650 651 func TestInvalidVariant(t *testing.T) { 652 testutil.Run(t, "", func(t *testutil.T) { 653 _, err := NewGitCommit("", "Invalid", false) 654 655 t.CheckErrorContains("\"Invalid\" is not a valid git tagger variant", err) 656 }) 657 } 658 659 func TestSanitizeTag(t *testing.T) { 660 testutil.Run(t, "valid tags", func(t *testutil.T) { 661 t.CheckDeepEqual("abcdefghijklmnopqrstuvwxyz", sanitizeTag("abcdefghijklmnopqrstuvwxyz")) 662 t.CheckDeepEqual("ABCDEFGHIJKLMNOPQRSTUVWXYZ", sanitizeTag("ABCDEFGHIJKLMNOPQRSTUVWXYZ")) 663 t.CheckDeepEqual("0123456789-_.", sanitizeTag("0123456789-_.")) 664 t.CheckDeepEqual("_v1", sanitizeTag("_v1")) 665 }) 666 667 testutil.Run(t, "sanitized tags", func(t *testutil.T) { 668 t.CheckDeepEqual("v_1", sanitizeTag("v/1")) 669 t.CheckDeepEqual("v____1", sanitizeTag("v%$@!1")) 670 t.CheckDeepEqual("__v1", sanitizeTag("--v1")) 671 t.CheckDeepEqual("__v1", sanitizeTag("..v1")) 672 t.CheckDeepEqual(128, len(sanitizeTag(strings.Repeat("0123456789", 20)))) 673 }) 674 } 675 676 // gitRepo deals with test git repositories 677 type gitRepo struct { 678 dir string 679 repo *git.Repository 680 workTree *git.Worktree 681 t *testing.T 682 } 683 684 func gitInit(t *testing.T, dir string) *gitRepo { 685 repo, err := git.PlainInit(dir, false) 686 failNowIfError(t, err) 687 688 w, err := repo.Worktree() 689 failNowIfError(t, err) 690 691 return &gitRepo{ 692 dir: dir, 693 repo: repo, 694 workTree: w, 695 t: t, 696 } 697 } 698 699 func (g *gitRepo) mkdir(folder string) *gitRepo { 700 err := os.MkdirAll(filepath.Join(g.dir, folder), os.ModePerm) 701 failNowIfError(g.t, err) 702 return g 703 } 704 705 func (g *gitRepo) write(file string, content string) *gitRepo { 706 err := ioutil.WriteFile(filepath.Join(g.dir, file), []byte(content), os.ModePerm) 707 failNowIfError(g.t, err) 708 return g 709 } 710 711 func (g *gitRepo) rename(file, to string) *gitRepo { 712 err := os.Rename(filepath.Join(g.dir, file), filepath.Join(g.dir, to)) 713 failNowIfError(g.t, err) 714 return g 715 } 716 717 func (g *gitRepo) delete(files ...string) *gitRepo { 718 for _, file := range files { 719 err := os.Remove(filepath.Join(g.dir, file)) 720 failNowIfError(g.t, err) 721 } 722 return g 723 } 724 725 func (g *gitRepo) add(files ...string) *gitRepo { 726 for _, file := range files { 727 _, err := g.workTree.Add(file) 728 failNowIfError(g.t, err) 729 } 730 return g 731 } 732 733 func (g *gitRepo) commit(msg string) *gitRepo { 734 now, err := time.Parse("Jan 2, 2006 at 15:04:05 -0700 MST", "Feb 3, 2013 at 19:54:00 -0700 MST") 735 failNowIfError(g.t, err) 736 737 _, err = g.workTree.Commit(msg, &git.CommitOptions{ 738 AllowEmptyCommits: true, 739 Author: &object.Signature{ 740 Name: "John Doe", 741 Email: "john@doe.org", 742 When: now, 743 }, 744 }) 745 failNowIfError(g.t, err) 746 747 return g 748 } 749 750 func (g *gitRepo) tag(tag string) *gitRepo { 751 head, err := g.repo.Head() 752 failNowIfError(g.t, err) 753 754 n := plumbing.ReferenceName("refs/tags/" + tag) 755 t := plumbing.NewHashReference(n, head.Hash()) 756 757 err = g.repo.Storer.SetReference(t) 758 failNowIfError(g.t, err) 759 760 return g 761 } 762 763 func (g *gitRepo) branch(newBranchName string) *gitRepo { 764 refName := plumbing.NewBranchReferenceName(newBranchName) 765 headRef, err := g.repo.Head() 766 failNowIfError(g.t, err) 767 ref := plumbing.NewHashReference(refName, headRef.Hash()) 768 err = g.repo.Storer.SetReference(ref) 769 failNowIfError(g.t, err) 770 771 err = g.workTree.Checkout(&git.CheckoutOptions{Branch: ref.Name()}) 772 failNowIfError(g.t, err) 773 774 return g 775 } 776 777 func failNowIfError(t *testing.T, err error) { 778 if err != nil { 779 t.Fatal(err) 780 } 781 }