package pkglint import "gopkg.in/check.v1" func (s *Suite) Test_CheckLinesDistinfo__parse_errors(c *check.C) { t := s.Init(c) t.Chdir("category/package") t.CreateFileLines("patches/patch-aa", CvsID+" line is ignored for computing the SHA1 hash", "patch contents") t.CreateFileLines("patches/patch-ab", "patch contents") lines := t.SetUpFileLines("distinfo", "should be the CVS ID", "should be empty", "MD5 (distfile-1.0.tar.gz) = 12345678901234567890123456789012", "SHA1 (distfile-1.0.tar.gz) = 1234567890123456789012345678901234567890", "SHA1 (patch-aa) = 6b98dd609f85a9eb9c4c1e4e7055a6aaa62b7cc7", "Size (patch-aa) = 104", "SHA1 (patch-ab) = 6b98dd609f85a9eb9c4c1e4e7055a6aaa62b7cc7", "Another invalid line", "SHA1 (patch-nonexistent) = 1234") pkg := NewPackage(".") CheckLinesDistinfo(pkg, lines) t.CheckOutputLines( "ERROR: distinfo:1: Expected \"$"+"NetBSD$\".", "NOTE: distinfo:1: Empty line expected above this line.", "ERROR: distinfo:1: Invalid line: should be the CVS ID", "ERROR: distinfo:2: Invalid line: should be empty", "ERROR: distinfo:8: Invalid line: Another invalid line", "ERROR: distinfo:3: Expected BLAKE2s, SHA512, Size checksums for \"distfile-1.0.tar.gz\", got MD5, SHA1.", "ERROR: distinfo:5: Expected SHA1 hash for patch-aa, got SHA1, Size.", "WARN: distinfo:9: Patch file \"patch-nonexistent\" does not exist in directory \"patches\".") } func (s *Suite) Test_CheckLinesDistinfo__DISTINFO_FILE(c *check.C) { t := s.Init(c) t.SetUpPackage("category/package", "DISTINFO_FILE=\t${.CURDIR}/../../category/package/distinfo", "PATCHDIR=\t${.CURDIR}/../../category/package/patches") t.Chdir("category/package") t.CreateFileDummyPatch("patches/patch-dummy_txt") t.CreateFileLines("patches/CVS/Entries", "/other/1.1/modified//") t.CreateFileLines("distinfo", CvsID, "", "SHA1 (patch-dummy_txt) = 2388e84518db54eaa827c68f191d9a87e90f7f00") t.CreateFileLines("CVS/Entries", "/distinfo/1.1/modified//") t.FinishSetUp() G.Check(".") t.CheckOutputLines( "WARN: distinfo:3: ../../category/package/patches/patch-dummy_txt " + "is registered in distinfo but not added to CVS.") } func (s *Suite) Test_distinfoLinesChecker_parse__trailing_empty_line(c *check.C) { t := s.Init(c) lines := t.SetUpFileLines("distinfo", CvsID, "") CheckLinesDistinfo(nil, lines) t.CheckOutputLines( "NOTE: ~/distinfo:2: Trailing empty lines.") } func (s *Suite) Test_distinfoLinesChecker_parse__empty_file(c *check.C) { t := s.Init(c) lines := t.SetUpFileLines("distinfo", CvsID) CheckLinesDistinfo(nil, lines) t.CheckOutputLines( "NOTE: ~/distinfo:1: Empty line expected below this line.") } func (s *Suite) Test_distinfoLinesChecker_parse__commented_first_line(c *check.C) { t := s.Init(c) // This mismatch can happen for inexperienced pkgsrc users. // It's not easy to keep all these different file types apart. lines := t.SetUpFileLines("distinfo", PlistCvsID) CheckLinesDistinfo(nil, lines) t.CheckOutputLines( "ERROR: ~/distinfo:1: Expected \""+CvsID+"\".", "NOTE: ~/distinfo:1: Empty line expected above this line.", "ERROR: ~/distinfo:1: Invalid line: "+PlistCvsID) } func (s *Suite) Test_distinfoLinesChecker_parse__completely_empty_file(c *check.C) { t := s.Init(c) lines := t.SetUpFileLines("distinfo", nil...) CheckLinesDistinfo(nil, lines) t.CheckOutputLines( "NOTE: ~/distinfo:EOF: Empty line expected above this line.") } // When the distinfo file and the patches are placed in the same package, // their diagnostics use short relative paths. func (s *Suite) Test_distinfoLinesChecker_check__distinfo_and_patches_in_separate_directory(c *check.C) { t := s.Init(c) t.SetUpPackage("category/package", "DISTINFO_FILE=\t../../other/common/distinfo", "PATCHDIR=\t../../other/common/patches") t.Remove("category/package/distinfo") t.CreateFileLines("other/common/patches/CVS/Entries") t.CreateFileDummyPatch("other/common/patches/patch-aa") t.CreateFileDummyPatch("other/common/patches/patch-only-in-patches") t.SetUpFileLines("other/common/distinfo", CvsID, "", "SHA1 (patch-aa) = ...", "SHA1 (patch-only-in-distinfo) = ...") t.Chdir("category/package") t.FinishSetUp() G.checkdirPackage(".") t.CheckOutputLines( "ERROR: ../../other/common/distinfo:3: SHA1 hash of patches/patch-aa differs "+ "(distinfo has ..., patch file has 9a93207561abfef7e7550598c5a08f2c3226995b).", "WARN: ../../other/common/distinfo:4: Patch file \"patch-only-in-distinfo\" "+ "does not exist in directory \"patches\".", "ERROR: ../../other/common/distinfo: Patch \"patches/patch-only-in-patches\" "+ "is not recorded. Run \""+confMake+" makepatchsum\".") } func (s *Suite) Test_distinfoLinesChecker_check__manual_patches(c *check.C) { t := s.Init(c) t.Chdir("category/package") t.CreateFileLines("patches/manual-libtool.m4") lines := t.SetUpFileLines("distinfo", CvsID, "", "SHA1 (patch-aa) = ...") CheckLinesDistinfo(nil, lines) // When a distinfo file is checked on its own, without belonging to a package, // the PATCHDIR is not known and therefore no diagnostics are logged. t.CheckOutputEmpty() pkg := NewPackage(".") CheckLinesDistinfo(pkg, lines) // When a distinfo file is checked in the context of a package, // the PATCHDIR is known, therefore the check is active. t.CheckOutputLines( "WARN: distinfo:3: Patch file \"patch-aa\" does not exist in directory \"patches\".") } // PHP modules that are not PECL use the distinfo file from lang/php* but // their own patches directory. Therefore the distinfo file refers to missing // patches. Since this strange situation is caused by the pkgsrc // infrastructure, there is nothing a package author can do. // // XXX: Re-check the documentation for this test. func (s *Suite) Test_distinfoLinesChecker_check__missing_php_patches(c *check.C) { t := s.Init(c) t.SetUpPkgsrc() t.CreateFileLines("licenses/unknown-license") t.CreateFileLines("lang/php/ext.mk", MkCvsID, "", "PHPEXT_MK= # defined", "PHPPKGSRCDIR= ../../lang/php72", "LICENSE?= unknown-license", "COMMENT?= Some PHP package", "GENERATE_PLIST+=# none", "", ".if !defined(PECL_VERSION)", "DISTINFO_FILE= ${.CURDIR}/${PHPPKGSRCDIR}/distinfo", ".endif", ".if defined(USE_PHP_EXT_PATCHES)", "PATCHDIR= ${.CURDIR}/${PHPPKGSRCDIR}/patches", ".endif") t.CreateFileDummyPatch("lang/php72/patches/patch-php72") t.CreateFileLines("lang/php72/distinfo", CvsID, "", "SHA1 (patch-php72) = 9bd4352244636c587db21abfbb99bb34ded1e333") t.CreateFileLines("archivers/php-bz2/Makefile", MkCvsID, "", "USE_PHP_EXT_PATCHES=\tyes", "", ".include \"../../lang/php/ext.mk\"", ".include \"../../mk/bsd.pkg.mk\"") t.CreateFileLines("archivers/php-bz2/DESCR", "Description") t.FinishSetUp() G.Check(t.File("archivers/php-bz2")) t.CheckOutputEmpty() t.CreateFileLines("archivers/php-zlib/Makefile", MkCvsID, "", ".include \"../../lang/php/ext.mk\"", ".include \"../../mk/bsd.pkg.mk\"") t.CreateFileLines("archivers/php-zlib/DESCR", "Description") G.Check(t.File("archivers/php-zlib")) t.CheckOutputEmpty() } func (s *Suite) Test_distinfoLinesChecker_checkFilename(c *check.C) { t := s.Init(c) t.SetUpPackage("category/package") t.CreateFileLines("category/package/distinfo", CvsID, "", "BLAKE2s (ok-1.0.tar.gz) = 1234", "SHA512 (ok-1.0.tar.gz) = 1234", "Size (ok-1.0.tar.gz) = 1234", "BLAKE2s (not-ok.tar.gz) = 1234", "SHA512 (not-ok.tar.gz) = 1234", "Size (not-ok.tar.gz) = 1234", "BLAKE2s (non-versioned/not-ok.tar.gz) = 1234", "SHA512 (non-versioned/not-ok.tar.gz) = 1234", "Size (non-versioned/not-ok.tar.gz) = 1234", "BLAKE2s (versioned-1/ok.tar.gz) = 1234", "SHA512 (versioned-1/ok.tar.gz) = 1234", "Size (versioned-1/ok.tar.gz) = 1234") t.Chdir("category/package") t.FinishSetUp() G.Check(".") t.CheckOutputLines( "WARN: distinfo:6: Distfiles without version number "+ "should be placed in a versioned DIST_SUBDIR.", "WARN: distinfo:9: Distfiles without version number "+ "should be placed in a versioned DIST_SUBDIR.") } func (s *Suite) Test_distinfoLinesChecker_checkAlgorithms__nonexistent_distfile_called_patch(c *check.C) { t := s.Init(c) t.Chdir("category/package") lines := t.SetUpFileLines("distinfo", CvsID, "", "MD5 (patch-5.3.tar.gz) = 12345678901234567890123456789012", "SHA1 (patch-5.3.tar.gz) = 1234567890123456789012345678901234567890") pkg := NewPackage(".") CheckLinesDistinfo(pkg, lines) // Even though the filename starts with "patch-" and therefore looks like // a patch, it is a normal distfile because it has other hash algorithms // than exactly SHA1. t.CheckOutputLines( "ERROR: distinfo:3: Expected BLAKE2s, SHA512, Size checksums " + "for \"patch-5.3.tar.gz\", got MD5, SHA1.") } func (s *Suite) Test_distinfoLinesChecker_checkAlgorithms__wrong_distfile_algorithms(c *check.C) { t := s.Init(c) t.Chdir("category/package") lines := t.SetUpFileLines("distinfo", CvsID, "", "MD5 (distfile.tar.gz) = 12345678901234567890123456789012", "SHA1 (distfile.tar.gz) = 1234567890123456789012345678901234567890") CheckLinesDistinfo(nil, lines) t.CheckOutputLines( "ERROR: distinfo:3: Expected BLAKE2s, SHA512, Size checksums " + "for \"distfile.tar.gz\", got MD5, SHA1.") } // This case only happens when a distinfo file is checked on its own, // without any reference to a pkgsrc package. Additionally the distfile // must start with the patch- prefix and the algorithms must be wrong // for both distfile or patch. // // This test only demonstrates the edge case. func (s *Suite) Test_distinfoLinesChecker_checkAlgorithms__ambiguous_distfile(c *check.C) { t := s.Init(c) t.SetUpCommandLine("--explain") t.Chdir("category/package") lines := t.SetUpFileLines("distinfo", CvsID, "", "MD5 (patch-4.2.tar.gz) = 12345678901234567890123456789012") CheckLinesDistinfo(nil, lines) t.CheckOutputLines( "ERROR: distinfo:3: Wrong checksum algorithms MD5 for patch-4.2.tar.gz.", "", "\tDistfiles that are downloaded from external sources must have the", "\tchecksum algorithms BLAKE2s, SHA512, Size.", "", "\tPatch files from pkgsrc must have only the SHA1 hash.", "") } func (s *Suite) Test_distinfoLinesChecker_checkAlgorithms__wrong_patch_algorithms(c *check.C) { t := s.Init(c) t.SetUpPackage("category/package") t.Chdir("category/package") t.CreateFileDummyPatch("patches/patch-aa") t.SetUpFileLines("distinfo", CvsID, "", "MD5 (patch-aa) = 12345678901234567890123456789012", "SHA1 (patch-aa) = 1234567890123456789012345678901234567890") t.FinishSetUp() G.Check(".") t.CheckOutputLines( "ERROR: distinfo:3: Expected SHA1 hash for patch-aa, got MD5, SHA1.", "ERROR: distinfo:4: SHA1 hash of patches/patch-aa differs "+ "(distinfo has 1234567890123456789012345678901234567890, "+ "patch file has 9a93207561abfef7e7550598c5a08f2c3226995b).") } func (s *Suite) Test_distinfoLinesChecker_checkAlgorithms__missing_patch_with_distfile_checksums(c *check.C) { t := s.Init(c) lines := t.SetUpFileLines("distinfo", CvsID, "", "BLAKE2s (patch-aa) = ...", "SHA512 (patch-aa) = ...", "Size (patch-aa) = ... bytes") CheckLinesDistinfo(nil, lines) // The file name certainly looks like a pkgsrc patch, but there // is no corresponding file in the file system, and there is no // current package to correctly determine the PATCHDIR. Therefore, // pkglint doesn't know whether this is a distfile or a missing // patch file and doesn't warn at all. t.CheckOutputEmpty() } func (s *Suite) Test_distinfoLinesChecker_checkAlgorithms__existing_patch_with_distfile_checksums(c *check.C) { t := s.Init(c) t.SetUpPackage("category/package") t.CreateFileLines("category/package/distinfo", CvsID, "", "BLAKE2s (patch-aa) = ...", "SHA512 (patch-aa) = ...", "Size (patch-aa) = ... bytes") t.CreateFileDummyPatch("category/package/patches/patch-aa") t.FinishSetUp() G.Check(t.File("category/package")) // Even though the checksums in the distinfo file look as if they // refer to a distfile, there is a patch file in the file system // that matches the distinfo lines. When checking a pkgsrc package // (as opposed to checking a distinfo file on its own), this means // that the distinfo lines clearly refer to that patch file and not // to a distfile. t.CheckOutputLines( "ERROR: ~/category/package/distinfo:3: " + "Expected SHA1 hash for patch-aa, got BLAKE2s, SHA512, Size.") } func (s *Suite) Test_distinfoLinesChecker_checkAlgorithms__missing_patch_with_wrong_algorithms(c *check.C) { t := s.Init(c) t.SetUpPackage("category/package") t.SetUpFileLines("category/package/distinfo", CvsID, "", "BLAKE2s (patch-aa) = ...") t.FinishSetUp() G.Check(t.File("category/package")) // Patch files usually have the SHA1 hash or none at all if they are fresh. // In all other cases pkglint assumes that the file is a distfile, // therefore it requires the usual distfile checksum algorithms here. t.CheckOutputLines( "ERROR: ~/category/package/distinfo:3: " + "Expected BLAKE2s, SHA512, Size checksums for \"patch-aa\", got BLAKE2s.") } // When there is at least one correct hash for a distfile and the distfile // has already been downloaded to pkgsrc/distfiles, which is the standard // distfiles location, running pkglint --autofix adds the missing hashes. func (s *Suite) Test_distinfoLinesChecker_checkAlgorithmsDistfile__add_missing_hashes_for_existing_distfile(c *check.C) { t := s.Init(c) t.SetUpCommandLine("-Wall", "--explain") t.SetUpPackage("category/package") t.CreateFileLines("category/package/distinfo", CvsID, "", "BLAKE2s (package-1.0.txt) = ee494623e60caeda840ed7de4fb70db4a36bc92b445b09f12b9ed46094e9bd59", "Size (package-1.0.txt) = 13 bytes", "CRC32 (package-1.0.txt) = asdf") t.CreateFileLines("distfiles/package-1.0.txt", "hello, world") t.FinishSetUp() // This run is only used to verify that the BLAKE2s hash is correct, and if // it should ever differ, the correct hash will appear in an error message. G.Check(t.File("category/package")) t.CheckOutputLines( "ERROR: ~/category/package/distinfo:3: "+ "Expected BLAKE2s, SHA512, Size checksums for \"package-1.0.txt\", "+ "got BLAKE2s, Size, CRC32.", "ERROR: ~/category/package/distinfo:3: Missing SHA512 hash for package-1.0.txt.") t.SetUpCommandLine("-Wall", "--autofix", "--show-autofix", "--source") G.Check(t.File("category/package")) // Since the file exists in the distfiles directory, pkglint checks the // hash right away. It also adds the missing hashes since this file is // not a patch file. t.CheckOutputLines( "ERROR: ~/category/package/distinfo:3: Missing SHA512 hash for package-1.0.txt.", "AUTOFIX: ~/category/package/distinfo:3: "+ "Inserting a line \"SHA512 (package-1.0.txt) "+ "= f65f341b35981fda842b09b2c8af9bcdb7602a4c2e6fa1f7d41f0974d3e3122f"+ "268fc79d5a4af66358f5133885cd1c165c916f80ab25e5d8d95db46f803c782c\" below this line.", ">\tBLAKE2s (package-1.0.txt) = ee494623e60caeda840ed7de4fb70db4a36bc92b445b09f12b9ed46094e9bd59", "+\tSHA512 (package-1.0.txt) = f65f341b35981fda842b09b2c8af9bcdb7602a4c2e6fa1f7d41f0974d3e3122f"+ "268fc79d5a4af66358f5133885cd1c165c916f80ab25e5d8d95db46f803c782c") t.SetUpCommandLine("-Wall") G.Check(t.File("category/package")) t.CheckOutputLines( "ERROR: ~/category/package/distinfo:3: " + "Expected BLAKE2s, SHA512, Size checksums for \"package-1.0.txt\", " + "got BLAKE2s, SHA512, Size, CRC32.") } // When some of the hashes for a distfile are missing, pkglint can calculate // them. In order to do this, the distfile needs to be downloaded first. This // often requires manual work, otherwise it would have been done already. // // Since the distfile has not been downloaded in this test case, pkglint can // only explain how to download the distfile. func (s *Suite) Test_distinfoLinesChecker_checkAlgorithmsDistfile__add_missing_hashes_for_nonexistent_distfile(c *check.C) { t := s.Init(c) t.SetUpCommandLine("-Wall", "--explain") t.SetUpPackage("category/package") t.CreateFileLines("category/package/distinfo", CvsID, "", "BLAKE2s (package-1.0.txt) = ee494623e60caeda840ed7de4fb70db4a36bc92b445b09f12b9ed46094e9bd59", "Size (package-1.0.txt) = 13 bytes", "CRC32 (package-1.0.txt) = asdf") t.FinishSetUp() G.Check(t.File("category/package")) t.CheckOutputLines( "ERROR: ~/category/package/distinfo:3: "+ "Expected BLAKE2s, SHA512, Size checksums for \"package-1.0.txt\", "+ "got BLAKE2s, Size, CRC32.", "", "\tTo add the missing lines to the distinfo file, run", "\t\t"+confMake+" distinfo", "\tfor each variant of the package until all distfiles are downloaded", "\tto ${PKGSRCDIR}/distfiles.", "", "\tThe variants are typically selected by setting EMUL_PLATFORM or", "\tsimilar variables in the command line.", "", "\tAfter that, run \"cvs update -C distinfo\" to revert the distinfo file", "\tto the previous state, since the above commands have removed some of", "\tthe entries.", "", "\tAfter downloading all possible distfiles, run \"pkglint --autofix\",", "\twhich will find the downloaded distfiles and add the missing hashes", "\tto the distinfo file.", "") t.SetUpCommandLine("-Wall", "--autofix", "--show-autofix", "--source") G.Check(t.File("category/package")) // Since the distfile does not exist, pkglint cannot fix anything. t.CheckOutputEmpty() } func (s *Suite) Test_distinfoLinesChecker_checkAlgorithmsDistfile__wrong_distfile_hash(c *check.C) { t := s.Init(c) t.SetUpPackage("category/package") t.CreateFileLines("category/package/distinfo", CvsID, "", "BLAKE2s (package-1.0.txt) = 1234wrongHash1234") t.CreateFileLines("distfiles/package-1.0.txt", "hello, world") t.FinishSetUp() G.Check(t.File("category/package")) t.CheckOutputLines( "ERROR: ~/category/package/distinfo:3: "+ "Expected BLAKE2s, SHA512, Size checksums for \"package-1.0.txt\", "+ "got BLAKE2s.", "ERROR: ~/category/package/distinfo:3: "+ "The BLAKE2s checksum for \"package-1.0.txt\" is 1234wrongHash1234 in distinfo, "+ "ee494623e60caeda840ed7de4fb70db4a36bc92b445b09f12b9ed46094e9bd59 in ../../distfiles/package-1.0.txt.") } func (s *Suite) Test_distinfoLinesChecker_checkAlgorithmsDistfile__no_usual_algorithm(c *check.C) { t := s.Init(c) t.SetUpPackage("category/package") t.CreateFileLines("category/package/distinfo", CvsID, "", "MD5 (package-1.0.txt) = 1234wrongHash1234") t.CreateFileLines("distfiles/package-1.0.txt", "hello, world") t.FinishSetUp() G.Check(t.File("category/package")) t.CheckOutputLines( "ERROR: ~/category/package/distinfo:3: " + "Expected BLAKE2s, SHA512, Size checksums for \"package-1.0.txt\", " + "got MD5.") } func (s *Suite) Test_distinfoLinesChecker_checkAlgorithmsDistfile__top_algorithm_missing(c *check.C) { t := s.Init(c) t.SetUpPackage("category/package") t.CreateFileLines("category/package/distinfo", CvsID, "", "SHA512 (package-1.0.txt) = f65f341b35981fda842b09b2c8af9bcdb7602a4c2e6fa1f7"+ "d41f0974d3e3122f268fc79d5a4af66358f5133885cd1c165c916f80ab25e5d8d95db46f803c782c", "Size (package-1.0.txt) = 13 bytes") t.CreateFileLines("distfiles/package-1.0.txt", "hello, world") t.FinishSetUp() G.Check(t.File("category/package")) t.CheckOutputLines( "ERROR: ~/category/package/distinfo:3: "+ "Expected BLAKE2s, SHA512, Size checksums for \"package-1.0.txt\", "+ "got SHA512, Size.", "ERROR: ~/category/package/distinfo:3: Missing BLAKE2s hash for package-1.0.txt.") } func (s *Suite) Test_distinfoLinesChecker_checkAlgorithmsDistfile__bottom_algorithms_missing(c *check.C) { t := s.Init(c) t.SetUpPackage("category/package") t.CreateFileLines("category/package/distinfo", CvsID, "", "BLAKE2s (package-1.0.txt) = ee494623e60caeda840ed7de4fb70db4a36bc92b445b09f12b9ed46094e9bd59") t.CreateFileLines("distfiles/package-1.0.txt", "hello, world") t.FinishSetUp() G.Check(t.File("category/package")) t.CheckOutputLines( "ERROR: ~/category/package/distinfo:3: "+ "Expected BLAKE2s, SHA512, Size checksums for \"package-1.0.txt\", "+ "got BLAKE2s.", "ERROR: ~/category/package/distinfo:3: Missing SHA512 hash for package-1.0.txt.", "ERROR: ~/category/package/distinfo:3: Missing Size hash for package-1.0.txt.") t.SetUpCommandLine("-Wall", "--autofix") G.Check(t.File("category/package")) t.CheckOutputLines( "AUTOFIX: ~/category/package/distinfo:3: "+ "Inserting a line \"SHA512 (package-1.0.txt) = f65f341b35981fda842b"+ "09b2c8af9bcdb7602a4c2e6fa1f7d41f0974d3e3122f268fc79d5a4af66358f513"+ "3885cd1c165c916f80ab25e5d8d95db46f803c782c\" below this line.", "AUTOFIX: ~/category/package/distinfo:3: "+ "Inserting a line \"Size (package-1.0.txt) = 13 bytes\" below this line.") } func (s *Suite) Test_distinfoLinesChecker_checkAlgorithmsDistfile__algorithms_in_wrong_order(c *check.C) { t := s.Init(c) t.SetUpPackage("category/package") t.CreateFileLines("category/package/distinfo", CvsID, "", "BLAKE2s (package-1.0.txt) = ee494623e60caeda840ed7de4fb70db4a36bc92b445b09f12b9ed46094e9bd59", "Size (package-1.0.txt) = 13 bytes", "SHA512 (package-1.0.txt) = f65f341b35981fda842b09b2c8af9bcdb7602a4c2e6fa1f7"+ "d41f0974d3e3122f268fc79d5a4af66358f5133885cd1c165c916f80ab25e5d8d95db46f803c782c") t.CreateFileLines("distfiles/package-1.0.txt", "hello, world") t.FinishSetUp() G.Check(t.File("category/package")) // This case doesn't happen in practice, therefore there's no autofix for it. t.CheckOutputLines( "ERROR: ~/category/package/distinfo:3: " + "Expected BLAKE2s, SHA512, Size checksums for \"package-1.0.txt\", " + "got BLAKE2s, Size, SHA512.") } func (s *Suite) Test_distinfoLinesChecker_checkUnrecordedPatches(c *check.C) { t := s.Init(c) t.SetUpPackage("category/package") t.Chdir("category/package") t.CreateFileLines("patches/CVS/Entries") t.CreateFileDummyPatch("patches/patch-aa") t.CreateFileDummyPatch("patches/patch-src-Makefile") t.SetUpFileLines("distinfo", CvsID, "", "BLAKE2s (distfile.tar.gz) = ...", "SHA512 (distfile.tar.gz) = ...", "Size (distfile.tar.gz) = 1024 bytes") t.FinishSetUp() G.checkdirPackage(".") t.CheckOutputLines( "WARN: distinfo:3: Distfiles without version number should be placed in a versioned DIST_SUBDIR.", "ERROR: distinfo: Patch \"patches/patch-aa\" is not recorded. Run \""+confMake+" makepatchsum\".", "ERROR: distinfo: Patch \"patches/patch-src-Makefile\" is not recorded. Run \""+confMake+" makepatchsum\".") } // When checking the complete pkgsrc tree, pkglint has all information it needs // to check whether different packages use the same distfile but require // different hashes for it. // // In such a case, typically one of the packages should put its distfiles into // a DIST_SUBDIR. func (s *Suite) Test_distinfoLinesChecker_checkGlobalDistfileMismatch(c *check.C) { t := s.Init(c) t.SetUpPkgsrc() t.SetUpPackage("category/package1") t.SetUpPackage("category/package2") t.CreateFileLines("category/package1/distinfo", CvsID, "", "SHA512 (distfile-1.0.tar.gz) = 1234567811111111", "SHA512 (distfile-1.1.tar.gz) = 1111111111111111", "SHA512 (patch-4.2.tar.gz) = 1234567812345678") t.CreateFileLines("category/package2/distinfo", CvsID, "", "SHA512 (distfile-1.0.tar.gz) = 1234567822222222", "SHA512 (distfile-1.1.tar.gz) = 1111111111111111", "SHA512 (encoding-error.tar.gz) = 12345678abcdefgh") t.CreateFileLines("Makefile", MkCvsID, "", "COMMENT=\tThis is pkgsrc", "", "SUBDIR+=\tcategory") t.CreateFileLines("category/Makefile", MkCvsID, "", "COMMENT=\tUseful programs", "", "SUBDIR+=\tpackage1", "SUBDIR+=\tpackage2", "", ".include \"../mk/misc/category.mk\"") t.Main("-r", "-Wall", "-Call", ".") t.CheckOutputLines( "ERROR: ~/category/package1/distinfo:3: "+ "Expected BLAKE2s, SHA512, Size checksums for \"distfile-1.0.tar.gz\", got SHA512.", "ERROR: ~/category/package1/distinfo:4: "+ "Expected BLAKE2s, SHA512, Size checksums for \"distfile-1.1.tar.gz\", got SHA512.", "ERROR: ~/category/package1/distinfo:5: "+ "Expected BLAKE2s, SHA512, Size checksums for \"patch-4.2.tar.gz\", got SHA512.", "ERROR: ~/category/package2/distinfo:3: "+ "Expected BLAKE2s, SHA512, Size checksums for \"distfile-1.0.tar.gz\", got SHA512.", "ERROR: ~/category/package2/distinfo:3: "+ "The SHA512 hash for distfile-1.0.tar.gz is 1234567822222222, "+ "which conflicts with 1234567811111111 in ../../category/package1/distinfo:3.", "ERROR: ~/category/package2/distinfo:4: "+ "Expected BLAKE2s, SHA512, Size checksums for \"distfile-1.1.tar.gz\", got SHA512.", "ERROR: ~/category/package2/distinfo:5: "+ "Expected BLAKE2s, SHA512, Size checksums for \"encoding-error.tar.gz\", got SHA512.", "ERROR: ~/category/package2/distinfo:5: "+ "The SHA512 hash for encoding-error.tar.gz contains a non-hex character.", "WARN: ~/licenses/gnu-gpl-v2: This license seems to be unused.", "8 errors and 1 warning found.", t.Shquote("(Run \"pkglint -e -r -Wall -Call %s\" to show explanations.)", ".")) // Ensure that hex.DecodeString does not waste memory here. t.CheckEquals(len(G.InterPackage.hashes["SHA512:distfile-1.0.tar.gz"].hash), 8) t.CheckEquals(cap(G.InterPackage.hashes["SHA512:distfile-1.0.tar.gz"].hash), 8) } func (s *Suite) Test_distinfoLinesChecker_checkUncommittedPatch__bad(c *check.C) { t := s.Init(c) t.SetUpPackage("category/package") t.Chdir("category/package") t.CreateFileDummyPatch("patches/patch-aa") t.CreateFileLines("CVS/Entries", "/distinfo//modified//") t.SetUpFileLines("distinfo", CvsID, "", "SHA1 (patch-aa) = 9a93207561abfef7e7550598c5a08f2c3226995b") t.FinishSetUp() G.checkdirPackage(".") t.CheckOutputLines( "WARN: distinfo:3: patches/patch-aa is registered in distinfo but not added to CVS.") } func (s *Suite) Test_distinfoLinesChecker_checkUncommittedPatch__good(c *check.C) { t := s.Init(c) t.SetUpPackage("category/package") t.Chdir("category/package") t.CreateFileDummyPatch("patches/patch-aa") t.CreateFileLines("CVS/Entries", "/distinfo//modified//") t.CreateFileLines("patches/CVS/Entries", "/patch-aa//modified//") t.SetUpFileLines("distinfo", CvsID, "", "SHA1 (patch-aa) = 9a93207561abfef7e7550598c5a08f2c3226995b") t.FinishSetUp() G.checkdirPackage(".") t.CheckOutputEmpty() } // The distinfo file and the patches are usually placed in the package // directory. By defining PATCHDIR or DISTINFO_FILE, a package can define // that they are somewhere else in pkgsrc. func (s *Suite) Test_distinfoLinesChecker_checkPatchSha1__relative_path_in_distinfo(c *check.C) { t := s.Init(c) t.SetUpPackage("category/package", "DISTINFO_FILE=\t../../other/common/distinfo", "PATCHDIR=\t../../devel/patches/patches") t.Remove("category/package/distinfo") t.CreateFileLines("devel/patches/patches/CVS/Entries") t.CreateFileDummyPatch("devel/patches/patches/patch-aa") t.CreateFileDummyPatch("devel/patches/patches/patch-only-in-patches") t.SetUpFileLines("other/common/distinfo", CvsID, "", "SHA1 (patch-aa) = ...", "SHA1 (patch-only-in-distinfo) = ...") t.Chdir("category/package") t.FinishSetUp() G.checkdirPackage(".") t.CheckOutputLines( "ERROR: ../../other/common/distinfo:3: SHA1 hash of ../../devel/patches/patches/patch-aa differs "+ "(distinfo has ..., patch file has 9a93207561abfef7e7550598c5a08f2c3226995b).", "WARN: ../../other/common/distinfo:4: Patch file \"patch-only-in-distinfo\" "+ "does not exist in directory \"../../devel/patches/patches\".", "ERROR: ../../other/common/distinfo: Patch \"../../devel/patches/patches/patch-only-in-patches\" "+ "is not recorded. Run \""+confMake+" makepatchsum\".") } func (s *Suite) Test_distinfoLinesChecker_checkPatchSha1(c *check.C) { t := s.Init(c) pkg := NewPackage(t.File("category/package")) distinfoLine := t.NewLine(t.File("category/package/distinfo"), 5, "") checker := distinfoLinesChecker{pkg, nil, "", false, nil, nil} checker.checkPatchSha1(distinfoLine, "patch-nonexistent", "distinfo-sha1") t.CheckOutputLines( "ERROR: ~/category/package/distinfo:5: Patch patch-nonexistent does not exist.") } func (s *Suite) Test_distinfoFileInfo_filename(c *check.C) { t := s.Init(c) info := distinfoFileInfo{ isPatch: no, hashes: []distinfoHash{{ line: t.NewLine("irrelevant", 12345, "irrelevant"), filename: "distinfo", algorithm: "irrelevant", hash: "irrelevant", }}, } t.CheckEquals(info.filename(), RelPath("distinfo")) } func (s *Suite) Test_distinfoFileInfo_line(c *check.C) { t := s.Init(c) line := t.NewLine("irrelevant", 12345, "irrelevant") info := distinfoFileInfo{ isPatch: no, hashes: []distinfoHash{{ line: line, filename: "irrelevant", algorithm: "irrelevant", hash: "irrelevant", }}, } t.CheckEquals(info.line(), line) } func (s *Suite) Test_distinfoFileInfo_algorithms(c *check.C) { t := s.Init(c) info := distinfoFileInfo{ isPatch: no, hashes: []distinfoHash{ { line: t.NewLine("irrelevant", 12345, "irrelevant"), filename: "irrelevant", algorithm: "SHA1", hash: "irrelevant", }, { line: t.NewLine("irrelevant", 12346, "irrelevant"), filename: "irrelevant", algorithm: "Size", hash: "irrelevant", }, }, } t.CheckEquals(info.algorithms(), "SHA1, Size") } // The check for versioned distfiles only makes sense if the file // has the usual hashes for distfiles. func (s *Suite) Test_distinfoFileInfo_hasDistfileAlgorithms__code_coverage(c *check.C) { t := s.Init(c) t.SetUpPackage("category/package") t.CreateFileLines("category/package/distinfo", CvsID, "", "other (dist-a.tar.gz) = 1234", "BLAKE2s (dist-a.tar.gz) = 1234", "SHA512 (dist-a.tar.gz) = 1234", "Size (dist-a.tar.gz) = 1234", "SHA1 (dist-b.tar.gz) = 1234", "other (dist-b.tar.gz) = 1234", "SHA512 (dist-b.tar.gz) = 1234", "Size (dist-b.tar.gz) = 1234", "SHA1 (dist-c.tar.gz) = 1234", "BLAKE2s (dist-c.tar.gz) = 1234", "other (dist-c.tar.gz) = 1234", "Size (dist-c.tar.gz) = 1234", "SHA1 (dist-d.tar.gz) = 1234", "BLAKE2s (dist-d.tar.gz) = 1234", "SHA512 (dist-d.tar.gz) = 1234", "other (dist-d.tar.gz) = 1234") t.Chdir("category/package") t.FinishSetUp() G.Check(".") t.CheckOutputLines( "ERROR: distinfo:3: Expected BLAKE2s, SHA512, Size checksums for "+ "\"dist-a.tar.gz\", got other, BLAKE2s, SHA512, Size.", "ERROR: distinfo:7: Expected BLAKE2s, SHA512, Size checksums for "+ "\"dist-b.tar.gz\", got SHA1, other, SHA512, Size.", "ERROR: distinfo:11: Expected BLAKE2s, SHA512, Size checksums for "+ "\"dist-c.tar.gz\", got SHA1, BLAKE2s, other, Size.", "ERROR: distinfo:15: Expected BLAKE2s, SHA512, Size checksums for "+ "\"dist-d.tar.gz\", got SHA1, BLAKE2s, SHA512, other.") } func (s *Suite) Test_computePatchSha1Hex(c *check.C) { t := s.Init(c) test := func(expectedHash string, lines ...string) { fileLines := t.NewLines("irrelevant", lines...) hash := computePatchSha1Hex(fileLines) t.CheckEquals(hash, expectedHash) } // The well-known hash for an empty string. test( "da39a3ee5e6b4b0d3255bfef95601890afd80709", nil..., ) // Any line containing "$" + "NetBSD" is ignored for computing // the hash since the CVS IDs are irrelevant. This assumes that // the patch hunks themselves do not contain CVS IDs, and this // is checked in PatchChecker.checktextCvsID. test( "da39a3ee5e6b4b0d3255bfef95601890afd80709", CvsID, CvsID+"$", // This is not a CVS ID since the final '$' is missing, but it is // close enough. See mk/checksum/distinfo.awk, function patchsum. "Some text $"+"NetBSD-2020", ) test( // == sha1Hex("--- old\n+++ new\n") "bb5a3903635415d367f47c02990e031469ab0346", "--- old", "+++ new", ) }