def run_cli()

in src/open_vp_cal/main.py [0:0]


def run_cli(
        project_settings_file_path: str,
        output_folder: str,
        ocio_config_path: str = None, force=False, error_log: str = None ) -> dict[str, LedWallSettings]:
    """ Runs the application in CLI mode to process the given project settings file.

    Args:
        project_settings_file_path: The project settings file path
        output_folder: The output folder path
        ocio_config_path: The OCIO config path
        force: Whether to force the processing to continue even if there are warnings and errors, highly discouraged and
            primarily for testing purposes
        error_log: The error log file path to store errors in as a json file

    Returns: The list of ProcessingResults

    """
    project_settings = ProjectSettings.from_json(project_settings_file_path)
    project_settings.output_folder = output_folder
    open_vp_cal_base = OpenVPCalBase()

    if ocio_config_path:
        project_settings.ocio_config_path = ocio_config_path

    # Load all the led walls and load the sequences
    for led_wall in project_settings.led_walls:
        if not led_wall.input_sequence_folder:
            output = f"Input sequence folder not set for '{led_wall.name}'"
            add_error_to_log(error_log, output)
            raise IOError(output)
        if not os.path.exists(led_wall.input_sequence_folder):
            output = f"Input sequence folder '{led_wall.input_sequence_folder}' does not exist"
            add_error_to_log(error_log, output)
            raise IOError(output)
        led_wall.sequence_loader.load_sequence(led_wall.input_sequence_folder)

        if not led_wall.roi:
            _, auto_roi_results = open_vp_cal_base.run_auto_detect(led_wall)
            if not auto_roi_results or not auto_roi_results.is_valid:
                output = "Auto ROI detection failed."
                add_error_to_log(error_log, output)
                raise ValueError(output)

        led_wall.sequence_loader.set_current_frame(led_wall.sequence_loader.start_frame)

    # Now we have everything lets sort the led walls so they are in the correct order
    status = open_vp_cal_base.analyse(project_settings.led_walls)
    if not status:
        error_messages = "\n".join(open_vp_cal_base.error_messages())
        warning_messages = "\n".join(open_vp_cal_base.warning_messages())
        output = f"Analysis Failed\nWarning Messages:\n{warning_messages}\nError Messages:\n{error_messages}\n"
        add_error_to_log(error_log, output)
        if not force:
            raise ValueError(output)

    status = open_vp_cal_base.post_analysis_validations(project_settings.led_walls)
    if not status:
        error_messages = "\n".join(open_vp_cal_base.error_messages())
        warning_messages = "\n".join(open_vp_cal_base.warning_messages())
        output = f"Analysis Validation Failed\nWarning Messages:\n{warning_messages}\nError Messages:\n{error_messages}\n"
        add_error_to_log(error_log, output)
        if not force:
            raise ValueError(output)

    status = open_vp_cal_base.calibrate(project_settings.led_walls)
    if not status:
        error_messages = "\n".join(open_vp_cal_base.error_messages())
        warning_messages = "\n".join(open_vp_cal_base.warning_messages())
        output = f"Calibrate Failed\nWarning Messages:\n{warning_messages}\nError Messages:\n{error_messages}\n"
        add_error_to_log(error_log, output)
        if not force:
            raise ValueError(output)

    status, led_walls = open_vp_cal_base.export(project_settings, project_settings.led_walls)
    if not status:
        error_messages = "\n".join(open_vp_cal_base.error_messages())
        warning_messages = "\n".join(open_vp_cal_base.warning_messages())
        output = f"Export Failed\nWarning Messages:\n{warning_messages}\nError Messages:\n{error_messages}\n"
        add_error_to_log(error_log, output)
        if not force:
            raise ValueError(output)

    return {led_wall.name: led_wall for led_wall in led_walls}