2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
# This file has been auto-generated.
|
||||
# All changes will be lost, see Projectfile.
|
||||
#
|
||||
# Updated at 2017-05-28 22:04:19.262686
|
||||
# Updated at 2017-05-31 22:08:42.384770
|
||||
|
||||
PACKAGE ?= bonobo
|
||||
PYTHON ?= $(shell which python)
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
import argparse
|
||||
|
||||
import logging
|
||||
from stevedore import ExtensionManager
|
||||
from bonobo import logging, settings
|
||||
|
||||
logger = logging.get_logger()
|
||||
|
||||
|
||||
def entrypoint(args=None):
|
||||
logging.basicConfig()
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--debug', '-D', action='store_true')
|
||||
|
||||
subparsers = parser.add_subparsers(dest='command')
|
||||
subparsers.required = True
|
||||
@ -18,10 +19,17 @@ def entrypoint(args=None):
|
||||
parser = subparsers.add_parser(ext.name)
|
||||
commands[ext.name] = ext.plugin(parser)
|
||||
except Exception:
|
||||
logging.exception('Error while loading command {}.'.format(ext.name))
|
||||
logger.exception('Error while loading command {}.'.format(ext.name))
|
||||
|
||||
from stevedore import ExtensionManager
|
||||
mgr = ExtensionManager(namespace='bonobo.commands')
|
||||
mgr.map(register_extension)
|
||||
|
||||
args = parser.parse_args(args).__dict__
|
||||
if args.pop('debug', False):
|
||||
settings.DEBUG = True
|
||||
settings.LOGGING_LEVEL = logging.DEBUG
|
||||
logging.set_level(settings.LOGGING_LEVEL)
|
||||
|
||||
logger.debug('Command: ' + args['command'] + ' Arguments: ' + repr(args))
|
||||
commands[args.pop('command')](**args)
|
||||
|
||||
@ -1,6 +1,3 @@
|
||||
import os
|
||||
|
||||
|
||||
def execute(name):
|
||||
try:
|
||||
from cookiecutter.main import cookiecutter
|
||||
|
||||
@ -1,10 +1,4 @@
|
||||
import importlib
|
||||
import os
|
||||
import runpy
|
||||
|
||||
import pip
|
||||
|
||||
import bonobo
|
||||
|
||||
DEFAULT_SERVICES_FILENAME = '_services.py'
|
||||
DEFAULT_SERVICES_ATTR = 'get_services'
|
||||
@ -12,7 +6,6 @@ DEFAULT_SERVICES_ATTR = 'get_services'
|
||||
DEFAULT_GRAPH_FILENAME = '__main__.py'
|
||||
DEFAULT_GRAPH_ATTR = 'get_graph'
|
||||
|
||||
|
||||
def get_default_services(filename, services=None):
|
||||
dirname = os.path.dirname(filename)
|
||||
services_filename = os.path.join(dirname, DEFAULT_SERVICES_FILENAME)
|
||||
@ -33,7 +26,8 @@ def get_default_services(filename, services=None):
|
||||
|
||||
|
||||
def execute(filename, module, install=False, quiet=False, verbose=False):
|
||||
from bonobo import settings
|
||||
import runpy
|
||||
from bonobo import Graph, run, settings
|
||||
|
||||
if quiet:
|
||||
settings.QUIET = True
|
||||
@ -44,6 +38,8 @@ def execute(filename, module, install=False, quiet=False, verbose=False):
|
||||
if filename:
|
||||
if os.path.isdir(filename):
|
||||
if install:
|
||||
import importlib
|
||||
import pip
|
||||
requirements = os.path.join(filename, 'requirements.txt')
|
||||
pip.main(['install', '-r', requirements])
|
||||
# Some shenanigans to be sure everything is importable after this, especially .egg-link files which
|
||||
@ -62,7 +58,7 @@ def execute(filename, module, install=False, quiet=False, verbose=False):
|
||||
else:
|
||||
raise RuntimeError('UNEXPECTED: argparse should not allow this.')
|
||||
|
||||
graphs = dict((k, v) for k, v in context.items() if isinstance(v, bonobo.Graph))
|
||||
graphs = dict((k, v) for k, v in context.items() if isinstance(v, Graph))
|
||||
|
||||
assert len(graphs) == 1, (
|
||||
'Having zero or more than one graph definition in one file is unsupported for now, '
|
||||
@ -73,7 +69,7 @@ def execute(filename, module, install=False, quiet=False, verbose=False):
|
||||
|
||||
# todo if console and not quiet, then add the console plugin
|
||||
# todo when better console plugin, add it if console and just disable display
|
||||
return bonobo.run(
|
||||
return run(
|
||||
graph,
|
||||
plugins=[],
|
||||
services=get_default_services(
|
||||
@ -82,8 +78,8 @@ def execute(filename, module, install=False, quiet=False, verbose=False):
|
||||
)
|
||||
|
||||
|
||||
def register_generic_run_arguments(parser):
|
||||
source_group = parser.add_mutually_exclusive_group(required=True)
|
||||
def register_generic_run_arguments(parser, required=True):
|
||||
source_group = parser.add_mutually_exclusive_group(required=required)
|
||||
source_group.add_argument('filename', nargs='?', type=str)
|
||||
source_group.add_argument('--module', '-m', type=str)
|
||||
return parser
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
import bonobo
|
||||
from bonobo.util.pkgs import bonobo_packages
|
||||
|
||||
|
||||
def format_version(mod, *, name=None, quiet=False):
|
||||
from bonobo.util.pkgs import bonobo_packages
|
||||
args = {
|
||||
'name': name or mod.__name__,
|
||||
'version': mod.__version__,
|
||||
@ -20,6 +17,9 @@ def format_version(mod, *, name=None, quiet=False):
|
||||
|
||||
|
||||
def execute(all=False, quiet=False):
|
||||
import bonobo
|
||||
from bonobo.util.pkgs import bonobo_packages
|
||||
|
||||
print(format_version(bonobo, quiet=quiet))
|
||||
if all:
|
||||
for name in sorted(bonobo_packages):
|
||||
|
||||
75
bonobo/logging.py
Normal file
75
bonobo/logging.py
Normal file
@ -0,0 +1,75 @@
|
||||
import logging
|
||||
import sys
|
||||
import textwrap
|
||||
from logging import CRITICAL, DEBUG, ERROR, INFO, WARNING
|
||||
|
||||
from colorama import Fore, Style
|
||||
|
||||
from bonobo import settings
|
||||
from bonobo.util.term import CLEAR_EOL
|
||||
|
||||
|
||||
def get_format():
|
||||
yield '{b}[%(fg)s%(levelname)s{b}][{w}'
|
||||
yield '{b}][{w}'.join(('%(spent)04d', '%(name)s'))
|
||||
yield '{b}]'
|
||||
yield ' %(fg)s%(message)s{r}'
|
||||
yield CLEAR_EOL
|
||||
|
||||
|
||||
colors = {
|
||||
'b': Fore.BLACK,
|
||||
'w': Fore.LIGHTBLACK_EX,
|
||||
'r': Style.RESET_ALL,
|
||||
}
|
||||
format = (''.join(get_format())).format(**colors)
|
||||
|
||||
|
||||
class Filter(logging.Filter):
|
||||
def filter(self, record):
|
||||
record.spent = record.relativeCreated // 1000
|
||||
if record.levelname == 'DEBG':
|
||||
record.fg = Fore.LIGHTBLACK_EX
|
||||
elif record.levelname == 'INFO':
|
||||
record.fg = Fore.LIGHTWHITE_EX
|
||||
elif record.levelname == 'WARN':
|
||||
record.fg = Fore.LIGHTYELLOW_EX
|
||||
elif record.levelname == 'ERR ':
|
||||
record.fg = Fore.LIGHTRED_EX
|
||||
elif record.levelname == 'CRIT':
|
||||
record.fg = Fore.RED
|
||||
else:
|
||||
record.fg = Fore.LIGHTWHITE_EX
|
||||
return True
|
||||
|
||||
|
||||
class Formatter(logging.Formatter):
|
||||
def formatException(self, ei):
|
||||
tb = super().formatException(ei)
|
||||
return textwrap.indent(tb, Fore.BLACK + ' | ' + Fore.WHITE)
|
||||
|
||||
|
||||
def setup(level):
|
||||
logging.addLevelName(DEBUG, 'DEBG')
|
||||
logging.addLevelName(INFO, 'INFO')
|
||||
logging.addLevelName(WARNING, 'WARN')
|
||||
logging.addLevelName(ERROR, 'ERR ')
|
||||
logging.addLevelName(CRITICAL, 'CRIT')
|
||||
handler = logging.StreamHandler(sys.stderr)
|
||||
handler.setFormatter(Formatter(format))
|
||||
handler.addFilter(Filter())
|
||||
root = logging.getLogger()
|
||||
root.addHandler(handler)
|
||||
root.setLevel(level)
|
||||
|
||||
|
||||
def set_level(level):
|
||||
logging.getLogger().setLevel(level)
|
||||
|
||||
|
||||
def get_logger(name='bonobo'):
|
||||
return logging.getLogger(name)
|
||||
|
||||
|
||||
# Setup formating and level.
|
||||
setup(level=settings.LOGGING_LEVEL)
|
||||
@ -1,5 +1,7 @@
|
||||
import os
|
||||
|
||||
import logging
|
||||
|
||||
|
||||
def to_bool(s):
|
||||
if len(s):
|
||||
@ -10,13 +12,16 @@ def to_bool(s):
|
||||
|
||||
|
||||
# Debug/verbose mode.
|
||||
DEBUG = to_bool(os.environ.get('BONOBO_DEBUG', 'f'))
|
||||
DEBUG = to_bool(os.environ.get('DEBUG', 'f'))
|
||||
|
||||
# Profile mode.
|
||||
PROFILE = to_bool(os.environ.get('BONOBO_PROFILE', 'f'))
|
||||
PROFILE = to_bool(os.environ.get('PROFILE', 'f'))
|
||||
|
||||
# Quiet mode.
|
||||
QUIET = to_bool(os.environ.get('BONOBO_QUIET', 'f'))
|
||||
QUIET = to_bool(os.environ.get('QUIET', 'f'))
|
||||
|
||||
# Logging level.
|
||||
LOGGING_LEVEL = logging.DEBUG if DEBUG else logging.INFO
|
||||
|
||||
|
||||
def check():
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
""" Iterator utilities. """
|
||||
import functools
|
||||
|
||||
|
||||
def force_iterator(mixed):
|
||||
@ -20,7 +21,20 @@ def force_iterator(mixed):
|
||||
def ensure_tuple(tuple_or_mixed):
|
||||
if isinstance(tuple_or_mixed, tuple):
|
||||
return tuple_or_mixed
|
||||
return (tuple_or_mixed, )
|
||||
return (tuple_or_mixed,)
|
||||
|
||||
|
||||
def tuplize(generator):
|
||||
""" Takes a generator and make it a tuple-returning function. As a side
|
||||
effect, it can also decorate any iterator-returning function to force
|
||||
return value to be a tuple.
|
||||
"""
|
||||
|
||||
@functools.wraps(generator)
|
||||
def tuplized(*args, **kwargs):
|
||||
return tuple(generator(*args, **kwargs))
|
||||
|
||||
return tuplized
|
||||
|
||||
|
||||
def iter_if_not_sequence(mixed):
|
||||
|
||||
@ -20,10 +20,10 @@ py==1.4.33
|
||||
pygments==2.2.0
|
||||
pytest-cov==2.5.1
|
||||
pytest-timeout==1.2.0
|
||||
pytest==3.1.0
|
||||
pytest==3.1.1
|
||||
python-dateutil==2.6.0
|
||||
pytz==2017.2
|
||||
requests==2.16.5
|
||||
requests==2.17.3
|
||||
six==1.10.0
|
||||
snowballstemmer==1.2.1
|
||||
sphinx==1.6.2
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
-e .[docker]
|
||||
appdirs==1.4.3
|
||||
bonobo-docker==0.2.3
|
||||
bonobo-docker==0.2.4
|
||||
bonobo==0.3.1
|
||||
certifi==2017.4.17
|
||||
chardet==3.0.3
|
||||
@ -15,8 +15,8 @@ pbr==3.0.1
|
||||
psutil==5.2.2
|
||||
pyparsing==2.2.0
|
||||
pytz==2017.2
|
||||
requests==2.16.5
|
||||
requests==2.17.3
|
||||
six==1.10.0
|
||||
stevedore==1.21.0
|
||||
stevedore==1.22.0
|
||||
urllib3==1.21.1
|
||||
websocket-client==0.40.0
|
||||
|
||||
@ -11,7 +11,7 @@ pbr==3.0.1
|
||||
psutil==5.2.2
|
||||
pyparsing==2.2.0
|
||||
pytz==2017.2
|
||||
requests==2.16.5
|
||||
requests==2.17.3
|
||||
six==1.10.0
|
||||
stevedore==1.21.0
|
||||
stevedore==1.22.0
|
||||
urllib3==1.21.1
|
||||
|
||||
Reference in New Issue
Block a user