podlinkcheck - Man Page
check Perl pod L<> link references
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
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
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/>.