github.com/goreleaser/nfpm/v2@v2.44.0/apk/apk_test.go (about) 1 package apk 2 3 import ( 4 "archive/tar" 5 "bytes" 6 "compress/gzip" 7 "crypto/sha1" // nolint:gosec 8 "crypto/sha256" 9 "errors" 10 "flag" 11 "fmt" 12 "io" 13 "os" 14 "path" 15 "path/filepath" 16 "testing" 17 18 "github.com/goreleaser/nfpm/v2" 19 "github.com/goreleaser/nfpm/v2/files" 20 "github.com/goreleaser/nfpm/v2/internal/sign" 21 "github.com/stretchr/testify/require" 22 ) 23 24 // nolint: gochecknoglobals 25 var update = flag.Bool("update", false, "update apk .golden files") 26 27 func exampleInfo() *nfpm.Info { 28 return nfpm.WithDefaults(&nfpm.Info{ 29 Name: "foo", 30 Arch: "amd64", 31 Description: "Foo does things", 32 Priority: "extra", 33 Maintainer: "Carlos A Becker <pkg@carlosbecker.com>", 34 Version: "v1.0.0", 35 Prerelease: "beta1", 36 Release: "r1", 37 Section: "default", 38 Homepage: "http://carlosbecker.com", 39 Vendor: "nope", 40 Overridables: nfpm.Overridables{ 41 Depends: []string{ 42 "bash", 43 "foo", 44 }, 45 Recommends: []string{ 46 "git", 47 "bar", 48 }, 49 Suggests: []string{ 50 "bash", 51 "lala", 52 }, 53 Replaces: []string{ 54 "svn", 55 "subversion", 56 }, 57 Provides: []string{ 58 "bzr", 59 "zzz", 60 }, 61 Conflicts: []string{ 62 "zsh", 63 "foobarsh", 64 }, 65 Contents: []*files.Content{ 66 { 67 Source: "../testdata/fake", 68 Destination: "/usr/bin/fake", 69 }, 70 { 71 Source: "../testdata/whatever.conf", 72 Destination: "/usr/share/doc/fake/fake.txt", 73 }, 74 { 75 Source: "../testdata/whatever.conf", 76 Destination: "/etc/fake/fake.conf", 77 Type: files.TypeConfig, 78 }, 79 { 80 Source: "../testdata/whatever.conf", 81 Destination: "/etc/fake/fake2.conf", 82 Type: files.TypeConfigNoReplace, 83 }, 84 { 85 Source: "../testdata/whatever.conf", 86 Destination: "/etc/fake/fake3.conf", 87 Type: files.TypeConfigMissingOK, 88 }, 89 { 90 Destination: "/var/log/whatever", 91 Type: files.TypeDir, 92 }, 93 { 94 Destination: "/usr/share/whatever", 95 Type: files.TypeDir, 96 }, 97 }, 98 }, 99 }) 100 } 101 102 func TestConventionalExtension(t *testing.T) { 103 require.Equal(t, ".apk", Default.ConventionalExtension()) 104 } 105 106 func TestCreateBuilderData(t *testing.T) { 107 info := exampleInfo() 108 require.NoError(t, nfpm.PrepareForPackager(info, "apk")) 109 size := int64(0) 110 builderData := createBuilderData(info, &size) 111 112 var buf bytes.Buffer 113 tw := tar.NewWriter(&buf) 114 115 require.NoError(t, builderData(tw)) 116 117 require.Equal(t, 15872, buf.Len(), buf.String()) 118 } 119 120 func TestCombineToApk(t *testing.T) { 121 var bufData bytes.Buffer 122 bufData.Write([]byte{1}) 123 124 var bufControl bytes.Buffer 125 bufControl.Write([]byte{2}) 126 127 var bufTarget bytes.Buffer 128 129 require.NoError(t, combineToApk(&bufTarget, &bufData, &bufControl)) 130 require.Equal(t, 2, bufTarget.Len()) 131 } 132 133 func TestDefaultWithArch(t *testing.T) { 134 expectedChecksums := map[string]string{ 135 "usr/share/doc/fake/fake.txt": "96c335dc28122b5f09a4cef74b156cd24c23784c", 136 "usr/bin/fake": "f46cece3eeb7d9ed5cb244d902775427be71492d", 137 "etc/fake/fake.conf": "96c335dc28122b5f09a4cef74b156cd24c23784c", 138 "etc/fake/fake2.conf": "96c335dc28122b5f09a4cef74b156cd24c23784c", 139 "etc/fake/fake3.conf": "96c335dc28122b5f09a4cef74b156cd24c23784c", 140 } 141 for _, arch := range []string{"386", "amd64"} { 142 arch := arch 143 t.Run(arch, func(t *testing.T) { 144 info := exampleInfo() 145 info.Arch = arch 146 147 var f bytes.Buffer 148 require.NoError(t, Default.Package(info, &f)) 149 150 gz, err := gzip.NewReader(&f) 151 require.NoError(t, err) 152 defer gz.Close() 153 tr := tar.NewReader(gz) 154 155 for { 156 hdr, err := tr.Next() 157 if errors.Is(err, io.EOF) { 158 break // End of archive 159 } 160 require.NoError(t, err) 161 162 require.Equal(t, expectedChecksums[hdr.Name], hdr.PAXRecords["APK-TOOLS.checksum.SHA1"], hdr.Name) 163 } 164 }) 165 } 166 } 167 168 func TestApkPlatform(t *testing.T) { 169 f, err := os.CreateTemp(t.TempDir(), "test*.apk") 170 require.NoError(t, err) 171 t.Cleanup(func() { require.NoError(t, f.Close()) }) 172 info := exampleInfo() 173 info.Platform = "darwin" 174 err = Default.Package(info, f) 175 require.Error(t, err) 176 } 177 178 func TestNoInfo(t *testing.T) { 179 err := Default.Package(nfpm.WithDefaults(&nfpm.Info{}), io.Discard) 180 require.Error(t, err) 181 } 182 183 func TestFileDoesNotExist(t *testing.T) { 184 abs, err := filepath.Abs("../testdata/whatever.confzzz") 185 require.NoError(t, err) 186 err = Default.Package( 187 nfpm.WithDefaults(&nfpm.Info{ 188 Name: "foo", 189 Arch: "amd64", 190 Description: "Foo does things", 191 Priority: "extra", 192 Maintainer: "Carlos A Becker <pkg@carlosbecker.com>", 193 Version: "1.0.0", 194 Section: "default", 195 Homepage: "http://carlosbecker.com", 196 Vendor: "nope", 197 Overridables: nfpm.Overridables{ 198 Depends: []string{ 199 "bash", 200 }, 201 Contents: []*files.Content{ 202 { 203 Source: "../testdata/fake", 204 Destination: "/usr/bin/fake", 205 }, 206 { 207 Source: "../testdata/whatever.confzzz", 208 Destination: "/etc/fake/fake.conf", 209 Type: files.TypeConfig, 210 }, 211 }, 212 }, 213 }), 214 io.Discard, 215 ) 216 require.EqualError(t, err, fmt.Sprintf("matching \"%s\": file does not exist", filepath.ToSlash(abs))) 217 } 218 219 func TestNoFiles(t *testing.T) { 220 err := Default.Package( 221 nfpm.WithDefaults(&nfpm.Info{ 222 Name: "foo", 223 Arch: "amd64", 224 Description: "Foo does things", 225 Priority: "extra", 226 Maintainer: "Carlos A Becker <pkg@carlosbecker.com>", 227 Version: "1.0.0", 228 Section: "default", 229 Homepage: "http://carlosbecker.com", 230 Vendor: "nope", 231 Overridables: nfpm.Overridables{ 232 Depends: []string{ 233 "bash", 234 }, 235 }, 236 }), 237 io.Discard, 238 ) 239 require.NoError(t, err) 240 } 241 242 func TestCreateBuilderControl(t *testing.T) { 243 info := exampleInfo() 244 size := int64(12345) 245 err := nfpm.PrepareForPackager(info, "apk") 246 require.NoError(t, err) 247 builderControl := createBuilderControl(info, size, sha256.New().Sum(nil)) 248 249 var w bytes.Buffer 250 tw := tar.NewWriter(&w) 251 require.NoError(t, builderControl(tw)) 252 253 control := string(extractFromTar(t, w.Bytes(), ".PKGINFO")) 254 golden := "testdata/TestCreateBuilderControl.golden" 255 if *update { 256 require.NoError(t, os.WriteFile(golden, []byte(control), 0o655)) // nolint: gosec 257 } 258 bts, err := os.ReadFile(golden) //nolint:gosec 259 require.NoError(t, err) 260 require.Equal(t, string(bts), control) 261 } 262 263 func TestCreateBuilderControlScripts(t *testing.T) { 264 info := exampleInfo() 265 info.Scripts = nfpm.Scripts{ 266 PreInstall: "../testdata/scripts/preinstall.sh", 267 PostInstall: "../testdata/scripts/postinstall.sh", 268 PreRemove: "../testdata/scripts/preremove.sh", 269 PostRemove: "../testdata/scripts/postremove.sh", 270 } 271 info.APK.Scripts = nfpm.APKScripts{ 272 PreUpgrade: "../testdata/scripts/preupgrade.sh", 273 PostUpgrade: "../testdata/scripts/postupgrade.sh", 274 } 275 err := nfpm.PrepareForPackager(info, "apk") 276 require.NoError(t, err) 277 278 size := int64(12345) 279 builderControl := createBuilderControl(info, size, sha256.New().Sum(nil)) 280 281 var w bytes.Buffer 282 tw := tar.NewWriter(&w) 283 require.NoError(t, builderControl(tw)) 284 285 control := string(extractFromTar(t, w.Bytes(), ".PKGINFO")) 286 golden := "testdata/TestCreateBuilderControlScripts.golden" 287 if *update { 288 require.NoError(t, os.WriteFile(golden, []byte(control), 0o655)) // nolint: gosec 289 } 290 bts, err := os.ReadFile(golden) //nolint:gosec 291 require.NoError(t, err) 292 require.Equal(t, string(bts), control) 293 294 // Validate scripts are correct 295 script := string(extractFromTar(t, w.Bytes(), ".pre-install")) 296 require.Contains(t, script, `echo "Preinstall" > /dev/null`) 297 script = string(extractFromTar(t, w.Bytes(), ".post-install")) 298 require.Contains(t, script, `echo "Postinstall" > /dev/null`) 299 script = string(extractFromTar(t, w.Bytes(), ".pre-upgrade")) 300 require.Contains(t, script, `echo "PreUpgrade" > /dev/null`) 301 script = string(extractFromTar(t, w.Bytes(), ".post-upgrade")) 302 require.Contains(t, script, `echo "PostUpgrade" > /dev/null`) 303 script = string(extractFromTar(t, w.Bytes(), ".pre-deinstall")) 304 require.Contains(t, script, `echo "Preremove" > /dev/null`) 305 script = string(extractFromTar(t, w.Bytes(), ".post-deinstall")) 306 require.Contains(t, script, `echo "Postremove" > /dev/null`) 307 } 308 309 func TestControl(t *testing.T) { 310 var w bytes.Buffer 311 require.NoError(t, writeControl(&w, controlData{ 312 Info: exampleInfo(), 313 InstalledSize: 10, 314 })) 315 golden := "testdata/TestControl.golden" 316 if *update { 317 require.NoError(t, os.WriteFile(golden, w.Bytes(), 0o655)) // nolint: gosec 318 } 319 bts, err := os.ReadFile(golden) //nolint:gosec 320 require.NoError(t, err) 321 require.Equal(t, string(bts), w.String()) 322 } 323 324 func TestSignatureName(t *testing.T) { 325 info := exampleInfo() 326 info.APK.Signature.KeyFile = "../internal/sign/testdata/rsa.priv" 327 info.APK.Signature.KeyName = "testkey" 328 info.APK.Signature.KeyPassphrase = "hunter2" 329 err := nfpm.PrepareForPackager(info, "apk") 330 require.NoError(t, err) 331 332 digest := sha1.New().Sum(nil) // nolint:gosec 333 334 var signatureTarGz bytes.Buffer 335 tw := tar.NewWriter(&signatureTarGz) 336 require.NoError(t, createSignatureBuilder(digest, info)(tw)) 337 338 signature := extractFromTar(t, signatureTarGz.Bytes(), ".SIGN.RSA.testkey.rsa.pub") 339 err = sign.RSAVerifySHA1Digest(digest, signature, "../internal/sign/testdata/rsa.pub") 340 require.NoError(t, err) 341 342 err = Default.Package(info, io.Discard) 343 require.NoError(t, err) 344 } 345 346 func TestSignature(t *testing.T) { 347 info := exampleInfo() 348 info.APK.Signature.KeyFile = "../internal/sign/testdata/rsa.priv" 349 info.APK.Signature.KeyName = "testkey.rsa.pub" 350 info.APK.Signature.KeyPassphrase = "hunter2" 351 err := nfpm.PrepareForPackager(info, "apk") 352 require.NoError(t, err) 353 354 digest := sha1.New().Sum(nil) // nolint:gosec 355 356 var signatureTarGz bytes.Buffer 357 tw := tar.NewWriter(&signatureTarGz) 358 require.NoError(t, createSignatureBuilder(digest, info)(tw)) 359 360 signature := extractFromTar(t, signatureTarGz.Bytes(), ".SIGN.RSA.testkey.rsa.pub") 361 err = sign.RSAVerifySHA1Digest(digest, signature, "../internal/sign/testdata/rsa.pub") 362 require.NoError(t, err) 363 364 err = Default.Package(info, io.Discard) 365 require.NoError(t, err) 366 } 367 368 func TestSignatureError(t *testing.T) { 369 info := exampleInfo() 370 info.APK.Signature.KeyFile = "../internal/sign/testdata/rsa.priv" 371 info.APK.Signature.KeyName = "testkey.rsa.pub" 372 info.APK.Signature.KeyPassphrase = "hunter2" 373 err := nfpm.PrepareForPackager(info, "apk") 374 require.NoError(t, err) 375 376 // wrong hash format 377 digest := sha256.New().Sum(nil) 378 379 var signatureTarGz bytes.Buffer 380 381 err = createSignature(&signatureTarGz, info, digest) 382 require.Error(t, err) 383 384 var expectedError *nfpm.ErrSigningFailure 385 require.ErrorAs(t, err, &expectedError) 386 387 info.APK.Signature.KeyName = "" 388 info.Maintainer = "" 389 digest = sha1.New().Sum(nil) // nolint:gosec 390 err = createSignature(&signatureTarGz, info, digest) 391 require.ErrorAs(t, err, &expectedError) 392 } 393 394 func TestSignatureCallback(t *testing.T) { 395 info := exampleInfo() 396 info.APK.Signature.SignFn = func(r io.Reader) ([]byte, error) { 397 digest, err := io.ReadAll(r) 398 if err != nil { 399 return nil, err 400 } 401 return sign.RSASignSHA1Digest(digest, "../internal/sign/testdata/rsa.priv", "hunter2") 402 } 403 info.APK.Signature.KeyName = "testkey.rsa.pub" 404 err := nfpm.PrepareForPackager(info, "apk") 405 require.NoError(t, err) 406 407 digest := sha1.New().Sum(nil) // nolint:gosec 408 409 var signatureTarGz bytes.Buffer 410 tw := tar.NewWriter(&signatureTarGz) 411 require.NoError(t, createSignatureBuilder(digest, info)(tw)) 412 413 signature := extractFromTar(t, signatureTarGz.Bytes(), ".SIGN.RSA.testkey.rsa.pub") 414 err = sign.RSAVerifySHA1Digest(digest, signature, "../internal/sign/testdata/rsa.pub") 415 require.NoError(t, err) 416 417 err = Default.Package(info, io.Discard) 418 require.NoError(t, err) 419 } 420 421 func TestDisableGlobbing(t *testing.T) { 422 info := exampleInfo() 423 info.DisableGlobbing = true 424 info.Contents = []*files.Content{ 425 { 426 Source: "../testdata/{file}[", 427 Destination: "/test/{file}[", 428 }, 429 } 430 err := nfpm.PrepareForPackager(info, "apk") 431 require.NoError(t, err) 432 433 size := int64(0) 434 var dataTarGz bytes.Buffer 435 _, err = createData(&dataTarGz, info, &size) 436 require.NoError(t, err) 437 438 gzr, err := gzip.NewReader(&dataTarGz) 439 require.NoError(t, err) 440 dataTar, err := io.ReadAll(gzr) 441 require.NoError(t, err) 442 443 extractedContent := extractFromTar(t, dataTar, "test/{file}[") 444 actualContent, err := os.ReadFile("../testdata/{file}[") 445 require.NoError(t, err) 446 require.Equal(t, actualContent, extractedContent) 447 } 448 449 func extractFromTar(t *testing.T, tarFile []byte, fileName string) []byte { 450 t.Helper() 451 452 tr := tar.NewReader(bytes.NewReader(tarFile)) 453 454 for { 455 hdr, err := tr.Next() 456 if errors.Is(err, io.EOF) { 457 break 458 } 459 require.NoError(t, err) 460 461 if hdr.Name != fileName { 462 continue 463 } 464 465 data, err := io.ReadAll(tr) 466 require.NoError(t, err) 467 return data 468 } 469 470 t.Fatalf("file %q not found in tar file", fileName) 471 return nil 472 } 473 474 func tarContents(tb testing.TB, tarFile []byte) []string { 475 tb.Helper() 476 477 contents := []string{} 478 479 tr := tar.NewReader(bytes.NewReader(tarFile)) 480 for { 481 hdr, err := tr.Next() 482 if errors.Is(err, io.EOF) { 483 break // End of archive 484 } 485 require.NoError(tb, err) 486 487 contents = append(contents, hdr.Name) 488 } 489 490 return contents 491 } 492 493 func TestAPKConventionalFileName(t *testing.T) { 494 apkName := "default" 495 testCases := []struct { 496 Arch string 497 Version string 498 Meta string 499 Release string 500 Prerelease string 501 Expect string 502 }{ 503 { 504 Arch: "amd64", Version: "1.2.3", 505 Expect: "default_1.2.3_x86_64.apk", 506 }, 507 { 508 Arch: "386", Version: "1.2.3", Meta: "git", 509 Expect: "default_1.2.3-git_x86.apk", 510 }, 511 { 512 Arch: "386", Version: "1.2.3", Meta: "1", Release: "10", 513 Expect: "default_1.2.3-r10-p1_x86.apk", 514 }, 515 { 516 Arch: "386", Version: "1.2.3", Prerelease: "git", Release: "1", 517 Expect: "default_1.2.3_git-r1_x86.apk", 518 }, 519 { 520 Arch: "all", Version: "1.2.3", 521 Expect: "default_1.2.3_all.apk", 522 }, 523 { 524 Arch: "386", Version: "1.2.3", Release: "1", Prerelease: "beta1", 525 Expect: "default_1.2.3_beta1-r1_x86.apk", 526 }, 527 { 528 Arch: "amd64", Version: "1.2.3a", Prerelease: "alpha1", Release: "47", Meta: "git-aaaccc", 529 Expect: "default_1.2.3a_alpha1-r47-git-aaaccc_x86_64.apk", 530 }, 531 } 532 533 for _, testCase := range testCases { 534 info := &nfpm.Info{ 535 Name: apkName, 536 Arch: testCase.Arch, 537 Version: testCase.Version, 538 VersionMetadata: testCase.Meta, 539 Release: testCase.Release, 540 Prerelease: testCase.Prerelease, 541 } 542 require.Equal(t, testCase.Expect, Default.ConventionalFileName(info)) 543 } 544 } 545 546 func TestPackageSymlinks(t *testing.T) { 547 info := exampleInfo() 548 info.Contents = []*files.Content{ 549 { 550 Source: "../testdata/fake", 551 Destination: "fake", 552 Type: files.TypeSymlink, 553 }, 554 } 555 require.NoError(t, Default.Package(info, io.Discard)) 556 } 557 558 func TestDirectories(t *testing.T) { 559 info := exampleInfo() 560 info.Contents = []*files.Content{ 561 { 562 Source: "../testdata/whatever.conf", 563 Destination: "/etc/foo/file", 564 }, 565 { 566 Source: "../testdata/whatever.conf", 567 Destination: "/etc/bar/file", 568 }, 569 { 570 Destination: "/etc/bar", 571 Type: files.TypeDir, 572 FileInfo: &files.ContentFileInfo{ 573 Owner: "test", 574 Mode: 0o700, 575 }, 576 }, 577 { 578 Destination: "/etc/baz", 579 Type: files.TypeDir, 580 }, 581 { 582 Destination: "/usr/lib/something/somethingelse", 583 Type: files.TypeDir, 584 }, 585 } 586 587 require.NoError(t, nfpm.PrepareForPackager(info, "apk")) 588 589 var buf bytes.Buffer 590 size := int64(0) 591 err := createFilesInsideTarGz(info, tar.NewWriter(&buf), &size) 592 require.NoError(t, err) 593 594 require.Equal(t, []string{ 595 "etc/", 596 "etc/bar/", 597 "etc/bar/file", 598 "etc/baz/", 599 "etc/foo/", 600 "etc/foo/file", 601 "usr/", 602 "usr/lib/", 603 "usr/lib/something/", 604 "usr/lib/something/somethingelse/", 605 }, getTree(t, buf.Bytes())) 606 607 // for apks all implicit or explicit directories are created in the tarball 608 h := extractFileHeaderFromTar(t, buf.Bytes(), "/etc") 609 require.Equal(t, h.Typeflag, byte(tar.TypeDir)) 610 h = extractFileHeaderFromTar(t, buf.Bytes(), "/etc/foo") 611 require.Equal(t, h.Typeflag, byte(tar.TypeDir)) 612 h = extractFileHeaderFromTar(t, buf.Bytes(), "/etc/bar") 613 require.Equal(t, h.Typeflag, byte(tar.TypeDir)) 614 require.Equal(t, int64(0o700), h.Mode) 615 require.Equal(t, "test", h.Uname) 616 h = extractFileHeaderFromTar(t, buf.Bytes(), "/etc/baz") 617 require.Equal(t, h.Typeflag, byte(tar.TypeDir)) 618 } 619 620 func TestNoDuplicateAutocreatedDirectories(t *testing.T) { 621 info := exampleInfo() 622 info.DisableGlobbing = true 623 info.Contents = []*files.Content{ 624 { 625 Source: "../testdata/fake", 626 Destination: "/etc/foo/bar", 627 }, 628 { 629 Type: files.TypeDir, 630 Destination: "/etc/foo", 631 }, 632 } 633 require.NoError(t, nfpm.PrepareForPackager(info, "apk")) 634 635 expected := map[string]bool{ 636 "etc/": true, 637 "etc/foo/": true, 638 "etc/foo/bar": true, 639 } 640 641 var buf bytes.Buffer 642 size := int64(0) 643 err := createFilesInsideTarGz(info, tar.NewWriter(&buf), &size) 644 require.NoError(t, err) 645 646 contents := tarContents(t, buf.Bytes()) 647 648 if len(expected) != len(contents) { 649 t.Fatalf("contents has %d entries instead of %d: %#v", len(contents), len(expected), contents) 650 } 651 652 for _, entry := range contents { 653 if !expected[entry] { 654 t.Fatalf("unexpected content: %q", entry) 655 } 656 } 657 } 658 659 func TestNoDuplicateDirectories(t *testing.T) { 660 info := exampleInfo() 661 info.DisableGlobbing = true 662 info.Contents = []*files.Content{ 663 { 664 Type: files.TypeDir, 665 Destination: "/etc/foo", 666 }, 667 { 668 Type: files.TypeDir, 669 Destination: "/etc/foo/", 670 }, 671 } 672 require.Error(t, nfpm.PrepareForPackager(info, "apk")) 673 } 674 675 func TestNoDuplicateContents(t *testing.T) { 676 info := exampleInfo() 677 info.Contents = []*files.Content{ 678 { 679 Source: "../testdata/whatever.conf", 680 Destination: "/etc/foo/file", 681 }, 682 { 683 Source: "../testdata/whatever.conf", 684 Destination: "/etc/bar/file", 685 }, 686 { 687 Destination: "/etc/bar", 688 Type: files.TypeDir, 689 FileInfo: &files.ContentFileInfo{ 690 Owner: "test", 691 Mode: 0o700, 692 }, 693 }, 694 { 695 Destination: "/etc/baz", 696 Type: files.TypeDir, 697 }, 698 } 699 700 require.NoError(t, nfpm.PrepareForPackager(info, "apk")) 701 702 var buf bytes.Buffer 703 size := int64(0) 704 err := createFilesInsideTarGz(info, tar.NewWriter(&buf), &size) 705 require.NoError(t, err) 706 707 exists := map[string]bool{} 708 709 tr := tar.NewReader(bytes.NewReader(buf.Bytes())) 710 for { 711 hdr, err := tr.Next() 712 if errors.Is(err, io.EOF) { 713 break // End of archive 714 } 715 require.NoError(t, err) 716 717 _, ok := exists[hdr.Name] 718 if ok { 719 t.Fatalf("%s exists more than once in tarball", hdr.Name) 720 } 721 722 exists[hdr.Name] = true 723 } 724 } 725 726 func extractFileHeaderFromTar(tb testing.TB, tarFile []byte, filename string) *tar.Header { 727 tb.Helper() 728 729 tr := tar.NewReader(bytes.NewReader(tarFile)) 730 for { 731 hdr, err := tr.Next() 732 if errors.Is(err, io.EOF) { 733 break // End of archive 734 } 735 require.NoError(tb, err) 736 737 if path.Join("/", hdr.Name) != path.Join("/", filename) { // nolint:gosec 738 continue 739 } 740 741 return hdr 742 } 743 744 tb.Fatalf("file %q does not exist in tar", filename) 745 746 return nil 747 } 748 749 func getTree(tb testing.TB, tarFile []byte) []string { 750 tb.Helper() 751 752 var result []string 753 tr := tar.NewReader(bytes.NewReader(tarFile)) 754 for { 755 hdr, err := tr.Next() 756 if errors.Is(err, io.EOF) { 757 break // End of archive 758 } 759 require.NoError(tb, err) 760 761 result = append(result, hdr.Name) 762 } 763 764 return result 765 } 766 767 func TestArches(t *testing.T) { 768 for k := range archToAlpine { 769 t.Run(k, func(t *testing.T) { 770 info := exampleInfo() 771 info.Arch = k 772 info = ensureValidArch(info) 773 require.Equal(t, archToAlpine[k], info.Arch) 774 }) 775 } 776 777 t.Run("override", func(t *testing.T) { 778 info := exampleInfo() 779 info.APK.Arch = "foo64" 780 info = ensureValidArch(info) 781 require.Equal(t, "foo64", info.Arch) 782 }) 783 } 784 785 func TestGlob(t *testing.T) { 786 require.NoError(t, Default.Package(nfpm.WithDefaults(&nfpm.Info{ 787 Name: "nfpm-repro", 788 Version: "1.0.0", 789 Maintainer: "asdfasdf", 790 791 Overridables: nfpm.Overridables{ 792 Contents: files.Contents{ 793 { 794 Destination: "/usr/share/nfpm-repro", 795 Source: "../files/*", 796 }, 797 }, 798 }, 799 }), io.Discard)) 800 }