Chronaxis用户手册English
本页目录

chronaxis.cli

源码基线:8904c2f744951857659abd40aaa3535d57faf53c

1"""提供当前配置检查、分析发布、独立批量和高性能积分器入口。23参数为命令行选项;按命令延迟导入实现,帮助只依赖标准库。4检查按需读取配置和DBC元数据,运行命令才扫描业务输入并发布结果。5结果目录可复用;完成清单最后写入,失败不报告正常完成。6"""78import argparse9import json10from pathlib import Path11import sys121314def _parser() -> argparse.ArgumentParser:15    """定义已交付命令,未知命令和缺参数由argparse定位。1617    参数: 无。返回: ArgumentParser,不读取任何配置或来源。18    异常: 原参数构造错误传播;解析时的帮助/坏参数分别SystemExit(0/2)。19    """20    parser = argparse.ArgumentParser(prog='chronaxis', description='Chronaxis当前配置检查与分析')21    commands = parser.add_subparsers(dest='command', required=True)22    fast = commands.add_parser('fast', help='校验、解释或执行单会话同帧累计')23    actions = fast.add_subparsers(dest='fast_command',required=True)24    for action in ('validate','explain','run'):25        sub = actions.add_parser(action)26        sub.add_argument('config')27        sub.add_argument('--process-count', type=int, default=None, help='覆盖本次读取、解码和单帧求值工作进程上限')28        if action == 'run':29            sub.add_argument('--output',required=True)30    fast_batch = actions.add_parser('batch',help='并行运行独立文件并发布批量报告')31    fast_batch.add_argument('config')32    fast_batch.add_argument('--output',required=True)33    fast_batch.add_argument('--process-count', type=int, default=None, help='覆盖独立任务工作进程数;不建立嵌套池')34    fast_batch.add_argument('--total',action='store_true',help='对同一模板内可比指标求总量')35    guide = commands.add_parser('guide', help='显示可直接阅读的AI指南路径')36    guide.add_argument('--language', choices=('zh', 'en'), default='zh', help='阅读入口语言,默认zh;不写文件')37    guide.add_argument('--output', help='可选:另存完整双语ZIP;父目录须存在,目标不能已存在')38    configuration = commands.add_parser('config', help='初始化及检查配置文件')39    configuration_actions = configuration.add_subparsers(dest='config_command', required=True)40    initialize = configuration_actions.add_parser('init', help='从合成场景生成完整新目录')41    initialize.add_argument('scene', nargs='?', help='场景名;用--list查看可选场景')42    initialize.add_argument('--list', action='store_true', help='列出全部场景,不写文件')43    initialize.add_argument('--output', help='全新目录;父目录须已存在')44    initialize.add_argument('--style', choices=('minimal','annotated'), default='annotated', help='默认完整注释版')45    convert = configuration_actions.add_parser('convert', help='当前JSON/YAML互转,保持类型和值;不保留注释')46    convert.add_argument('input', help='当前分析或批量配置')47    convert.add_argument('--output', required=True, help='新.json/.yaml/.yml文件;相对路径配置须写同目录')48    resolve = configuration_actions.add_parser('resolve', help='展开有效配置,固定绝对路径;可选显示实际默认')49    resolve.add_argument('input', help='当前分析或批量配置')50    resolve.add_argument('--output', help='可选全新JSON/YAML文件;省略时输出到终端')51    resolve.add_argument('--format', choices=('json','yaml'), help='终端默认yaml;文件由扩展名确定')52    resolve.add_argument('--defaults', action='store_true', help='写出适用的执行、输出、信号与规则等默认值')53    # 来源报告只按请求生成,不混入可重新加载的resolve输出。54    origins = configuration_actions.add_parser('origins', help='查看定义来自哪个配置文件,不读取业务输入')55    origins.add_argument('input', help='当前分析或批量配置')56    origins.add_argument('--fields', action='store_true', help='列所有显式叶字段;默认列来源、信号和派生定义')57    origins.add_argument('--format', choices=('text','json'), default='text', help='默认中文文本,json用于机器读取')58    # 静态命令只接受配置和明确后端,不提供输出目录等会误导为已运行的选项。59    for name, help_text in (('validate', '检查配置、绑定和当前执行能力'),60                            ('explain', '显示依赖、节点后端与预算声明')):61        check = commands.add_parser(name, help=help_text)62        check.add_argument('plan', help='分析计划YAML或JSON;来源相对路径按配置文件目录解释')63        check.add_argument('--backend', choices=('reference', 'numpy', 'auto'), default=None,64                           help='显式覆盖本次后端;省略则沿用计划声明')65        check.add_argument('--process-count', type=int, default=None, help='覆盖本次读取解码进程上限;正整数,省略沿用配置')66        check.add_argument('--format', choices=('text','json'), default='text',67                           help='默认显示易读说明;json用于程序读取')68    # 结果目录可复用;文件由本次时间区分,数值与格式仍来自同一个计划。69    execute = commands.add_parser('run', help='分析计划并发布带时间文件名的结果')70    execute.add_argument('plan', help='分析计划YAML或JSON')71    execute.add_argument('--output', required=True, help='结果目录,可重复使用;不覆盖已有文件')72    execute.add_argument('--work-dir', default=None, help='可选全新工作目录;省略沿AnalysisRunner唯一专用暂存')73    execute.add_argument('--backend', choices=('reference', 'numpy', 'auto'), default=None,74                         help='显式覆盖本次后端;省略沿用计划声明')75    execute.add_argument('--process-count', type=int, default=None, help='覆盖本次读取解码进程上限;正整数,省略沿用配置')76    batch = commands.add_parser('batch', help='独立分析任务批量运行')77    batch_actions = batch.add_subparsers(dest='batch_command', required=True)78    batch_run = batch_actions.add_parser('run', help='执行批量YAML或JSON并保存逐任务状态')79    batch_run.add_argument('plan', help='批量YAML或JSON,各任务计划路径相对此文件目录')80    batch_run.add_argument('--output', required=True, help='批量结果目录,可重复使用;每批使用独立时间标识')81    batch_run.add_argument('--process-count', type=int, default=None, help='可选覆盖同时运行数,须为正整数')82    return parser838485def main(argv=None) -> int:86    """执行共享CLI并给出固定退出码,完整事实保在报告和原异常中。8788    参数: argv为参数字符串序列或None(使用进程参数)。89    返回: 0成功、130取消;失败按入口/阶段返回1或2。普通文件失败为1,90        fast单会话准备失败(含文件错误)为2、运行失败为1;批量规则见手册CLI。91    异常: argparse帮助/参数错误按标准抛SystemExit;MemoryError及内部编程错误不伪装配置错误。92    副作用: 静态命令只读计划;run分析后发布本次时间文件到可复用目录。93    """94    arguments = _parser().parse_args(argv)95    operation = {'guide': '资料读取'}.get(arguments.command, '计划')96    try:97        if arguments.command == 'guide':98            # 默认只定位已经存在的README;显式output才生成独立副本。99            from .user_guide import export_guide, guide_path100            print(export_guide(arguments.output) if arguments.output else guide_path(arguments.language))101            return 0102        if arguments.command == 'fast':103            from .fast.cli import execute104            return execute(arguments)105        if arguments.command == 'config':106            from .configuration.cli import run_configuration_cli107            return run_configuration_cli(arguments)108        if arguments.command == 'batch':109            from .batch.cli import run_batch_cli110            return run_batch_cli(arguments)111        # 帮助和参数错误先由argparse结束;只有实际计划命令才加载计划依赖。112        from .analysis_cli import run_static, run_analysis113        return run_analysis(arguments) if arguments.command == 'run' else run_static(arguments)114    except KeyboardInterrupt:115        # 发布器已尝试最小收尾并保恢复owner;CLI退出后系统还会关闭进程持有的FD。116        if arguments.command == 'run':117            message = '分析已取消;输出可能已发布,请核对目标目录 ' + str(Path(arguments.output).absolute())118        elif arguments.command == 'batch':119            message = '批量操作已取消;请核对各任务结果和批量报告目录 ' + str(Path(arguments.output).absolute())120        else:121            message = '计划操作已取消。'122        print(message, file=sys.stderr)123        return 130124    except NotImplementedError as error:125        print(operation + '功能不可用:' + str(error), file=sys.stderr)126        return 1127    except OSError as error:128        print(operation + '文件操作失败:' + str(error), file=sys.stderr)129        return 1130    except ValueError as error:131        if arguments.command in ('run', 'batch'):132            # run只把明确的配置异常归为2;未包装的内部ValueError仍保原异常传播。133            from .planning.checks import PlanValidationError134            if not isinstance(error, PlanValidationError):135                raise136        # 共享语法加载增加一层配置错误,仍沿有限原异常链区分真实文件失败。137        from .analysis_cli import _cause_chain138        file_error = any(isinstance(cause,OSError) for issue in getattr(error, 'diagnostics', (error,))139                         for cause in _cause_chain(issue))140        if arguments.command in ('validate','explain') and arguments.format=='json':141            from .planning.checks import PlanValidationError142            if isinstance(error,PlanValidationError):143                payload = dict(valid=False, errors=[item.to_dict() for item in error.diagnostics])144                if error.blocked_checks:145                    payload['blocked_checks'] = error.blocked_checks146                print(json.dumps(payload,ensure_ascii=False,allow_nan=False))147                return 1 if file_error else 2148        print(operation + ('文件操作失败:' if file_error else '配置错误:') + str(error), file=sys.stderr)149        return 1 if file_error else 2150
Chronaxis 用户手册 · 离线阅读