add python tool to detect and remove (if desired) error docs from headers

also document the tools in the manual.
This commit is contained in:
Axel Kohlmeyer
2022-04-23 13:52:12 -04:00
parent 78c10bac4a
commit 4d1bdb4741
6 changed files with 179 additions and 86 deletions

View File

@ -87,7 +87,7 @@ Miscellaneous tools
.. table_from_list::
:columns: 6
* :ref:`CMake <cmake>`
* :ref:`LAMMPS coding standards <coding_standard>`
* :ref:`emacs <emacs>`
* :ref:`i-pi <ipi>`
* :ref:`kate <kate>`
@ -189,27 +189,32 @@ for the :doc:`chain benchmark <Speed_bench>`.
----------
.. _cmake:
.. _coding_standard:
CMake tools
-----------
LAMMPS coding standard
----------------------
The ``cmbuild`` script is a wrapper around using ``cmake --build <dir>
--target`` and allows compiling LAMMPS in a :ref:`CMake build folder
<cmake_build>` with a make-like syntax regardless of the actual build
tool and the specific name of the program used (e.g. ``ninja-v1.10`` or
``gmake``) when using ``-D CMAKE_MAKE_PROGRAM=<name>``.
The ``coding_standard`` folder contains multiple python scripts to
check for and apply some LAMMPS coding conventions. The following
scripts are available:
.. parsed-literal::
Usage: cmbuild [-v] [-h] [-C <dir>] [-j <num>] [<target>]
permissions.py # detects if sources have executable permissions and scripts have not
whitespace.py # detects TAB characters and trailing whitespace
homepage.py # detects outdated LAMMPS homepage URLs (pointing to sandia.gov instead of lammps.org)
errordocs.py # detects deprecated error docs in header files
Options:
-h print this message
-j <NUM> allow processing of NUM concurrent tasks
-C DIRECTORY execute build in folder DIRECTORY
-v produce verbose output
The tools need to be given the main folder of the LAMMPS distribution
or individual file names as argument and will by default check them
and report any non-compliance. With the optional ``-f`` argument the
corresponding script will try to change the non-compliant file(s) to
match the conventions.
For convenience this scripts can also be invoked by the make file in
the ``src`` folder with, `make check-whitespace` or `make fix-whitespace`
to either detect or edit the files. Correspondingly for the other python
scripts. `make check` will run all checks.
----------

View File

@ -472,6 +472,8 @@ tar:
@cd STUBS; $(MAKE)
@echo "Created $(ROOT)_src.tar.gz"
check: check-whitespace check-permissions check-homepage check-errordocs
check-whitespace:
$(PYTHON) ../tools/coding_standard/whitespace.py ..
@ -490,6 +492,12 @@ check-homepage:
fix-homepage:
$(PYTHON) ../tools/coding_standard/homepage.py .. -f
check-errordocs:
$(PYTHON) ../tools/coding_standard/errordocs.py ..
fix-errordocs:
$(PYTHON) ../tools/coding_standard/errordocs.py .. -f
format-src:
clang-format -i --verbose --style=file *.cpp *.h */*.cpp */*.h

View File

@ -16,7 +16,6 @@ amber2lmp python scripts for using AMBER to setup LAMMPS input
binary2txt convert a LAMMPS dump file from binary to ASCII text
ch2lmp convert CHARMM files to LAMMPS input
chain create a data file of bead-spring chains
cmake tools and scripts for use with CMake
coding_standard python scripts to detect and fix some LAMMPS conventions
colvars post-process output of the fix colvars command
createatoms generate lattices of atoms within a geometry

View File

@ -1,69 +0,0 @@
#!/bin/bash
# make like wrapper around "cmake --build"
# (c) 2020 Axel Kohlmeyer <akohlmey@temple.edu>
# This file is in the public domain
WORKDIR="${PWD}"
PARAMS=""
MYARGS=""
usage()
{
echo "Usage: cmbuild [-v] [-h] [-C <dir>] [-j <num>] [<target>]" >&2
}
help()
{
usage
cat >&2 <<EOF
Options:
-h print this message
-j <NUM> allow processing of NUM concurrent tasks
-C DIRECTORY execute build in folder DIRECTORY
-v produce verbose output
EOF
}
while (( "$#" )); do
case "$1" in
-C)
WORKDIR="$2"
shift 2
;;
-v)
MYARGS="${MYARGS} -v"
shift
;;
-h)
help
exit 2
;;
-j)
MYARGS="${MYARGS} -j $2"
shift 2
;;
--)
shift
break
;;
-*)
echo "Error: Unsupported flag $1" >&2
echo
usage
exit 1
;;
*)
PARAMS="${PARAMS} $1"
shift
;;
esac
done
if [ ! -f "${WORKDIR}/CMakeCache.txt" ] ; then
echo "Must execute in a CMake build directory or use -C flag to select one" >&2
exit 3
fi
eval set -- "${PARAMS} $@"
exec cmake --build "${WORKDIR}" ${MYARGS} --target "$@"

