From 18334588bc86fd3cf345a64885ad9aa23e7ec051 Mon Sep 17 00:00:00 2001 From: Frantisek Hrbata Date: Tue, 28 Nov 2023 12:53:27 +0100 Subject: [PATCH] feat(tools): esp_idf_size.ng integration This integrates esp_idf_size.ng, refactored esp-idf-size version, into esp-idf and enables it by default. The esp_idf_size.ng may be enabled by using the --ng option, but also via ESP_IDF_SIZE_NG env. variable, which is used in this integration. New -l/--legacy option is added, which enforces usage of the old version. This option can be also set via "ESP_IDF_SIZE_LEGACY" env. variable. This should allow to easily switch back to old version if there is any problem. The new version is used by default for all formats, except for the "json". Examples: $ idf.py size # uses refactored version $ idf.py size --legacy # uses legacy version $ idf.py size --l # uses legacy version $ idf.py size --format json # uses legacy version $ idf.py size --format json2 # uses refactored version $ export ESP_IDF_SIZE_LEGACY="1" # use legacy version only from now on ESP_IDF_SIZE_FORCE_TERMINAL, which forces terminal control codes(colors), is also set when running from idf.py, so the colors are propagated even if stdout for esp_idf_size.ng is not attached to tty. The same changes are applied also to the idf_size.py wrapper. There is an import check if esp_idf_size.ng is available. If not, we switch into the legacy mode. This should cover situation when the esp-idf has support for refactored version, but it's not installed. This should also allow users to bind to a legacy version(<1.0.0) and the idf.py size and idf_size.py should still work. This also allow us to restring the version in constraints file if we need to switch back to legacy version globally. Signed-off-by: Frantisek Hrbata --- tools/idf_py_actions/core_ext.py | 34 ++++++++++++++++++++++++++++---- tools/idf_size.py | 24 +++++++++++++++++++++- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/tools/idf_py_actions/core_ext.py b/tools/idf_py_actions/core_ext.py index 3466b0e953..2b1fc96daa 100644 --- a/tools/idf_py_actions/core_ext.py +++ b/tools/idf_py_actions/core_ext.py @@ -19,7 +19,7 @@ from idf_py_actions.constants import GENERATORS, PREVIEW_TARGETS, SUPPORTED_TARG from idf_py_actions.errors import FatalError from idf_py_actions.global_options import global_options from idf_py_actions.tools import (PropertyDict, TargetChoice, ensure_build_directory, generate_hints, get_target, - idf_version, merge_action_lists, run_target, yellow_print) + idf_version, merge_action_lists, print_warning, run_target, yellow_print) def action_extensions(base_actions: Dict, project_path: str) -> Any: @@ -33,7 +33,8 @@ def action_extensions(base_actions: Dict, project_path: str) -> Any: ensure_build_directory(args, ctx.info_name) run_target(target_name, args, force_progression=GENERATORS[args.generator].get('force_progression', False)) - def size_target(target_name: str, ctx: Context, args: PropertyDict, output_format: str, output_file: str) -> None: + def size_target(target_name: str, ctx: Context, args: PropertyDict, output_format: str, + output_file: str, legacy: bool) -> None: """ Builds the app and then executes a size-related target passed in 'target_name'. `tool_error_handler` handler is used to suppress errors during the build, @@ -44,6 +45,27 @@ def action_extensions(base_actions: Dict, project_path: str) -> Any: for hint in generate_hints(stdout, stderr): yellow_print(hint) + if not legacy and output_format != 'json': + try: + import esp_idf_size.ng # noqa: F401 + except ImportError: + print_warning('WARNING: refactored esp-idf-size not installed, using legacy mode') + legacy = True + else: + # Legacy mode is used only when explicitly requested with --legacy option + # or when "--format json" option is specified. Here we enable the + # esp-idf-size refactored version with ESP_IDF_SIZE_NG env. variable. + os.environ['ESP_IDF_SIZE_NG'] = '1' + # ESP_IDF_SIZE_FORCE_TERMINAL is set to force terminal control codes even + # if stdout is not attached to terminal. This is set to pass color codes + # from esp-idf-size to idf.py. + os.environ['ESP_IDF_SIZE_FORCE_TERMINAL'] = '1' + + if legacy and output_format in ['json2', 'raw', 'tree']: + # These formats are supported in new version only. + # We would get error from the esp-idf-size anyway, so print error early. + raise FatalError(f'Legacy esp-idf-size does not support {output_format} format') + os.environ['SIZE_OUTPUT_FORMAT'] = output_format if output_file: os.environ['SIZE_OUTPUT_FILE'] = os.path.abspath(output_file) @@ -354,9 +376,13 @@ def action_extensions(base_actions: Dict, project_path: str) -> Any: # if the user explicitly specified the format or not. If the format is not specified, then # the legacy OUTPUT_JSON CMake variable will be taken into account. size_options = [{'names': ['--format', 'output_format'], - 'type': click.Choice(['default', 'text', 'csv', 'json']), - 'help': 'Specify output format: text (same as "default"), csv or json.', + 'type': click.Choice(['default', 'text', 'csv', 'json', 'json2', 'tree', 'raw']), + 'help': 'Specify output format: text (same as "default"), csv, json, json2, tree or raw.', 'default': 'default'}, + {'names': ['--legacy', '-l'], + 'is_flag': True, + 'default': os.environ.get('ESP_IDF_SIZE_LEGACY', '0') == '1', + 'help': 'Use legacy esp-idf-size version'}, {'names': ['--output-file', 'output_file'], 'help': 'Print output to the specified file instead of to the standard output'}] diff --git a/tools/idf_size.py b/tools/idf_size.py index 322d527f6f..342340002c 100755 --- a/tools/idf_size.py +++ b/tools/idf_size.py @@ -5,8 +5,30 @@ # SPDX-License-Identifier: Apache-2.0 # +import argparse +import os import subprocess import sys if __name__ == '__main__': - sys.exit(subprocess.run([sys.executable, '-m', 'esp_idf_size'] + sys.argv[1:]).returncode) + parser = argparse.ArgumentParser() + parser.add_argument('--format') + parser.add_argument('-l', '--legacy', action='store_true', default=os.environ.get('ESP_IDF_SIZE_LEGACY', '0') == '1') + args, rest = parser.parse_known_args() + + if not args.legacy and args.format != 'json': + try: + import esp_idf_size.ng # noqa: F401 + except ImportError: + print('warning: refactored esp-idf-size not installed, using legacy mode', file=sys.stderr) + args.legacy = True + else: + os.environ['ESP_IDF_SIZE_NG'] = '1' + + if args.legacy and args.format in ['json2', 'raw', 'tree']: + sys.exit(f'Legacy esp-idf-size does not support {args.format} format') + + if args.format is not None: + rest = ['--format', args.format] + rest + + sys.exit(subprocess.run([sys.executable, '-m', 'esp_idf_size'] + rest).returncode)