12bfe3f2eSlogwang#! /bin/sh
2d30ea906Sjfb8856606# SPDX-License-Identifier: BSD-3-Clause
32bfe3f2eSlogwang# Copyright 2015 6WIND S.A.
42bfe3f2eSlogwang
52bfe3f2eSlogwang# Do some basic checks in MAINTAINERS file
62bfe3f2eSlogwang
72bfe3f2eSlogwangcd $(dirname $0)/..
82bfe3f2eSlogwang
92bfe3f2eSlogwang# speed up by ignoring Unicode details
102bfe3f2eSlogwangexport LC_ALL=C
112bfe3f2eSlogwang
122bfe3f2eSlogwang# Get files matching paths with wildcards and / meaning recursing
132bfe3f2eSlogwangfiles () # <path> [<path> ...]
142bfe3f2eSlogwang{
152bfe3f2eSlogwang	if [ -z "$1" ] ; then
162bfe3f2eSlogwang		return
172bfe3f2eSlogwang	fi
182bfe3f2eSlogwang	if [ -d .git ] ; then
192bfe3f2eSlogwang		git ls-files "$1"
202bfe3f2eSlogwang	else
212bfe3f2eSlogwang		find "$1" -type f |
222bfe3f2eSlogwang		sed 's,^\./,,'
232bfe3f2eSlogwang	fi |
242bfe3f2eSlogwang	# if not ended by /
252bfe3f2eSlogwang	if ! echo "$1" | grep -q '/[[:space:]]*$' ; then
262bfe3f2eSlogwang		# filter out deeper directories
272bfe3f2eSlogwang		sed "/\(\/[^/]*\)\{$(($(echo "$1" | grep -o / | wc -l) + 1))\}/d"
282bfe3f2eSlogwang	else
292bfe3f2eSlogwang		cat
302bfe3f2eSlogwang	fi
312bfe3f2eSlogwang	# next path
322bfe3f2eSlogwang	shift
332bfe3f2eSlogwang	files "$@"
342bfe3f2eSlogwang}
352bfe3f2eSlogwang
362bfe3f2eSlogwang# Get all files matching F: and X: fields
372bfe3f2eSlogwangparse_fx () # <index file>
382bfe3f2eSlogwang{
392bfe3f2eSlogwang	IFS='
402bfe3f2eSlogwang'
412bfe3f2eSlogwang	# parse each line excepted underlining
422bfe3f2eSlogwang	for line in $( (sed '/^-\+$/d' $1 ; echo) | sed 's,^$,§,') ; do
432bfe3f2eSlogwang		if echo "$line" | grep -q '^§$' ; then
442bfe3f2eSlogwang			# empty line delimit end of section
45*2d9fd380Sjfb8856606			include_files=$(files $flines)
46*2d9fd380Sjfb8856606			exclude_files=$(files $xlines)
47*2d9fd380Sjfb8856606			match=$(aminusb "$include_files" "$exclude_files")
48*2d9fd380Sjfb8856606			if [ -n "$include_files" ] ; then
492bfe3f2eSlogwang				printf "# $title "
502bfe3f2eSlogwang				maintainers=$(echo "$maintainers" | sed -r 's,.*<(.*)>.*,\1,')
512bfe3f2eSlogwang				maintainers=$(printf "$maintainers" | sed -e 's,^,<,' -e 's,$,>,')
522bfe3f2eSlogwang				echo $maintainers
532bfe3f2eSlogwang			fi
542bfe3f2eSlogwang			if [ -n "$match" ] ; then
552bfe3f2eSlogwang				echo "$match"
562bfe3f2eSlogwang			fi
572bfe3f2eSlogwang			# flush section
582bfe3f2eSlogwang			unset maintainers
592bfe3f2eSlogwang			unset flines
602bfe3f2eSlogwang			unset xlines
612bfe3f2eSlogwang		elif echo "$line" | grep -q '^[A-Z]: ' ; then
622bfe3f2eSlogwang			# maintainer
632bfe3f2eSlogwang			maintainers=$(add_line_to_if "$line" "$maintainers" 'M: ')
642bfe3f2eSlogwang			# file matching pattern
652bfe3f2eSlogwang			flines=$(add_line_to_if "$line" "$flines" 'F: ')
662bfe3f2eSlogwang			# file exclusion pattern
672bfe3f2eSlogwang			xlines=$(add_line_to_if "$line" "$xlines" 'X: ')
682bfe3f2eSlogwang		else # assume it is a title
692bfe3f2eSlogwang			title="$line"
702bfe3f2eSlogwang		fi
712bfe3f2eSlogwang	done
722bfe3f2eSlogwang}
732bfe3f2eSlogwang
742bfe3f2eSlogwang# Check patterns in F: and X:
752bfe3f2eSlogwangcheck_fx () # <index file>
762bfe3f2eSlogwang{
772bfe3f2eSlogwang	IFS='
782bfe3f2eSlogwang'
792bfe3f2eSlogwang	for line in $(sed -n 's,^[FX]: ,,p' $1 | tr '*' '#') ; do
802bfe3f2eSlogwang		line=$(printf "$line" | tr '#' '*')
812bfe3f2eSlogwang		match=$(files "$line")
822bfe3f2eSlogwang		if [ -z "$match" ] ; then
832bfe3f2eSlogwang			echo "$line"
842bfe3f2eSlogwang		fi
852bfe3f2eSlogwang	done
862bfe3f2eSlogwang}
872bfe3f2eSlogwang
882bfe3f2eSlogwang# Add a line to a set of lines if it begins with right pattern
892bfe3f2eSlogwangadd_line_to_if () # <new line> <lines> <head pattern>
902bfe3f2eSlogwang{
912bfe3f2eSlogwang	(
922bfe3f2eSlogwang		echo "$2"
932bfe3f2eSlogwang		echo "$1" | sed -rn "s,^$3(.*),\1,p"
942bfe3f2eSlogwang	) |
952bfe3f2eSlogwang	sed '/^$/d'
962bfe3f2eSlogwang}
972bfe3f2eSlogwang
982bfe3f2eSlogwang# Subtract two sets of lines
992bfe3f2eSlogwangaminusb () # <lines a> <lines b>
1002bfe3f2eSlogwang{
1012bfe3f2eSlogwang	printf "$1\n$2\n$2" | sort | uniq -u | sed '/^$/d'
1022bfe3f2eSlogwang}
1032bfe3f2eSlogwang
1042bfe3f2eSlogwangprintf 'sections: '
1052bfe3f2eSlogwangparsed=$(parse_fx MAINTAINERS)
1062bfe3f2eSlogwangecho "$parsed" | grep -c '^#'
1072bfe3f2eSlogwangprintf 'with maintainer: '
1082bfe3f2eSlogwangecho "$parsed" | grep -c '^#.*@'
1092bfe3f2eSlogwangprintf 'maintainers: '
1102bfe3f2eSlogwanggrep '^M:.*<' MAINTAINERS | sort -u | wc -l
1112bfe3f2eSlogwang
1122bfe3f2eSlogwangecho
1132bfe3f2eSlogwangecho '##########'
1142bfe3f2eSlogwangecho '# orphan areas'
1152bfe3f2eSlogwangecho '##########'
1162bfe3f2eSlogwangecho "$parsed" | sed -rn 's,^#([^@]*)$,\1,p' | uniq
1172bfe3f2eSlogwang
1182bfe3f2eSlogwangecho
1192bfe3f2eSlogwangecho '##########'
1202bfe3f2eSlogwangecho '# files not listed'
1212bfe3f2eSlogwangecho '##########'
1222bfe3f2eSlogwangall=$(files ./)
1232bfe3f2eSlogwanglisted=$(echo "$parsed" | sed '/^#/d' | sort -u)
1242bfe3f2eSlogwangaminusb "$all" "$listed"
1252bfe3f2eSlogwang
1262bfe3f2eSlogwangecho
1272bfe3f2eSlogwangecho '##########'
1282bfe3f2eSlogwangecho '# wrong patterns'
1292bfe3f2eSlogwangecho '##########'
1302bfe3f2eSlogwangcheck_fx MAINTAINERS
1312bfe3f2eSlogwang
1322bfe3f2eSlogwang# TODO: check overlaps
133