rubocop-git2 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 971494e62d00b8014fc19631734832640325d7cdda40489802c2fae1fd500004
4
- data.tar.gz: 27194c03771bd5855c83331fb25dfdd77e0e507be9f49af740a2021c5a97bcef
3
+ metadata.gz: 4b3ebd323c15d20d452fff488d6f4710bb97104acf4cddab72faaaa2421f461a
4
+ data.tar.gz: 3f502393adaf844a52f37bd9c85b5bca049c5c1fffa39bfd04391bd63ec6abac
5
5
  SHA512:
6
- metadata.gz: '009a9ab5e998a0e3e1e837ed28ad773c319f198233c6d7e447c4a09ae793af43297043441730df0b041ff17db35022ed9b6ab9f814cfdc444e1606c381a0ba8c'
7
- data.tar.gz: 2cc49969985c8ff0e9b98d51bf83a4897ef22d0acd224ac946bef250ca3d37280164d64b43f65347a2830739a532e635cd84e2f1c38708e3784008e8a73edecb
6
+ metadata.gz: a301bd97fbefb05b71880a7e927ebc48b7789f040a3dfe4e85fe4f7731e68b2fa03b44f05a760525599f345b57d23b1bc9112c85c9ad0ae948a0de5d748e8dd5
7
+ data.tar.gz: 00ec8f7a896238519a26f0c3007e65c8eedf0743d576f93cd7086e58e137615b3d9fb620e8b1c42a41bb9f87e5e9c52e243be0b82bcb0d7ae71affed6e6d2f17
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.rubocop.yml CHANGED
@@ -1,11 +1,15 @@
1
1
  AllCops:
2
2
  NewCops: enable
3
+ SuggestExtensions: false
3
4
  TargetRubyVersion: 2.6 # really 2.4, but 2.6 is lowest supported by rubocop
4
5
 
6
+ # warning! changes here might break specs that test config evaluation.
7
+ Gemspec/RequireMFA:
8
+ Enabled: false
5
9
  Layout/DotPosition:
6
10
  Enabled: false
7
11
  Metrics/BlockLength:
8
- Exclude: ['test/**/*.rb']
12
+ Exclude: ['spec/**/*.rb']
9
13
  Style/Documentation:
10
14
  Enabled: false
11
15
  Style/FrozenStringLiteralComment:
@@ -14,6 +18,8 @@ Style/ClassAndModuleChildren:
14
18
  Enabled: false
15
19
  Style/IfUnlessModifier:
16
20
  Enabled: false
21
+ Style/Lambda:
22
+ Enabled: false
17
23
  Style/SelectByRegexp:
18
24
  Enabled: false
19
25
  Style/StringLiterals:
data/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.1.5] - 2023-03-27
8
+
9
+ ### Fixed
10
+
11
+ - stop using unsafe `YAML.load` on rubocop.yml
12
+
7
13
  ## [0.1.4] - 2023-03-24
8
14
 
9
15
  First release as `rubocop-git2`.
data/Gemfile CHANGED
@@ -3,5 +3,5 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  gem 'bundler'
6
- gem 'minitest'
7
6
  gem 'rake'
7
+ gem 'rspec'
data/README.md CHANGED
@@ -9,16 +9,45 @@ RuboCop for git diff.
9
9
 
10
10
  ## Installation
11
11
 
12
- Add or install `rubocop-git2`. NOT YET RELEASED - will happen soon!
12
+ Add or install `rubocop-git2`.
13
13
 
14
14
  ## Usage
15
15
 
16
+ ### Examples
17
+
18
+ ```sh
19
+ # check unstaged changes
20
+ rubocop-git
21
+
22
+ # check staged changes
23
+ rubocop-git --staged
24
+
25
+ # positional arguments are passed as git refs to git diff, e.g.:
26
+
27
+ # check both staged and unstaged changes
28
+ rubocop-git HEAD
29
+
30
+ # check the previous commit
31
+ rubocop-git HEAD~1 HEAD
32
+
33
+ # check changes between two tags
34
+ rubocop-git v1.0.0 v1.0.1
35
+
36
+ # check all changes in a branch in github actions
37
+ bundle exec rubocop-git origin/${{ github.base_ref }}
38
+ ```
39
+
40
+ ### Options
41
+
42
+ Output of `rubocop-git --help`:
43
+
16
44
  Usage: rubocop-git [options] [[commit] commit]
17
45
  -c, --config FILE Specify configuration file
18
- -r, --require FILE Require Ruby file
19
46
  -d, --debug Display debug info
20
47
  -D, --display-cop-names Display cop names in offense messages
21
- --only COP1,COP2 Run only specific cops or departments
22
- --cached git diff --cached
23
- --staged synonym of --cached
48
+ -f, --format FORMAT Set output format (see rubocop --help)
24
49
  --hound Hound compatibility mode
50
+ --only COP1,COP2 Run only specific cops or departments
51
+ -r, --require FILE Require Ruby file
52
+ --staged Inspect staged changes
53
+ --version Display version
data/Rakefile CHANGED
@@ -1,16 +1,8 @@
1
1
  require 'bundler/gem_tasks'
2
- require 'rake/testtask'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
3
4
 
4
- task default: %i[test selftest]
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ RuboCop::RakeTask.new
5
7
 
