RuboCop v0.29.0 版本解读:--except 选项、四个新 cop 与自动纠正能力全面升级
RuboCop v0.29.0 版本解读--except 选项、四个新 cop 与自动纠正能力全面升级【免费下载链接】rubocopA Ruby static code analyzer and formatter, based on the community Ruby style guide.项目地址: https://gitcode.com/GitHub_Trending/rub/rubocopRuboCop v0.29.0 是该项目在静态分析能力上的一次密集迭代命令行新增--except选项--only/--except开始支持按命名空间如Lint批量筛选 cop新增StructInheritance、DuplicateMethods、FirstParameterIndentation、SpaceAroundBlockParameters四个 cop多个既有 copEvenOdd、Lambda、SelfAssignment、RedundantException获得自动纠正支持。阅读本文后你将掌握 v0.29.0 引入的新命令行用法、新配置项、新检查规则与自动纠正行为并能在当前仓库源码中定位到对应的实现证据。本文对应官方发布说明为 relnotes/v0.29.0.md。一、版本概览一次检查能力 纠正能力 稳定性的同步升级v0.29.0 的发布说明分为三大部分这也构成了本文的三个主线New features新功能2 个命令行/配置能力--except、AllCops/DisplayCopNames、4 个新增 cop、以及一批 cop 的自动纠正支持Changes行为变更自动纠正无限循环改为直接中止、废弃选项-e/--emacs与-s/--silent被移除、--fail-level A语义调整、MultilineBlockLayout支持参数处理Bugs fixed缺陷修复覆盖自动纠正、配置继承、误报/漏报、退出码等多个维度共二十余项。这些内容在当前仓库中均有对应实现可查下文逐一展开。二、命令行能力升级--except 与命名空间筛选1. 新增--except在命令行按 cop 白名单/黑名单控制检查范围v0.29.0 前命令行只有--only能限制只运行哪些 copv0.29.0 通过 issue #1430 引入--except用于在命令行直接排除指定 cop而无需改动.rubocop.yml# 运行全部检查但跳过 Style/EvenOdd 与 Lint/Debugger rubocop --except Style/EvenOdd,Lint/Debugger # 排除整个命名空间 rubocop --except Metrics # 与 --only 组合使用只运行 Lint 部门再从中剔除 Lint/Debugger rubocop --only Lint --except Lint/Debugger从源码看--only与--except共用一个解析入口。在 lib/rubocop/options.rb 中add_check_options通过add_cop_selection_csv_option(except, opts)与add_cop_selection_csv_option(only, opts)注册两个选项其底层实现lib/rubocop/options.rb按逗号拆分参数def add_cop_selection_csv_option(option, opts) option(opts, --#{option} [COP1,COP2,...]) do |list| unless list message --#{option} argument should be [COP1,COP2,...]. raise OptionArgumentError, message end cop_names list.empty? ? [] : list.split(,) cop_names.unshift(Lint/Syntax) if option only !cop_names.include?(Lint/Syntax) options[:#{option}] cop_names end end有两个值得注意的实现细节使用--only时Lint/Syntax会被自动追加到 cop 列表中除非用户已显式包含保证语法检查始终开启而--except不会做此处理。正因如此lib/rubocop/options.rb 的兼容性校验中会拦截--except Lint/Syntax或--except Syntax并抛出OptionArgumentError: Syntax checking cannot be turned off.。在 lib/rubocop/options.rb 中validate_cop_options会对only与except两处列表统一做合法性校验遇到拼写错误的 cop 名会基于NameSimilarity给出 Did you mean? 提示见 lib/rubocop/options.rb。2.--only/--except支持命名空间参数v0.29.0 的另一个 CLI 增强issue #1284--only与--except的参数不再局限于单个 cop 全名还可以直接传入部门名namespace例如Lint、Style、Metrics# 只运行全部 Lint 检查 rubocop --only Lint # 运行除 Style 部门外的全部检查 rubocop --except Style # 运行 Lint 与 Metrics 两个部门 rubocop --only Lint,Metrics这与仓库中-l/--lint等价于--only Lint见 lib/rubocop/options.rb、-x/--fix-layout等价于--only Layout并开启自动纠正的语义保持一致方便在 CI 或本地快速聚焦某一类问题。三、报告输出配置AllCops/DisplayCopNamesv0.29.0 将命令行--display-cop-names的能力下沉为配置文件选项AllCops/DisplayCopNamesissue #1324使团队可以在.rubocop.yml中统一控制违规报告中是否显示 cop 名称。在仓库默认配置 config/default.yml 中# Cop names are displayed in offense messages by default. Change behavior # by overriding DisplayCopNames, or by giving the --no-display-cop-names # option. DisplayCopNames: true要点默认值为true即默认在报告每条违规时附带 cop 全名如Style/EvenOdd命令行对应选项是-D/--display-cop-names/--no-display-cop-names其注册位置在 lib/rubocop/options.rb属于 Output Options 分组优先级高于配置文件与相邻的DisplayStyleGuide: false、StyleGuideBaseURL: https://rubystyle.guide配合可以控制报告中是否附带风格指南链接。典型用法在项目.rubocop.yml中关闭 cop 名称以精简终端输出或显式开启以便在 CI 日志中直接按 cop 名聚合问题。四、四个新增 cop 详解v0.29.0 新增四个 cop分属 Style 与 Lint 两个部门覆盖了继承结构、方法重名、参数缩进、块参数间距四类常见代码问题。1.Style/StructInheritance禁止继承自Struct.new该 copissue #1571MSG Dont extend an instance initialized by Struct.new. \ Use a block to customize the struct. def on_class(node) return unless struct_constructor?(node.parent_class) return if defines_constants?(node.body) add_offense(node.parent_class) do |corrector| ... end end官方示例展示了坏与好两种写法# bad —— 多出一层匿名类Person.ancestors 会包含 #Class:... class Person Struct.new(:first_name, :last_name) def age 42 end end # good —— 直接把块传给 Struct.new Person Struct.new(:first_name, :last_name) do def age 42 end end该 cop 支持自动纠正extend AutoCorrector但源码注释明确标注Autocorrection is unsafe它会改变继承树如Module#ancestors的返回值也可能让原本通过祖先链解析的常量在块内失效。2.Lint/DuplicateMethods类/模块中的重复方法定义该 copissue #1575。仓库配套测试见 spec/rubocop/cop/lint/duplicate_methods_spec.rb。# bad —— foo 被定义了两次 class Example def foo; end def foo; end end3.Layout/FirstParameterIndentation方法调用首个参数的缩进该 copissue #1144# bad —— 首个参数缩进与调用行不一致 foo( bar, baz ) # good foo( bar, baz )它关注的是第一行参数这个此前未被单独覆盖的边界场景与既有的Layout/AlignParameters等 cop 形成互补。4.Layout/SpaceAroundBlockParameters块参数竖线内外的空格该 copissue #1627# bad list.map {|x| x * 2 } list.map { |x,y| x * y } # good list.map { |x| x * 2 } list.map { |x, y| x * y }即竖线内侧紧贴参数不加空格外侧与块体之间保留一个空格多个参数之间遵循逗号后空一格。五、自动纠正能力扩展五个 cop 加入 autocorrect 阵营v0.29.0 大幅扩展了-a/--autocorrect旧名--auto-correct见 lib/rubocop/options.rb 的选项映射注释的覆盖面Cop部门说明Style/EvenOddStyle将n % 2 0类写法纠正为n.even?issue #1506Style/LambdaStyle支持在 lambda 字面量-与lambda关键字之间自动转换issue #1271Style/SelfAssignmentStyle支持x x 1到x 1的合并赋值纠正issue #1276Style/RedundantExceptionStyle支持将raise RuntimeError, msg纠正为raise msg实现见 lib/rubocop/cop/style/redundant_exception.rbRails/ReadWriteAttributeRails支持read_attribute/write_attribute到self[:attr]的纠正issue #1539需要特别说明的是Rails/ReadWriteAttribute属于 Rails 部门 cop。在 v0.29.0 时代 Rails cop 还内置于 RuboCop 主仓库中而当前仓库的 lib/rubocop/cop 目录下已不再包含rails/子目录Rails 相关检查已迁移至独立的 rubocop-rails 扩展仓库因此本文仅将其作为 v0.29.0 发布说明中的历史事实列出当前主仓库中无法直接找到其实现文件。Lint/Debugger扩展识别 Capybara 调试方法Lint/Debuggercopissue #1507。六、行为变更v0.29.0 的兼容性提醒1. 自动纠正导致无限循环时直接中止v0.29.0issue #1492 与infinite_loop_during_autocorrect_with_change.rb用于验证死循环检测逻辑的触发与报错行为。2. 废弃选项移除-e/--emacs与-s/--silentv0.29.0 起-e/--emacs与-s/--silent两个选项不再被识别使用它们会直接抛出错误。在当前仓库的 lib/rubocop/options.rb 中可以看到短选项-s已被重新分配给--stdin FILE而-E对应--extra-details——旧选项确实已从解析表中消失。升级时若脚本中仍在使用这两个参数需要改为对应的 formatter如-f emacs或删除。3.--fail-level A全部违规被纠正后也返回失败v0.29.0issue #1565形成对比——目的是让 CI 感知到代码被修改过从而触发重新构建或提醒提交。--fail-level的取值表见 lib/rubocop/options.rb其中A被映射为:autocorrect。4.MultilineBlockLayout支持参数处理Layout/MultilineBlockLayoutissue #1309。七、Bug 修复精选自动纠正、配置与误报的全面收敛v0.29.0 修复了二十余项缺陷可归纳为四个主题每项都对应发布说明中标注的 issue 编号可据此回溯讨论1. 自动纠正相关的稳定性修复Style/PerlBackrefs自动纠正不再抛异常#1634--auto-correct --only IndentationWidth组合不再崩溃#1500Style/BracesAroundHashParameter纠正后保留正确空格数#1527Layout/BlockAlignment修复赋值相关的自动纠正#1573避免将Hash.new纠正为{}时与块语法产生歧义#1574Style/Semicolon、Style/TrivialAccessors在纠正被跳过时不再误打印[Corrected]标记#1547、#1580——这直接影响 CI 日志的可信度Rake任务中的auto_correct能正确继承父任务传入的选项。2. 配置与文件处理Exclude属性从上级目录继承时的 bug修复了高层目录Exclude未正确向下生效的问题配置文件格式错误时给出有意义的报错#1504而不是晦涩的解析异常.rubocop.yml的inherit_from支持expand_path#1612修复从其他目录运行时文件包含范围错误的问题#1598。3. 误报/漏报修复Layout/EmptyLinesAroundAccessModifier不再把名称恰好是 access modifier 的方法调用误判为违规#1484也修复了与EmptyLinesAroundBlockBody在块首 access modifier 场景下的冲突#1553Lint/AssignmentInCondition开始处理元素赋值如a[i] v修复典型字符串格式化示例的漏报#1512Layout/MultilineOperationIndentation不再检查[]内的参数#1591Rails/Delegate忽略类方法#1509Style/ClassMethods校验类方法名是否与所在类/模块名一致#1610Style/LineEndConcatenation正确处理拼接字符串中的注释#1054。4. 退出码与文档存在崩溃的 cop发生错误的 cop时以退出码 1 结束#1587避免看似成功实则跳过检查的假绿修复 Yard 文档生成时example的警告#1594。八、升级与验证如何在本仓库复现 v0.29.0 行为当前仓库已是远高于 v0.29.0 的版本但上述能力大多延续至今。你可以在仓库中通过以下方式验证# 1. 查看 --except 与 --display-cop-names 的完整帮助文本 bundle exec rubocop --help # 2. 用 --only 加命名空间运行单一部门检查以 Lint 为例 bundle exec rubocop --only Lint # 3. 用 --except 排除指定 cop bundle exec rubocop --except Layout/SpaceAroundBlockParameters # 4. 查看当前默认配置中 DisplayCopNames 等 AllCops 项 sed -n 60,80p config/default.yml如需回归验证 v0.29.0 引入的 cop可运行对应的 spec 文件例如spec/rubocop/cop/style/struct_inheritance_spec.rbspec/rubocop/cop/lint/duplicate_methods_spec.rbspec/rubocop/cop/layout/first_parameter_indentation_spec.rbspec/rubocop/cop/layout/space_around_block_parameters_spec.rb发布说明中相关代码实现可进一步查阅 lib/rubocop/cop/style、lib/rubocop/cop/lint 与 lib/rubocop/cop/layout 等目录以了解这些规则在当前版本中的最新形态。【免费下载链接】rubocopA Ruby static code analyzer and formatter, based on the community Ruby style guide.项目地址: https://gitcode.com/GitHub_Trending/rub/rubocop创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考