View File

@ -2,4 +2,6 @@ These Python scripts help to detect whether files in the repository
conform to LAMMPS coding conventions or not, and can fix those issues, too.
permissions.py detects if sources have executable permissions and scripts have not
whitespace.py (currently) detects trailing whitespace
whitespace.py detects TAB characters and trailing whitespace
homepage.py detects outdated LAMMPS homepage URLs (pointing to sandia.gov instead of lammps.org)
errordocs.py detects deprecated error docs in header files

View File

@ -0,0 +1,148 @@
#!/usr/bin/env python3
# Utility for detecting leftover error/warning docs in header files
#
# Written by Axel Kohlmeyer (Temple University)
from __future__ import print_function
import sys
if sys.version_info.major < 3:
sys.exit('This script must be run with Python 3.5 or later')
if sys.version_info.minor < 5:
sys.exit('This script must be run with Python 3.5 or later')
import os
import glob
import re
import yaml
import argparse
import shutil
DEFAULT_CONFIG = """
recursive: true
include:
- src/**
patterns:
- "*.h"
"""
def check_errordocs(f):
pattern = re.compile(r'^ */\* *ERROR/WARNING messag')
lineno = 1
errors = set()
for line in f:
if pattern.match(line):
errors.add(lineno)
lineno += 1
return errors
def check_file(path):
if path.find('errordocs.py') >= 0: return { 'errordocs_errors' : '' }
encoding = 'UTF-8'
errordocs_errors = set()
try:
with open(path, 'r') as f:
errordocs_errors = check_errordocs(f)
except UnicodeDecodeError:
encoding = 'ISO-8859-1'
try:
with open(path, 'r', encoding=encoding) as f:
errordocs_errors = check_errordocs(f)
except Exception:
encoding = 'unknown'
return {
'errordocs_errors': errordocs_errors,
'encoding': encoding
}
def fix_file(path, check_result):
if path.find('errordocs.py') >= 0: return
newfile = path + ".modified"
pattern = re.compile(r'[\n\r ]* */\* *ERROR/WARNING *messag.*\*/', re.DOTALL)
with open(newfile, 'w', encoding='UTF-8') as out:
with open(path, 'r', encoding=check_result['encoding']) as src:
filetxt = re.sub(pattern,'', src.read());
print(filetxt, end='', file=out)
shutil.copymode(path, newfile)
shutil.move(newfile, path)
def check_folder(directory, config, fix=False, verbose=False):
success = True
files = []
for base_path in config['include']:
for pattern in config['patterns']:
path = os.path.join(directory, base_path, pattern)
files += glob.glob(path, recursive=config['recursive'])
for f in files:
path = os.path.normpath(f)
if verbose:
print("Checking file:", path)
result = check_file(path)
has_resolvable_errors = False
for lineno in result['errordocs_errors']:
print("[Error] Found LAMMPS errordocs @ {}:{}".format(path, lineno))
has_resolvable_errors = True
if has_resolvable_errors:
if fix:
print("Applying automatic fixes to file:", path)
fix_file(path, result)
else:
success = False
return success
def main():
parser = argparse.ArgumentParser(description='Utility for detecting and fixing whitespace issues in LAMMPS')
parser.add_argument('-c', '--config', metavar='CONFIG_FILE', help='location of a optional configuration file')
parser.add_argument('-f', '--fix', action='store_true', help='automatically fix URLs')
parser.add_argument('-v', '--verbose', action='store_true', help='verbose output')
parser.add_argument('DIRECTORY', help='directory (or file) that should be checked')
args = parser.parse_args()
lammpsdir = os.path.abspath(os.path.expanduser(args.DIRECTORY))
if args.config:
with open(args.config, 'r') as cfile:
config = yaml.load(cfile, Loader=yaml.FullLoader)
else:
config = yaml.load(DEFAULT_CONFIG, Loader=yaml.FullLoader)
if os.path.isdir(lammpsdir):
if not check_folder(lammpsdir, config, args.fix, args.verbose):
sys.exit(1)
else:
success = True
path = os.path.normpath(lammpsdir)
if args.verbose:
print("Checking file:", path)
result = check_file(path)
has_resolvable_errors = False
for lineno in result['errordocs_errors']:
print("[Error] Found LAMMPS errordocs @ {}:{}".format(path, lineno))
has_resolvable_errors = True
if has_resolvable_errors:
if args.fix:
print("Applying automatic fixes to file:", path)
fix_file(path, result)
else:
success = False
if not success:
sys.exit(1)
if __name__ == "__main__":
main()