6
- Rake::TestTask.new(:test) do |t|
7
- t.libs << 'test'
8
- t.libs << 'lib'
9
- t.test_files = FileList['test/**/*_test.rb']
10
- end
11
-
12
- desc 'Run RuboCop::Git over itself'
13
- task :selftest do
14
- require_relative 'lib/rubocop/git'
15
- RuboCop::Git::Runner.new.run(commits: ['v0.0.4'])
16
- end
8
+ task default: %i[spec rubocop]
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "rubocop-git2"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -1,76 +1,72 @@
1
1
  require_relative '../git'
2
2
  require 'optparse'
3
3
 
4
- module RuboCop
5
- module Git
6
- class CLI
7
- def run(args = ARGV)
8
- @options = Options.new
9
- parse_arguments(args)
10
- Runner.new.run(@options)
11
- end
12
-
13
- private
4
+ class RuboCop::Git::CLI
5
+ def run(args = ARGV.dup)
6
+ @options = RuboCop::Git::Options.new
7
+ parse_arguments(args)
8
+ RuboCop::Git::Runner.new.run(@options)
9
+ end
14
10
 
15
- def parse_arguments(args)
16
- @options.commits = option_parser.parse(args)
17
- rescue OptionParser::InvalidOption, Options::Invalid => ex
18
- warn "ERROR: #{ex.message}"
19
- $stderr.puts
20
- warn option_parser
21
- exit 1
22
- end
11
+ private
23
12
 
24
- def option_parser
25
- @option_parser ||= OptionParser.new do |opt|
26
- opt.banner << ' [[commit] commit]'
13
+ def parse_arguments(args)
14
+ args << '--staged' if args.delete('--cached') # support synonymous flag
15
+ @options.commits = option_parser.parse(args)
16
+ rescue OptionParser::InvalidOption, Options::Invalid => e
17
+ warn "ERROR: #{e.message}"
18
+ $stderr.puts
19
+ warn option_parser
20
+ exit 1
21
+ end
27
22
 
28
- opt.on('-c', '--config FILE',
29
- 'Specify configuration file') do |config|
30
- @options.config = config
31
- end
23
+ # rubocop:disable Metrics
24
+ def option_parser
25
+ @option_parser ||= OptionParser.new do |opt|
26
+ opt.banner << ' [[commit] commit]'
32
27
 
33
- opt.on('-r', '--require FILE',
34
- 'Require Ruby file') do |file|
35
- require file
36
- end
28
+ opt.on('-c', '--config FILE',
29
+ 'Specify configuration file') do |config|
30
+ @options.config = config
31
+ end
37
32
 
38
- opt.on('-d', '--debug', 'Display debug info') do
39
- @options.rubocop[:debug] = true
40
- end
33
+ opt.on('-d', '--debug', 'Display debug info') do
34
+ @options.rubocop[:debug] = true
35
+ end
41
36
 
42
- opt.on('-D', '--display-cop-names',
43
- 'Display cop names in offense messages') do
44
- @options.rubocop[:display_cop_names] = true
45
- end
37
+ opt.on('-D', '--display-cop-names',
38
+ 'Display cop names in offense messages') do
39
+ @options.rubocop[:display_cop_names] = true
40
+ end
46
41
 
47
- opt.on('--only COP1,COP2', Array) do |args|
48
- @options.rubocop[:only] = args
49
- end
42
+ opt.on('-f', '--format FORMAT',
43
+ 'Set output format (see rubocop --help)') do |format|
44
+ @options.format = format
45
+ end
50
46
 
51
- opt.on('--cached', 'git diff --cached') do
52
- @options.cached = true
53
- end
47
+ opt.on('--hound', 'Hound compatibility mode') do
48
+ @options.hound = true
49
+ end
54
50
 
55
- opt.on('--staged', 'synonym of --cached') do
56
- @options.cached = true
57
- end
51
+ opt.on('--only COP1,COP2', Array,
52
+ 'Run only specific cops or departments') do |args|
53
+ @options.rubocop[:only] = args
54
+ end
58
55
 
59
- opt.on('--hound', 'Hound compatibility mode') do
60
- @options.hound = true
61
- end
56
+ opt.on('-r', '--require FILE',
57
+ 'Require Ruby file') do |file|
58
+ require file
59
+ end
62
60
 
63
- opt.on('-f', '--format FORMAT',
64
- 'Choose an output formatter') do |format|
65
- @options.format = format
66
- end
61
+ opt.on('--staged', 'Inspect staged changes') do
62
+ @options.cached = true
63
+ end
67
64
 
68
- opt.on('--version', 'Display version') do
69
- puts RuboCop::Git::VERSION
70
- exit 0
71
- end
72
- end
65
+ opt.on('--version', 'Display version') do
66
+ puts RuboCop::Git::VERSION
67
+ exit 0
73
68
  end
74
69
  end
75
70
  end
71
+ # rubocop:enable Metrics
76
72
  end
@@ -1,22 +1,18 @@
1
1
  require 'shellwords'
2
2
 
3
- module RuboCop
4
- module Git
5
- # ref. https://github.com/thoughtbot/hound/blob/d2f3933/app/models/commit.rb
6
- class Commit
7
- def initialize(options)
8
- @options = options
9
- end
3
+ class RuboCop::Git::Commit
4
+ # ref. https://github.com/thoughtbot/hound/blob/d2f3933/app/models/commit.rb
5
+ def initialize(options)
6
+ @options = options
7
+ end
10
8
 
