rubocop_challenger 1.2.0 → 2.0.0.pre

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: ca4060e23f09a0c2a36203f0ce089fe50c91d789ba6ed19a108633ee5f874048
4
- data.tar.gz: cd0fd5ab050e01188cf86513734ba468c754cda0dcf946315fb51766e60bc2f9
3
+ metadata.gz: 88964a115a552a48b7462b24e329661fe2254f14e83a0effb9ce3cdf088d3abb
4
+ data.tar.gz: 81dbae9e07d6c9b51bea98db1f14196431563420b7c22a61a4e98b3b10559647
5
5
  SHA512:
6
- metadata.gz: a67157938b07fa52da89dbcbc3ef4dbcdd244207131dbe7dbcca31823c13de13d98810380a99e61c96f1535c873ee20265eb0e28a0d408780334235887c3a6b4
7
- data.tar.gz: 3d1fa7adc9d4cb3b6516faf6aebced9609098e69275fb92dbce0af7589a0edb7b308d9f8e4209f2f869d0a708f89b5c36c58c98298d392a08a420b438118d6f0
6
+ metadata.gz: 4ba31abab9fc1f3a6446db04e6e05490896be15e6916682deb8dcf49d784c021e4e7fd72fb96f17e8f0b004a4baaf1884308e75670ebab38c2115461c17b7686
7
+ data.tar.gz: 20bc09b991dda4c2cb7c2868527673409baff908c4712afb505152b78dc46fb8227bde6a65814217d8b0075a24cfc0be31a836dc7987e48d7979164d5be3250f
data/.circleci/config.yml CHANGED
@@ -82,10 +82,6 @@ references:
82
82
  destination: yardoc
83
83
 
84
84
  jobs:
85
- build_on_ruby_2.3:
86
- docker:
87
- - image: circleci/ruby:2.3-node-browsers
88
- <<: *build
89
85
  build_on_ruby_2.4:
90
86
  docker:
91
87
  - image: circleci/ruby:2.4-node-browsers
@@ -104,15 +100,15 @@ jobs:
104
100
  <<: *build
105
101
  rubocop:
106
102
  docker:
107
- - image: circleci/ruby:2.3-node-browsers
103
+ - image: circleci/ruby:2.4-node-browsers
108
104
  <<: *rubocop
109
105
  yardoc:
110
106
  docker:
111
- - image: circleci/ruby:2.3-node-browsers
107
+ - image: circleci/ruby:2.4-node-browsers
112
108
  <<: *yardoc
113
109
  verify_rubocop_challenge:
114
110
  docker:
115
- - image: circleci/ruby:2.3-node-browsers
111
+ - image: circleci/ruby:2.4-node-browsers
116
112
  working_directory: ~/repo
117
113
  steps:
118
114
  - checkout
@@ -134,12 +130,11 @@ jobs:
134
130
  --email=ryz310@gmail.com \
135
131
  --name=ryz310 \
136
132
  --mode=random \
137
- --labels='rubocop challenge' 'in progress' \
138
- --no-commit
133
+ --no-create-pr
139
134
 
140
135
  rubocop_challenge:
141
136
  docker:
142
- - image: circleci/ruby:2.3-node-browsers
137
+ - image: circleci/ruby:2.4-node-browsers
143
138
  working_directory: ~/repo
144
139
  steps:
145
140
  - checkout
@@ -150,12 +145,11 @@ jobs:
150
145
  bundle exec rubocop_challenger go \
151
146
  --email=ryz310@gmail.com \
152
147
  --name=ryz310 \
153
- --template=./lib/templates/checklist.md.erb \
154
- --labels='rubocop challenge' 'in progress'
148
+ --template=./lib/templates/checklist.md.erb
155
149
 
156
150
  release:
157
151
  docker:
158
- - image: circleci/ruby:2.3-node-browsers
152
+ - image: circleci/ruby:2.4-node-browsers
159
153
  working_directory: ~/repo
160
154
  steps:
161
155
  - checkout
@@ -179,7 +173,6 @@ workflows:
179
173
 
180
174
  commit:
181
175
  jobs:
182
- - build_on_ruby_2.3
183
176
  - build_on_ruby_2.4
184
177
  - build_on_ruby_2.5
185
178
  - build_on_ruby_2.6
@@ -190,7 +183,6 @@ workflows:
190
183
  - release:
191
184
  context: RubyGems API Key
192
185
  requires:
193
- - build_on_ruby_2.3
194
186
  - build_on_ruby_2.4
195
187
  - build_on_ruby_2.5
196
188
  - build_on_ruby_2.6
data/.rubocop.yml CHANGED
@@ -3,7 +3,7 @@ require: rubocop-rspec
3
3
  inherit_from: .rubocop_todo.yml
4
4
 
5
5
  AllCops:
6
- TargetRubyVersion: 2.3
6
+ TargetRubyVersion: 2.4
7
7
 
