ruby-on-rails 如何运行Rubocop只在一个拉请求中更改的文件?

5anewei6  于 2022-11-19  发布在  Ruby
关注(0)|答案(7)|浏览(167)

我已经创建了spec/lint/rubocop_spec.rb,它在当前分支和主分支之间更改的文件上运行Rubocop样式检查器。当我在本地测试时,它工作,但当在构建服务器Circle.ci上运行测试时,它不工作。我怀疑这是因为只下载了有问题的分支,所以它没有发现master之间的任何差异。有没有比git co master && git pull origin master更好的方法?我可以查询Github API也许得到改变的文件列表吗?

require 'spec_helper'

describe 'Check that the files we have changed have correct syntax' do
  before do
    current_sha = `git rev-parse --verify HEAD`.strip!
    files = `git diff master #{current_sha} --name-only | grep .rb`
    files.tr!("\n", ' ')
    @report = 'nada'
    if files.present?
      puts "Changed files: #{files}"

      @report = `rubocop #{files}`
      puts "Report: #{@report}"
    end
  end

  it { @report.match('Offenses').should_not be true }
end
p1iqtdky

p1iqtdky1#

你不需要使用github api,甚至ruby(除非你想 Package 响应),你只需要运行:

git fetch && git diff-tree -r --no-commit-id --name-only master@\{u\} head | xargs ls -1 2>/dev/null | xargs rubocop --force-exclusion

请参见http://www.red56.uk/2017/03/26/running-rubocop-on-changed-files/,了解有关此问题的更详细说明

i1icjdpr

i1icjdpr2#

我通过查询api.github.com修复了这个问题。这将在current_sha和master分支之间更改的所有文件上运行rubocop。

require 'spec_helper'

describe 'Check that the files we have changed have correct syntax' do
  before do
    current_sha = `git rev-parse --verify HEAD`.strip!
    token = 'YOUR GITHUB TOKEN'
    url = 'https://api.github.com/repos/orwapp/orwapp/compare/' \
          "master...#{current_sha}?access_token=#{token}"
    files = `curl -i #{url} | grep filename | cut -f2 -d: | grep \.rb | tr '"', '\ '`
    files.tr!("\n", ' ')
    @report = 'nada'
    if files.present?
      puts "Changed files: #{files}"

      @report = `rubocop #{files}`
      puts "Report: #{@report}"
    end
  end

  it { expect(@report.match('Offenses')).to be_falsey }
end
swvgeqrz

swvgeqrz3#

我找到了https://github.com/m4i/rubocop-git,它运行得很好。但是它在你的git diff上运行(可选地使用--cached),所以它不允许你比较分支。

bf1o4zei

bf1o4zei4#

我没有足够高的声誉来评论一个答案,所以我张贴一个答案,添加一个我认为有用的改进:

git fetch && git diff-tree -r --no-commit-id --name-only master@\{u\} HEAD | xargs ls -1 2>/dev/null | grep '\.rb$' | xargs bundle exec rubocop --force-exclusion

--force-exclusion的添加使RuboCop尊重其配置文件中的Exclude声明(这里使用默认的./.rubocop.yml)。)

falq053o

falq053o5#

这里有另一个比较当前分支和origin/master的方法(应该可以在任何存储库主机上使用a-只是在circleci上用bitbucket存储库尝试了一下),它还传递了一个.rubocop.yml配置文件选项(如果不需要的话,可以删除这部分)。

require 'spec_helper'

RSpec.describe 'Check that the files we have changed have correct syntax' do
  before do
    current_sha = 'origin/master..HEAD'
    @files = `git diff-tree --no-commit-id --name-only -r #{current_sha} | grep .rb`
    @files.tr!("\n", ' ')
  end

  it 'runs rubocop on changed ruby files' do
    if @files.empty?
      puts "Linting not performed. No ruby files changed."
    else
      puts "Running rubocop for changed files: #{@files}"
      result = system "bundle exec rubocop --config .rubocop.yml --fail-level warn #{@files}"
      expect(result).to be(true)
    end
  end
end

原文大意如下:https://gist.github.com/djburdick/5104d15f612c15dde65f#gistcomment-2029606

f4t66c6m

f4t66c6m6#

一个更简单的解决方案:

git diff origin/master --name-only | xargs rubocop --force-exclusion

说明:我很少在本地更新master,但是执行git fetch会更新origin/master,所以我想对此进行比较。我不能让其他建议的diff-treeorigin/master解决方案工作。

fkaflof6

fkaflof67#

也许你可以利用CircleCI’s dynamic configuration feature
有一个关于如何根据修改了哪些文件来执行特定工作流或步骤的特定指南(https://circleci.com/docs/using-dynamic-configuration/#execute-specific-workflows-or-steps-based-onwhich-files-are-modified)。

相关问题