11
- def file_content(filename)
12
- if @options.cached
13
- `git show :#{filename.shellescape}`
14
- elsif @options.commit_last
15
- `git show #{@options.commit_last.shellescape}:#{filename.shellescape}`
16
- else
17
- File.read(filename)
18
- end
19
- end
9
+ def file_content(filename)
10
+ if @options.cached
11
+ `git show :#{filename.shellescape}`
12
+ elsif @options.commit_last
13
+ `git show #{@options.commit_last.shellescape}:#{filename.shellescape}`
14
+ else
15
+ File.read(filename)
20
16
  end
21
17
  end
22
18
  end
@@ -1,6 +1,5 @@
1
- module RuboCop::Git
2
1
  # c.f. https://github.com/thoughtbot/hound/blob/d2f3933/app/models/commit_file.rb
3
- class CommitFile
2
+ class RuboCop::Git::CommitFile
4
3
  def initialize(file, commit)
5
4
  @file = file
6
5
  @commit = commit
@@ -15,11 +14,9 @@ class CommitFile
15
14
  end
16
15
 
17
16
  def content
18
- @content ||= begin
19
- unless removed?
20
- @commit.file_content(filename)
21
- end
22
- end
17
+ @content ||= unless removed?
18
+ @commit.file_content(filename)
19
+ end
23
20
  end
24
21
 
25
22
  def relevant_line?(line_number)
@@ -41,7 +38,6 @@ class CommitFile
41
38
  private
42
39
 
43
40
  def patch
44
- Patch.new(@file.patch)
41
+ RuboCop::Git::Patch.new(@file.patch)
45
42
  end
46
43
  end
47
- end
@@ -1,31 +1,25 @@
1
- module RuboCop
2
- module Git
3
- class DiffParser
4
- class << self
5
- def parse(diff)
6
- new.parse(diff)
7
- end
8
- end
9
-
10
- def parse(diff)
11
- files = []
12
- in_patch = false
13
-
14
- diff.each_line do |line|
15
- case line
16
- when /^diff --git/
17
- in_patch = false
18
- when %r{^\+{3} b/(?<path>[^\t\n\r]+)}
19
- files << PseudoResource.new(Regexp.last_match[:path])
20
- when /^@@/
21
- in_patch = true
22
- end
1
+ class RuboCop::Git::DiffParser
2
+ def self.parse(diff)
3
+ new.parse(diff)
4
+ end
23
5
 
24
- files.last.patch << line if in_patch
25
- end
6
+ def parse(diff) # rubocop:disable Metrics/MethodLength
7
+ files = []
8
+ in_patch = false
26
9
 
27
- files
10
+ diff.each_line do |line|
11
+ case line
12
+ when /^diff --git/
13
+ in_patch = false
14
+ when %r{^\+{3} b/(?<path>[^\t\n\r]+)}
15
+ files << RuboCop::Git::PseudoResource.new(Regexp.last_match[:path])
16
+ when /^@@/
17
+ in_patch = true
28
18
  end
19
+
20
+ files.last.patch << line if in_patch
29
21
  end
22
+
23
+ files
30
24
  end
31
25
  end
@@ -1,5 +1,2 @@
1
- module RuboCop::Git
2
1
  # ref. https://github.com/thoughtbot/hound/blob/d2f3933/app/models/file_violation.rb
3
- class FileViolation < Struct.new(:filename, :offenses)
4
- end
5
- end
2
+ RuboCop::Git::FileViolation = Struct.new(:filename, :offenses)
@@ -1,8 +1,6 @@
1
- module RuboCop::Git
2
1
  # similar to https://github.com/thoughtbot/hound/blob/d2f3933/app/models/line.rb
3
- class Line < Struct.new(:content, :line_number, :patch_position)
4
- def ==(other_line)
5
- content == other_line.content
2
+ RuboCop::Git::Line = Struct.new(:content, :line_number, :patch_position) do
3
+ def ==(other)
4
+ content == other.content
6
5
  end
7
6
  end
