热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

在Memory.ai,我们开始大量使用RuboCop。这是关于我们如何将RuboCop集成到现有应用程序中的故事。这不是RuboCop的介绍性帖子。在深入了解我们的体

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

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

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

require:- rubocop-rspec- rubocop-rails- rubocop-performanceAllCops:EnabledByDefault: trueTargetRubyVersion: 2.6 . 3Exclude:- '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..C38 files inspected, 40 offenses detected
Created .rubocop_todo.yml.
Phase 2 of 2 : run all cops
Inspecting 38 files
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC38 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。

▶ bundle exec 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模型上调用了该方法。

因此,在我们的案例中,它将对custom 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/AnyInstance , RSpec/ExpectInHook, RSpec/AlignRightLetBrace

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

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

您使用RuboCop吗? 在下面的评论中或在@ _cha1tanya的 Twitter上告诉我

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



推荐阅读
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 安装mysqlclient失败解决办法
    本文介绍了在MAC系统中,使用django使用mysql数据库报错的解决办法。通过源码安装mysqlclient或将mysql_config添加到系统环境变量中,可以解决安装mysqlclient失败的问题。同时,还介绍了查看mysql安装路径和使配置文件生效的方法。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 本文介绍了C++中的引用运算符及其应用。引用运算符是一种将变量定义为另一个变量的引用变量的方式,在改变其中一个变量时,两者均会同步变化。引用变量来源于数学,在计算机语言中用于储存计算结果或表示值抽象概念。变量可以通过变量名访问,在指令式语言中引用变量通常是可变的,但在纯函数式语言中可能是不可变的。本文还介绍了引用变量的示例及验证,以及引用变量在函数形参中的应用。当定义的函数使用引用型形参时,函数调用时形参的改变会同时带来实参的改变。 ... [详细]
author-avatar
琪琪格
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有