Git fork
1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
6# Parse arguments, a simple state machine for input like:
7#
8# <file-to-check.adoc> <valid-files-to-link-to> --section=1 git.adoc git-add.adoc [...] --to-lint git-add.adoc a-file.adoc [...]
9my %TXT;
10my %SECTION;
11my $section;
12my $lint_these = 0;
13my $to_check = shift @ARGV;
14for my $arg (@ARGV) {
15 if (my ($sec) = $arg =~ /^--section=(\d+)$/s) {
16 $section = $sec;
17 next;
18 }
19
20 my ($name) = $arg =~ /^(.*?)\.adoc$/s;
21 unless (defined $section) {
22 $TXT{$name} = $arg;
23 next;
24 }
25
26 $SECTION{$name} = $section;
27}
28
29my $exit_code = 0;
30sub report {
31 my ($pos, $line, $target, $msg) = @_;
32 substr($line, $pos) = "' <-- HERE";
33 $line =~ s/^\s+//;
34 print STDERR "$ARGV:$.: error: $target: $msg, shown with 'HERE' below:\n";
35 print STDERR "$ARGV:$.:\t'$line\n";
36 $exit_code = 1;
37}
38
39@ARGV = sort values %TXT;
40die "BUG: No list of valid linkgit:* files given" unless @ARGV;
41@ARGV = $to_check;
42while (<>) {
43 my $line = $_;
44 while ($line =~ m/(.{,8})((git[-a-z]+|scalar)\[(\d)*\])/g) {
45 my $pos = pos $line;
46 my ($macro, $target, $page, $section) = ($1, $2, $3, $4);
47 if ( $macro ne "linkgit:" && $macro !~ "ifn?def::" && $macro ne "endif::" ) {
48 report($pos, $line, $target, "linkgit: macro expected");
49 }
50 }
51 while ($line =~ m/linkgit:((.*?)\[(\d)\])/g) {
52 my $pos = pos $line;
53 my ($target, $page, $section) = ($1, $2, $3);
54
55 # De-AsciiDoc
56 $page =~ s/{litdd}/--/g;
57
58 if (!exists $TXT{$page}) {
59 report($pos, $line, $target, "link outside of our own docs");
60 next;
61 }
62 if (!exists $SECTION{$page}) {
63 report($pos, $line, $target, "link outside of our sectioned docs");
64 next;
65 }
66 my $real_section = $SECTION{$page};
67 if ($section != $SECTION{$page}) {
68 report($pos, $line, $target, "wrong section (should be $real_section)");
69 next;
70 }
71 }
72 # this resets our $. for each file
73 close ARGV if eof;
74}
75
76exit $exit_code;