8
- end
@@ -1,94 +1,93 @@
1
- module RuboCop
2
- module Git
3
- class Options
4
- class Invalid < StandardError; end
5
-
6
- HOUND_DEFAULT_CONFIG_FILE =
7
- File.expand_path('../../../../hound.yml', __FILE__)
8
-
9
- attr_accessor :config
10
- attr_reader :cached, :hound, :rubocop, :format
11
-
12
- def initialize(hash_options = nil)
13
- @config = nil
14
- @cached = false
15
- @hound = false
16
- @format = RuboCop::Formatter::ClangStyleFormatter
17
- @rubocop = {}
18
- @commits = []
19
-
20
- from_hash(hash_options) if hash_options
21
- end
22
-
23
- def cached=(cached_)
24
- if cached_ && !@commits.empty?
25
- fail Invalid, 'cached and commit cannot be specified together'
26
- end
27
- @cached = !!cached_
28
- end
29
-
30
- def hound=(hound_)
31
- @hound = !!hound_
32
- end
33
-
34
- def rubocop=(rubocop_)
35
- unless rubocop_.nil? || rubocop_.is_a?(Hash)
36
- fail Invalid, "invalid rubocop: #{rubocop_.inspect}"
37
- end
38
- @rubocop = rubocop_.to_h
39
- end
40
-
41
- def commits=(commits)
42
- unless commits.is_a?(Array) && commits.length <= 2
43
- fail Invalid, "invalid commits: #{commits.inspect}"
44
- end
45
- if !commits.empty? && cached
46
- fail Invalid, 'cached and commit cannot be specified together'
47
- end
48
- @commits = commits
49
- end
50
-
51
- def format=(format)
52
- formatters =
53
- RuboCop::Formatter::FormatterSet::BUILTIN_FORMATTERS_FOR_KEYS
54
- formatter_key = formatters.keys.find do |key|
55
- key.start_with?(format)
56
- end
57
- @format = formatters[formatter_key] if formatter_key
58
- end
59
-
60
- def config_file
61
- if hound
62
- HOUND_DEFAULT_CONFIG_FILE
63
- elsif config
64
- config
65
- elsif File.exist?(RuboCop::ConfigLoader::DOTFILE)
66
- RuboCop::ConfigLoader::DOTFILE
67
- else
68
- RuboCop::ConfigLoader::DEFAULT_FILE
69
- end
70
- end
71
-
72
- def commit_first
73
- @commits.first
74
- end
75
-
76
- def commit_last
77
- @commits.length == 1 ? false : @commits.last
78
- end
79
-
80
- private
81
-
82
- def from_hash(hash_options)
83
- hash_options = hash_options.dup
84
- %w(config cached hound rubocop commits).each do |key|
85
- value = hash_options.delete(key) || hash_options.delete(key.to_sym)
86
- public_send("#{key}=", value)
87
- end
88
- unless hash_options.empty?
89
- fail Invalid, "invalid keys: #{hash_options.keys.join(' ')}"
90
- end
91
- end
1
+ class RuboCop::Git::Options
2
+ class Invalid < StandardError; end
3
+
4
+ HOUND_DEFAULT_CONFIG_FILE =
5
+ File.expand_path('../../../hound.yml', __dir__)
6
+
7
+ attr_accessor :config
8
+ attr_reader :cached, :hound, :rubocop, :format
9
+
10
+ def initialize(hash_options = nil)
11
+ @config = nil
12
+ @cached = false
13
+ @hound = false
14
+ @format = RuboCop::Formatter::ClangStyleFormatter
15
+ @rubocop = {}
16
+ @commits = []
17
+
18
+ from_hash(hash_options) if hash_options
19
+ end
20
+
21
+ def cached=(cached_)
22
+ if cached_ && !@commits.empty?
23
+ raise Invalid, 'cached and commit cannot be specified together'
24
+ end
25
+
26
+ @cached = !!cached_
27
+ end
28
+
29
+ def hound=(hound_)
30
+ @hound = !!hound_
31
+ end
32
+
33
+ def rubocop=(rubocop_)
34
+ unless rubocop_.nil? || rubocop_.is_a?(Hash)
35
+ raise Invalid, "invalid rubocop: #{rubocop_.inspect}"
36
+ end
37
+
38
+ @rubocop = rubocop_.to_h
39
+ end
40
+
41
+ def commits=(commits)
42
+ unless commits.is_a?(Array) && commits.length <= 2
43
+ raise Invalid, "invalid commits: #{commits.inspect}"
44
+ end
45
+ if !commits.empty? && cached
46
+ raise Invalid, 'cached and commit cannot be specified together'
92
47
  end
48
+
49
+ @commits = commits
50
+ end
51
+
52
+ def format=(format)
53
+ formatters =
54
+ RuboCop::Formatter::FormatterSet::BUILTIN_FORMATTERS_FOR_KEYS
55
+ formatter_key = formatters.keys.find do |key|
56
+ key.start_with?(format)
57
+ end
58
+ @format = formatters[formatter_key] if formatter_key
59
+ end
60
+
61
+ def config_file
62
+ if hound
63
+ HOUND_DEFAULT_CONFIG_FILE
64
+ elsif config
65
+ config
66
+ elsif File.exist?(RuboCop::ConfigLoader::DOTFILE)
67
+ RuboCop::ConfigLoader::DOTFILE
68
+ else
69
+ RuboCop::ConfigLoader::DEFAULT_FILE
70
+ end
71
+ end
72
+
73
+ def commit_first
74
+ @commits.first
75
+ end
76
+
77
+ def commit_last
78
+ @commits.length == 1 ? false : @commits.last
79
+ end
80
+
81
+ private
82
+
83
+ def from_hash(hash_options)
84
+ hash_options = hash_options.dup
85
+ %w[config cached hound rubocop commits].each do |key|
86
+ value = hash_options.delete(key) || hash_options.delete(key.to_sym)
87
+ public_send("#{key}=", value)
88
+ end
89
+ return if hash_options.empty?
90
+
91
+ raise Invalid, "invalid keys: #{hash_options.keys.join(' ')}"
93
92
  end
94
93
  end
@@ -1,9 +1,8 @@
1
- module RuboCop::Git
2
1
  # copy from https://github.com/thoughtbot/hound/blob/5269fa5/app/models/patch.rb
3
- class Patch
4
- RANGE_INFORMATION_LINE = /^@@ .+\+(?<line_number>\d+),/
5
- MODIFIED_LINE = /^\+(?!\+|\+)/
6
- NOT_REMOVED_LINE = /^[^-]/
2
+ class RuboCop::Git::Patch
3
+ RANGE_INFORMATION_LINE = /^@@ .+\+(?<line_number>\d+),/.freeze
4
+ MODIFIED_LINE = /^\+(?!\+|\+)/.freeze
5
+ NOT_REMOVED_LINE = /^[^-]/.freeze
7
6
 
8
7
  def initialize(body)
9
8
  @body = body || ''
@@ -18,7 +17,7 @@ class Patch
18
17
  when RANGE_INFORMATION_LINE
19
18
  line_number = Regexp.last_match[:line_number].to_i
20
19
  when MODIFIED_LINE
21
- line = Line.new(content, line_number, patch_position)
20
+ line = RuboCop::Git::Line.new(content, line_number, patch_position)
22
21
  hash[line_number] = line
23
22
  line_number += 1
24
23
  when NOT_REMOVED_LINE
@@ -33,4 +32,3 @@ class Patch
33
32
  @body.each_line
34
33
  end
35
34
  end
36
- end
@@ -1,36 +1,33 @@
1
- module RuboCop
2
- module Git
3
- # ref. https://github.com/thoughtbot/hound/blob/d2f3933/app/models/pull_request.rb
4
- class PseudoPullRequest
5
- HOUND_CONFIG_FILE = '.hound.yml'
1
+ # ref. https://github.com/thoughtbot/hound/blob/d2f3933/app/models/pull_request.rb
2
+ class RuboCop::Git::PseudoPullRequest
3
+ HOUND_CONFIG_FILE = '.hound.yml'.freeze
6
4
 
7
- def initialize(files, options)
8
- @files = files
9
- @options = options
10
- end
5
+ def initialize(files, options)
6
+ @files = files
7
+ @options = options
8
+ end
11
9
 
12
- def pull_request_files
13
- @files.map do |file|
14
- build_commit_file(file)
15
- end
16
- end
10
+ def pull_request_files
11
+ @files.map do |file|
12
+ build_commit_file(file)
13
+ end
14
+ end
17
15
 
18
- def config
19
- return unless @options.hound
20
- File.read(HOUND_CONFIG_FILE)
21
- rescue Errno::ENOENT
22
- nil
23
- end
16
+ def config
17
+ return unless @options.hound
24
18
 
25
- private
19
+ File.read(HOUND_CONFIG_FILE)
20
+ rescue Errno::ENOENT
21
+ nil
22
+ end
26
23
 
27
- def build_commit_file(file)
28
- CommitFile.new(file, head_commit)
29
- end
24
+ private
30
25
 
31
- def head_commit
32
- @head_commit ||= Commit.new(@options)
33
- end
34
- end
26
+ def build_commit_file(file)
27
+ RuboCop::Git::CommitFile.new(file, head_commit)
28
+ end
29
+
30
+ def head_commit
31
+ @head_commit ||= RuboCop::Git::Commit.new(@options)
35
32
  end
36
33
  end
@@ -1,24 +1,20 @@
1
- module RuboCop
2
- module Git
3
- class PseudoResource
4
- attr_reader :patch, :pwd, :file_relative_path
1
+ class RuboCop::Git::PseudoResource
2
+ attr_reader :patch, :pwd, :file_relative_path
5
3
 
6
- alias filename file_relative_path
4
+ alias filename file_relative_path
7
5
 
8
- def initialize(file_relative_path, pwd = Dir.pwd)
9
- @file_relative_path = file_relative_path
10
- @pwd = pwd
11
- @patch = ''
12
- end
6
+ def initialize(file_relative_path, pwd = Dir.pwd)
7
+ @file_relative_path = file_relative_path
8
+ @pwd = pwd
9
+ @patch = ''
10
+ end
13
11
 
14
- def absolute_path
15
- filename
16
- File.join(pwd, filename)
17
- end
12
+ def absolute_path
13
+ filename
14
+ File.join(pwd, filename)
15
+ end
18
16
 
19
- def status
20
- 'modified'
21
- end
22
- end
17
+ def status
18
+ 'modified'
23
19
  end
24
20
  end
@@ -1,75 +1,73 @@
1
1
  require 'shellwords'
2
2
 
3
- module RuboCop
4
- module Git
5
- # ref. https://github.com/thoughtbot/hound/blob/d2f3933/app/services/build_runner.rb
6
- class Runner
7
- def initialize(exit_on_offence: true)
8
- @exit_on_offence = exit_on_offence
9
- end
10
-
11
- def run(options = {})
12
- options = Options.new(options) unless options.is_a?(Options)
13
-
14
- @options = options
15
- @files = DiffParser.parse(git_diff(options))
16
-
17
- display_violations($stdout)
18
-
19
- ok = violations_with_valid_offences.none?
20
- exit(1) if @exit_on_offence && !ok
21
- ok
22
- end
23
-
24
- private
25
-
26
- def violations
27
- @violations ||= style_checker.violations
28
- end
29
-
30
- def violations_with_valid_offences
31
- @violations_with_valid_offences ||= violations.select { |v| valid_offences(v).any? }
32
- end
33
-
34
- def valid_offences(violation)
35
- offenses = violation.offenses
36
- offenses = offenses.reject(&:disabled?) if offenses.first.respond_to?(:disabled?)
37
- offenses.compact.sort.freeze
38
- end
39
-
40
- def style_checker
41
- StyleChecker.new(
42
- pull_request.pull_request_files,
43
- @options.rubocop,
44
- @options.config_file,
45
- pull_request.config
46
- )
47
- end
48
-
49
- def pull_request
50
- @pull_request ||= PseudoPullRequest.new(@files, @options)
51
- end
52
-
53
- def git_diff(options)
54
- args = %w(diff --diff-filter=AMCR --find-renames --find-copies)
55
-
56
- args << '--cached' if options.cached
57
- args << options.commit_first.shellescape if options.commit_first
58
- args << options.commit_last.shellescape if options.commit_last
59
-
60
- `git #{args.join(' ')}`
61
- end
62
-
63
- def display_violations(io)
64
- formatter = @options.format.new(io)
65
- formatter.started(@files)
66
-
67
- violations.map do |violation|
68
- formatter.file_finished(violation.filename, valid_offences(violation))
69
- end
70
-
71
- formatter.finished(@files.map(&:filename).freeze)
72
- end
3
+ # ref. https://github.com/thoughtbot/hound/blob/d2f3933/app/services/build_runner.rb
4
+ class RuboCop::Git::Runner
5
+ def initialize(exit_on_offence: true)
6
+ @exit_on_offence = exit_on_offence
7
+ end
8
+
9
+ def run(options = {})
10
+ unless options.is_a?(RuboCop::Git::Options)
11
+ options = RuboCop::Git::Options.new(options)
73
12
  end
