rubocop_challenger 1.2.0 → 2.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
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