Integrate colorama for coloured output #164
|
@ -3,13 +3,14 @@ import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from borgmatic.borg import extract
|
from borgmatic.borg import extract
|
||||||
|
from borgmatic.logger import get_logger
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_CHECKS = ('repository', 'archives')
|
DEFAULT_CHECKS = ('repository', 'archives')
|
||||||
DEFAULT_PREFIX = '{hostname}-'
|
DEFAULT_PREFIX = '{hostname}-'
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def _parse_checks(consistency_config):
|
def _parse_checks(consistency_config):
|
||||||
|
|
|
@ -5,9 +5,10 @@ import os
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from borgmatic.borg.execute import execute_command
|
from borgmatic.borg.execute import execute_command
|
||||||
|
from borgmatic.logger import get_logger
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def _expand_directory(directory):
|
def _expand_directory(directory):
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import logging
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
from borgmatic.logger import get_logger
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def execute_command(full_command, capture_output=False):
|
def execute_command(full_command, capture_output=False):
|
||||||
|
|
|
@ -2,8 +2,10 @@ import logging
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
from borgmatic.logger import get_logger
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def extract_last_archive_dry_run(repository, lock_wait=None, local_path='borg', remote_path=None):
|
def extract_last_archive_dry_run(repository, lock_wait=None, local_path='borg', remote_path=None):
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from borgmatic.borg.execute import execute_command
|
from borgmatic.borg.execute import execute_command
|
||||||
|
from borgmatic.logger import get_logger
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def display_archives_info(
|
def display_archives_info(
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import logging
|
import logging
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
from borgmatic.logger import get_logger
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def initialize_repository(
|
def initialize_repository(
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from borgmatic.borg.execute import execute_command
|
from borgmatic.borg.execute import execute_command
|
||||||
|
from borgmatic.logger import get_logger
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def list_archives(
|
def list_archives(
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import logging
|
import logging
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
from borgmatic.logger import get_logger
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def _make_prune_flags(retention_config):
|
def _make_prune_flags(retention_config):
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
import collections
|
import collections
|
||||||
|
import colorama
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
@ -20,12 +21,12 @@ from borgmatic.borg import (
|
||||||
)
|
)
|
||||||
from borgmatic.commands import hook
|
from borgmatic.commands import hook
|
||||||
from borgmatic.config import checks, collect, convert, validate
|
from borgmatic.config import checks, collect, convert, validate
|
||||||
|
from borgmatic.logger import should_do_markup, get_logger
|
||||||
from borgmatic.signals import configure_signals
|
from borgmatic.signals import configure_signals
|
||||||
from borgmatic.verbosity import verbosity_to_log_level
|
from borgmatic.verbosity import verbosity_to_log_level
|
||||||
|
|||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
LEGACY_CONFIG_PATH = '/etc/borgmatic/config'
|
LEGACY_CONFIG_PATH = '/etc/borgmatic/config'
|
||||||
|
|
||||||
|
@ -169,6 +170,9 @@ def parse_arguments(*arguments):
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='Go through the motions, but do not actually write to any repositories',
|
help='Go through the motions, but do not actually write to any repositories',
|
||||||
)
|
)
|
||||||
|
common_group.add_argument(
|
||||||
|
'-nc', '--no-color', dest='no_color', action='store_true', help='Disable colored output'
|
||||||
witten
commented
May seem silly, but I think I'd prefer American spelling for this. I don't have any good reason except perhaps it's just more common among users: https://en.wikipedia.org/wiki/Comparison_of_American_and_British_English#Demographics But if you like, you can include flags for both (e.g. May seem silly, but I think I'd prefer American spelling for this. I don't have any good reason except perhaps it's just more common among users: https://en.wikipedia.org/wiki/Comparison_of_American_and_British_English#Demographics
But if you like, you can include flags for both (e.g. `--no-color` and `--no-colour`) to be more inclusive!
|
|||||||
|
)
|
||||||
common_group.add_argument(
|
common_group.add_argument(
|
||||||
'-v',
|
'-v',
|
||||||
'--verbosity',
|
'--verbosity',
|
||||||
|
@ -472,6 +476,8 @@ def main(): # pragma: no cover
|
||||||
logger.critical(error)
|
logger.critical(error)
|
||||||
exit_with_help_link()
|
exit_with_help_link()
|
||||||
|
|
||||||
|
colorama.init(autoreset=True, strip=not should_do_markup(args.no_color))
|
||||||
|
|
||||||
logging.basicConfig(level=verbosity_to_log_level(args.verbosity), format='%(message)s')
|
logging.basicConfig(level=verbosity_to_log_level(args.verbosity), format='%(message)s')
|
||||||
|
|
||||||
if args.version:
|
if args.version:
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import logging
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
from borgmatic.logger import get_logger
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def execute_hook(commands, config_filename, description, dry_run):
|
def execute_hook(commands, config_filename, description, dry_run):
|
||||||
|
|
|
@ -3,8 +3,9 @@ import sys
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from borgmatic.config import collect, validate
|
from borgmatic.config import collect, validate
|
||||||
|
from borgmatic.logger import get_logger
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def parse_arguments(*arguments):
|
def parse_arguments(*arguments):
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import os
|
import os
|
||||||
import logging
|
|
||||||
|
|
||||||
import ruamel.yaml
|
import ruamel.yaml
|
||||||
|
|
||||||
|
from borgmatic.logger import get_logger
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def load_configuration(filename):
|
def load_configuration(filename):
|
||||||
|
|
|
@ -6,9 +6,10 @@ import pykwalify.errors
|
||||||
import ruamel.yaml
|
import ruamel.yaml
|
||||||
|
|
||||||
from borgmatic.config import load
|
from borgmatic.config import load
|
||||||
|
from borgmatic.logger import get_logger
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def schema_filename():
|
def schema_filename():
|
||||||
|
|
75
borgmatic/logger.py
Normal file
75
borgmatic/logger.py
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import colorama
|
||||||
|
|
||||||
|
|
||||||
|
def to_bool(arg):
|
||||||
|
'''
|
||||||
|
Return a boolean value based on `arg`.
|
||||||
|
'''
|
||||||
|
if arg is None or isinstance(arg, bool):
|
||||||
|
return arg
|
||||||
|
|
||||||
|
if isinstance(arg, str):
|
||||||
|
arg = arg.lower()
|
||||||
|
|
||||||
|
if arg in ('yes', 'on', '1', 'true', 1):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
witten
commented
It'd be good to have a simple automated test or three for this function, given that it's pure logic. It'd be good to have a simple automated test or three for this function, given that it's pure logic.
decentral1se
commented
Makes sense! Also, to note, I took this implementation from the Ansible utility, so it is well battle tested for this use case. Makes sense! Also, to note, I took this implementation from the Ansible utility, so it is well battle tested for this use case.
|
|||||||
|
|
||||||
|
|
||||||
|
def should_do_markup(no_colour):
|
||||||
|
'''
|
||||||
|
Determine if we should enable colorama marking up.
|
||||||
|
'''
|
||||||
|
if no_colour:
|
||||||
|
return False
|
||||||
|
|
||||||
|
py_colors = os.environ.get('PY_COLORS', None)
|
||||||
|
|
||||||
|
if py_colors is not None:
|
||||||
|
return to_bool(py_colors)
|
||||||
|
|
||||||
|
return sys.stdout.isatty() and os.environ.get('TERM') != 'dumb'
|
||||||
witten
commented
Nice to have the auto-detection here! Nice to have the auto-detection here!
|
|||||||
|
|
||||||
|
|
||||||
|
class BorgmaticLogger(logging.Logger):
|
||||||
|
def warn(self, msg, *args, **kwargs):
|
||||||
|
return super(BorgmaticLogger, self).warn(
|
||||||
|
color_text(colorama.Fore.YELLOW, msg), *args, **kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
def info(self, msg, *args, **kwargs):
|
||||||
|
return super(BorgmaticLogger, self).info(
|
||||||
|
color_text(colorama.Fore.GREEN, msg), *args, **kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
def debug(self, msg, *args, **kwargs):
|
||||||
|
return super(BorgmaticLogger, self).debug(
|
||||||
|
color_text(colorama.Fore.CYAN, msg), *args, **kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
def critical(self, msg, *args, **kwargs):
|
||||||
|
return super(BorgmaticLogger, self).critical(
|
||||||
|
color_text(colorama.Fore.RED, msg), *args, **kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_logger(name=None):
|
||||||
|
'''
|
||||||
|
Build a logger with the given name.
|
||||||
|
'''
|
||||||
|
logging.setLoggerClass(BorgmaticLogger)
|
||||||
|
logger = logging.getLogger(name)
|
||||||
|
logger.propagate = False
|
||||||
witten
commented
Given that these Given that these `*_text()` functions are only used in one place, I might be inclined to just inline them there. Do not feel strongly though.
|
|||||||
|
return logger
|
||||||
|
|
||||||
|
|
||||||
|
def color_text(color, msg):
|
||||||
|
'''
|
||||||
|
Give colored text.
|
||||||
|
'''
|
||||||
|
return '{}{}{}'.format(color, msg, colorama.Style.RESET_ALL)
|
Loading…
Reference in New Issue
Block a user
Super minor: I tend to alpha order imports within each group, just to make visual scanning easier. E.g.,
from borgmatic.logger
would go on the line afterfrom borgmatic.config
.I'll fix. I'd recommend integrating https://isort.readthedocs.io/en/latest/ so that the tooling mandates and saves you time checking it yourself. Here's a configuration I use myself that plays well with Black: https://git.coop/decentral1se/pypkgtemplate/blob/master/%7B%7Bcookiecutter.package%7D%7D/setup.cfg#L7.
Point taken. I filed witten/borgmatic#169 for that.