13
+
14
+ @options = options
15
+ @files = RuboCop::Git::DiffParser.parse(git_diff(options))
16
+
17
+ display_violations($stdout)
18
+
19
+ ok = violations_with_valid_offences.none?
20
+ exit(1) if @exit_on_offence && !ok
21
+ ok
22
+ end
23
+
24
+ private
25
+
26
+ def violations
27
+ @violations ||= style_checker.violations
28
+ end
29
+
30
+ def violations_with_valid_offences
31
+ @violations_with_valid_offences ||= violations.select { |v| valid_offences(v).any? }
32
+ end
33
+
34
+ def valid_offences(violation)
35
+ offenses = violation.offenses
36
+ offenses = offenses.reject(&:disabled?) if offenses.first.respond_to?(:disabled?)
37
+ offenses.compact.sort.freeze
38
+ end
39
+
40
+ def style_checker
41
+ RuboCop::Git::StyleChecker.new(
42
+ pull_request.pull_request_files,
43
+ @options.rubocop,
44
+ @options.config_file,
45
+ pull_request.config
46
+ )
47
+ end
48
+
49
+ def pull_request
50
+ @pull_request ||= RuboCop::Git::PseudoPullRequest.new(@files, @options)
51
+ end
52
+
53
+ def git_diff(options)
54
+ args = %w[diff --diff-filter=AMCR --find-renames --find-copies]
55
+
56
+ args << '--cached' if options.cached
57
+ args << options.commit_first.shellescape if options.commit_first
58
+ args << options.commit_last.shellescape if options.commit_last
59
+
60
+ `git #{args.join(' ')}`
61
+ end
62
+
63
+ def display_violations(io)
64
+ formatter = @options.format.new(io)
65
+ formatter.started(@files)
66
+
67
+ violations.map do |violation|
68
+ formatter.file_finished(violation.filename, valid_offences(violation))
69
+ end
70
+
71
+ formatter.finished(@files.map(&:filename).freeze)
74
72
  end
75
73
  end