8
8
  Metrics/BlockLength:
9
9
  Exclude:
@@ -13,3 +13,6 @@ Metrics/BlockLength:
13
13
  RSpec/MultipleExpectations:
14
14
  Exclude:
15
15
  - 'spec/rubocop_challenger/cli_spec.rb'
16
+
17
+ RSpec/NestedGroups:
18
+ Max: 4
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2019-02-27 22:11:30 +0900 using RuboCop version 0.65.0.
3
+ # on 2019-03-31 02:56:49 +0900 using RuboCop version 0.66.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rubocop_challenger (1.2.0)
4
+ rubocop_challenger (2.0.0.pre)
5
5
  octokit
6
6
  rubocop
7
7
  rubocop-rspec
@@ -14,7 +14,7 @@ GEM
14
14
  addressable (2.5.2)
15
15
  public_suffix (>= 2.0.2, < 4.0)
16
16
  ast (2.4.0)
17
- byebug (11.0.0)
17
+ byebug (11.0.1)
18
18
  coderay (1.1.2)
19
19
  diff-lcs (1.3)
20
20
  docile (1.3.1)
@@ -24,12 +24,11 @@ GEM
24
24
  json (2.2.0)
25
25
  method_source (0.9.2)
26
26
  multipart-post (2.0.0)
27
- octokit (4.13.0)
27
+ octokit (4.14.0)
28
28
  sawyer (~> 0.8.0, >= 0.5.3)
29
- parallel (1.14.0)
30
- parser (2.6.0.0)
29
+ parallel (1.16.2)
30
+ parser (2.6.2.0)
31
31
  ast (~> 2.4.0)
32
- powerpack (0.1.2)
33
32
  pry (0.12.2)
34
33
  coderay (~> 1.1.0)
35
34
  method_source (~> 0.9.0)
@@ -55,15 +54,14 @@ GEM
55
54
  rspec-support (3.8.0)
56
55
  rspec_junit_formatter (0.4.1)
57
56
  rspec-core (>= 2, < 4, != 2.12.0)
58
- rubocop (0.65.0)
57
+ rubocop (0.66.0)
59
58
  jaro_winkler (~> 1.5.1)
60
59
  parallel (~> 1.10)
61
60
  parser (>= 2.5, != 2.5.1.1)
62
- powerpack (~> 0.1)
63
61
  psych (>= 3.1.0)
64
62
  rainbow (>= 2.2.2, < 4.0)
65
63
  ruby-progressbar (~> 1.7)
66
- unicode-display_width (~> 1.4.0)
64
+ unicode-display_width (>= 1.4.0, < 1.6)
67
65
  rubocop-rspec (1.32.0)
68
66
  rubocop (>= 0.60.0)
69
67
  ruby-progressbar (1.10.0)
@@ -76,7 +74,7 @@ GEM
76
74
  simplecov-html (~> 0.10.0)
77
75
  simplecov-html (0.10.2)
78
76
  thor (0.20.3)
79
- unicode-display_width (1.4.1)
77
+ unicode-display_width (1.5.0)
80
78
  yard (0.9.18)
81
79
 
82
80
  PLATFORMS
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Rubocop Challenger
2
2
 
