资讯详情

资讯详情

Credo 退出状态码(Exit Status)完全指南:按位编码原理与 CI 集成实战

静态分析代码质量Lint开发工具【免费下载链接】credoA static code analysis tool for the Elixir language with a focus on code consistency and teaching.项目地址https://gitcode.com/gh_mirrors/cr/credo点击查看免费下载本篇指南聚焦于 Elixir 静态代码分析工具 Credo 的退出状态码机制详细讲解 Credo 如何通过0、1-127与 128三档退出码区分「分析通过」「发现问题」和「运行期错误」并深入拆解其背后基于类别位图bitmap的按位或bitwise OR编码原理。读完本文你将掌握如何从$?中解读 Credo 的分析结果类别、如何在.credo.exs中为检查项定制:exit_status参数、如何为自定义检查与插件预留状态码区间以及如何在 CI 流水线中利用退出状态构建 Credo 合规性检查。一、退出状态码的总览Credo 遵循 Unix 程序的退出状态约定用退出状态码向调用方Shell、CI 系统、脚本传递本次分析的结果。其约定分为三档状态码范围含义0分析成功未发现任何问题与其他正常退出程序一致1 - 127分析成功但发现了若干问题Issues 128分析本身发生了运行时错误Actual Errors这一约定在官方文档 guides/introduction/exit_statuses.md 中有明确说明。它使基于 Shell 的流水线工作流例如 CI 系统得以实现只需检查命令的退出状态即可判定本次代码是否满足 Credo 的合规要求。状态码如何被真正吐出当用户键入mix credo时Credo 的入口 Credo.CLI 会执行run_to_halt/1把 argv 交给Credo.run/1后通过halt_if_exit_status_assigned/1读取执行结构中保存的退出状态并调用exit({:shutdown, exit_status})结束进程见 lib/credo/cli.ex#L39-L56。退出状态存放在Execution结构中由put_exit_status/2与get_exit_status/1读写默认值为0见 lib/credo/execution.ex#L655-L662。也就是说只要执行管线中没有任务主动写入退出状态最终就会以0退出。二、问题状态码按位编码原理Credo 最值得称道的设计在于退出状态不仅仅是一个有/无问题的开关它本身携带了问题类别的信息。按位或Bitwise OR聚合文档中给出了构造最终退出状态的逻辑import Bitwise issues | Enum.map((1.exit_status)) | Enum.reduce(0, (1 ||| 2))每个 Issue 都携带一个exit_status字段把所有 Issue 的exit_status按位或|||起来就得到最终退出状态。因此最终状态码是由各 Issue 状态位叠加复合而成的。这段逻辑与源码实现完全吻合在 lib/credo/execution/task/assign_exit_status_for_issues.ex 中to_exit_status/1对空列表返回0否则对每个 Issue 的exit_status执行与上面完全一致的Enum.reduce(0, (1 ||| 2))。该任务挂载在执行管线最后的halt_execution阶段见 lib/credo/execution.ex#L128保证退出状态在命令全部执行完毕后统一计算。Issue 结构体lib/credo/issue.ex的exit_status字段默认值为0由检查项通过format_issue/3写入见 lib/credo/check.ex#L696-L744。写入时的优先级为显式传入的:exit_status选项 检查项配置参数exit_status 检查项自身的类别。类别与状态位的默认映射由于每个检查项Check都有一个类别categoryCredo 按类别定义了默认的状态位类别默认退出状态consistency一致性1design设计2readability可读性4refactor重构8warning警告16该映射定义在 lib/credo/check.ex#L169-L175 的base_category_exit_status_map中。可以看到它们分别是2^0、2^1、2^2、2^3、2^4每位互不重叠这正是按位或编码能够保留类别信息的前提。当检查项通过use Credo.Check声明时如果没有显式指定:exit_status则会自动生成def exit_status, do: Credo.Check.to_exit_status(category())见 lib/credo/check.ex#L261-L274即按类别取默认值。Credo.Check.to_exit_status/1的实现lib/credo/check.ex#L840-L847接收nil返回0、接收 atom 则查映射表、接收数字则原样返回。用具体例子理解状态位文档给出了一个经典示例。在某个项目上运行$ mix credo [...snip...] $ echo $? 12退出状态12意味着什么呢把12拆开看12 4 8。也就是说本次分析发现了可读性问题readability位值为4与重构机会refactor位值为8但没有出现警告类问题warning位值为1612 16 0。按位或编码允许你从单个状态码中同时推知多种问题的存在。只要逐一检查状态码的各个位 1、 2、 4、 8、 16……就能精确还原问题类别的组合。为检查项定制状态码五种内置类别之外自定义检查项Custom Checks与插件Plugins可以定义自己的状态码例如custom category: 32 custom category: 64也就是使用16之后未占用的位2^5 32、2^6 64……从而保证与内置类别的位不冲突、可继续按位叠加。在.credo.exs配置文件中所有检查项都可以通过通用参数:exit_status覆盖默认状态码# .credo.exs %{ configs: [ %{ name: default, checks: %{ enabled: [ # 覆盖该检查项的退出状态码为 0不参与状态位聚合 {Credo.Check.Warning.IoInspect, exit_status: 0}, # 自定义检查项使用自定义状态位 {MyApp.CheckModule, exit_status: 32} ] } } ] }:exit_status是 Credo 提供的五个通用检查参数之一category、exit_status、files、priority、tags详见 guides/configuration/check_params.md#exit_status。其取值既可以是数字也可以是类别 atom会通过to_exit_status/1转换为对应位值。在源码层面Credo.Check.Params.exit_status/2的读取顺序是params[:__exit_status__]params[:exit_status]check_mod.exit_status()见 lib/credo/check/params.ex#L100-L103。:exit_status与:__exit_status__均被列为内置参数名lib/credo/check/params.ex#L80-L93其中双下划线前缀的版本由命令行选项解析写入属于内部机制。一个实用的场景如果你不希望某个检查项的发现影响 CI 的退出状态可以像上面例子一样把它的exit_status设为0——分析照常进行、问题照常展示但该问题不会参与状态位聚合最终退出码不会因此为非零。读取状态码的正确姿势由于是按位聚合最终状态码可能由多个位组合而成。若需判定是否存在某类问题应使用按位与而非相等比较例如在 Shell 中$ mix credo $ if [ $(( $? 16 )) -eq 16 ]; then echo 存在 Warning 类问题; fi也可以借助 Bash 的位运算检查复合状态码的任意位。三、真实错误状态码分析过程本身的故障要区分代码有问题和Credo 分析过程出错Credo 把 128的状态码保留给后者。由于这类错误状态码彼此互斥、不会叠加因此不遵循上述按位或的编码规则状态码含义128通用 Credo 错误Generic Credo error129 - 131Credo 配置错误Credo Config errors132 - 191保留错误Reserved errors192 - 255插件自定义错误由插件提供这些常量定义在 lib/credo/cli/exit_status.exdefmodule Credo.CLI.ExitStatus do moduledoc false def generic_error, do: 128 def config_parser_error, do: 129 def config_loaded_but_invalid, do: 130 end文档中提到的129-131区间目前由源码中的129config_parser_error配置文件解析错误与130config_loaded_but_invalid配置加载后校验失败占据131作为区间末位保留。它们分别对应执行管线中的两个任务129由 lib/credo/execution/task/convert_cli_options_to_config.ex 使用当ConfigBuilder.parse/1解析 CLI 选项或配置文件失败例如.credo.exs语法错误、指定的配置名不存在时任务会Execution.halt(exec, error)并打印** (config) Error while loading config file!之类的错误信息随后在error/2回调中把退出状态写为129。130由 lib/credo/execution/task/validate_options.ex 使用当检测到未知的命令行参数或未知开关unknown_args或unknown_switches非空时会打印** (credo) Unknown argument/switch for ... command并以130退出。128作为通用兜底在 lib/credo/execution/task/run_command.ex 中如果执行命令本身抛错且当前退出状态仍为0则在error/2回调中写入128。此外还有一个重要的命令行开关与退出状态直接相关$ mix credo --mute-exit-status--mute-exit-status会在配置中置位mute_exit_status: true见 lib/credo/config_builder.ex#L182-L188。此时 lib/credo/cli.ex#L45-L47 会跳过halt_if_exit_status_assigned/1的退出动作——即使发现了问题Credo 也总是以0退出。该开关适用于只展示分析结果、但不中断构建的流水线场景。四、自定义检查与插件专属状态位与错误码为自定义检查分配状态位自定义检查在声明类别后即可自动获得该类别对应的默认状态位defmodule MyApp.MyCustomCheck do use Credo.Check, category: :warning, base_priority: :high def run(%SourceFile{} source_file, params) do # ... end end如需使用独立的状态位直接在use Credo.Check中传入:exit_status选项exit_status已被列入valid_use_opts见 lib/credo/check.ex#L189-L200defmodule MyApp.MyCustomCheck do use Credo.Check, category: :warning, exit_status: 32 end这样当该检查项发现问题时退出状态码中会置起32这一位而不会与内置类别位混淆。注意状态位应选取尚未被占用的2^n值以免与其他类别位冲突导致状态码不可区分。为插件分配错误码区间与问题状态位类似插件可以在192-255区间内定义自己的错误状态码。插件在init/1回调中注册自定义命令、CLI 开关与任务参考 lib/credo/plugin.ex 中register_command/3、register_cli_switch/4、append_task/3等 API 的文档示例其自定义任务出错时即可通过Credo.Execution.put_exit_status/2写入自定义错误码。文档指出 128的错误状态码无法组合Since one cannot combine these。这是因为错误码是互斥的一次执行只会因为某一个具体环节的故障而终止不会像问题状态位那样多个叠加。五、在 CI 流水线中的应用实践基础用法合规性门禁文档强调退出状态机制enables shell based pipeline workflows (e.g. on CI systems) which test Credo compliance。最简单的用法是让 CI 在 Credo 发现问题时失败# .github/workflows/ci.yml示例 steps: - uses: actions/checkoutv4 - name: Setup Elixir uses: erlef/setup-beamv1 with: elixir-version: 1.16 otp-version: 26 - name: Mix deps run: mix deps.get - name: Credo check run: mix credo --strict--strict会让 Credo 展示并计入所有优先级的 Issue一旦发现任何问题mix credo将以非零状态退出CI 步骤随之失败从而实现Credo 合规性门禁。区分失败原因问题 vs 故障借助状态码的三档划分可以在 CI 脚本中区分代码不合规与工具运行故障mix credo --strict exit_code$? if [ $exit_code -eq 0 ]; then echo ✓ Credo 通过 elif [ $exit_code -ge 128 ]; then echo ✗ Credo 分析过程出错配置错误或运行时故障状态码: $exit_code exit 1 else echo ✗ 发现代码问题状态码: $exit_code位编码的问题类别见下文 exit 1 fi按类别精细控制失败条件状态位编码的最大价值在于CI 可以只对特定类别的问题亮红灯。例如只关心 Warning 类问题状态位16mix credo --strict exit_code$? if [ $(( exit_code 16 )) -ne 0 ]; then echo 存在 Warning 类问题阻止合并 exit 1 fi更进一步可以在.credo.exs中把某些检查项的exit_status调成0使其不再影响退出状态从而让严格门禁与容忍项并存。静默退出状态对于只想输出分析结果、不希望打断流水线的场景使用--mute-exit-statusmix credo --mute-exit-status关于 diff 命令的补充说明mix credo diff在分析结束后还会经过filter_issues_for_exit_status任务仅保留diff_marker: :new本次改动新增的 Issue 参与最终退出状态计算见 lib/credo/cli/command/diff/task/filter_issues_for_exit_status.ex 与 lib/credo/cli/command/diff/diff_command.ex。这意味着在 CI 中对改动文件做增量检查时历史遗留问题不会影响本次提交的退出状态——这在新代码必须合规的门禁场景中非常实用。六、排查与调试建议查看退出状态在终端运行mix credo后立刻执行echo $?。遇到128分析过程发生了未预期的运行时错误可加--debug查看调试输出或检查插件/自定义检查是否抛出了异常。遇到129配置文件.credo.exs解析失败终端会给出出错文件与行号重点检查配置语法与配置名。遇到130命令行参数或开关未知如拼写错误终端会提示Unknown argument/switch。需要定位问题类别对退出状态做按位与运算逐一与1/2/4/8/16及自定义状态位比对。不想让某个检查项影响退出码在其配置元组中设置exit_status: 0或直接使用--mute-exit-status全局静默。七、小结Credo 的退出状态码是一套信息密度很高的协议0表示干净通过1-127表示发现了问题且状态码本身通过按位或编码了问题的类别组合consistency1、design2、readability4、refactor8、warning16 128表示分析过程本身出错128通用错误、129配置解析错误、130配置校验失败该区间不参与按位叠加且192-255留给插件。检查项可以在配置中通过通用参数:exit_status覆盖默认状态位自定义检查与插件也可分别利用未占用的状态位如32、64与错误码区间192-255扩展这一协议。在 CI 与 Shell 流水线中你可以直接以退出状态为门禁也可以用按位与精确甄别问题类别从而构建精细化、可解释的 Credo 合规检查。相关实现文件状态码常量见 lib/credo/cli/exit_status.ex按位聚合逻辑见 lib/credo/execution/task/assign_exit_status_for_issues.ex类别映射见 lib/credo/check.ex通用参数:exit_status的完整用法见 guides/configuration/check_params.md。赞分享静态分析代码质量Lint开发工具【免费下载链接】credoA static code analysis tool for the Elixir language with a focus on code consistency and teaching.项目地址https://gitcode.com/gh_mirrors/cr/credo点击查看免费下载相关推荐minikube status 命令全解析集群状态检测、退出码位编码与自定义输出minikube status 命令全解析集群状态检测、退出码位编码与自定义输出 minikube status 是 minikube 中最常用的诊断命令之一云原生容器编排CLI开发工具Cargo 退出码Exit Status全解析0 成功与 101 失败的约定及源码实现Cargo 退出码Exit Status全解析0 成功与 101 失败的约定及源码实现 本文以 Cargo 官方手册中通用参考章节 section exi开发工具包管理器CLI构建工具Linux exit 命令详解退出状态码约定与 Shell 脚本错误处理实战Linux exit 命令详解退出状态码约定与 Shell 脚本错误处理实战 exit 是 bash 内建命令用于以指定状态码退出当前 shell是 Sh文档教程上一篇微信QQ消息防撤回神器RevokeMsgPatcher让你不再错过重要信息下一篇10个顶级科技公司SRE实战案例从GitHub加速计划中学习可靠性工程精髓创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →