ruby代码分析_与RuboCop交朋友:Ruby静态代码分析器

ruby代码分析

在Memory.ai,我们开始大量使用RuboCop。 这是关于我们如何将RuboCop集成到现有应用程序中的故事。

这不是RuboCop的介绍性帖子。 在深入了解我们的体验报告之前,请先查看RuboCop是什么。

我们从rubocoprubocop-performancerubocop-railsrubocop-rspec宝石开始。 默认情况下,我们启用了所有警察,这是我们在rubocop.yml.的初始配置rubocop.yml.

require:
  - rubocop-rspec
  - rubocop-rails
  - rubocop-performance

AllCops:
  EnabledByDefault: true
  TargetRubyVersion: 2.6 . 3
  Exclude:
    - 'app/views/**/*'
    - 'db/**/*'
    - 'bin/**/*'
    - 'csv/**/*'
    - 'slate/**/*'
    - 'vendor/bundle/**/*'
    - 'node_modules/**/*'

如果在现有项目中启用了RuboCop随附的所有警察,则将收到无数警告和冒犯。 在添加以上配置后运行rubocop时,这一点非常明显。

工作正在进行中

对于现有项目,有一种更好的方式集成RuboCop。 RuboCop提供了一个.rubocop_todo.yml文件,该文件记录了我们代码库中的所有违规行为。 当我们触摸特定代码段时,我们可以一一解决这些违规行为。 因此,我们不必先解决所有问题。

要开始使用.rubocop_todo.yml ,请执行以下步骤。

bundle exec rubocop --auto-gen-config
Added inheritance from`.rubocop_todo.yml` in `.rubocop.yml` .
Phase 1 of 2 : run Metrics/LineLength cop
Inspecting 38 files
CC....C..C..C...C..CCC..CC....CC..C..C

38 files inspected, 40 offenses detected
Created .rubocop_todo.yml.
Phase 2 of 2 : run all cops
Inspecting 38 files
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

38 files inspected, 104 offenses detected
Created .rubocop_todo.yml.

您将看到类似的输出,但是根据代码库的状态,攻击的数量可能极大,也可能非常少:)

这个命令做了三件事。

  • 继承自.rubocop_todo.yml的.rubocop.yml(稍后我们会再介绍)
  • 在我们所有的代码上运行rubocop
  • 生成一个新文件.rubocop_todo.yml

让我们看看.rubocop_todo.yml内容 。 它记录了我们代码中存在的所有违法行为。 让我们看一下其中一位警察的示例,以更好地理解。

# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: TreatCommentsAsGroupSeparators, Include.
# Include: **/*.gemfile, **/Gemfile, **/gems.rb
Bundler/OrderedGems:
  Exclude:
    - 'Gemfile'

Bundler/OrderedGems代码告诉我们,我们的代码库对Bundler/OrderedGems cop有一个冒犯,我们该如何解决。 但更重要的是,它会将存在该攻击的文件标记为将从中运行RuboCop的文件列表中排除

这是什么意思? 好吧,让我们现在尝试在整个项目上运行rubocop。

▶ bundleexec rubocop
Inspecting 38 files
......................................

38 files inspected, no offenses detected

哇! 我们的代码是干净的,它通过了所有警察,可以参加聚会了!

好吧,不是真的。 这是需要查看注释从.rubocop_todo.yml继承的.rubocop.yml的地方

▶ cat .rubocop.yml
inherit_from: .rubocop_todo.yml

.rubocop_todo.yml记录了我们代码库的所有违规行为,并且还从将运行rubocop的列表中排除了这些文件。

.rubocop.yml继承自.rubocop_todo.yml因此它也从将运行rubocop的列表中排除了那些文件。

当我们运行bundle exec rubocop ,从拿起配置.rubocop.yml这反过来又拾起从配置.rubocop_todo.yml已经排除了所有具有罪行的文件。 所有这些结果从bundle exec rubocop命令变为绿色输出。

因此,我们仍然拥有RuboCop不喜欢的令人讨厌的代码,但是我们有一种策略来逐步修复它,而不是一次全部修复它。

专家提示:将Rubocop集​​成到现有项目时,请始终生成.rubocop_todo.yml。

Git工作流程

下一步自然是对.rubocop_todo.yml文件采取行动,并在我们触及现有的攻击性代码并确保我们编写的新代码紧随警察之后,修复攻击。

我们决定添加一个git钩子,该钩子将在分阶段的更改上运行RuboCop。 RuboCop提供了--safe-autocorrect选项,该选项--safe-autocorrect根据特定警察是否被认为可以自动更正来自动更正某些代码。 我们在git commit钩子中利用了这一点,以便开发人员不必担心手动修复所有问题。 当机器可以做到时,为什么不呢?

我们用huskylint-staged NPM包来实现这一目标。

npm install --save-dev lint-staged husky

package.json添加以下内容

{"scripts" : {
    "precommit" : "lint-staged"
  },
  "lint-staged" : {
    {app,spec}/**/*.rb ": [
      " bundle exec rubocop --safe-autocorrect ",
      " git add "
    ]
  },
  " devDependencies ": {
    " husky ": " ^ 0.13 .4 ",
    " lint-staged ": " ^ 3.6 .0 "
  }
}

这种配置确保了每当开发人员尝试提交代码时,RuboCop认为该代码中的安全漏洞以及支持“ 自动更正”机制的警察都已得到修复。 此后,我们的开发人员无需做任何其他事情,除了修复RuboCop认为不安全的违法行为。

进行中的工作继续

一旦自动更正git钩子开始起作用,我们的攻击清单就会开始下降。 我们必须在两者之间重新生成.rubocop_todo.yml才能获得准确的犯罪清单。 我们决定不将.rubocop_todo.yml的再生添加到Git挂钩中,因为在我们的情况下这很慢。

.rubocop_todo.yml可以从生成它的同一命令中重新生成。

幸福还是痛苦?

毕竟,我们希望攻击性代码会下降,并且代码质量会每天提高,而不会出现任何错误。 但是我们面临的挑战很少。

自动更正钩子在此过程中对我们的代码进行了一些意外更改。

我们有一段代码,其中包含方法update_attributes。 rubocop-rails gem有一个cop ActiveRecord/Aliases rubocop-rails ,可以通过update更改对update_attributes的调用。 尽管此更改仅应在Active Record模型上发生,但cop不会检查是否在Active Record模型上调用了该方法。

因此,在我们的案例中,它将对update_attributes的调用更改为update,但未更改方法定义。 它仍然是update_attributes。 这导致了错误。 由于我们启用了安全自动校正Git钩子,因此开发人员只有在CI中的构建失败时才知道这一点。

我们还遇到了其他一些警察的问题,例如Rails / SaveBang和Style/StringHashKeys ,他们更改了原本应该Style/StringHashKeys的代码。

最后,我们决定删除安全的自动更正钩子,并依靠手动固定攻击性代码。

回馈

当我们遇到与某些警察相关的问题,这些问题对于安全自动更正选项而言并不十分安全时,我们尝试通过将补丁提交给RuboCop来修复它们。

  1. https://github.com/rubocop-hq/rubocop-rails/pull/101
  2. https://github.com/rubocop-hq/rubocop-rails/pull/98
  3. https://github.com/rubocop-hq/rubocop/pull/7312

我会鼓励每个人都这样做,因为它使RuboCop对每个人都更好。

最后,我将列出从这次采用中学到的知识。

增量采用是关键。

自动更正可能会很棘手,具体取决于您的测试覆盖率和许多其他因素,因此如果不需要,请不要使用它。

禁用您的团队不同意的警察。 我们禁用了警察,例如RSpec/AnyInstanceRSpec/ExpectInHook, RSpec/AlignRightLetBrace

通过您的发现和代码修复为社区做出贡献 ,从而使RuboCop等关键工具对每个人都变得更好。

想知道我们如何做Ruby和Rails在Memory.ai,订阅我的通讯 这里

您使用RuboCop吗? 让我知道下面的评论或Twitter上的评论 @ _cha1tanya

翻译自: https://hackernoon.com/making-friends-with-rubocop-ruby-static-code-analyzer-rp9c36wr

ruby代码分析

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值