3
- [![CircleCI](https://circleci.com/gh/ryz310/rubocop_challenger/tree/master.svg?style=svg&circle-token=cdf0ffce5b4c0c7804b50dde00ca5ef09cbadb67)](https://circleci.com/gh/ryz310/rubocop_challenger/tree/master) [![Gem Version](https://badge.fury.io/rb/rubocop_challenger.svg)](https://badge.fury.io/rb/rubocop_challenger) [![Maintainability](https://api.codeclimate.com/v1/badges/a18c1c17fc534bb32473/maintainability)](https://codeclimate.com/github/ryz310/rubocop_challenger/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/a18c1c17fc534bb32473/test_coverage)](https://codeclimate.com/github/ryz310/rubocop_challenger/test_coverage) [![Waffle.io - Columns and their card count](https://badge.waffle.io/ryz310/rubocop_challenger.svg?columns=all)](https://waffle.io/ryz310/rubocop_challenger)
3
+ [![CircleCI](https://circleci.com/gh/ryz310/rubocop_challenger/tree/master.svg?style=svg&circle-token=cdf0ffce5b4c0c7804b50dde00ca5ef09cbadb67)](https://circleci.com/gh/ryz310/rubocop_challenger/tree/master) [![Gem Version](https://badge.fury.io/rb/rubocop_challenger.svg)](https://badge.fury.io/rb/rubocop_challenger) [![Maintainability](https://api.codeclimate.com/v1/badges/a18c1c17fc534bb32473/maintainability)](https://codeclimate.com/github/ryz310/rubocop_challenger/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/a18c1c17fc534bb32473/test_coverage)](https://codeclimate.com/github/ryz310/rubocop_challenger/test_coverage)
4
4
 
5
5
  If you introduce [`rubocop`](https://github.com/rubocop-hq/rubocop) to an existing Rails project later, you will use [`$ rubocop --auto-gen-config`](https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md#automatically-generated-configuration). But it will make a huge `.rubocop_todo.yml` and make you despair.
6
6
  On the other hand, `rubocop` has [`--auto-correct`](https://github.com/rubocop-hq/rubocop/blob/master/manual/basic_usage.md#other-useful-command-line-flags) option, it is possible to automatically repair the writing which does not conform to the rule. But since it occasionally destroys your code, it is quite dangerous to apply all at once.
@@ -19,7 +19,9 @@ I call such work *Rubocop Challenge*. And the *RubocopChallenger* is a gem to su
19
19
 
20
20
  ### 1. Edit your Gemfile
21
21
 
22
- Put this line in your Gemfile.
22
+ If you do not specify the version of `rubocop` gem so you do not have to add `rubocop_challenger` gem in your Gemfile (**Recommended**).
23
+
24
+ If you specify the version so put this line in your Gemfile.
23
25
 
24
26
  ```rb
25
27
  gem 'rubocop_challenger', group: :development, require: false
@@ -53,8 +55,8 @@ jobs:
53
55
  - run:
54
56
  name: Rubocop Challenge
55
57
  command: |
56
- bundle install
57
- bundle exec rubocop_challenger go \
58
+ gem install rubocop_challenger
59
+ rubocop_challenger go \
58
60
  --email=rubocop-challenger@example.com \
59
61
  --name="Rubocop Challenger"
60
62
 
@@ -73,13 +75,27 @@ workflows:
73
75
  - rubocop_challenge
74
76
  ```
75
77
 
78
+ If you added `rubocop_challenger` gem in your Gemfile so please modify script of installing and execution as following:
79
+
80
+ ```yml
81
+ steps:
82
+ - checkout
83
+ - run:
84
+ name: Rubocop Challenge
85
+ command: |
86
+ bundle install
87
+ bundle exec rubocop_challenger go \
88
+ --email=rubocop-challenger@example.com \
89
+ --name="Rubocop Challenger"
90
+ ```
91
+
76
92
  ## CLI command references
77
93
 
78
94
  ```sh
79
95
  $ rubocop_challenger help
80
96
 
81
97
  Commands:
82
- rubocop_challenger go --email=EMAIL --name=NAME # Run `$ rubocop --auto-correct` and create PR to GitHub repo
98
+ rubocop_challenger go --email=EMAIL --name=NAME # Run `$ rubocop --auto-correct` and create a PR to GitHub repo
83
99
  rubocop_challenger help [COMMAND] # Describe available commands or one specific command
84
100
  rubocop_challenger version # Show current version
85
101
  ```
@@ -93,26 +109,23 @@ Usage:
93
109
  rubocop_challenger go --email=EMAIL --name=NAME
94
110
 
95
111
  Options:
96
- --email=EMAIL # Pull Request committer email
97
- --name=NAME # Pull Request committer name
98
- f, [--file-path=FILE_PATH] # Set your ".rubocop_todo.yml" path
99
- # Default: .rubocop_todo.yml
100
- t, [--template=TEMPLATE] # Pull Request template `erb` file path.You can use variable that `title`, `rubydoc_url`, `description` and `examples` into the erb file.
101
- [--mode=MODE] # Mode to select deletion target. You can choice "most_occurrence", "least_occurrence", or "random"
102
- # Default: most_occurrence
103
- [--base=BASE] # Base branch of Pull Request
104
- # Default: master
105
- l, [--labels=one two three] # Label to give to Pull Request
106
- # Default: ["rubocop challenge"]
107
- [--no-commit] # No commit after autocorrect
108
-
109
- Run `$ rubocop --auto-correct` and create PR to GitHub repo
112
+ --email=EMAIL # The Pull Request committer email
113
+ --name=NAME # The Pull Request committer name
114
+ f, [--file-path=FILE_PATH] # Set your ".rubocop_todo.yml" path
115
+ # Default: .rubocop_todo.yml
116
+ t, [--template=TEMPLATE] # A Pull Request template `erb` file path.You can use variable that `title`, `rubydoc_url`, `description` and `examples` into the erb file.
117
+ [--mode=MODE] # Mode to select deletion target. You can choice "most_occurrence", "least_occurrence", or "random"
118
+ # Default: most_occurrence
119
+ l, [--labels=one two three] # Label to give to Pull Request
120
+ # Default: ["rubocop challenge"]
121
+ [--no-create-pr] # No create a pull request (for testing)
122
+
123
+ Run `$ rubocop --auto-correct` and create a PR to GitHub repo
110
124
  ```
111
125
 
112
126
  ## Requirement
113
127
 
114
- * Ruby 2.3 or higher
115
- * NOTE: Ruby 2.3 will EOL soon (See: [Ruby Maintenance Branches](https://www.ruby-lang.org/en/downloads/branches/))
128
+ * Ruby 2.4 or higher
116
129
 
117
130
  ## Development
118
131
 
@@ -6,20 +6,17 @@
6
6
  require 'bundler/setup'
7
7
  require 'rubocop_challenger'
8
8
 
9
- def exit_process(error_message)
10
- puts error_message
11
- exit!
12
- end
13
-
14
9
  VERSION_FORMAT = /\A\d+\.\d+\.\d+(\.(pre|beta|rc)\d?)?\z/.freeze
15
10
  version = ARGV[0]
16
11
  rubocop = RubocopChallenger::Rubocop::Command.new
17
12
  pr_creater =
18
- RubocopChallenger::Github::PrCreater.new(branch: "update/v#{version}")
13
+ RubocopChallenger::Github::PrCreater.new(
14
+ base: 'master', branch: "update/v#{version}"
15
+ )
19
16
 
20
17
  # Verifying
21
- exit_process 'usage: bin/create_release_pr VERSION' if version.nil?
22
- exit_process 'A version must be like a `1.2.3`' unless version =~ VERSION_FORMAT
18
+ abort 'usage: bin/create_release_pr VERSION' if version.nil?
19
+ abort 'A version must be like a `1.2.3`' unless version =~ VERSION_FORMAT
23
20
 
24
21
  # Modify a version file
25
22
  pr_creater.commit 'Update version' do
@@ -43,4 +40,4 @@ pr_creater.commit 'Regenerate .rubocop_todo.yml' do
43
40
  end
44
41
 
45
42
  # Create PR
46
- pr_creater.create_pr(title: "Update v#{version}", body: '', base: 'master')
43
+ pr_creater.create_pr(title: "Update v#{version}", body: '')
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubocopChallenger
4
+ module Bundler
5
+ # To execute bundler command
6
+ class Command
7
+ include CommandLine
8
+
9
+ def update(*gem_names)
10
+ run('update', *gem_names)
11
+ end
12
+
13
+ def installed?(gem_name)
14
+ !run('list', '|', 'grep', gem_name).empty?
15
+ end
16
+
17
+ private
18
+
19
+ def run(*subcommands)
20
+ command = "bundle #{subcommands.join(' ')}"
21
+ execute(command)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -32,19 +32,15 @@ module RubocopChallenger
32
32
  default: 'most_occurrence',
33
33
  desc: 'Mode to select deletion target. You can choice ' \
34
34
  '"most_occurrence", "least_occurrence", or "random"'
35
- option :base,
36
- type: :string,
37
- default: 'master',
38
- desc: 'Base branch of Pull Request'
39
35
  option :labels,
40
36
  type: :array,
41
37
  default: ['rubocop challenge'],
42
38
  aliases: :l,
43
39
  desc: 'Label to give to Pull Request'
44
- option :'no-commit',
40
+ option :'no-create-pr',
45
41
  type: :boolean,
46
42
  default: false,
47
- desc: 'No commit after autocorrect'
43
+ desc: 'No create a pull request (for testing)'
48
44
  def go
49
45
  Go.new(options).exec
50
46
  rescue Errors::NoAutoCorrectableRule => e
@@ -61,17 +57,15 @@ module RubocopChallenger
61
57
 
62
58
  # Workaround to return exit code 1 when an error occurs
63
59
  # @see https://github.com/erikhuda/thor/issues/244
64
- module ClassMethods
65
- def exit_on_failure?
66
- true
67
- end
60
+ def self.exit_on_failure?
61
+ true
68
62
  end
69
63
 
70
64
  private
71
65
 
72
66
  # Exit process (Mainly for mock when testing)
73
67
  def exit_process!
74
- exit!
68
+ abort
75
69
  end
76
70
  end
77
71
  end
@@ -7,13 +7,15 @@ module RubocopChallenger
7
7
  # Returns a new instance of Github::PrCreater
8
8
  #
9
9
  # @note You have to set ENV['GITHUB_ACCESS_TOKEN']
10
+ # @param base [String] The branch you want your changes pulled into
10
11
  # @param branch [String] The branch where your changes are going to
11
12
  # implement.
12
13
  # @param user_name [String] The username to use for committer and author
13
14
  # @param user_email [String] The email to use for committer and author
14
- def initialize(branch:, user_name: nil, user_email: nil)
15
+ def initialize(base:, branch:, user_name: nil, user_email: nil)
15
16
  raise "You have to set ENV['GITHUB_ACCESS_TOKEN']" if access_token.nil?
16
17
 
18
+ @base_branch = base
17
19
  @topic_branch = branch
18
20
  @git = Git::Command.new(user_name: user_name, user_email: user_email)
19
21
  @github = Github::Client.new(access_token, git.remote_url('origin'))
@@ -40,36 +42,22 @@ module RubocopChallenger
40
42
  #
41
43
  # @param title [String] Title for the pull request
42
44
  # @param body [String] The body for the pull request
43
- # @param base [String] The branch you want your changes pulled into
44
45
  # @param labels [Array<String>] An array of labels to apply to this PR
45
46
  # @return [Boolean] Return true if its successed
46
- def create_pr(title:, body:, base:, labels: nil)
47
+ def create_pr(title:, body:, labels: nil)
47
48
  return false unless git_condition_valid?
48
49
 
49
50
  git.push(github_token_url, topic_branch)
50
51
  pr_number = github.create_pull_request(
51
- base: base, head: topic_branch, title: title, body: body
52
+ base: base_branch, head: topic_branch, title: title, body: body
52
53
  )
53
54
  github.add_labels(pr_number, *labels) unless labels.nil?
54
55
  true
55
56
  end
56
57
 
57
- # Stubing each PrCreater methods for testing
58
- class Mock
59
- def initialize(*); end
60
-
61
- def commit(*)
62
- yield if block_given?
63
- end
64
-
65
- def create_pr(*)
66
- true
67
- end
68
- end
69
-
70
58
  private
71
59
 
72
- attr_reader :git, :github, :topic_branch, :initial_sha1
60
+ attr_reader :git, :github, :base_branch, :topic_branch, :initial_sha1
73
61
 
74
62
  def git_condition_valid?
75
63
  !git.current_sha1?(initial_sha1) && git.current_branch?(topic_branch)
@@ -11,7 +11,7 @@ module RubocopChallenger
11
11
  @yardoc = Rubocop::Yardoc.new(title)
12
12
  end
13
13
 
14
- def generate_pullrequest_markdown
14
+ def generate
15
15
  <<~TEMPLATE
16
16
  #{ERB.new(template, nil, '-').result(binding)}
17
17
  Auto generated by [rubocop_challenger](https://github.com/ryz310/rubocop_challenger)
@@ -8,104 +8,135 @@ module RubocopChallenger
8
8
  # @param options [Hash] describe_options_here
9
9
  def initialize(options)
10
10
  @options = options
11
+ @pull_request = PullRequest.new(
12
+ options[:name],
13
+ options[:email],
14
+ options[:labels],
15
+ options[:'no-create-pr']
16
+ )
11
17
  end
12
18
 
19
+ # Executes Rubocop Challenge flow
20
+ #
13
21
  # @raise [Errors::NoAutoCorrectableRule]
22
+ # Raises if there is no auto correctable rule in ".rubocop_todo.yml"
14
23
  def exec
24
+ update_rubocop!
25
+ before_version, after_version = regenerate_rubocop_todo!
26
+ corrected_rule = rubocop_challenge!(before_version, after_version)
15
27
  regenerate_rubocop_todo!
16
- corrected_rule = rubocop_challenge!
17
- regenerate_rubocop_todo!
18
- if auto_correct_incomplete?(corrected_rule)
19
- add_ignore_list!(corrected_rule)
20
- end
28
+ add_to_ignore_list_if_challenge_is_incomplete(corrected_rule)
21
29
  create_pull_request!(corrected_rule)
22
30
  end
23
31
 
24
32
  private
25
33
 
26
- attr_reader :options
34
+ attr_reader :options, :pull_request
35
+
36
+ def update_rubocop!
37
+ bundler = Bundler::Command.new
38
+ pull_request.commit! ':police_car: $ bundle update rubocop' do
39
+ bundler.update 'rubocop'
40
+ bundler.update 'rubocop-rspec' if bundler.installed?('rubocop-rspec')
41
+ end
42
+ end
27
43
 
28
44
  # Re-generate .rubocop_todo.yml and run git commit.
45
+ #
46
+ # @return [Array<String>]
47
+ # Returns the versions of RuboCop which created ".rubocop_todo.yml" before
48
+ # and after re-generate.
29
49
  def regenerate_rubocop_todo!
30
- pr_creater.commit ':police_car: regenerate rubocop todo' do
50
+ before_version = scan_rubocop_version_in_rubocop_todo_file
51
+ pull_request.commit! ':police_car: regenerate rubocop todo' do
31
52
  Rubocop::Command.new.auto_gen_config
32
53
  end
54
+ after_version = scan_rubocop_version_in_rubocop_todo_file
55
+
56
+ [before_version, after_version]
57
+ end
58
+
59
+ # @return [String] The version of RuboCop which created ".rubocop_todo.yml"
60
+ def scan_rubocop_version_in_rubocop_todo_file
61
+ Rubocop::TodoReader.new(options[:file_path]).version
33
62
  end
34
63
 
35
64
  # Run rubocop challenge.
36
65
  #
37
- # @return [Rubocop::Rule] The corrected rule
38
- def rubocop_challenge!
39
- corrected_rule =
40
- Rubocop::Challenge.exec(options[:file_path], options[:mode])
41
- pr_creater.commit ":police_car: #{corrected_rule.title}"
42
- corrected_rule
66
+ # @param before_version [String]
67
+ # The version of RuboCop which created ".rubocop_todo.yml" before
68
+ # re-generate.
69
+ # @param after_version [String]
70
+ # The version of RuboCop which created ".rubocop_todo.yml" after
71
+ # re-generate
72
+ # @return [Rubocop::Rule]
73
+ # The corrected rule
74
+ # @raise [Errors::NoAutoCorrectableRule]
75
+ # Raises if there is no auto correctable rule in ".rubocop_todo.yml"
76
+ def rubocop_challenge!(before_version, after_version)
77
+ Rubocop::Challenge.exec(options[:file_path], options[:mode]).tap do |rule|
78
+ pull_request.commit! ":police_car: #{rule.title}"
79
+ end
80
+ rescue Errors::NoAutoCorrectableRule => e
81
+ create_another_pull_request!(before_version, after_version)
82
+ raise e
43
83
  end
44
84
 
45
- # GitHub PR creater instance.
46
- def pr_creater
47
- @pr_creater ||= Github::PrCreater.new(
48
- branch: "rubocop-challenge/#{timestamp}",
49
- user_name: options[:name],
50
- user_email: options[:email]
85
+ # Creates a pull request for the Rubocop Challenge
86
+ #
87
+ # @param corrected_rule [Rubocop::Rule] The corrected rule
88
+ def create_pull_request!(corrected_rule)
89
+ pull_request.create_rubocop_challenge_pr!(
90
+ corrected_rule, options[:template]
51
91
  )
52
92
  end
53
93
 
54
- # Check the challenge result. When the challenge successed, the rule dose
55
- # not exist in the .rubocop_todo.yml after regenerate it too.
94
+ # Creates a pull request which re-generate ".rubocop_todo.yml" with new
95
+ # version RuboCop. Use this method if it does not need to make a challenge
96
+ # but ".rubocop_todo.yml" is out of date. If same both `before_version` and
97
+ # `after_version`, it does not work.
56
98
  #
57
- # @param rule [Rubocop::Rule] The target rule
58
- # @return [Boolean] Return true if the challenge successed
59
- def auto_correct_incomplete?(rule)
60
- todo_reader = Rubocop::TodoReader.new(options[:file_path])
61
- todo_reader.all_rules.include?(rule)
99
+ # @param before_version [String]
100
+ # The version of RuboCop which created ".rubocop_todo.yml" before
101
+ # re-generate.
102
+ # @param after_version [String]
103
+ # The version of RuboCop which created ".rubocop_todo.yml" after
104
+ # re-generate
105
+ def create_another_pull_request!(before_version, after_version)
106
+ return if before_version == after_version
107
+
108
+ pull_request.create_regenerate_todo_pr!(before_version, after_version)
62
109
  end
63
110
 
64
- # If still exist the rule, the rule regard as cannot correct automatically
65
- # then add to ignore list and it is not chosen as target rule from next
66
- # time.
111
+ DESCRIPTION_THAT_CHALLENGE_IS_INCOMPLETE = <<~MSG
112
+ Rubocop Challenger has executed auto-correcting but it is incomplete.
113
+ Therefore the rule add to ignore list.
114
+ MSG
115
+
116
+ # If still exist the rule after a challenge, the rule regard as cannot
117
+ # correct automatically then add to ignore list and it is not chosen as
118
+ # target rule from next time.
67
119
  #
68
- # @param rule [Rubocop::Rule] The target rule
69
- def add_ignore_list!(rule)
70
- pr_creater.commit ':police_car: add the rule to the ignore list' do
120
+ # @param rule [Rubocop::Rule] The corrected rule
121
+ def add_to_ignore_list_if_challenge_is_incomplete(rule)
122
+ return unless auto_correct_incomplete?(rule)
123
+
124
+ pull_request.commit! ':police_car: add the rule to the ignore list' do
71
125
  config_editor = Rubocop::ConfigEditor.new
72
126
  config_editor.add_ignore(rule)
73
127
  config_editor.save
74
128
  end
75
- message = <<~MSG
76
- Rubocop Challenger has executed auto-correcting but it is incomplete.
77
- Therefore the rule add to ignore list.
78
- MSG
79
- color_puts message, CommandLine::YELLOW
129
+ color_puts DESCRIPTION_THAT_CHALLENGE_IS_INCOMPLETE, CommandLine::YELLOW
80
130
  end
81
131
 
82
- # Create a PR with description of what modification were made.
132
+ # Checks the challenge result. If the challenge is successed, the rule
133
+ # should not exist in the ".rubocop_todo.yml" after regenerate.
83
134
  #
84
- # @param rule [Rubocop::Rule] The target rule
85
- def create_pull_request!(rule)
86
- pr_creater_options = generate_pr_creater_options(rule)
87
- return if options[:'no-commit']
88
-
89
- pr_creater.create_pr(pr_creater_options)
90
- end
91
-
92
- def generate_pr_creater_options(rule)
93
- {
94
- title: "#{rule.title}-#{timestamp}",
95
- body: generate_pr_body(rule),
96
- base: options[:base],
97
- labels: options[:labels]
98
- }
99
- end
100
-
101
- def generate_pr_body(rule)
102
- Github::PrTemplate
103
- .new(rule, options[:template])
104
- .generate_pullrequest_markdown
105
- end
106
-
107
- def timestamp
108
- @timestamp ||= Time.now.strftime('%Y%m%d%H%M%S')
135
+ # @param rule [Rubocop::Rule] The corrected rule
136
+ # @return [Boolean] Return true if the challenge successed
137
+ def auto_correct_incomplete?(rule)
138
+ todo_reader = Rubocop::TodoReader.new(options[:file_path])
139
+ todo_reader.all_rules.include?(rule)
109
140
  end
110
141
  end
111
142
  end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubocopChallenger
4
+ # Creates a pull request
5
+ class PullRequest
6
+ # @param user_name [String]
7
+ # The author name which use at the git commit
8
+ # @param user_email [String]
9
+ # The email address which use at the git commit
10
+ # @param labels [Array<String>]
11
+ # Will create a pull request with the labels
12
+ # @param dry_run [Boolean]
13
+ # Does not create a pull request when given `true`
14
+ def initialize(user_name, user_email, labels, dry_run = false)
15
+ @pr_creater = Github::PrCreater.new(
16
+ base: 'master',
17
+ branch: "rubocop-challenge/#{timestamp}",
18
+ user_name: user_name,
19
+ user_email: user_email
20
+ )
21
+ @labels = labels
22
+ @dry_run = dry_run
23
+ end
24
+
25
+ # Add and commit local files to the pull request
26
+ #
27
+ # @param message [String] The commit message
28
+ # @yield Some commands where modify local files
29
+ # @return [Object] Return result of yield if you use &block
30
+ def commit!(message, &block)
31
+ pr_creater.commit message, &block
32
+ end
33
+
34
+ # Creates a pull request for the Rubocop Challenge
35
+ #
36
+ # @param rule [Rubocop::Rule]
37
+ # The corrected rule
38
+ # @param template_file_path [String, nil]
39
+ # The template file name which use to generate the pull request body
40
+ # @return [Boolean]
41
+ # Return true if its successed
42
+ def create_rubocop_challenge_pr!(rule, template_file_path = nil)
43
+ create_pull_request!(
44
+ title: "#{rule.title}-#{timestamp}",
45
+ body: Github::PrTemplate.new(rule, template_file_path).generate,
46
+ labels: labels
47
+ )
48
+ end
49
+
50
+ # Creates a pull request which re-generate ".rubocop_todo.yml" with new
51
+ # version RuboCop.
52
+ #
53
+ # @param before_version [String]
54
+ # The version of RuboCop which created ".rubocop_todo.yml" before
55
+ # re-generate.
56
+ # @param after_version [String]
57
+ # The version of RuboCop which created ".rubocop_todo.yml" after
58
+ # re-generate
59
+ # @return [Boolean]
60
+ # Return true if its successed
61
+ def create_regenerate_todo_pr!(before_version, after_version)
62
+ create_pull_request!(
63
+ title: "Re-generate .rubocop_todo.yml with RuboCop v#{after_version}",
64
+ body: generate_pull_request_body(before_version, after_version),
65
+ labels: labels
66
+ )
67
+ end
68
+
69
+ private
70
+
71
+ attr_reader :pr_creater, :labels, :dry_run
72
+
73
+ # Create a PR with description of what modification were made.
74
+ def create_pull_request!(pr_creater_options)
75
+ pr_creater.create_pr(pr_creater_options) unless dry_run
76
+ end
77
+
78
+ def generate_pull_request_body(before_version, after_version)
79
+ <<~MARKDOWN
80
+ Re-generated the .rubocop_todo.yml because it was generated by old version RuboCop.
81
+
82
+ * Using RuboCop version: `#{before_version}` -> `#{after_version}`
83
+
84
+ Auto generated by [rubocop_challenger](https://github.com/ryz310/rubocop_challenger)
85
+ MARKDOWN
86
+ end
87
+
88
+ def timestamp
89
+ @timestamp ||= Time.now.strftime('%Y%m%d%H%M%S')
90
+ end
91
+ end
92
+ end
@@ -8,22 +8,41 @@ module RubocopChallenger
8
8
  @rubocop_todo_file_path = rubocop_todo_file_path
9
9
  end
10
10
 
11
+ # Returns the version of RuboCop used to create the ".rubocop_todo.yml"
12
+ #
13
+ # @return [Type] the RuboCop version
14
+ def version
15
+ file_contents =~ /using RuboCop version (\d{1,}\.\d{1,}\.\d{1,})/
16
+ Regexp.last_match(1)
17
+ end
18
+
19
+ # @return [Array<Rule>]
20
+ # Array of rubocop rule instances which ordered by offense count
11
21
  def all_rules
12
- @all_rules ||= extract_rubocop_rules
22
+ @all_rules ||=
23
+ file_contents
24
+ .split(/\n{2,}/)
25
+ .map! { |content| Rule.new(content) }
26
+ .reject! { |rule| invalid?(rule) }
27
+ .sort!
13
28
  end
14
29
 
30
+ # @return [Array<Rule>]
15
31
  def auto_correctable_rules
16
32
  all_rules.select(&:auto_correctable?)
17
33
  end
18
34
 
35
+ # @return [Rule]
19
36
  def least_occurrence_rule
20
37
  auto_correctable_rules.first
21
38
  end
22
39
 
40
+ # @return [Rule]
23
41
  def most_occurrence_rule
24
42
  auto_correctable_rules.last
25
43
  end
26
44
 
45
+ # @return [Rule]
27
46
  def any_rule
28
47
  auto_correctable_rules.sample
29
48
  end
@@ -32,19 +51,18 @@ module RubocopChallenger
32
51
 
33
52
  attr_reader :rubocop_todo_file_path
34
53
 
35
- def extract_rubocop_rules
36
- File
37
- .read(rubocop_todo_file_path)
38
- .split(/\n{2,}/)
39
- .map! { |content| Rule.new(content) }
40
- .reject! { |rule| invalid?(rule) }
41
- .sort!
54
+ # @return [String] the ".rubocop_todo.yml" contents
55
+ def file_contents
56
+ @file_contents ||= File.read(rubocop_todo_file_path)
42
57
  end
43
58
 
59
+ # @param rule [Rule] the target rule
60
+ # @return [Boolean]
44
61
  def invalid?(rule)
45
62
  rule.offense_count.zero? || ignored_rules.include?(rule.title)
46
63
  end
47
64
 
65
+ # @return [Array<String>] Ignored rule titles
48
66
  def ignored_rules
49
67
  @ignored_rules ||= ConfigEditor.new.ignored_rules
50
68
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubocopChallenger
4
- VERSION = '1.2.0'
4
+ VERSION = '2.0.0.pre'
5
5
  end
@@ -15,8 +15,10 @@ require 'rubocop_challenger/rubocop/todo_writer'
15
15
  require 'rubocop_challenger/rubocop/command'
16
16
  require 'rubocop_challenger/rubocop/challenge'
17
17
  require 'rubocop_challenger/rubocop/yardoc'
18
+ require 'rubocop_challenger/pull_request'
18
19
  require 'rubocop_challenger/go'
19
20
  require 'rubocop_challenger/cli'
21
+ require 'rubocop_challenger/bundler/command'
20
22
  require 'rubocop_challenger/git/command'
21
23
  require 'rubocop_challenger/github/client'
22
24
  require 'rubocop_challenger/github/pr_template'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop_challenger
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 2.0.0.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - ryosuke_sato
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-02-27 00:00:00.000000000 Z
11
+ date: 2019-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: octokit
@@ -194,6 +194,7 @@ files:
194
194
  - images/generate_token.png
195
195
  - images/rubocop_challenge.png
196
196
  - lib/rubocop_challenger.rb
197
+ - lib/rubocop_challenger/bundler/command.rb
197
198
  - lib/rubocop_challenger/cli.rb
198
199
  - lib/rubocop_challenger/command_line.rb
199
200
  - lib/rubocop_challenger/errors.rb
@@ -202,6 +203,7 @@ files:
202
203
  - lib/rubocop_challenger/github/pr_creater.rb
203
204
  - lib/rubocop_challenger/github/pr_template.rb
204
205
  - lib/rubocop_challenger/go.rb
206
+ - lib/rubocop_challenger/pull_request.rb
205
207
  - lib/rubocop_challenger/rubocop/challenge.rb
206
208
  - lib/rubocop_challenger/rubocop/command.rb
207
209
  - lib/rubocop_challenger/rubocop/config_editor.rb
@@ -228,11 +230,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
228
230
  version: '0'
229
231
  required_rubygems_version: !ruby/object:Gem::Requirement
230
232
  requirements:
231
- - - ">="
233
+ - - ">"
232
234
  - !ruby/object:Gem::Version
233
- version: '0'
235
+ version: 1.3.1
234
236
  requirements: []
235
- rubygems_version: 3.0.1
237
+ rubygems_version: 3.0.3
236
238
  signing_key:
237
239
  specification_version: 4
238
240
  summary: Make a clean your rubocop_todo.yml with CI