@@ -1,6 +1,5 @@
1
- module RuboCop::Git
2
- # ref. https://github.com/thoughtbot/hound/blob/d2f3933/app/models/style_checker.rb
3
- class StyleChecker
1
+ class RuboCop::Git::StyleChecker
2
+ # ref. https://github.com/thoughtbot/hound/blob/d2f3933/app/models/style_checker.rb
4
3
  def initialize(modified_files,
5
4
  rubocop_options,
6
5
  config_file,
@@ -13,7 +12,10 @@ class StyleChecker
13
12
 
14
13
  def violations
15
14
  file_violations = @modified_files.map do |modified_file|
16
- FileViolation.new(modified_file.absolute_path, offenses(modified_file))
15
+ RuboCop::Git::FileViolation.new(
16
+ modified_file.absolute_path,
17
+ offenses(modified_file)
18
+ )
17
19
  end
18
20
 
19
21
  file_violations.select do |file_violation|
@@ -35,9 +37,10 @@ class StyleChecker
35
37
  end
36
38
 
37
39
  def style_guide
38
- @style_guide ||= StyleGuide.new(@rubocop_options,
39
- @config_file,
40
- @custom_config)
40
+ @style_guide ||= RuboCop::Git::StyleGuide.new(
41
+ @rubocop_options,
42
+ @config_file,
43
+ @custom_config
44
+ )
41
45
  end
42
46
  end
43
- end
@@ -1,10 +1,9 @@
1
- module RuboCop::Git
2
1
  # ref. https://github.com/thoughtbot/hound/blob/d2f3933/app/models/style_guide.rb
3
- class StyleGuide
4
- def initialize(rubocop_options, config_file, override_config_content = nil)
2
+ class RuboCop::Git::StyleGuide
3
+ def initialize(rubocop_options, config_file, custom_config = nil)
5
4
  @rubocop_options = rubocop_options
6
5
  @config_file = config_file
7
- @override_config_content = override_config_content
6
+ @custom_config = custom_config
8
7
  end
9
8
 
10
9
  def violations(file)
@@ -77,8 +76,8 @@ class StyleGuide
77
76
  end
78
77
 
79
78
  def override_config
80
- if @override_config_content
81
- config_content = YAML.load(@override_config_content)
79
+ if @custom_config
80
+ config_content = RuboCop::Config.load_yaml_configuration(@custom_config)
82
81
  override_config = RuboCop::Config.new(config_content, "")
83
82
  override_config.add_missing_namespaces
84
83
  override_config.make_excludes_absolute
@@ -88,4 +87,3 @@ class StyleGuide
88
87
  end
89
88
  end
90
89
  end
91
- end
@@ -1,5 +1,5 @@
1
1
  module RuboCop
2
2
  module Git
3
- VERSION = '0.1.4'.freeze
3
+ VERSION = '0.1.5'.freeze
4
4
  end
5
5
  end
data/lib/rubocop/git.rb CHANGED
@@ -1,7 +1,7 @@
1
- require_relative 'git/version'
2
1
  require 'rubocop'
3
2
 
4
3
  module RuboCop::Git
4
+ autoload :CLI, "#{__dir__}/git/cli"
5
5
  autoload :Commit, "#{__dir__}/git/commit"
6
6
  autoload :CommitFile, "#{__dir__}/git/commit_file"
7
7
  autoload :DiffParser, "#{__dir__}/git/diff_parser"
@@ -14,4 +14,5 @@ module RuboCop::Git
14
14
  autoload :Runner, "#{__dir__}/git/runner"
15
15
  autoload :StyleChecker, "#{__dir__}/git/style_checker"
16
16
  autoload :StyleGuide, "#{__dir__}/git/style_guide"
17
+ autoload :VERSION, "#{__dir__}/git/version"
17
18
  end
data/rubocop-git.gemspec CHANGED
@@ -5,14 +5,14 @@ Gem::Specification.new do |spec|
5
5
  spec.version = RuboCop::Git::VERSION
6
6
  spec.authors = ['Masaki Takeuchi', 'Janosch Müller']
7
7
  spec.email = ['janosch84@gmail.com']
8
- spec.summary = %q{RuboCop for git diff.}
9
- spec.description = %q{RuboCop for git diff.}
8
+ spec.summary = 'RuboCop for git diff.'
9
+ spec.description = 'RuboCop for git diff.'
10
10
  spec.homepage = 'https://github.com/jaynetics/rubocop-git2'
11
11
  spec.license = 'MIT'
12
12
 
13
13
  spec.files = `git ls-files -z`.split("\x0")
14
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
15
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
14
+ spec.bindir = 'exe'
15
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
16
16
  spec.require_paths = ['lib']
17
17
 
18
18
  spec.required_ruby_version = '>= 2.6.0'
@@ -0,0 +1,7 @@
1
+ describe RuboCop::Git::CLI do
2
+ it "fails with invalid options" do
3
+ expect { subject.run(["--gru\u00DF"]) }
4
+ .to output(/Usage/).to_stderr
5
+ .and raise_error(SystemExit)
6
+ end
7
+ end
@@ -0,0 +1,17 @@
1
+ describe RuboCop::Git::Options do
2
+ it "fails with no options" do
3
+ expect { RuboCop::Git::Options.new({}) }.to raise_error(/invalid/)
4
+ end
5
+
6
+ it "fails with unknown options" do
7
+ expect { RuboCop::Git::Options.new({ foo: 1 }) }.to raise_error(/invalid/)
8
+ end
9
+
10
+ it "can pass string hash options" do
11
+ RuboCop::Git::Options.new("rubocop" => {}, "commits" => [])
12
+ end
13
+
14
+ it "can pass symbol hash options" do
15
+ RuboCop::Git::Options.new(rubocop: {}, commits: [])
16
+ end
17
+ end
@@ -0,0 +1,52 @@
1
+ describe RuboCop::Git::Runner do
2
+ it "exits with violations" do
3
+ options = RuboCop::Git::Options.new
4
+ options.commits = ["v0.0.4", "v0.0.5"]
5
+ expect { RuboCop::Git::Runner.new.run(options) }
6
+ .to output(%r{Layout/TrailingWhitespace}).to_stdout
7
+ .and raise_error(SystemExit)
8
+ end
9
+
10
+ it "enables cops passed via --only flag" do
11
+ # WITHOUT only flag
12
+ options = RuboCop::Git::Options.new
13
+ options.commits = ["v0.0.0", "v0.0.4"]
14
+ output = capture_stdout do
15
+ res = RuboCop::Git::Runner.new(exit_on_offence: false).run(options)
16
+ expect(res).to eq false
17
+ end
18
+ # check that rubocop's default `Include:` applies
19
+ expect(output).not_to include 'bad_ruby.txt'
20
+ # check that cop disabled via rubocop.yml isn't used
21
+ expect(output).not_to include 'Style/FrozenStringLiteralComment'
22
+ # check that enabled cop is used
23
+ expect(output).to include 'Style/MutableConstant'
24
+
25
+ # WITH only flag
26
+ options.rubocop[:only] = ["Style/FrozenStringLiteralComment"]
27
+ output = capture_stdout do
28
+ res = RuboCop::Git::Runner.new(exit_on_offence: false).run(options)
29
+ expect(res).to eq false
30
+ end
31
+ # check that rubocop's default `Include:` applies
32
+ expect(output).to include 'Rakefile'
33
+ # check that passed cop is used despite being disabled in rubocop.yml
34
+ expect(output).to include 'Style/FrozenStringLiteralComment'
35
+ # check that other enabled cop isn't used
36
+ expect(output).not_to include 'Style/MutableConstant'
37
+ end
38
+
39
+ it "fails with no options" do
40
+ expect { RuboCop::Git::Runner.new.run({}) }.to raise_error(/invalid/)
41
+ end
42
+
43
+ def capture_stdout(&block)
44
+ captured_stream = StringIO.new
45
+ original_stream = $stdout
46
+ $stdout = captured_stream
47
+ block.call
48
+ captured_stream.string
49
+ ensure
50
+ $stdout = original_stream
51
+ end
52
+ end
@@ -0,0 +1 @@
1
+ require 'rubocop/git'
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-git2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masaki Takeuchi
8
8
  - Janosch Müller
9
9
  autorequire:
10
- bindir: bin
10
+ bindir: exe
11
11
  cert_chain: []
12
- date: 2023-03-24 00:00:00.000000000 Z
12
+ date: 2023-03-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rubocop
@@ -35,13 +35,16 @@ extra_rdoc_files: []
35
35
  files:
36
36
  - ".github/workflows/tests.yml"
37
37
  - ".gitignore"
38
+ - ".rspec"
38
39
  - ".rubocop.yml"
39
40
  - CHANGELOG.md
40
41
  - Gemfile
41
42
  - LICENSE.txt
42
43
  - README.md
43
44
  - Rakefile
44
- - bin/rubocop-git
45
+ - bin/console
46
+ - bin/setup
47
+ - exe/rubocop-git
45
48
  - hound.yml
46
49
  - lib/rubocop/git.rb
47
50
  - lib/rubocop/git/cli.rb
@@ -59,11 +62,11 @@ files:
59
62
  - lib/rubocop/git/style_guide.rb
60
63
  - lib/rubocop/git/version.rb
61
64
  - rubocop-git.gemspec
62
- - test/bad_ruby.txt
63
- - test/rubocop/git/cli_test.rb
64
- - test/rubocop/git/options_test.rb
65
- - test/rubocop/git/runner_test.rb
66
- - test/test_helper.rb
65
+ - spec/bad_ruby.txt
66
+ - spec/rubocop/git/cli_spec.rb
67
+ - spec/rubocop/git/options_spec.rb
68
+ - spec/rubocop/git/runner_spec.rb
69
+ - spec/spec_helper.rb
67
70
  homepage: https://github.com/jaynetics/rubocop-git2
68
71
  licenses:
69
72
  - MIT
@@ -87,9 +90,4 @@ rubygems_version: 3.4.1
87
90
  signing_key:
88
91
  specification_version: 4
89
92
  summary: RuboCop for git diff.
90
- test_files:
91
- - test/bad_ruby.txt
92
- - test/rubocop/git/cli_test.rb
93
- - test/rubocop/git/options_test.rb
94
- - test/rubocop/git/runner_test.rb
95
- - test/test_helper.rb
93
+ test_files: []
@@ -1,12 +0,0 @@
1
- require_relative '../../test_helper'
2
- require 'rubocop/git/cli'
3
-
4
- describe RuboCop::Git::CLI do
5
- it 'fail with invalid options' do
6
- _ do
7
- _out, _err = capture_io do
8
- RuboCop::Git::CLI.new.run(['--gruß'])
9
- end
10
- end.must_raise(SystemExit)
11
- end
12
- end
@@ -1,18 +0,0 @@
1
- require_relative '../../test_helper'
2
- require 'rubocop/git/options'
3
-
4
- describe RuboCop::Git::Options do
5
- it 'fail with no options' do
6
- _ do
7
- RuboCop::Git::Options.new({})
8
- end.must_raise(RuboCop::Git::Options::Invalid)
9
- end
10
-
11
- it 'can pass string hash options' do
12
- RuboCop::Git::Options.new('rubocop' => {}, 'commits' => [])
13
- end
14
-
15
- it 'can pass symbol hash options' do
16
- RuboCop::Git::Options.new(rubocop: {}, commits: [])
17
- end
18
- end
@@ -1,43 +0,0 @@
1
- require_relative '../../test_helper'
2
- require 'rubocop/git/runner'
3
-
4
- describe RuboCop::Git::Runner do
5
- it 'exit with violations' do
6
- options = RuboCop::Git::Options.new
7
- options.commits = ["v0.0.4", "v0.0.5"]
8
- _ do
9
- capture_io do
10
- RuboCop::Git::Runner.new.run(options)
11
- end
12
- end.must_raise(SystemExit)
13
- end
14
-
15
- it 'enables cops passed via --only flag' do
16
- options = RuboCop::Git::Options.new
17
- options.commits = ["v0.0.0"]
18
- out, _err = capture_io do
19
- res = RuboCop::Git::Runner.new(exit_on_offence: false).run(options)
20
- res.must_equal(false)
21
- end
22
- _(out).must_match('Style/MutableConstant')
23
- _(out).wont_match('Style/FrozenStringLiteralComment')
24
- _(out).wont_match('bad_ruby.txt') # check that default `Include:` applies
25
-
26
- options.rubocop[:only] = ['Style/FrozenStringLiteralComment']
27
- out, _err = capture_io do
28
- res = RuboCop::Git::Runner.new(exit_on_offence: false).run(options)
29
- res.must_equal(false)
30
- end
31
- _(out).wont_match('Style/MutableConstant')
32
- _(out).must_match('Style/FrozenStringLiteralComment')
33
- _(out).must_match('Rakefile') # check that default `Include:` applies
34
- end
35
-
36
- it 'fail with no options' do
37
- _ do
38
- _out, _err = capture_io do
39
- RuboCop::Git::Runner.new.run({})
40
- end
41
- end.must_raise(RuboCop::Git::Options::Invalid)
42
- end
43
- end
data/test/test_helper.rb DELETED
@@ -1,2 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'rubocop/git'
File without changes
File without changes