From 86b1c13790ad45af9bf3c1a0da0eba03509c5a33 Mon Sep 17 00:00:00 2001 From: "Salvador E. Tropea" Date: Fri, 22 Jan 2021 17:17:41 -0300 Subject: [PATCH] Now information messages go to stdout (not stderr). Debug, warning and error messages still use stderr. --- CHANGELOG.md | 2 + kibot/log.py | 74 ++++++++++++++++++++----------- tests/test_plot/test_ibom.py | 2 +- tests/test_plot/test_int_bom.py | 2 +- tests/test_plot/test_misc.py | 22 ++++----- tests/test_plot/test_print_sch.py | 4 +- tests/test_plot/test_svg.py | 2 +- 7 files changed, 66 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2c571ac..075df460 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 This status was moved to a separated column named `Status`. You can join both columns if you want. - Internal BoM: HTML rows are highlighted on hover (not just the cell). +- Now information messages go to stdout (not stderr). + Debug, warning and error messages still use stderr. ### Fixed - Extra data about drill marks in gerber files. diff --git a/kibot/log.py b/kibot/log.py index f1f4d227..e6454171 100644 --- a/kibot/log.py +++ b/kibot/log.py @@ -99,13 +99,33 @@ def set_verbosity(logger, verbose, quiet): logger.setLevel(log_level) +class FilterOnlyInfo(object): + def filter(self, record): + return record.levelno == logging.INFO + + +class FilterNoInfo(object): + def filter(self, record): + return record.levelno != logging.INFO + + def init(): """Initialize the logging feature using a custom format""" # Use a class to count and filter warnings logging.setLoggerClass(MyLogger) logger = get_logger() + # Handler for all but info. + # Outputs to stderr ch = logging.StreamHandler() - ch.setFormatter(CustomFormatter()) + ch.addFilter(FilterNoInfo()) + ch.setFormatter(CustomFormatter(sys.stderr)) + logger.addHandler(ch) + # Handler for t info. + # Outputs to stdout + ch = logging.StreamHandler() + ch.setStream(sys.stdout) + ch.addFilter(FilterOnlyInfo()) + ch.setFormatter(CustomFormatter(sys.stdout)) logger.addHandler(ch) return logger @@ -113,32 +133,34 @@ def init(): class CustomFormatter(logging.Formatter): """Logging Formatter to add colors""" - if sys.stderr.isatty(): - white = Fore.WHITE - yellow = Fore.YELLOW + Style.BRIGHT - red = Fore.RED + Style.BRIGHT - red_alarm = Fore.RED + Back.WHITE + Style.BRIGHT - cyan = Fore.CYAN + Style.BRIGHT - reset = Style.RESET_ALL - else: - white = "" - yellow = "" - red = "" - red_alarm = "" - cyan = "" - reset = "" - # format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s " - # "(%(filename)s:%(lineno)d)" - format = "%(levelname)s:%(message)s (%(name)s - %(filename)s:%(lineno)d)" - format_simple = "%(message)s" + def __init__(self, stream): + super().__init__() + if stream.isatty(): + white = Fore.WHITE + yellow = Fore.YELLOW + Style.BRIGHT + red = Fore.RED + Style.BRIGHT + red_alarm = Fore.RED + Back.WHITE + Style.BRIGHT + cyan = Fore.CYAN + Style.BRIGHT + reset = Style.RESET_ALL + else: + white = "" + yellow = "" + red = "" + red_alarm = "" + cyan = "" + reset = "" + # format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s " + # "(%(filename)s:%(lineno)d)" + format = "%(levelname)s:%(message)s (%(name)s - %(filename)s:%(lineno)d)" + format_simple = "%(message)s" - FORMATS = { - logging.DEBUG: cyan + format + reset, - logging.INFO: white + format_simple + reset, - logging.WARNING: yellow + format + reset, - logging.ERROR: red + format + reset, - logging.CRITICAL: red_alarm + format + reset - } + self.FORMATS = { + logging.DEBUG: cyan + format + reset, + logging.INFO: white + format_simple + reset, + logging.WARNING: yellow + format + reset, + logging.ERROR: red + format + reset, + logging.CRITICAL: red_alarm + format + reset + } def format(self, record): log_fmt = self.FORMATS.get(record.levelno) diff --git a/tests/test_plot/test_ibom.py b/tests/test_plot/test_ibom.py index 1bc4992c..87c074ef 100644 --- a/tests/test_plot/test_ibom.py +++ b/tests/test_plot/test_ibom.py @@ -52,7 +52,7 @@ def check_modules(ctx, fname, expected): logging.debug("List of components OK") -def test_ibom(): +def test_ibom_1(): prj = 'bom' ctx = context.TestContext('BoM_interactive', prj, 'ibom', BOM_DIR) ctx.run() diff --git a/tests/test_plot/test_int_bom.py b/tests/test_plot/test_int_bom.py index ccbfdabb..2ece4d19 100644 --- a/tests/test_plot/test_int_bom.py +++ b/tests/test_plot/test_int_bom.py @@ -1411,7 +1411,7 @@ def test_int_bom_variant_cl_gl(): prj = 'kibom-variante' ctx = context.TestContextSCH('test_int_bom_variant_cl_gl', prj, 'int_bom_var_t1_glb', BOM_DIR) ctx.run(extra=['--global-redef', 'variant=t1_v2']) - ctx.search_err(r'Using command line value .?t1_v2.? for global option .?variant.?') + ctx.search_out(r'Using command line value .?t1_v2.? for global option .?variant.?') # No variant -> t1_v2 logging.debug("* No variant -> t1_v2") rows, header, info = ctx.load_csv(prj+'-bom_(V2).csv') diff --git a/tests/test_plot/test_misc.py b/tests/test_plot/test_misc.py index d5088149..be5f3728 100644 --- a/tests/test_plot/test_misc.py +++ b/tests/test_plot/test_misc.py @@ -203,8 +203,8 @@ def test_auto_pcb_and_cfg(): ctx.dont_expect_out_file(ctx.get_pos_both_filename()) ctx.expect_out_file(ctx.get_pos_both_csv_filename()) - assert ctx.search_err('Using PCB file: '+board_file) - assert ctx.search_err('Using config file: '+yaml_file) + assert ctx.search_out('Using PCB file: '+board_file) + assert ctx.search_out('Using config file: '+yaml_file) ctx.clean_up() @@ -249,8 +249,8 @@ def test_auto_pcb_and_cfg_3(): ctx.run(extra=['-s', 'all', '-i'], no_out_dir=True, no_board_file=True, no_yaml_file=True, chdir_out=True) - assert ctx.search_err('Using SCH file: '+sch) - assert ctx.search_err('Using config file: '+yaml_file) + assert ctx.search_out('Using SCH file: '+sch) + assert ctx.search_out('Using config file: '+yaml_file) ctx.clean_up() @@ -273,7 +273,7 @@ def test_auto_pcb_and_cfg_4(): ctx.run(extra=['-s', 'all', '-i'], no_out_dir=True, no_board_file=True, no_yaml_file=True, chdir_out=True) assert ctx.search_err('Using '+sch) - assert ctx.search_err('Using config file: '+yaml_file) + assert ctx.search_out('Using config file: '+yaml_file) ctx.clean_up() @@ -293,7 +293,7 @@ def test_auto_pcb_and_cfg_5(): ctx.run(extra=['-s', 'all', '-i'], no_out_dir=True, no_board_file=True, no_yaml_file=True, chdir_out=True) assert ctx.search_err('Using (b_)?'+sch) - assert ctx.search_err('Using config file: '+yaml_file) + assert ctx.search_out('Using config file: '+yaml_file) ctx.clean_up() @@ -302,11 +302,11 @@ def test_list(): ctx = context.TestContext('List', '3Rs', 'pre_and_position', POS_DIR) ctx.run(extra=['--list'], no_verbose=True, no_out_dir=True, no_board_file=True) - assert ctx.search_err('run_erc: True') - assert ctx.search_err('run_drc: True') - assert ctx.search_err('update_xml: True') - assert ctx.search_err(r'Pick and place file.? \(position\) \[position\]') - assert ctx.search_err(r'Pick and place file.? \(pos_ascii\) \[position\]') + assert ctx.search_out('run_erc: True') + assert ctx.search_out('run_drc: True') + assert ctx.search_out('update_xml: True') + assert ctx.search_out(r'Pick and place file.? \(position\) \[position\]') + assert ctx.search_out(r'Pick and place file.? \(pos_ascii\) \[position\]') ctx.clean_up() diff --git a/tests/test_plot/test_print_sch.py b/tests/test_plot/test_print_sch.py index be7fa971..16c5d237 100644 --- a/tests/test_plot/test_print_sch.py +++ b/tests/test_plot/test_print_sch.py @@ -142,7 +142,7 @@ def test_sch_missing_1(): ctx.search_err("Component .?Resistor.? doesn't specify its library") ctx.search_err("Missing component .?l1:FooBar.?") ctx.search_err("Missing component(.*)Resistor", invert=True) - ctx.search_err(r"Found 3 unique warning/s \(4 total\)") + ctx.search_out(r"Found 3 unique warning/s \(4 total\)") ctx.clean_up() @@ -157,7 +157,7 @@ def test_sch_missing_filtered(): ctx.search_err("Component .?Resistor.? doesn't specify its library") ctx.search_err("Missing component .?l1:FooBar.?", invert=True) ctx.search_err("Missing component(.*)Resistor", invert=True) - ctx.search_err(r"Found 2 unique warning/s \(4 total, 2 filtered\)") + ctx.search_out(r"Found 2 unique warning/s \(4 total, 2 filtered\)") ctx.clean_up() diff --git a/tests/test_plot/test_svg.py b/tests/test_plot/test_svg.py index 2d0e09e5..083e86a8 100644 --- a/tests/test_plot/test_svg.py +++ b/tests/test_plot/test_svg.py @@ -200,7 +200,7 @@ def test_svg_anchor(): ctx = context.TestContext('test_svg_anchor', prj, 'svg_anchor', PS_DIR) ctx.run(extra=['SVG']) - assert ctx.search_err(r"- 'SVG files' \(SVG\) \[svg\]") + assert ctx.search_out(r"- 'SVG files' \(SVG\) \[svg\]") ctx.expect_out_file(ctx.get_gerber_filename('B_Cu', '.svg')) ctx.expect_out_file(ctx.get_gerber_filename('F_Cu', '.svg')) ctx.expect_out_file(ctx.get_gerber_filename('GND_Cu', '.svg'))