This repository has been archived on 2024-12-19. You can view files and clone it, but cannot push or open issues or pull requests.
PyBitmessage-2024-12-19/fabfile/tasks.py
2018-05-11 09:01:49 +01:00

270 lines
8.1 KiB
Python

"""
<<<<<<< HEAD
Fabric is a Python library for performing devops tasks. If you have Fabric installed (systemwide or via pip) you can
run commands from within the project directory like this:
$ fab code_quality
For a list of commands:
$ fab -l
Known bugs:
=======
Fabric tasks for PyBitmessage devops operations.
>>>>>>> 81c272dbc332d842b7f8ab548ebeef2dd9a73995
"""
import os
import sys
<<<<<<< HEAD
import fabric
from fabric.api import run, task, hide, cd
from fabfile.lib import pycodestyle, flake8, pylint, autopep8, PROJECT_ROOT, VENV_ROOT
from fabvenv import virtualenv
fabric.state.output['running'] = False
@task
def code_quality(top=10, verbose=True, details=False, fix=True, filename=None):
"""Intended to be temporary until we have improved code quality and have safeguards to maintain it in place."""
end = int(top) if int(top) else -1
if verbose == "0":
verbose = False
if not isinstance(verbose, bool):
print "Bad verbosity value, try 0"
sys.exit(1)
if details == "1":
details = True
if not isinstance(details, bool):
print "Bad details value, try 1"
sys.exit(1)
if fix == "0":
fix = False
if not isinstance(fix, bool):
print "Bad fix value, try 0"
sys.exit(1)
with hide('warnings'):
=======
from fabric.api import run, task, hide, cd
from fabvenv import virtualenv
from fabfile.lib import pycodestyle, flake8, pylint, autopep8, PROJECT_ROOT, VENV_ROOT, coerce_bool, flatten
def get_results_for_tools_applied_to_file_list(file_list):
"""Take a list of files and resuln the results of applying the tools"""
results = []
for path_to_file in file_list:
result = {}
result['pycodestyle_violations'] = [
i
for i in pycodestyle(path_to_file).split("\n")
if i
]
result['flake8_violations'] = [
i
for i in flake8(path_to_file).split("\n")
if i
]
result['pylint_violations'] = [
i
for i in pylint(path_to_file).split("\n")
if all([
i,
not i.startswith(' '),
not i.startswith('\r'),
not i.startswith('-'),
not i.startswith('Y'),
not i.startswith('*'),
not i.startswith('Using config file'),
])
]
result['path_to_file'] = path_to_file
result['total_violations'] = sum(
[
len(result['pycodestyle_violations']),
len(result['flake8_violations']),
len(result['pylint_violations']),
]
)
results.append(result)
return results
def print_item(item, verbose, details):
"""Print an item with the appropriate verbosity / detail"""
if verbose:
line = "{0} {1} {2} {3} {4}".format(
item['total_violations'],
len(item['pycodestyle_violations']),
len(item['flake8_violations']),
len(item['pylint_violations']),
item['path_to_file'],
)
else:
line = item['path_to_file']
print line
if details:
print "pycodestyle:"
for detail in flatten(item['pycodestyle_violations']):
print detail
print
print "flake8:"
for detail in flatten(item['flake8_violations']):
print detail
print
print "pylint:"
for detail in flatten(item['pylint_violations']):
print detail
print
@task
def code_quality(top=10, verbose=True, details=False, fix=False, filename=None):
"""
Check code quality.
By default this command will analyse each Python file in the project with a variety of tools and display the count
or details of the violations discovered, sorted by most iolations first.
Default usage:
$ fab -H localhost code_quality
Options:
top: Display / fix only the top violating files, a value of 0 will display / fix all files
verbose: Display a header and the counts. Without this you just get the filenames in order
details: Display the violations one per line after the count/file summary
fix: Run autopep8 on the displayed file(s)
filename: Rather than analysing all files and displaying / fixing the top N, just analyse / diaply / fix the
specified file
Intended to be temporary until we have improved code quality and have safeguards to maintain it in place.
"""
verbose = coerce_bool(verbose)
details = coerce_bool(details)
fix = coerce_bool(fix)
end = int(top) if int(top) else -1
with hide('warnings', 'running'): # pylint: disable=not-context-manager
>>>>>>> 81c272dbc332d842b7f8ab548ebeef2dd9a73995
with virtualenv(VENV_ROOT):
if filename:
filename = os.path.abspath(filename)
if not os.path.exists(filename):
print "Bad filename, specify a Python file"
sys.exit(1)
else:
file_list = [filename]
else:
<<<<<<< HEAD
with cd(PROJECT_ROOT):
file_list = run('find . -name "*.py"', capture=True).split("\n")
results = []
for path_to_file in file_list:
results.append(
{
'pycodestyle_violations': [
i
for i in pycodestyle(path_to_file).split("\n")
if i
],
'flake8_violations': [
i
for i in flake8(path_to_file).split("\n")
if i
],
'pylint_violations': [
i
for i in pylint(path_to_file).split("\n")
if all([
i,
not i.startswith(' '),
not i.startswith('-'),
not i.startswith('Y'),
not i.startswith('*'),
])
],
'path_to_file': path_to_file,
}
)
=======
with cd(PROJECT_ROOT): # pylint: disable=not-context-manager
file_list = run('find . -name "*.py"').split("\n")
if fix:
for path_to_file in file_list:
autopep8(path_to_file)
results = get_results_for_tools_applied_to_file_list(file_list)
>>>>>>> 81c272dbc332d842b7f8ab548ebeef2dd9a73995
if verbose:
print "\ntotal pycodestyle flake8 pylint path_to_file\n"
<<<<<<< HEAD
for item in sorted(
results,
reverse=True,
key=lambda x: len(x['pycodestyle_violations']) + len(x['flake8_violations']) + len(x['pylint_violations']),
)[:end]:
violation_detail = item['pycodestyle_violations'] + item['flake8_violations'] + item['pylint_violations'],
if verbose:
line = "{0} {1} {2} {3} {4}".format(
len(violation_detail[0]),
len(item['pycodestyle_violations']),
len(item['flake8_violations']),
len(item['pylint_violations']),
item['path_to_file'],
)
else:
line = item['path_to_file']
print line
if details:
for detail_line in violation_detail:
if isinstance(detail_line, list):
for subline in detail_line:
if isinstance(subline, list):
for subsubline in subline:
print subsubline
else:
print subline
else:
print detail_line
print
if fix:
autopep8_output = [i for i in autopep8(item['path_to_file']) if i]
print autopep8_output
=======
# Sort and slice
for item in sorted(
results,
reverse=True,
key=lambda x: x['total_violations']
)[:end]:
print_item(item, verbose, details)
>>>>>>> 81c272dbc332d842b7f8ab548ebeef2dd9a73995