devtools: add script to check for non inclusive naming
Checks
Commit Message
Script to find words that should not be used.
Really just a wrapper around git grep command.
By default it prints matches.
Uses the word lists from Inclusive Naming Initiative
see https://inclusivenaming.org/word-lists/
Examples:
$ ./devtools/check-naming-policy.sh -c
app/test-compress-perf/comp_perf_test_cyclecount.c:1
uapp/test-compress-perf/comp_perf_test_throughput.c:1
app/test-compress-perf/comp_perf_test_verify.c:1
app/test/test_common.c:1
...
$ ./devtools/check-naming-policy.py lib/pcapng
lib/pcapng/rte_pcapng.c: /* sanity check that is really a pcapng mbuf */
$ ./devtools/check-naming-policy.py -l lib/eal
lib/eal/common/eal_common_memory.c
lib/eal/common/eal_common_proc.c
lib/eal/common/eal_common_trace.c
lib/eal/common/eal_memcfg.h
lib/eal/common/rte_malloc.c
lib/eal/freebsd/eal.c
lib/eal/include/generic/rte_power_intrinsics.h
lib/eal/include/generic/rte_rwlock.h
lib/eal/include/generic/rte_spinlock.h
lib/eal/include/rte_debug.h
lib/eal/include/rte_seqlock.h
lib/eal/linux/eal.c
lib/eal/windows/eal.c
lib/eal/x86/include/rte_rtm.h
lib/eal/x86/include/rte_spinlock.h
lib/eal/x86/rte_power_intrinsics.c
$ ./devtools/check-inclusive-naming -h
usage: check-inclusive-naming.py [-h] [-c] [-d] [-l] [-t {0,1,2,3}]
[-x EXCLUDE] [--url URL]
[paths ...]
Identify word usage not aligned with inclusive naming
positional arguments:
paths files and directory to scan
options:
-h, --help show this help message and exit
-c, --count Show the nuber of lines that match
-d, --debug Debug this script
-l, --files-with-matches
Show only names of files with hits
-t {0,1,2,3}, --tier {0,1,2,3}
Show non-conforming words of particular tier
-x EXCLUDE, --exclude EXCLUDE
Exclude path from scan
--url URL URL for the non-inclusive naming word list
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
v4 - fix python lint warnings and spelling
MAINTAINERS | 1 +
devtools/check-inclusive-naming.py | 137 +++++++++++++++++++++++++++++
2 files changed, 138 insertions(+)
create mode 100755 devtools/check-inclusive-naming.py
@@ -89,6 +89,7 @@ F: devtools/check-doc-vs-code.sh
F: devtools/check-dup-includes.sh
F: devtools/check-maintainers.sh
F: devtools/check-forbidden-tokens.awk
+F: devtools/check-inclusive-naming.py
F: devtools/check-git-log.sh
F: devtools/check-spdx-tag.sh
F: devtools/check-symbol-change.sh
new file mode 100755
@@ -0,0 +1,137 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2023 Stephen Hemminger
+#
+# This script scans the source tree and creates list of files
+# containing words that are recommended to avoided by the
+# Inclusive Naming Initiative.
+# See: https://inclusivenaming.org/word-lists/
+
+"""Script to run git grep to finds strings in inclusive naming word list."""
+
+import argparse
+import json
+import subprocess
+import sys
+from urllib.request import urlopen
+
+WORDLIST_URL = 'https://inclusivenaming.org/word-lists/index.json'
+
+# These give false positives
+dont_scan = [
+ 'doc/guides/rel_notes/',
+ 'doc/guides/contributing/coding_style.rst'
+ 'doc/guides/prog_guide/glossary.rst'
+]
+
+
+def args_parse():
+ "parse arguments and return the argument object back to main"
+
+ parser = argparse.ArgumentParser(
+ description="Identify word usage not aligned with inclusive naming")
+ parser.add_argument("-c",
+ "--count",
+ help="Show the number of lines that match",
+ action='store_true')
+ parser.add_argument("-d",
+ "--debug",
+ default=False,
+ help="Debug this script",
+ action='store_true')
+ parser.add_argument("-l",
+ "--files-with-matches",
+ help="Show only names of files with hits",
+ action='store_true')
+ parser.add_argument("-n",
+ "--line-number",
+ help="Prefix with line number to matching lines",
+ action='store_true')
+ # note: tier 0 is "OK to use"
+ parser.add_argument("-t",
+ "--tier",
+ type=int,
+ choices=range(0, 4),
+ action='append',
+ help="Show non-conforming words of particular tier")
+ parser.add_argument('-x',
+ "--exclude",
+ default=dont_scan,
+ action='append',
+ help="Exclude path from scan")
+ parser.add_argument('--url',
+ default=WORDLIST_URL,
+ help="URL for the non-inclusive naming word list")
+ parser.add_argument('paths', nargs='*',
+ help='files and directory to scan')
+
+ return parser.parse_args()
+
+
+def fetch_wordlist(url, tiers):
+ "Read list of words from inclusivenaming.org"
+
+ # The word list is returned as JSON like:
+ # {
+ # "data" :
+ # [
+ # {
+ # "term": "abort",
+ # "tier" : "1",
+ # "recommendation": "Replace when possible.",
+ # ...
+ with urlopen(url) as response:
+ entries = json.loads(response.read())['data']
+
+ wordlist = []
+ for item in entries:
+ tier = int(item['tier'])
+ if tiers.count(tier) > 0:
+ # convert minus sign to minus or space regex
+ pattern = item['term'].replace('-', '[- ]')
+ wordlist.append(pattern.lower())
+ return wordlist
+
+
+def git_args(args):
+ "Construct command line based on args"
+
+ # Default to Tier 1, 2 and 3.
+ if args.tier:
+ tiers = args.tier
+ else:
+ tiers = list(range(1, 4))
+
+ wordlist = fetch_wordlist(args.url, tiers)
+ if args.debug:
+ print(f"Matching on: {wordlist}")
+
+ cmd = ['git', 'grep', '-i']
+ if args.files_with_matches:
+ cmd.append('-l')
+ if args.count:
+ cmd.append('-c')
+ if args.line_number:
+ cmd.append('-n')
+ for word in wordlist:
+ cmd.append('-e')
+ cmd.append(word)
+ cmd.append('--')
+ # convert the dont_scan paths to regexp
+ for path in dont_scan:
+ cmd.append(f":^{path}")
+ cmd += args.paths
+ if args.debug:
+ print(cmd)
+ return cmd
+
+
+def main():
+ "decode command line arguments then run setup to run"
+
+ grep = subprocess.run(git_args(args_parse()), check=False)
+ sys.exit(grep.returncode)
+
+
+if __name__ == "__main__":
+ main()