{"id":13679461,"url":"https://github.com/perlpunk/perl5-module-meta","last_synced_at":"2025-10-04T08:58:03.293Z","repository":{"id":141767726,"uuid":"219142906","full_name":"perlpunk/perl5-module-meta","owner":"perlpunk","description":"Best Practices for Perl5 CPAN Modules Metadata","archived":false,"fork":false,"pushed_at":"2019-11-15T22:55:58.000Z","size":15,"stargazers_count":19,"open_issues_count":5,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-06-04T22:11:30.291Z","etag":null,"topics":["best-practices","deb","metadata","module","packaging","perl5","rpm"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/perlpunk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-02T11:15:12.000Z","updated_at":"2025-03-31T10:58:19.000Z","dependencies_parsed_at":null,"dependency_job_id":"2bc8ffa7-b731-42e3-9a07-c8c737bec15f","html_url":"https://github.com/perlpunk/perl5-module-meta","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/perlpunk/perl5-module-meta","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perlpunk%2Fperl5-module-meta","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perlpunk%2Fperl5-module-meta/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perlpunk%2Fperl5-module-meta/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perlpunk%2Fperl5-module-meta/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/perlpunk","download_url":"https://codeload.github.com/perlpunk/perl5-module-meta/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perlpunk%2Fperl5-module-meta/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278289499,"owners_count":25962356,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-04T02:00:05.491Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["best-practices","deb","metadata","module","packaging","perl5","rpm"],"created_at":"2024-08-02T13:01:05.803Z","updated_at":"2025-10-04T08:58:03.278Z","avatar_url":"https://github.com/perlpunk.png","language":null,"funding_links":[],"categories":["Others"],"sub_categories":[],"readme":"# Perl5 Module Meta - Best Practices\n\nThis is a collection of things that help making your CPAN module \"portable\"\nwith regard to metadata.\n\nCPAN/PAUSE itself is not very strict about these things. But turning a module\ninto an RPM or Debian package for example can be hard if it is missing\nmeta data.\n\nPeople maintaining `rpm` or `deb` repositories for perl often have to do a lot\nof manual work, although theoretically most of it can be automated.\n\n## Table of Contents\n\n* [Versions](#Versions) - Use a consistent versioning scheme\n* [Description](#Description) - Create a useful description\n* [Archive filename](#Archive-filename) - Create a correct archive\n* [`.` in `@INC`](#INC) - The current directory `.` is not in `@INC`\n* [Changelog](#Changelog) - Use a common filename and format\n* [License](#License) - Correctly specify license\n* [Dependencies](#Dependencies) - Specify all dependencies\n* [Shebang](#Shebang) - Use a portable shebang for scripts\n* [MANIFEST](#MANIFEST) - Exclude certain files from your archive\n* [Bugtracker](#Bugtracker) - Specify URL to Bugtracker\n* [Tests](#Tests) - Make sure tests are passing everywhere\n* [Installer](#Installer)\n* [Author Tests](#Author-Tests) - Useful Author tests\n* [Other Resources](#Other-Resources)\n\n## Versions\n\n### Use a consistent versioning scheme\n\nThe short story: Always use the same amount of digits after the major version.\n\nThe long story:\n\nPerl versions are different from common versioning schemes.\n\nIn Perl, the version `1.1901` is semantically equal to `v1.190.100`,\nand `1.20` to `v1.200`.\n\nSo it can happen that a CPAN module was released with version `1.1901`, and\na year later a new version `1.20` is released. For perl, the new version is\nbigger.\n\nIf vendors want to turn the module into an `rpm` or `deb`, they would have to\nturn the version into `1.190.100`/`1.200` to be correct. The only disadvantage\nis that the version may not look the same as the original CPAN version anymore.\n\nBut if they take the version as it is, then `1.190` is bigger than the following\n`1.20`.\n\nMake it easier for vendors and always use the same amounts of digits. If you want\nto change to a different versioning scheme, then at least change the major\nversion before.\n\nUse the same distribution version everywhere (`META.*` files, `Makefile.PL`,\narchive name, Changelog).\n\n### Do not reuse versions\n\nAlways increase the version for a new upload and do not reuse the same version.\n\nAlso have a look at Grinnz' [Guide to Versions in\nPerl](http://blogs.perl.org/users/grinnz/2018/04/a-guide-to-versions-in-perl.html).\n\n## Description\n\nEvery module should have a `DESCRIPTION` section in the pod documentation.\n\n    =head1 NAME\n\n    Module::Name - Abstract\n\n    =head1 SYNOPSIS\n\n        use Module::Name;\n        # example code\n\n    =head1 DESCRIPTION\n\n    A few paragraphs with a description of your module.\n\nThis description is usually what ends up in the vendor package description.\nDon't make it too long and create extra headers for more specific parts.\n\nAlso check for spelling mistakes. See [Author Tests](#Author-Tests).\n\n## Archive filename\n\nThe filename you upload should match the distribution name and version, e.g.\n\n    Your-Module-1.23.tar.gz\n    Your-Module-1.23.zip\n    Your-Module-v1.23.tar.gz\n    Your-Module-v1.23.zip\n\n`tgz` and `tar.bz2` might also work.\n\nThe archive should unpack to `Your-Module-version`. Do not omit the version.\nIf people unpack different versions of your module, they should not end up\nin the same directory.\n\nThe contents of the module should be in the top folder of the archive, e.g.\n\n    Your-Module-1.23/\n        lib/Your/Module.pm\n        t/...\n        LICENSE\n        Makefile.PL\n\n## `@INC`\n\nIn perl 5.26, the current directory `.` was removed from `@INC`. Make sure\nyou don't rely on `.`, for example when using `Module::Install`, or when\nusing modules in your test directory.\n\nDon't use\n\n    use t::lib::Some::Module;\n\nInstead do:\n\n    use lib 't/lib';\n    use Some::Module;\n\nOr:\n\n    use FindBin '$Bin';\n    use lib \"$Bin/lib\";\n    use Some::Module;\n\n## Changelog\n\nUse a common format and filename for your changelog file. The most common filename\nis `Changes`.\n\nFor vendors to be able to parse the file, use a format like this:\n\n    1.23 2019-11-02 12:34:56+02:00\n\n        - Bug fix: ...\n        - New Feature: ...\n\nThe version should exactly match the version of the distribution.\n\nNewer versions should be above older versions.\n\nIf you fixed a bug that was reported in an issue, mention the issue.\nVendors often create local patches for modules and, if they have time, create\nan issue.\nIf you fixed the issue and mention it in the changelog, vendors can more\neasily remove outdated patches.\n\n\n## License\n\nThe license should appear ideally in four places:\n\n* META.json\n* META.yml\n* LICENSE file\n* The pod documentation of your main module\n\n## Dependencies\n\nList *all* dependencies. The list of modules contained in core may change over\ntime. It's best to include all dependencies including the ones that are\ncurrently in core.\n\nIf possible, add the minimum required version of the dependency. For example,\nwhen using `Test::More::done_testing()`, require `Test::More` version `0.88`,\nas it was added in this version.\n\nAlso don't forget to specify the minimum perl version.\n\nAlso have a look at Neil's [Specifying dependencies for your CPAN\ndistribution](http://blogs.perl.org/users/neilb/2017/05/specifying-dependencies-for-your-cpan-distribution.html).\n\n### Non-perl dependencies\n\nIf your module needs an external library, there is currently no way to specify\nthis in `META.json`/`META.yml`. But you can help vendors by documenting\nthe external libaries your module needs in pod.\n\n## Shebang\n\nThe first line of any perl scripts included in your distribution, especially\nthe ones that will be installed, should look like that:\n\n    #!/usr/bin/perl\n\nWhen the module is installed, this line will be automatically replaced with\nthe path to perl that was used for building.\n\nAlternatively `#!perl` should also work.\n\nNote that if you use\n\n    #!/usr/bin/env perl\n\nthe line is currently not rewritten. See\n[Perl-Toolchain-Gang/ExtUtils-MakeMaker#58](https://github.com/Perl-Toolchain-Gang/ExtUtils-MakeMaker/issues/58)\nfor a discussion on this.  If the line is not rewritten and your installed\nscript is executed with a different perl, this can lead to problems, for example\ndependencies will not be found.\n\n## MANIFEST\n\nMake sure to not include files in your archive that don't belong there,\nlike editor backup files (`.swp`), the `.git` folder, forgotten tarballs.\n\nUsually build tools will skip files listed in `MANIFEST.SKIP`.\n\n## Bugtracker\n\nIf your repository is hosted at a site like GitHub or BitBucket, and you are\nusing the bugtracker it provides, add the URL to the bugtracker in the\n`META.json/META.yml`. That makes it easier for people to find existing\nand file new bugs.\n\n## Tests\n\nRegularly look at the CPAN Testers site (linked from your module page on MetaCPAN)\nto see if there are any test failures.\n\nIf possible, don't rely on a working network and mock network operations.\n\nDon't rely on a fixed order of hash keys.\n\nTests should not create or alter files in the distribution.\nIf you have to create files for tests, delete them at the end.\n\nThis can be done in an `END` block, so the files will be deleted also when\na test fails and exits unexpectedly.\n\n    use File::Path 'rmtree';\n    ...\n    END {\n        rmtree \"/path/to/temporary/testfiles\";\n    }\n\n## Installer\n\nDon't prompt for input in the install process, for example in `Makefile.PL` or\n`Build.PL`. This will break automatic installations.\nIf you need a prompt, use `ExtUtils::MakeMaker::prompt()`, as it will detect\nif it's running interactively or not and use a default.\n\n## Author Tests\n\nThere are a number of Test modules that help you avoiding some of the mentioned\nissues.\n\n* [Test::Pod](https://metacpan.org/pod/Test::Pod) - Check for correct POD\n* [Test::Spelling](https://metacpan.org/pod/Test::Spelling) - Check for spelling mistakes in POD\n* [Test::CPAN::Meta](https://metacpan.org/pod/Test::CPAN::Meta) - Validate `META.yml`\n* [Test::Kwalitee](https://metacpan.org/pod/Test::Kwalitee) - Includes a number of different checks\n* [Test::CheckChanges](https://metacpan.org/pod/Test::CheckChanges) - Check that the Changes file matches the distribution\n* [Test::CPAN::Changes](https://metacpan.org/pod/Test::CPAN::Changes) - Check format of Changes file\n\nPlace them in the `xt/` directory so they are not run by default. They\nshould be run by the author before releasing.\n\n## Other resources\n\n### openSUSE\n\nYou can find a lot of CPAN modules in the [devel:languages:perl](https://build.opensuse.org/project/show/devel:languages:perl)\nrepository of openSUSE Build Service (OBS).\n\nLook if you can find your module there. Maybe you'll find out that it contains\nlocal patches.\n\nThe most used tool to create `.spec` files for CPAN modules is\n[cpanspec](https://github.com/openSUSE/cpanspec).  It can use a `cpanspec.yml`\nfile for any changes necessary to make the module build successfully.\n\nYou will also see a lot of modules not using `cpanspec.yml` yet. The spec was\nprobably created manually.\n\nThe `cpanspec.yml` can be used for adding forgotten dependencies, but also for\nnon-perl dependencies, like you can see in the\n[Gtk3](https://build.opensuse.org/package/show/devel:languages:perl/perl-Gtk3)\ndistribution.\n\n`cpanspec` is not perfect, and OBS maintainers will be glad for help in making\nit handle more distributions correctly.\n\n### Debian\n\nSee the [Debian Perl Group](https://perl-team.pages.debian.net/)\n\n* List of [perl modules maintained by the Debian Perl\n  Group](https://salsa.debian.org/perl-team/modules/packages)\n* [Debian Package Tracker](https://tracker.debian.org/teams/pkg-perl/)\n* [How to request a package](https://perl-team.pages.debian.net/howto/RFP.html)\n* Presentation [From Debian, with ♥](https://perl-team.pages.debian.net/docs/yapc-europe-2016/from_debian_with_love.pdf)\n\nThe tool to create debian packages from Perl modules is\n[dh-make-perl](https://salsa.debian.org/perl-team/modules/packages/dh-make-perl).\n\n### Fedora\n\n[List of perl packages](https://apps.fedoraproject.org/packages/s/perl)\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperlpunk%2Fperl5-module-meta","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fperlpunk%2Fperl5-module-meta","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperlpunk%2Fperl5-module-meta/lists"}