New POW calculation module #1284

Open
Kleshni wants to merge 38 commits from Kleshni/POW into v0.6
3 changed files with 79 additions and 6 deletions
Showing only changes of commit 6fb637d1df - Show all commits

View File

@ -17,7 +17,7 @@ For more help on a particular command
from fabric.api import env
from fabfile.tasks import code_quality, build_docs, push_docs, clean
from fabfile.tasks import code_quality, build_docs, push_docs, clean, test
# Without this, `fab -l` would display the whole docstring as preamble
@ -26,6 +26,7 @@ __doc__ = ""
# This list defines which tasks are made available to the user
__all__ = [
"code_quality",
"test",
"build_docs",
"push_docs",
"clean",

View File

@ -6,8 +6,10 @@ A library of functions and constants for tasks to make use of.
import os
import sys
import re
from functools import wraps
from fabric.api import run, hide
from fabric.api import run, hide, cd, env
from fabric.context_managers import settings, shell_env
from fabvenv import virtualenv
@ -18,6 +20,14 @@ VENV_ROOT = os.path.expanduser(os.path.join('~', '.virtualenvs', 'pybitmessage-d
PYTHONPATH = os.path.join(PROJECT_ROOT, 'src',)
def coerce_list(value):
"""Coerce a value into a list"""
if isinstance(value, str):
return value.split(',')
else:
sys.exit("Bad string value {}".format(value))
def coerce_bool(value):
"""Coerce a value into a boolean"""
if isinstance(value, bool):
@ -51,6 +61,29 @@ def flatten(data):
return result
def filelist_from_git(rev=None):
"""Return a list of files based on git output"""
cmd = 'git diff --name-only'
if rev:
if rev in ['cached', 'staged']:
cmd += ' --{}'.format(rev)
elif rev == 'working':
pass
else:
cmd += ' -r {}'.format(rev)
with cd(PROJECT_ROOT):
with hide('running', 'stdout'):
results = []
ansi_escape = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
clean = ansi_escape.sub('', run(cmd))
clean = re.sub('\n', '', clean)
for line in clean.split('\r'):
if line.endswith(".py"):
results.append(os.path.abspath(line))
return results
def pycodestyle(path_to_file):
"""Run pycodestyle on a file"""
with virtualenv(VENV_ROOT):
@ -148,3 +181,20 @@ def get_filtered_pylint_output(path_to_file):
not i.startswith('Using config file'),
])
]
def default_hosts(hosts):
"""Decorator to apply default hosts to a task"""
def real_decorator(func):
"""Manipulate env"""
env.hosts = env.hosts or hosts
@wraps(func)
def wrapper(*args, **kwargs):
"""Original function called from here"""
return func(*args, **kwargs)
return wrapper
return real_decorator

View File

@ -15,7 +15,7 @@ from fabric.contrib.project import rsync_project
from fabvenv import virtualenv
from fabfile.lib import (
autopep8, PROJECT_ROOT, VENV_ROOT, coerce_bool, flatten,
autopep8, PROJECT_ROOT, VENV_ROOT, coerce_bool, flatten, filelist_from_git, default_hosts,
get_filtered_pycodestyle_output, get_filtered_flake8_output, get_filtered_pylint_output,
)
@ -45,7 +45,7 @@ def get_tool_results(file_list):
def print_results(results, top, verbose, details):
"""Print an item with the appropriate verbosity / detail"""
if verbose:
if verbose and results:
print ''.join(
[
os.linesep,
@ -160,7 +160,8 @@ def create_dependency_graphs():
@task
def code_quality(verbose=True, details=False, fix=False, filename=None, top=10):
@default_hosts(['localhost'])
def code_quality(verbose=True, details=False, fix=False, filename=None, top=10, rev=None):
"""
Check code quality.
@ -171,6 +172,8 @@ def code_quality(verbose=True, details=False, fix=False, filename=None, top=10):
$ fab -H localhost code_quality
:param rev: If not None, act on files changed since this commit. 'cached/staged' and 'working' have special meaning
:type rev: str or None, default None
:param top: Display / fix only the top N violating files, a value of 0 will display / fix all files
:type top: int, default 10
:param verbose: Display a header and the counts, without this you just get the filenames in order
@ -187,13 +190,14 @@ def code_quality(verbose=True, details=False, fix=False, filename=None, top=10):
Intended to be temporary until we have improved code quality and have safeguards to maintain it in place.
"""
# pylint: disable=too-many-arguments
verbose = coerce_bool(verbose)
details = coerce_bool(details)
fix = coerce_bool(fix)
top = int(top) or -1
file_list = generate_file_list(filename)
file_list = generate_file_list(filename) if not rev else filelist_from_git(rev)
results = get_tool_results(file_list)
if fix:
@ -207,6 +211,22 @@ def code_quality(verbose=True, details=False, fix=False, filename=None, top=10):
@task
@default_hosts(['localhost'])
def test():
"""Run tests on the code"""
with cd(PROJECT_ROOT):
with virtualenv(VENV_ROOT):
run('pip uninstall -y pybitmessage')
run('python setup.py install')
run('pybitmessage -t')
run('python setup.py test')
@task
@default_hosts(['localhost'])
def build_docs(dep_graph=False, apidoc=True):
"""
Build the documentation locally.
@ -259,6 +279,7 @@ def build_docs(dep_graph=False, apidoc=True):
@task
@default_hosts(['localhost'])
def push_docs(path=None):
"""
Upload the generated docs to a public server.
@ -289,6 +310,7 @@ def push_docs(path=None):
@task
@default_hosts(['localhost'])
def clean():
"""Clean up files generated by fabric commands."""
with hide('running', 'stdout'):