forked from ungleich-public/cdist
		
	Respect NO_COLOR environment variable
This commit is contained in:
		
					parent
					
						
							
								48d66b0143
							
						
					
				
			
			
				commit
				
					
						747c6b1076
					
				
			
		
					 8 changed files with 47 additions and 38 deletions
				
			
		| 
						 | 
					@ -89,13 +89,6 @@ def check_lower_bounded_int(value, lower_bound, name):
 | 
				
			||||||
    return val
 | 
					    return val
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def colored_output_type(val):
 | 
					 | 
				
			||||||
    boolean_states = cdist.configuration.ColoredOutputOption.BOOLEAN_STATES
 | 
					 | 
				
			||||||
    if val not in boolean_states.keys():
 | 
					 | 
				
			||||||
        raise argparse.ArgumentError()
 | 
					 | 
				
			||||||
    return boolean_states[val]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def get_parsers():
 | 
					def get_parsers():
 | 
				
			||||||
    global parser
 | 
					    global parser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -140,7 +133,7 @@ def get_parsers():
 | 
				
			||||||
                 'It can be a boolean or "auto" (default) which enables this '
 | 
					                 'It can be a boolean or "auto" (default) which enables this '
 | 
				
			||||||
                 'feature if stdout is a tty and disables it otherwise.',
 | 
					                 'feature if stdout is a tty and disables it otherwise.',
 | 
				
			||||||
            action='store', dest='colored_output', required=False,
 | 
					            action='store', dest='colored_output', required=False,
 | 
				
			||||||
            type=colored_output_type)
 | 
					            choices=cdist.configuration.ColoredOutputOption.CHOICES)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    parser['beta'] = argparse.ArgumentParser(add_help=False)
 | 
					    parser['beta'] = argparse.ArgumentParser(add_help=False)
 | 
				
			||||||
    parser['beta'].add_argument(
 | 
					    parser['beta'].add_argument(
 | 
				
			||||||
| 
						 | 
					@ -501,7 +494,12 @@ def handle_loglevel(args):
 | 
				
			||||||
    if hasattr(args, 'quiet') and args.quiet:
 | 
					    if hasattr(args, 'quiet') and args.quiet:
 | 
				
			||||||
        args.verbose = _verbosity_level_off
 | 
					        args.verbose = _verbosity_level_off
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    logging.root.setLevel(_verbosity_level[args.verbose])
 | 
					    logging.getLogger().setLevel(_verbosity_level[args.verbose])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def handle_log_colors(args):
 | 
				
			||||||
 | 
					    if cdist.configuration.ColoredOutputOption.translate(args.colored_output):
 | 
				
			||||||
 | 
					        cdist.log.DefaultLog.USE_COLORS = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def parse_and_configure(argv, singleton=True):
 | 
					def parse_and_configure(argv, singleton=True):
 | 
				
			||||||
| 
						 | 
					@ -515,16 +513,13 @@ def parse_and_configure(argv, singleton=True):
 | 
				
			||||||
        raise cdist.Error(str(e))
 | 
					        raise cdist.Error(str(e))
 | 
				
			||||||
    # Loglevels are handled globally in here
 | 
					    # Loglevels are handled globally in here
 | 
				
			||||||
    handle_loglevel(args)
 | 
					    handle_loglevel(args)
 | 
				
			||||||
 | 
					    handle_log_colors(args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    log = logging.getLogger("cdist")
 | 
					    log = logging.getLogger("cdist")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    config = cfg.get_config()
 | 
					 | 
				
			||||||
    if config.get('GLOBAL', {}).get('colored_output', False):
 | 
					 | 
				
			||||||
        cdist.log.ColorFormatter.USE_COLORS = True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    log.verbose("version %s" % cdist.VERSION)
 | 
					    log.verbose("version %s" % cdist.VERSION)
 | 
				
			||||||
    log.trace('command line args: {}'.format(cfg.command_line_args))
 | 
					    log.trace('command line args: {}'.format(cfg.command_line_args))
 | 
				
			||||||
    log.trace('configuration: {}'.format(config))
 | 
					    log.trace('configuration: {}'.format(cfg.get_config()))
 | 
				
			||||||
    log.trace('configured args: {}'.format(args))
 | 
					    log.trace('configured args: {}'.format(args))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    check_beta(vars(args))
 | 
					    check_beta(vars(args))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -203,6 +203,7 @@ class Config(object):
 | 
				
			||||||
                cdist.log.setupParallelLogging()
 | 
					                cdist.log.setupParallelLogging()
 | 
				
			||||||
        elif args.timestamp:
 | 
					        elif args.timestamp:
 | 
				
			||||||
            cdist.log.setupTimestampingLogging()
 | 
					            cdist.log.setupTimestampingLogging()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        log = logging.getLogger("config")
 | 
					        log = logging.getLogger("config")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # No new child process if only one host at a time.
 | 
					        # No new child process if only one host at a time.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,7 +48,6 @@ _VERBOSITY_VALUES = (
 | 
				
			||||||
_ARCHIVING_VALUES = (
 | 
					_ARCHIVING_VALUES = (
 | 
				
			||||||
    'tar', 'tgz', 'tbz2', 'txz', 'none',
 | 
					    'tar', 'tgz', 'tbz2', 'txz', 'none',
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
_COLORED_OUTPUT_DEFAULT = sys.stdout.isatty()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OptionBase:
 | 
					class OptionBase:
 | 
				
			||||||
| 
						 | 
					@ -249,8 +248,22 @@ class LogLevelOption(OptionBase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ColoredOutputOption(BooleanOption):
 | 
					class ColoredOutputOption(BooleanOption):
 | 
				
			||||||
    BOOLEAN_STATES = dict(configparser.ConfigParser.BOOLEAN_STATES,
 | 
					    CHOICES = tuple(configparser.ConfigParser.BOOLEAN_STATES) + ('auto',)
 | 
				
			||||||
                          auto=_COLORED_OUTPUT_DEFAULT)
 | 
					    DEFAULT = 'auto'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_converter(self):
 | 
				
			||||||
 | 
					        return self.translate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @staticmethod
 | 
				
			||||||
 | 
					    def translate(val):
 | 
				
			||||||
 | 
					        if 'NO_COLOR' in os.environ:
 | 
				
			||||||
 | 
					            return False
 | 
				
			||||||
 | 
					        elif isinstance(val, bool):
 | 
				
			||||||
 | 
					            return val
 | 
				
			||||||
 | 
					        elif val == 'auto':
 | 
				
			||||||
 | 
					            return sys.stdout.isatty()
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return configparser.ConfigParser.BOOLEAN_STATES[val]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_ARG_OPTION_MAPPING = {
 | 
					_ARG_OPTION_MAPPING = {
 | 
				
			||||||
| 
						 | 
					@ -337,12 +350,10 @@ class Configuration(metaclass=Singleton):
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ARG_OPTION_MAPPING = _ARG_OPTION_MAPPING
 | 
					    ARG_OPTION_MAPPING = _ARG_OPTION_MAPPING
 | 
				
			||||||
    ADJUST_ARG_OPTION_MAPPING = {
 | 
					    ADJUST_ARG_OPTION_MAPPING = {v: k for k, v in _ARG_OPTION_MAPPING.items()}
 | 
				
			||||||
       _ARG_OPTION_MAPPING[key]: key for key in _ARG_OPTION_MAPPING
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    REQUIRED_DEFAULT_CONFIG_VALUES = {
 | 
					    REQUIRED_DEFAULT_CONFIG_VALUES = {
 | 
				
			||||||
        'GLOBAL': {
 | 
					        'GLOBAL': {
 | 
				
			||||||
            'colored_output': _COLORED_OUTPUT_DEFAULT,
 | 
					            'colored_output': 'auto',
 | 
				
			||||||
            'verbosity': 0,
 | 
					            'verbosity': 0,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -495,8 +506,7 @@ class Configuration(metaclass=Singleton):
 | 
				
			||||||
            newconfig = self._read_config_file(config_file)
 | 
					            newconfig = self._read_config_file(config_file)
 | 
				
			||||||
            self._update_config_dict(config, newconfig)
 | 
					            self._update_config_dict(config, newconfig)
 | 
				
			||||||
        # command line config file
 | 
					        # command line config file
 | 
				
			||||||
        if (self.args and 'config_file' in self.args and
 | 
					        if (self.args and self.args.get('config_file', None)):
 | 
				
			||||||
                self.args['config_file']):
 | 
					 | 
				
			||||||
            newconfig = self._read_config_file(self.args['config_file'])
 | 
					            newconfig = self._read_config_file(self.args['config_file'])
 | 
				
			||||||
            self._update_config_dict(config, newconfig)
 | 
					            self._update_config_dict(config, newconfig)
 | 
				
			||||||
        # command line
 | 
					        # command line
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,7 +119,7 @@ class Manifest(object):
 | 
				
			||||||
            '__cdist_log_level': util.log_level_env_var_val(self.log),
 | 
					            '__cdist_log_level': util.log_level_env_var_val(self.log),
 | 
				
			||||||
            '__cdist_log_level_name': util.log_level_name_env_var_val(
 | 
					            '__cdist_log_level_name': util.log_level_name_env_var_val(
 | 
				
			||||||
                self.log),
 | 
					                self.log),
 | 
				
			||||||
            '__cdist_colored_log': str(cdist.log.ColorFormatter.USE_COLORS),
 | 
					            '__cdist_colored_log': str(self.log.USE_COLORS).lower(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if dry_run:
 | 
					        if dry_run:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -129,8 +129,8 @@ class Emulator(object):
 | 
				
			||||||
            # if invalid __cdist_log_level value
 | 
					            # if invalid __cdist_log_level value
 | 
				
			||||||
            logging.root.setLevel(logging.WARNING)
 | 
					            logging.root.setLevel(logging.WARNING)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        colored_log = self.env.get('__cdist_colored_log', 'False')
 | 
					        colored_log = self.env.get('__cdist_colored_log', 'false')
 | 
				
			||||||
        cdist.log.ColorFormatter.USE_COLORS = colored_log == 'True'
 | 
					        cdist.log.ColorFormatter.USE_COLORS = colored_log == 'true'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.log = logging.getLogger(self.target_host[0])
 | 
					        self.log = logging.getLogger(self.target_host[0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										19
									
								
								cdist/log.py
									
										
									
									
									
								
							
							
						
						
									
										19
									
								
								cdist/log.py
									
										
									
									
									
								
							| 
						 | 
					@ -51,7 +51,6 @@ logging.trace = _trace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ColorFormatter(logging.Formatter):
 | 
					class ColorFormatter(logging.Formatter):
 | 
				
			||||||
    USE_COLORS = False
 | 
					 | 
				
			||||||
    RESET = '\033[0m'
 | 
					    RESET = '\033[0m'
 | 
				
			||||||
    COLOR_MAP = {
 | 
					    COLOR_MAP = {
 | 
				
			||||||
        'ERROR': '\033[0;31m',
 | 
					        'ERROR': '\033[0;31m',
 | 
				
			||||||
| 
						 | 
					@ -62,20 +61,19 @@ class ColorFormatter(logging.Formatter):
 | 
				
			||||||
        'TRACE': '\033[0;37m',
 | 
					        'TRACE': '\033[0;37m',
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, msg):
 | 
					    def __init__(self, fmt):
 | 
				
			||||||
        super().__init__(msg)
 | 
					        super().__init__(fmt=fmt)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def format(self, record):
 | 
					    def format(self, record):
 | 
				
			||||||
        msg = super().format(record)
 | 
					        msg = super().format(record)
 | 
				
			||||||
        if self.USE_COLORS:
 | 
					        color = self.COLOR_MAP.get(record.levelname)
 | 
				
			||||||
            color = self.COLOR_MAP.get(record.levelname)
 | 
					        if color:
 | 
				
			||||||
            if color:
 | 
					            msg = color + msg + self.RESET
 | 
				
			||||||
                msg = color + msg + self.RESET
 | 
					 | 
				
			||||||
        return msg
 | 
					        return msg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DefaultLog(logging.Logger):
 | 
					class DefaultLog(logging.Logger):
 | 
				
			||||||
 | 
					    USE_COLORS = False
 | 
				
			||||||
    FORMAT = '%(levelname)s: %(message)s'
 | 
					    FORMAT = '%(levelname)s: %(message)s'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class StdoutFilter(logging.Filter):
 | 
					    class StdoutFilter(logging.Filter):
 | 
				
			||||||
| 
						 | 
					@ -90,7 +88,10 @@ class DefaultLog(logging.Logger):
 | 
				
			||||||
        super().__init__(name)
 | 
					        super().__init__(name)
 | 
				
			||||||
        self.propagate = False
 | 
					        self.propagate = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        formatter = ColorFormatter(self.FORMAT)
 | 
					        if self.USE_COLORS:
 | 
				
			||||||
 | 
					            formatter = ColorFormatter(self.FORMAT)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            formatter = logging.Formatter(self.FORMAT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.addFilter(self)
 | 
					        self.addFilter(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,7 @@ import sys
 | 
				
			||||||
my_dir = op.abspath(op.dirname(__file__))
 | 
					my_dir = op.abspath(op.dirname(__file__))
 | 
				
			||||||
fixtures = op.join(my_dir, 'fixtures')
 | 
					fixtures = op.join(my_dir, 'fixtures')
 | 
				
			||||||
interpolation_config_file = op.join(fixtures, "interpolation-test.cfg")
 | 
					interpolation_config_file = op.join(fixtures, "interpolation-test.cfg")
 | 
				
			||||||
colored_output_default = sys.stdout.isatty()
 | 
					colored_output_default = 'auto'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def newConfigParser():
 | 
					def newConfigParser():
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,8 @@
 | 
				
			||||||
#     Use a colored output for different log levels.
 | 
					#     Use a colored output for different log levels.
 | 
				
			||||||
#     It can be a boolean or 'auto' (default) which enables this feature if
 | 
					#     It can be a boolean or 'auto' (default) which enables this feature if
 | 
				
			||||||
#     stdout is a tty and disables it otherwise.
 | 
					#     stdout is a tty and disables it otherwise.
 | 
				
			||||||
 | 
					#     Colored output is always disabled if the NO_COLOR environment variable is
 | 
				
			||||||
 | 
					#     defined (https://no-color.org/).
 | 
				
			||||||
# colored_output = auto
 | 
					# colored_output = auto
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# conf_dir
 | 
					# conf_dir
 | 
				
			||||||
| 
						 | 
					@ -51,7 +53,7 @@
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# out_path
 | 
					# out_path
 | 
				
			||||||
#     Directory to save cdist output in.
 | 
					#     Directory to save cdist output in.
 | 
				
			||||||
# out_path = 
 | 
					# out_path =
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# parallel
 | 
					# parallel
 | 
				
			||||||
#     Process hosts in parallel. If -1 then the default, number of CPU's in
 | 
					#     Process hosts in parallel. If -1 then the default, number of CPU's in
 | 
				
			||||||
| 
						 | 
					@ -77,6 +79,6 @@
 | 
				
			||||||
# remote_shell = /bin/sh
 | 
					# remote_shell = /bin/sh
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# verbosity
 | 
					# verbosity
 | 
				
			||||||
#     Set verbosity level. Valid values are: 
 | 
					#     Set verbosity level. Valid values are:
 | 
				
			||||||
#     ERROR, WARNING, INFO, VERBOSE, DEBUG, TRACE and OFF.
 | 
					#     ERROR, WARNING, INFO, VERBOSE, DEBUG, TRACE and OFF.
 | 
				
			||||||
# verbosity = INFO
 | 
					# verbosity = INFO
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue