Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
documentation-file-ref-check 3.72 KiB
#!/usr/bin/env perl
# SPDX-License-Identifier: GPL-2.0
#
# Treewide grep for references to files under Documentation, and report
# non-existing files in stderr.

use warnings;
use strict;
use Getopt::Long qw(:config no_auto_abbrev);

my $scriptname = $0;
$scriptname =~ s,.*/([^/]+/),$1,;

# Parse arguments
my $help = 0;
my $fix = 0;

GetOptions(
	'fix' => \$fix,
	'h|help|usage' => \$help,
);

if ($help != 0) {
    print "$scriptname [--help] [--fix]\n";
    exit -1;
}

# Step 1: find broken references
print "Finding broken references. This may take a while...  " if ($fix);

my %broken_ref;

open IN, "git grep 'Documentation/'|"
     or die "Failed to run git grep";
while (<IN>) {
	next if (!m/^([^:]+):(.*)/);

	my $f = $1;
	my $ln = $2;

	# Makefiles and scripts contain nasty expressions to parse docs
	next if ($f =~ m/Makefile/ || $f =~ m/\.sh$/);

	# Skip this script
	next if ($f eq $scriptname);

	if ($ln =~ m,\b(\S*)(Documentation/[A-Za-z0-9\_\.\,\~/\*\[\]\?+-]*)(.*),) {
		my $prefix = $1;
		my $ref = $2;
		my $base = $2;
		my $extra = $3;

		# some file references are like:
		# /usr/src/linux/Documentation/DMA-{API,mapping}.txt
		# For now, ignore them
		next if ($extra =~ m/^{/);

		# Remove footnotes at the end like:
		# Documentation/devicetree/dt-object-internal.txt[1]
		$ref =~ s/(txt|rst)\[\d+]$/$1/;

		# Remove ending ']' without any '['
		$ref =~ s/\].*// if (!($ref =~ m/\[/));

		# Remove puntuation marks at the end
		$ref =~ s/[\,\.]+$//;

		my $fulref = "$prefix$ref";

		$fulref =~ s/^(\<file|ref)://;