PODLINKCHECK(1)

πŸ“¦
version 15 Β· 5 versions
, in epel 9

Okay bestie, this is podlinkcheck(1) and it's literally here to check your Perl POD L<> links so you don't embarrass yourself in front of the whole CPAN. No cap. πŸŽ€


🌸 SYNOPSIS 🌸

podlinkcheck [--options] file-or-dir...

πŸ’… OPTIONS πŸ’…

The command line options are:

  • --help β€” Print a command line summary.
  • -I dir β€” Add an extra directory to look for target modules.
  • --verbose β€” Print more about program operation (including CPAN loading).
  • --version β€” Print the program version number and exit.

πŸ¦‹ DESCRIPTION πŸ¦‹

PodLinkCheck parses Perl POD from a script, module or documentation and checks that L<> links within it refer to a known program, module, or man page.

L<foo>          check module, pod or program "foo"
L<foo/section>    and check section within the pod
L<bar(1)>       check man page "bar(1)"

The command line is either individual files or whole directories. For a directory all the .pl, .pm and .pod files under it are checked. So for example to churn through all installed add-on modules,

podlinkcheck /usr/share/perl5

Bad links are usually typos in the module name or section name, or sometimes L<display|target> parts the wrong way around. Occasionally there may be an L<foo> used where just markup C<> or I<> was intended.

πŸ” Checks πŸ”

External links are checked by seeking the target .pm module or .pod documentation in the @INC path (per Pod::Find), or seeking a script (no file extension) in the usual executable PATH. A section name in a link is checked by parsing the POD in the target file.

If a module is not installed in @INC or extra -I directories then its existence is also checked in the CPAN indexes with App::cpanminus, CPAN::SQLite, CPAN or CPANPLUS. Nothing is downloaded, just current data consulted. A warning is given if a section name in a link goes unchecked because it's on CPAN but not available locally.

If checking your own work then most likely you will have copies of cross-referenced modules installed (having compared or tried them). In that sense the CPAN index lookups are a fallback.

Manpage links are checked by asking the man program if it recognises the name, including any number part like chmod(2). A manpage can also satisfy what otherwise appears to be a POD link with no sub-section, since there's often some confusion between the two.

Internal links are sometimes written

L<SYNOPSIS>                     # may be ambiguous

but the Perl 5.10 perlpodspec advice is to avoid ambiguity between an external module and a one-word internal section by writing a section with / or quotes,

See L</SYNOPSIS> above.         # good

See L<"SYNOPSIS"> above.        # good

podlinkcheck warns about L<SYNOPSIS> section links. But not if it's both an valid external module and internal section -- because it's not uncommon to have a module name as a heading or item and an L<> link still meaning the external one.

🌈 Section Name Matching 🌈

An L<> section name can use just the first word of an item or heading. This is how Pod::Checker behaves and it's good for perlfunc cross references where just the function name can be given without the full argument list of the =item. Eg.

L<perlfunc/split>

The first word is everything up to the first whitespace. This doesn't come out very well on a target like =item somefun( ARG ), but it's how Pod::Checker 1.45 behaves. If the targets are your own then you might make the first word or full item something sensible to appear in an L<>.

If a target section is not found then podlinkcheck will try to suggest something close, eg. differing only in punctuation or upper/lower case. Some of the POD translators may ignore upper/lower case anyway, but it's good to write an L<> the same as the actual target.

foo.pl:130:31: no section "constructor" in "CHI"
  (file /usr/share/perl5/CHI.pm)
  perhaps it should be "CONSTRUCTOR"

For reference, numbered =item section names go in an L<> without the number. This is good since the numbering might change. If podlinkcheck suggests a number in a target then it may be a mistake in the target document. A numbered item should have the number alone on the =item and the section name as the next paragraph.

=item 1.                        # good

The First Thing                 # the section name

Paragraph about this thing.

=item 2. The Second Thing       # bad

Paragraph about this next thing.

The second item 2. The Second Thing is not a numbered item for POD purposes, but rather text that happens to start with a number. Of course sometimes that's what you want, eg.

=item 64 Bit Support

podlinkcheck uses Pod::Simple for parsing and so follows its interpretation of the various hairy L<> link forms. If an L<> appears to be mis-interpreted you might rewrite or add some escapes (like E<sol>) for the benefit of all translators which use Pod::Simple. In Perl 5.10 that includes the basic pod2man.

πŸ‘‘ Other Ways to Do It πŸ‘‘

podchecker (the Pod::Checker module) checks internal links, but it doesn't check external links.

Test::Pod::LinkCheck is similar in a .t test framework. It uses some of PodLinkCheck but different reporting and a stricter approach to dubious POD.


πŸ’€ EXIT STATUS πŸ’€

Exit is 0 for no problems found, or non-zero for problems.


πŸ“ ENVIRONMENT VARIABLES πŸ“

  • PATH β€” The search path for installed scripts.
  • HOME β€” Used by the various CPAN modules for ~/.cpan etc directories.
  • PERL5LIB β€” The usual extra Perl module directories (see ENVIRONMENT in perlrun), which become @INC where link targets are sought.

πŸ™ˆ BUGS πŸ™ˆ

App::cpanminus is checked first since it's a bsearch of 02packages.details.txt, and CPAN::SQLite second since it's a database lookup. But if a target is not found there then the full CPAN and CPANPLUS caches are loaded and checked. This might use a fair bit of memory for a non-existent target, but it's also possible they're more up-to-date.

No attempt is made to tell which of the indexes is the most up-to-date. If a module has been renamed (bad) then it may still exist in an old index. The suggestion is to avoid having old stuff lying around (including old mirror files in App::cpanminus).

The code consulting CPAN.pm may need a tolerably new version of that module, maybe 1.61 circa Perl 5.8.0. On earlier versions its index is not used.

The line:column number reported for an offending L<> is found by some gambits extending what Pod::Simple normally records. There's a chance it could be a little off within the paragraph.

Pod::Simple prior to version 3.24 didn't allow dots . in man-page names, resulting in for example login.conf(5) being treated as a Perl module name not a man page name. If you have such links then use Pod::Simple 3.24 up.

Directories are currently traversed using File::Find::Iterator. It follows symlinks but neither its version 0.4 nor PodLinkCheck guard against infinite descent into symlink cycles. The intention perhaps would be follow all symlinks to files, but follow to a directory just once as protection against cycles.


🧚 FILES 🧚

  • ~/.cpanm/sources/*/02packages.details.txt files from App::cpanminus
  • ~/.cpan/cpandb.sql used by CPAN::SQLite
  • ~/.cpan/Metadata used by CPAN
  • ~/.cpanplus/* variously used by CPANPLUS

⭐ SEE ALSO ⭐

podchecker, podlint

Pod::Simple, Pod::Find, CPAN, CPAN::SQLite, CPANPLUS, cpanm

Test::Pod::LinkCheck, Pod::Checker, Test::Pod


🌟 HOME PAGE 🌟

http://user42.tuxfamily.org/podlinkcheck/index.html


πŸ’– LICENSE πŸ’–

Copyright 2010, 2011, 2012, 2013, 2016, 2017 Kevin Ryde

PodLinkCheck is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.

PodLinkCheck is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with PodLinkCheck. If not, see <http://www.gnu.org/licenses/>.


This page is from perl v5.32.1, dated 2022-01-14. Go check those links bestie, ily! πŸ’…βœ¨

πŸ“¦ where this page comes from