Complete updates of remaining code-smell tests. (#37743)
* Add text/binary file support to code smell tests. * Enhance line-endings code smell test. * Enhance no-smart-quotes code-smell test. * Enhance shebang code-smell test.
This commit is contained in:
parent
7c311ad615
commit
05220d693d
10 changed files with 157 additions and 63 deletions
|
@ -17,6 +17,7 @@ from lib.util import (
|
|||
load_plugins,
|
||||
parse_to_dict,
|
||||
ABC,
|
||||
is_binary_file,
|
||||
)
|
||||
|
||||
from lib.ansible_util import (
|
||||
|
@ -240,6 +241,7 @@ class SanityCodeSmellTest(SanityTest):
|
|||
prefixes = config.get('prefixes')
|
||||
files = config.get('files')
|
||||
always = config.get('always')
|
||||
text = config.get('text')
|
||||
|
||||
if output == 'path-line-column-message':
|
||||
pattern = '^(?P<path>[^:]*):(?P<line>[0-9]+):(?P<column>[0-9]+): (?P<message>.*)$'
|
||||
|
@ -257,6 +259,12 @@ class SanityCodeSmellTest(SanityTest):
|
|||
if sys.version_info[0] == 2:
|
||||
paths = [p.decode('utf-8') for p in paths]
|
||||
|
||||
if text is not None:
|
||||
if text:
|
||||
paths = [p for p in paths if not is_binary_file(p)]
|
||||
else:
|
||||
paths = [p for p in paths if is_binary_file(p)]
|
||||
|
||||
if extensions:
|
||||
paths = [p for p in paths if os.path.splitext(p)[1] in extensions or (p.startswith('bin/') and '.py' in extensions)]
|
||||
|
||||
|
|
4
test/sanity/code-smell/line-endings.json
Normal file
4
test/sanity/code-smell/line-endings.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"text": true,
|
||||
"output": "path-message"
|
||||
}
|
25
test/sanity/code-smell/line-endings.py
Executable file
25
test/sanity/code-smell/line-endings.py
Executable file
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
skip = set([
|
||||
'test/integration/targets/template/files/foo.dos.txt',
|
||||
'test/integration/targets/win_regmerge/templates/win_line_ending.j2',
|
||||
'test/integration/targets/win_template/files/foo.dos.txt',
|
||||
])
|
||||
|
||||
for path in sys.argv[1:] or sys.stdin.read().splitlines():
|
||||
if path in skip:
|
||||
continue
|
||||
|
||||
with open(path, 'rb') as path_fd:
|
||||
contents = path_fd.read()
|
||||
|
||||
if b'\r' in contents:
|
||||
print('%s: use "\\n" for line endings instead of "\\r\\n"' % path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,15 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
grep -rIPl '\r' . \
|
||||
--exclude-dir .git \
|
||||
--exclude-dir .tox \
|
||||
| grep -v -F \
|
||||
-e './test/integration/targets/template/files/foo.dos.txt' \
|
||||
-e './test/integration/targets/win_regmerge/templates/win_line_ending.j2' \
|
||||
-e './test/integration/targets/win_template/files/foo.dos.txt' \
|
||||
|
||||
if [ $? -ne 1 ]; then
|
||||
printf 'One or more file(s) listed above have invalid line endings.\n'
|
||||
printf 'Make sure all files use "\\n" for line endings instead of "\\r\\n".\n'
|
||||
exit 1
|
||||
fi
|
4
test/sanity/code-smell/no-smart-quotes.json
Normal file
4
test/sanity/code-smell/no-smart-quotes.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"text": true,
|
||||
"output": "path-line-column-message"
|
||||
}
|
37
test/sanity/code-smell/no-smart-quotes.py
Executable file
37
test/sanity/code-smell/no-smart-quotes.py
Executable file
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
skip = set([
|
||||
'test/sanity/code-smell/%s' % os.path.basename(__file__),
|
||||
'docs/docsite/rst/dev_guide/testing/sanity/no-smart-quotes.rst',
|
||||
'test/integration/targets/unicode/unicode.yml',
|
||||
'test/integration/targets/lookup_properties/lookup-8859-15.ini',
|
||||
])
|
||||
|
||||
for path in sys.argv[1:] or sys.stdin.read().splitlines():
|
||||
if path in skip:
|
||||
continue
|
||||
|
||||
with open(path, 'rb') as path_fd:
|
||||
for line, text in enumerate(path_fd.readlines()):
|
||||
try:
|
||||
text = text.decode('utf-8')
|
||||
except UnicodeDecodeError as ex:
|
||||
print('%s:%d:%d: UnicodeDecodeError: %s' % (path, line + 1, ex.start + 1, ex))
|
||||
continue
|
||||
|
||||
match = re.search(u'([‘’“”])', text)
|
||||
|
||||
if match:
|
||||
print('%s:%d:%d: use ASCII quotes `\'` and `"` instead of Unicode quotes' % (
|
||||
path, line + 1, match.start(1) + 1))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,24 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck disable=SC1015,SC1016
|
||||
egrep -r '[‘’“”]' . \
|
||||
--exclude-dir .git \
|
||||
--exclude-dir .tox \
|
||||
--exclude-dir __pycache__ \
|
||||
| grep -v \
|
||||
-e './test/sanity/code-smell/no-smart-quotes.sh' \
|
||||
-e './docs/docsite/rst/dev_guide/testing/sanity/no-smart-quotes.rst' \
|
||||
-e './test/integration/targets/unicode/unicode.yml' \
|
||||
-e '\.doctree matches$' \
|
||||
-e '\.pickle matches$' \
|
||||
-e './docs/docsite/_build/html/'
|
||||
|
||||
if [ $? -ne 1 ]; then
|
||||
printf 'The file(s) listed above have non-ascii quotes.\n'
|
||||
# shellcheck disable=SC1015,SC1016
|
||||
printf 'Make sure all files use " and '"'"' as quotation marks\n'
|
||||
printf 'These sed commands may be of help to you:\n'
|
||||
# shellcheck disable=SC1015,SC1016
|
||||
printf " sed 's/[”“]/\"/g' \$FILENAME -i && sed \"s/[‘’]/'/g\" \$FILENAME -i\\n"
|
||||
exit 1
|
||||
fi
|
4
test/sanity/code-smell/shebang.json
Normal file
4
test/sanity/code-smell/shebang.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"text": true,
|
||||
"output": "path-line-column-message"
|
||||
}
|
75
test/sanity/code-smell/shebang.py
Executable file
75
test/sanity/code-smell/shebang.py
Executable file
|
@ -0,0 +1,75 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
allowed = set([
|
||||
b'#!/bin/bash -eu',
|
||||
b'#!/bin/bash -eux',
|
||||
b'#!/bin/bash',
|
||||
b'#!/bin/sh',
|
||||
b'#!/usr/bin/env bash',
|
||||
b'#!/usr/bin/env fish',
|
||||
b'#!/usr/bin/env pwsh',
|
||||
b'#!/usr/bin/env python',
|
||||
b'#!/usr/bin/make -f',
|
||||
])
|
||||
|
||||
module_shebangs = {
|
||||
'': b'#!/usr/bin/python',
|
||||
'.py': b'#!/usr/bin/python',
|
||||
'.ps1': b'#!powershell',
|
||||
}
|
||||
|
||||
skip = set([
|
||||
'hacking/cherrypick.py',
|
||||
])
|
||||
|
||||
for path in sys.argv[1:] or sys.stdin.read().splitlines():
|
||||
if path in skip:
|
||||
continue
|
||||
|
||||
with open(path, 'rb') as path_fd:
|
||||
shebang = path_fd.readline().strip()
|
||||
|
||||
if not shebang:
|
||||
continue
|
||||
|
||||
if not shebang.startswith(b'#!'):
|
||||
continue
|
||||
|
||||
is_module = False
|
||||
|
||||
if path.startswith('lib/ansible/modules/'):
|
||||
is_module = True
|
||||
elif path.startswith('test/integration/targets/'):
|
||||
dirname = os.path.dirname(path)
|
||||
|
||||
if dirname.endswith('/library') or dirname in (
|
||||
# non-standard module library directories
|
||||
'test/integration/targets/module_precedence/lib_no_extension',
|
||||
'test/integration/targets/module_precedence/lib_with_extension',
|
||||
):
|
||||
is_module = True
|
||||
|
||||
if is_module:
|
||||
ext = os.path.splitext(path)[1]
|
||||
expected_shebang = module_shebangs.get(ext)
|
||||
expected_ext = ' or '.join(['"%s"' % k for k in module_shebangs])
|
||||
|
||||
if expected_shebang:
|
||||
if shebang == expected_shebang:
|
||||
continue
|
||||
|
||||
print('%s:%d:%d: expected module shebang "%s" but found: %s' % (path, 1, 1, expected_shebang, shebang))
|
||||
else:
|
||||
print('%s:%d:%d: expected module extension %s but found: %s' % (path, 0, 0, expected_ext, ext))
|
||||
else:
|
||||
if shebang not in allowed:
|
||||
print('%s:%d:%d: unexpected non-module shebang: %s' % (path, 1, 1, shebang))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,24 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
grep '^#!' -rIn . \
|
||||
--exclude-dir .git \
|
||||
--exclude-dir .tox \
|
||||
| grep ':1:' | sed 's/:1:/:/' | grep -v -E \
|
||||
-e '^\./lib/ansible/modules/' \
|
||||
-e '^\./test/integration/targets/[^/]*/library/[^/]*:#!powershell$' \
|
||||
-e '^\./test/integration/targets/[^/]*/library/[^/]*:#!/usr/bin/python$' \
|
||||
-e '^\./test/integration/targets/module_precedence/.*lib.*:#!/usr/bin/python$' \
|
||||
-e '^\./hacking/cherrypick.py:#!/usr/bin/env python3$' \
|
||||
-e ':#!/bin/sh$' \
|
||||
-e ':#!/bin/bash( -[eux]|$)' \
|
||||
-e ':#!/usr/bin/make -f$' \
|
||||
-e ':#!/usr/bin/env python$' \
|
||||
-e ':#!/usr/bin/env bash$' \
|
||||
-e ':#!/usr/bin/env fish$' \
|
||||
-e ':#!/usr/bin/env pwsh$' \
|
||||
|
||||
if [ $? -ne 1 ]; then
|
||||
echo "One or more file(s) listed above have an unexpected shebang."
|
||||
echo "See $0 for the list of acceptable values."
|
||||
exit 1
|
||||
fi
|
Loading…
Reference in a new issue