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 +4 -4
- data/.circleci/config.yml +7 -15
- data/.rubocop.yml +4 -1
- data/.rubocop_todo.yml +1 -1
- data/Gemfile.lock +8 -10
- data/README.md +34 -21
- data/bin/create_release_pr +6 -9
- data/lib/rubocop_challenger/bundler/command.rb +25 -0
- data/lib/rubocop_challenger/cli.rb +5 -11
- data/lib/rubocop_challenger/github/pr_creater.rb +6 -18
- data/lib/rubocop_challenger/github/pr_template.rb +1 -1
- data/lib/rubocop_challenger/go.rb +94 -63
- data/lib/rubocop_challenger/pull_request.rb +92 -0
- data/lib/rubocop_challenger/rubocop/todo_reader.rb +26 -8
- data/lib/rubocop_challenger/version.rb +1 -1
- data/lib/rubocop_challenger.rb +2 -0
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88964a115a552a48b7462b24e329661fe2254f14e83a0effb9ce3cdf088d3abb
|
4
|
+
data.tar.gz: 81dbae9e07d6c9b51bea98db1f14196431563420b7c22a61a4e98b3b10559647
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
103
|
+
- image: circleci/ruby:2.4-node-browsers
|
108
104
|
<<: *rubocop
|
109
105
|
yardoc:
|
110
106
|
docker:
|
111
|
-
- image: circleci/ruby:2.
|
107
|
+
- image: circleci/ruby:2.4-node-browsers
|
112
108
|
<<: *yardoc
|
113
109
|
verify_rubocop_challenge:
|
114
110
|
docker:
|
115
|
-
- image: circleci/ruby:2.
|
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
|
-
--
|
138
|
-
--no-commit
|
133
|
+
--no-create-pr
|
139
134
|
|
140
135
|
rubocop_challenge:
|
141
136
|
docker:
|
142
|
-
- image: circleci/ruby:2.
|
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.
|
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.
|
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-
|
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 (
|
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.
|
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.
|
27
|
+
octokit (4.14.0)
|
28
28
|
sawyer (~> 0.8.0, >= 0.5.3)
|
29
|
-
parallel (1.
|
30
|
-
parser (2.6.
|
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.
|
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 (
|
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.
|
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)
|
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
|
-
|
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
|
-
|
57
|
-
|
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
|
97
|
-
--name=NAME
|
98
|
-
f, [--file-path=FILE_PATH]
|
99
|
-
|
100
|
-
t, [--template=TEMPLATE]
|
101
|
-
[--mode=MODE]
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
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.
|
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
|
|
data/bin/create_release_pr
CHANGED
@@ -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(
|
13
|
+
RubocopChallenger::Github::PrCreater.new(
|
14
|
+
base: 'master', branch: "update/v#{version}"
|
15
|
+
)
|
19
16
|
|
20
17
|
# Verifying
|
21
|
-
|
22
|
-
|
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: ''
|
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-
|
40
|
+
option :'no-create-pr',
|
45
41
|
type: :boolean,
|
46
42
|
default: false,
|
47
|
-
desc: 'No
|
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
|
-
|
65
|
-
|
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
|
-
|
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:,
|
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:
|
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
|
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
|
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
|
-
|
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
|
-
# @
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
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
|
-
#
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
-
#
|
55
|
-
#
|
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
|
58
|
-
#
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
-
|
65
|
-
|
66
|
-
|
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
|
69
|
-
def
|
70
|
-
|
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
|
-
|
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
|
-
#
|
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
|
85
|
-
|
86
|
-
|
87
|
-
|
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 ||=
|
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
|
-
|
36
|
-
|
37
|
-
|
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
|
data/lib/rubocop_challenger.rb
CHANGED
@@ -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:
|
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-
|
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:
|
235
|
+
version: 1.3.1
|
234
236
|
requirements: []
|
235
|
-
rubygems_version: 3.0.
|
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
|