diff --git a/tools/idf_py_actions/core_ext.py b/tools/idf_py_actions/core_ext.py index e8046354f1..dcd7f86bda 100644 --- a/tools/idf_py_actions/core_ext.py +++ b/tools/idf_py_actions/core_ext.py @@ -50,6 +50,37 @@ 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 confserver_target(target_name: str, ctx: Context, args: PropertyDict, buffer_size: int) -> None: + """ + Execute the idf.py confserver command with the specified buffer size. + """ + ensure_build_directory(args, ctx.info_name) + if buffer_size < 2048: + yellow_print( + f'WARNING: The specified buffer size {buffer_size} KB is less than the ' + 'recommended minimum of 2048 KB for idf.py confserver. Consider increasing it to at least 2048 KB ' + 'by setting environment variable IDF_CONFSERVER_BUFFER_SIZE= or by calling ' + 'idf.py confserver --buffer-size .' + ) + try: + run_target( + target_name, + args, + force_progression=GENERATORS[args.generator].get('force_progression', False), + buffer_size=buffer_size, + ) + except ValueError as e: + if str(e) == 'Separator is not found, and chunk exceed the limit': + # Buffer size too small/one-line output of the command too long + raise FatalError( + f'ERROR: Command failed with an error message "{e}". ' + 'Try increasing the buffer size to 2048 (or higher) by setting environment variable ' + 'IDF_CONFSERVER_BUFFER_SIZE= or by calling ' + 'idf.py confserver --buffer-size .' + ) + else: + raise + def size_target( target_name: str, ctx: Context, @@ -520,9 +551,22 @@ def action_extensions(base_actions: Dict, project_path: str) -> Any: ], }, 'confserver': { - 'callback': build_target, + 'callback': confserver_target, 'help': 'Run JSON configuration server.', - 'options': global_options, + 'options': global_options + + [ + { + 'names': ['--buffer-size'], + 'help': ( + 'Set the buffer size (in KB) in order to accommodate initial confserver response.' + 'Default value and recommended minimum is 2048 (KB), but it might need to be ' + 'increased for very large projects.' + ), + 'type': int, + 'default': 2048, + 'envvar': 'IDF_CONFSERVER_BUFFER_SIZE', + } + ], }, 'size': { 'callback': size_target, diff --git a/tools/idf_py_actions/tools.py b/tools/idf_py_actions/tools.py index 6fb9ce16ce..26b909ccfd 100644 --- a/tools/idf_py_actions/tools.py +++ b/tools/idf_py_actions/tools.py @@ -303,6 +303,7 @@ class RunTool: force_progression: bool = False, interactive: bool = False, convert_output: bool = False, + buffer_size: Optional[int] = None, ) -> None: self.tool_name = tool_name self.args = args @@ -315,6 +316,7 @@ class RunTool: self.force_progression = force_progression self.interactive = interactive self.convert_output = convert_output + self.buffer_size = buffer_size or 256 def __call__(self) -> None: def quote_arg(arg: str) -> str: @@ -373,7 +375,7 @@ class RunTool: p = await asyncio.create_subprocess_exec( *cmd, env=env_copy, - limit=1024 * 256, + limit=1024 * self.buffer_size, cwd=self.cwd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, @@ -525,6 +527,7 @@ def run_target( custom_error_handler: Optional[FunctionType] = None, force_progression: bool = False, interactive: bool = False, + buffer_size: Optional[int] = None, ) -> None: """Run target in build directory.""" if env is None: @@ -551,6 +554,7 @@ def run_target( hints=not args.no_hints, force_progression=force_progression, interactive=interactive, + buffer_size=buffer_size, )()