ci: validate "linkgit:" in documentation
It is easy to add incorrect "linkgit:<page>[<section>]" references to our documentation suite. Catch these common classes of errors: * Referring to Documentation/<page>.txt that does not exist. * Referring to a <page> outside the Git suite. In general, <page> must begin with "git". * Listing the manual <section> incorrectly. The first line of the Documentation/<page>.txt must end with "(<section>)". with a new script "ci/lint-gitlink", and drive it from "make check-docs". Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano committed
May 4, 2016 at 14:34 UTC
ab81411cede9e5fe52b416c4df835e19f1048426
3 files changed
+76
Documentation/Makefile
+4
@@ -204,6 +204,7 @@ ifndef V
204
QUIET_DBLATEX = @echo ' ' DBLATEX $@;
205
QUIET_XSLTPROC = @echo ' ' XSLTPROC $@;
206
QUIET_GEN = @echo ' ' GEN $@;
207
+ QUIET_LINT = @echo ' ' LINT $@;
208
QUIET_STDERR = 2> /dev/null
209
QUIET_SUBDIR0 = +@subdir=
210
QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \
@@ -427,4 +428,7 @@ quick-install-html: require-htmlrepo
428
print-man1:
429
@for i in $(MAN1_TXT); do echo $$i; done
430
431
+lint-docs::
432
+ $(QUIET_LINT)$(PERL_PATH) lint-gitlink.perl
433
+
434
.PHONY: FORCE
Documentation/lint-gitlink.perl
new
+71
@@ -0,0 +1,71 @@
1
+#!/usr/bin/perl
2
+
3
+use File::Find;
4
+use Getopt::Long;
5
+
6
+my $basedir = ".";
7
+GetOptions("basedir=s" => \$basedir)
8
+ or die("Cannot parse command line arguments\n");
9
+
10
+my $found_errors = 0;
11
+
12
+sub report {
13
+ my ($where, $what, $error) = @_;
14
+ print "$where: $error: $what\n";
15
+ $found_errors = 1;
16
+}
17
+
18
+sub grab_section {
19
+ my ($page) = @_;
20
+ open my $fh, "<", "$basedir/$page.txt";
21
+ my $firstline = <$fh>;
22
+ chomp $firstline;
23
+ close $fh;
24
+ my ($section) = ($firstline =~ /.*\((\d)\)$/);
25
+ return $section;
26
+}
27
+
28
+sub lint {
29
+ my ($file) = @_;
30
+ open my $fh, "<", $file
31
+ or return;
32
+ while (<$fh>) {
33
+ my $where = "$file:$.";
34
+ while (s/linkgit:((.*?)\[(\d)\])//) {
35
+ my ($target, $page, $section) = ($1, $2, $3);
36
+
37
+ # De-AsciiDoc
38
+ $page =~ s/{litdd}/--/g;
39
+
40
+ if ($page !~ /^git/) {
41
+ report($where, $target, "nongit link");
42
+ next;
43
+ }
44
+ if (! -f "$basedir/$page.txt") {
45
+ report($where, $target, "no such source");
46
+ next;
47
+ }
48
+ $real_section = grab_section($page);
49
+ if ($real_section != $section) {
50
+ report($where, $target,
51
+ "wrong section (should be $real_section)");
52
+ next;
53
+ }
54
+ }
55
+ }
56
+ close $fh;
57
+}
58
+
59
+sub lint_it {
60
+ lint($File::Find::name) if -f && /\.txt$/;
61
+}
62
+
63
+if (!@ARGV) {
64
+ find({ wanted => \&lint_it, no_chdir => 1 }, $basedir);
65
+} else {
66
+ for (@ARGV) {
67
+ lint($_);
68
+ }
69
+}
70
+
71
+exit $found_errors;
Makefile
+1
@@ -2496,6 +2496,7 @@ ALL_COMMANDS += git-gui git-citool
2496
2497
.PHONY: check-docs
2498
check-docs::
2499
+ $(MAKE) -C Documentation lint-docs
2500
@(for v in $(ALL_COMMANDS); \
2501
do \
2502
case "$$v" in \