rubocop_pr 0.1.0 → 0.2.0
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 +4 -4
- data/.gitignore +2 -0
- data/.overcommit.yml +93 -0
- data/.rubocop.yml +11 -0
- data/.travis.yml +11 -2
- data/Gemfile +4 -2
- data/README.md +48 -11
- data/Rakefile +5 -3
- data/bin/console +4 -3
- data/exe/rubocop_pr +17 -0
- data/lib/rubocop_pr/cli.rb +49 -0
- data/lib/rubocop_pr/environment_checker.rb +29 -0
- data/lib/rubocop_pr/git.rb +52 -0
- data/lib/rubocop_pr/options.rb +114 -0
- data/lib/rubocop_pr/repositories/github/checks/verify_hub_version.rb +29 -0
- data/lib/rubocop_pr/repositories/github.rb +55 -0
- data/lib/rubocop_pr/repository.rb +29 -0
- data/lib/rubocop_pr/rubocop.rb +48 -0
- data/lib/rubocop_pr/version.rb +3 -1
- data/lib/rubocop_pr.rb +21 -2
- data/rubocop_pr.gemspec +23 -17
- metadata +98 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 41140375dff6c844311e1bf2eea32974bdb78df0a703a117b0341eac7cb55928
|
|
4
|
+
data.tar.gz: b0bbd0edc7b6f6e9f084442630fa4dcc78e8212789207770fd83904241e08eb8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 01dfc86addb40874e9620b21233082cb093c6dca661accd2a451833730a78659e7bb147b2bc05afbccd1d742bdc301a95f126da010167ca9ff3fc1dfdee7b6c6
|
|
7
|
+
data.tar.gz: 5bf1b5cfbda7db9805638583b6260124e846b1cd8b948eee499801b13bf9f0bf3ba1fba8a3fb6f7f2ba8bbeb927e9dd3a006a2371aa88cd423f81b63b9e1c31c
|
data/.gitignore
CHANGED
data/.overcommit.yml
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
verify_signatures: false
|
|
2
|
+
CommitMsg:
|
|
3
|
+
ALL:
|
|
4
|
+
CapitalizedSubject:
|
|
5
|
+
enabled: true
|
|
6
|
+
description: 'Checking subject capitalization'
|
|
7
|
+
quiet: true
|
|
8
|
+
on_warn: fail
|
|
9
|
+
EmptyMessage:
|
|
10
|
+
enabled: true
|
|
11
|
+
description: 'Checking for empty commit message'
|
|
12
|
+
quiet: true
|
|
13
|
+
HardTabs:
|
|
14
|
+
enabled: true
|
|
15
|
+
description: 'Checking for hard tabs'
|
|
16
|
+
RussianNovel:
|
|
17
|
+
enabled: true
|
|
18
|
+
description: 'Checking length of commit message'
|
|
19
|
+
quiet: true
|
|
20
|
+
SingleLineSubject:
|
|
21
|
+
enabled: true
|
|
22
|
+
description: 'Checking subject line'
|
|
23
|
+
SpellCheck:
|
|
24
|
+
enabled: true
|
|
25
|
+
description: 'Checking for misspelled words'
|
|
26
|
+
required_executable: 'hunspell'
|
|
27
|
+
flags: ['-a']
|
|
28
|
+
on_fail: warn
|
|
29
|
+
TextWidth:
|
|
30
|
+
enabled: true
|
|
31
|
+
description: 'Checking text width'
|
|
32
|
+
max_subject_width: 60
|
|
33
|
+
max_body_width: 72
|
|
34
|
+
on_warn: fail
|
|
35
|
+
TrailingPeriod:
|
|
36
|
+
enabled: true
|
|
37
|
+
description: 'Checking for trailing periods in subject'
|
|
38
|
+
on_warn: fail
|
|
39
|
+
MessageFormat:
|
|
40
|
+
enabled: false
|
|
41
|
+
description: 'Message must be ended with task number'
|
|
42
|
+
expected_pattern_message: '<Commit Message Description> <Issue Id>'
|
|
43
|
+
sample_message: 'Refactored Onboarding flow FOO-1234'
|
|
44
|
+
pattern: '\s([A-Z]{1,4}-\d{1,4}|\d{1,6})$'
|
|
45
|
+
PreCommit:
|
|
46
|
+
ALL:
|
|
47
|
+
problem_on_unmodified_line: report
|
|
48
|
+
requires_files: true
|
|
49
|
+
required: false
|
|
50
|
+
quiet: false
|
|
51
|
+
AuthorEmail:
|
|
52
|
+
enabled: true
|
|
53
|
+
description: 'Checking author email'
|
|
54
|
+
requires_files: false
|
|
55
|
+
required: true
|
|
56
|
+
quiet: true
|
|
57
|
+
pattern: '^[^@]+@.*$'
|
|
58
|
+
AuthorName:
|
|
59
|
+
enabled: false
|
|
60
|
+
description: 'Checking for author name'
|
|
61
|
+
requires_files: false
|
|
62
|
+
required: true
|
|
63
|
+
quiet: true
|
|
64
|
+
BrokenSymlinks:
|
|
65
|
+
enabled: true
|
|
66
|
+
description: 'Checking for broken symlinks'
|
|
67
|
+
quiet: true
|
|
68
|
+
CaseConflicts:
|
|
69
|
+
enabled: true
|
|
70
|
+
description: 'Checking for case-insensitivity conflicts'
|
|
71
|
+
quiet: true
|
|
72
|
+
MergeConflicts:
|
|
73
|
+
enabled: true
|
|
74
|
+
description: 'Checking for merge conflicts'
|
|
75
|
+
quiet: true
|
|
76
|
+
required_executable: 'grep'
|
|
77
|
+
flags: ['-IHn', "^<<<<<<<[ \t]"]
|
|
78
|
+
|
|
79
|
+
RuboCop:
|
|
80
|
+
enabled: true
|
|
81
|
+
required: true
|
|
82
|
+
quiet: false
|
|
83
|
+
description: 'Analyzing with RuboCop'
|
|
84
|
+
command: ['bundle', 'exec', 'rubocop']
|
|
85
|
+
flags: ['--format=emacs', '--force-exclusion', '--display-cop-names']
|
|
86
|
+
install_command: 'gem install rubocop'
|
|
87
|
+
on_warn: fail
|
|
88
|
+
include:
|
|
89
|
+
- '**/*.gemspec'
|
|
90
|
+
- '**/*.rake'
|
|
91
|
+
- '**/*.rb'
|
|
92
|
+
- '**/Gemfile'
|
|
93
|
+
- '**/Rakefile'
|
data/.rubocop.yml
ADDED
data/.travis.yml
CHANGED
|
@@ -3,5 +3,14 @@ sudo: false
|
|
|
3
3
|
language: ruby
|
|
4
4
|
cache: bundler
|
|
5
5
|
rvm:
|
|
6
|
-
- 2.
|
|
7
|
-
|
|
6
|
+
- 2.1
|
|
7
|
+
- 2.2
|
|
8
|
+
- 2.3
|
|
9
|
+
- 2.4
|
|
10
|
+
- 2.5
|
|
11
|
+
- 2.6
|
|
12
|
+
before_install:
|
|
13
|
+
- gem install bundler -v 1.17.3
|
|
14
|
+
- sudo add-apt-repository ppa:cpick/hub -y
|
|
15
|
+
- sudo apt-get update
|
|
16
|
+
- sudo apt-get install hub
|
data/Gemfile
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
source 'https://rubygems.org'
|
|
4
|
+
|
|
5
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
4
6
|
|
|
5
7
|
# Specify your gem's dependencies in rubocop_pr.gemspec
|
|
6
8
|
gemspec
|
data/README.md
CHANGED
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
# RubocopPr
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[![Version ][rubygems_badge]][rubygems]
|
|
4
|
+
[![Build Status ][travisci_badge]][travisci]
|
|
5
|
+
[![Codacy Badge ][codacy_badge]][codacy]
|
|
6
|
+
[![Reviewed by Hound ][hound_badge]][hound]
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
CLI Issues and PR creator for Rubocop Cops. 1 linter == 1 issue == 1 PR.
|
|
9
|
+
|
|
10
|
+
With RubocopPr you can apply [Rubocop][rubocop_repo] clean and in a few minutes.
|
|
11
|
+
|
|
12
|
+
## Requirements
|
|
13
|
+
|
|
14
|
+
* Ruby 2.1+
|
|
15
|
+
* Hub 2.12.3 (tested with this version only, but should work with older versions)
|
|
16
|
+
* Github
|
|
6
17
|
|
|
7
18
|
## Installation
|
|
8
19
|
|
|
9
20
|
Add this line to your application's Gemfile:
|
|
10
21
|
|
|
11
22
|
```ruby
|
|
12
|
-
gem 'rubocop_pr'
|
|
23
|
+
gem 'rubocop_pr', require: false
|
|
13
24
|
```
|
|
14
25
|
|
|
15
26
|
And then execute:
|
|
@@ -22,22 +33,48 @@ Or install it yourself as:
|
|
|
22
33
|
|
|
23
34
|
## Usage
|
|
24
35
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
36
|
+
```bash
|
|
37
|
+
Usage: rubocop_pr [options]
|
|
38
|
+
-u, --hub-version [version] Set manually minimum required version of 'hub' utility for github (default: 2.12.3)
|
|
39
|
+
-b, --branch [branch] internal branch with '.rubocop_todo.yml' (default: 'rubocop_todo_branch')
|
|
40
|
+
-m, --master [branch] branch which will be the base for all PR's (default: 'master')
|
|
41
|
+
-r, --post-checkout [command] Running after each git checkout (default: "")
|
|
42
|
+
-l, --limit [limit] Limit the PS's for one run (default: 10)
|
|
43
|
+
-g, --repository [name] Set repository host (default: github)
|
|
44
|
+
-o, --origin [origin] origin option for 'git push' (default: 'origin')
|
|
45
|
+
-c, --continue Continue previous session (default: false)
|
|
46
|
+
-v, --version Display version
|
|
47
|
+
-h, --help Display help
|
|
48
|
+
```
|
|
28
49
|
|
|
29
|
-
|
|
50
|
+
#### Notes
|
|
30
51
|
|
|
31
|
-
|
|
52
|
+
* `brach` option is useful, if you want to prepare the `.rubocop-todo.yml` manually and feed it to `rubocop_pr`
|
|
53
|
+
* `post-checkout` handy for old Ruby versions, when shell may "forget" Ruby version.
|
|
32
54
|
|
|
33
55
|
## Contributing
|
|
34
56
|
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rubocop_pr. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant]
|
|
57
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rubocop_pr. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant][contributor_covenant_link] code of conduct.
|
|
36
58
|
|
|
37
59
|
## License
|
|
38
60
|
|
|
39
|
-
The gem is available as open source under the terms of the [MIT License]
|
|
61
|
+
The gem is available as open source under the terms of the [MIT License][mit_link].
|
|
40
62
|
|
|
41
63
|
## Code of Conduct
|
|
42
64
|
|
|
43
|
-
Everyone interacting in the RubocopPr project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct]
|
|
65
|
+
Everyone interacting in the RubocopPr project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct][code_of_conduct_link].
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
[rubocop_repo]: https://github.com/rubocop-hq/rubocop
|
|
69
|
+
[contributor_covenant_link]: http://contributor-covenant.org
|
|
70
|
+
[mit_link]: https://opensource.org/licenses/MIT
|
|
71
|
+
[code_of_conduct_link]: https://github.com/[USERNAME]/rubocop_pr/blob/master/CODE_OF_CONDUCT.md
|
|
72
|
+
|
|
73
|
+
[travisci_badge]: https://travis-ci.org/kvokka/rubocop_pr.svg?branch=master
|
|
74
|
+
[travisci]: https://travis-ci.org/kvokka/rubocop_pr
|
|
75
|
+
[rubygems]: https://rubygems.org/gems/rubocop_pr
|
|
76
|
+
[rubygems_badge]: http://img.shields.io/gem/v/rubocop_pr.svg
|
|
77
|
+
[codacy_badge]: https://api.codacy.com/project/badge/Grade/8be41ff90d294d7bb4c01fb3c98ebac9
|
|
78
|
+
[codacy]: https://app.codacy.com/app/kvokka/rubocop_pr?utm_source=github.com&utm_medium=referral&utm_content=kvokka/rubocop_pr&utm_campaign=Badge_Grade_Dashboard
|
|
79
|
+
[hound_badge]: https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg
|
|
80
|
+
[hound]: https://houndci.com
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'rubocop_pr'
|
|
5
6
|
|
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
|
@@ -10,5 +11,5 @@ require "rubocop_pr"
|
|
|
10
11
|
# require "pry"
|
|
11
12
|
# Pry.start
|
|
12
13
|
|
|
13
|
-
require
|
|
14
|
+
require 'irb'
|
|
14
15
|
IRB.start(__FILE__)
|
data/exe/rubocop_pr
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
$LOAD_PATH.unshift("#{__dir__}/../lib")
|
|
5
|
+
|
|
6
|
+
require 'rubocop_pr'
|
|
7
|
+
require 'benchmark'
|
|
8
|
+
|
|
9
|
+
cli = RubocopPr::CLI.new(ARGV)
|
|
10
|
+
result = 0
|
|
11
|
+
|
|
12
|
+
time = Benchmark.realtime do
|
|
13
|
+
result = cli.run!
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
puts "Finished in #{time} seconds" if cli.options[:debug]
|
|
17
|
+
exit result
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubocopPr
|
|
4
|
+
# Cunner from CLI interface
|
|
5
|
+
class CLI
|
|
6
|
+
attr_reader :options, :repository, :rubocop, :git
|
|
7
|
+
|
|
8
|
+
def initialize(argv = [])
|
|
9
|
+
@options = Options.new(argv).parse
|
|
10
|
+
@git = Git.new(post_checkout: @options.post_checkout, origin: @options.git_origin)
|
|
11
|
+
@repository = Repository.all.fetch(@options.repository)
|
|
12
|
+
@rubocop = RubocopPr::Rubocop.new(branch: @options.rubocop_todo_branch, git: @git)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def run!
|
|
16
|
+
EnvironmentChecker.call(repository, options)
|
|
17
|
+
run
|
|
18
|
+
git.checkout(options.master_branch)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def run
|
|
24
|
+
rubocop.inject(0) do |counter, cop|
|
|
25
|
+
next counter if git.status.blank?
|
|
26
|
+
next counter if options.continue && git.branch =~ /#{branch_suffix(cop)}\s/
|
|
27
|
+
next counter unless rubocop.corrected?
|
|
28
|
+
process_cop(cop)
|
|
29
|
+
|
|
30
|
+
break if counter >= options.limit - 1
|
|
31
|
+
counter + 1
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def process_cop(cop)
|
|
36
|
+
git.checkout(options.master_branch)
|
|
37
|
+
title = "Fix Rubocop #{cop} warnings"
|
|
38
|
+
issue_number = repository.create_issue(title: title)
|
|
39
|
+
git.checkout("#{issue_number}-#{branch_suffix(cop)}")
|
|
40
|
+
git.commit_all(title)
|
|
41
|
+
git.push
|
|
42
|
+
repository.create_pull_request(title: title, body: "Closes ##{issue_number}")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def branch_suffix(cop)
|
|
46
|
+
"rubocop-fix-#{cop.underscore.tr('/_', '-')}"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubocopPr
|
|
4
|
+
# Service class, which only goal is to check that the system is suitable to run the script.
|
|
5
|
+
class EnvironmentChecker
|
|
6
|
+
def self.checks
|
|
7
|
+
@checks ||= [GitStatus]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.call(repository, options)
|
|
11
|
+
checks.each { |c| c.call options }
|
|
12
|
+
repository.checks.each { |c| c.call options }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Check that we do not have any un-commited changes
|
|
16
|
+
module GitStatus
|
|
17
|
+
module_function
|
|
18
|
+
|
|
19
|
+
def call(*)
|
|
20
|
+
return true if git_status.empty?
|
|
21
|
+
raise 'You have un-commited changes in this branch'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def git_status
|
|
25
|
+
RubocopPr::Git.new.status
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module RubocopPr
|
|
2
|
+
# small helper for git commands, everything should be stubbed in tests
|
|
3
|
+
class Git
|
|
4
|
+
attr_reader :post_checkout, :origin
|
|
5
|
+
|
|
6
|
+
def initialize(post_checkout: '', origin: '', **_options)
|
|
7
|
+
@post_checkout = post_checkout
|
|
8
|
+
@origin = origin
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def checkout(file_or_branch)
|
|
12
|
+
return process_post_checkout if exec_checkout(file_or_branch)
|
|
13
|
+
exec_checkout file_or_branch, flags: ['-b']
|
|
14
|
+
process_post_checkout
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def commit_all(message)
|
|
18
|
+
system 'git add .'
|
|
19
|
+
system "git commit -m '#{message}'"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def push
|
|
23
|
+
system "git push --set-upstream #{origin} #{current_branch}"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def current_branch
|
|
27
|
+
`git branch --show-current`.chomp
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def status
|
|
31
|
+
`git status -s`
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def branch
|
|
35
|
+
`git branch`
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def process_post_checkout
|
|
41
|
+
post_checkout.blank? ? true : exec_post_checkout
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def exec_checkout(branch, flags: [])
|
|
45
|
+
system "git checkout #{flags.join(' ')} #{branch}"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def exec_post_checkout
|
|
49
|
+
system post_checkout.to_s
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubocopPr
|
|
4
|
+
# Parse the options from the command line
|
|
5
|
+
class Options
|
|
6
|
+
attr_reader :options, :args
|
|
7
|
+
|
|
8
|
+
def initialize(args)
|
|
9
|
+
@args = args
|
|
10
|
+
@options = OpenStruct.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def parse
|
|
14
|
+
build_parser.parse!(args)
|
|
15
|
+
options
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def build_parser # rubocop:disable Metrics/MethodLength
|
|
21
|
+
@parser = OptionParser.new do |opts|
|
|
22
|
+
opts.banner = 'Usage: rubocop_pr [options]'
|
|
23
|
+
|
|
24
|
+
add_hub_version_option(opts)
|
|
25
|
+
add_rubocop_todo_branch_option(opts)
|
|
26
|
+
add_master_branch_option(opts)
|
|
27
|
+
add_post_checkout_option(opts)
|
|
28
|
+
add_limit_option(opts)
|
|
29
|
+
add_repository_option(opts)
|
|
30
|
+
add_git_origin_option(opts)
|
|
31
|
+
add_continue_option(opts)
|
|
32
|
+
add_version_option(opts)
|
|
33
|
+
add_on_tail(opts)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def add_limit_option(opts)
|
|
38
|
+
@options.limit = 10
|
|
39
|
+
msg = "Limit the PS's for one run (default: 10)"
|
|
40
|
+
opts.on('-l [limit]', '--limit [limit]', Integer, msg) do |v|
|
|
41
|
+
@options.limit = v
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def add_post_checkout_option(opts)
|
|
46
|
+
@options.post_checkout = ''
|
|
47
|
+
msg = 'Running after each git checkout (default: "")'
|
|
48
|
+
opts.on('-r [command]', '--post-checkout [command]', String, msg) do |v|
|
|
49
|
+
@options.post_checkout = v
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def add_rubocop_todo_branch_option(opts)
|
|
54
|
+
@options.rubocop_todo_branch = 'rubocop_todo_branch'
|
|
55
|
+
msg = "internal branch with '.rubocop_todo.yml' (default: 'rubocop_todo_branch')"
|
|
56
|
+
opts.on('-b [branch]', '--branch [branch]', String, msg) do |v|
|
|
57
|
+
@options.rubocop_todo_branch = v
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def add_master_branch_option(opts)
|
|
62
|
+
@options.master_branch = 'master'
|
|
63
|
+
msg = "branch which will be the base for all PR's (default: 'master')"
|
|
64
|
+
opts.on('-m [branch]', '--master [branch]', String, msg) do |v|
|
|
65
|
+
@options.master_branch = v
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def add_git_origin_option(opts)
|
|
70
|
+
@options.git_origin = 'origin'
|
|
71
|
+
msg = "origin option for 'git push' (default: 'origin')"
|
|
72
|
+
opts.on('-o [origin]', '--origin [origin]', String, msg) do |v|
|
|
73
|
+
@options.git_origin = v
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def add_hub_version_option(opts)
|
|
78
|
+
@options.hub_version = HUB_VERSION
|
|
79
|
+
msg = "Set manually minimum required version of 'hub' utility for github (default: #{HUB_VERSION})"
|
|
80
|
+
opts.on('-u [version] ', '--hub-version [version]', msg) do |v|
|
|
81
|
+
@options.hub_version = v
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def add_repository_option(opts)
|
|
86
|
+
@options.repository = 'github'
|
|
87
|
+
msg = 'Set repository host (default: github)'
|
|
88
|
+
opts.on('-g [name] ', '--repository [name]', msg) do |v|
|
|
89
|
+
@options.repository = v
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def add_continue_option(opts)
|
|
94
|
+
@options.continue = false
|
|
95
|
+
opts.on('-c', '--continue', 'Continue previous session (default: false)') do |_v|
|
|
96
|
+
@options.continue = true
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def add_version_option(opts)
|
|
101
|
+
opts.on('-v', '--version', 'Display version') do
|
|
102
|
+
puts RubocopPr::VERSION
|
|
103
|
+
exit
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def add_on_tail(opts)
|
|
108
|
+
opts.on_tail('-h', '--help', 'Display help') do
|
|
109
|
+
puts opts
|
|
110
|
+
exit
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module RubocopPr
|
|
2
|
+
module Repositories
|
|
3
|
+
class Github < RubocopPr::Repository
|
|
4
|
+
module Checks
|
|
5
|
+
# Check, if `hub` installed and have right version
|
|
6
|
+
module VerifyHubVersion
|
|
7
|
+
module_function
|
|
8
|
+
|
|
9
|
+
def call(options)
|
|
10
|
+
return true if system_hub_version >= Gem::Version.new(options.hub_version)
|
|
11
|
+
warn "Script was tested with hub version #{HUB_VERSION}, while you are using #{system_hub_version}"
|
|
12
|
+
true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def system_hub_version
|
|
16
|
+
matches = hub_version.match(/hub version (?<hub_version>(.*))/)
|
|
17
|
+
Gem::Version.new matches.captures.last
|
|
18
|
+
rescue StandardError
|
|
19
|
+
raise "Robopop requires https://github.com/github/hub version >= #{RubocopPr::HUB_VERSION}"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def hub_version
|
|
23
|
+
`hub --version`
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module RubocopPr
|
|
2
|
+
module Repositories
|
|
3
|
+
# Github repository
|
|
4
|
+
class Github < RubocopPr::Repository
|
|
5
|
+
# The representation of the Issue
|
|
6
|
+
class Issue
|
|
7
|
+
attr_reader :title, :body
|
|
8
|
+
|
|
9
|
+
def initialize(title:, **other)
|
|
10
|
+
@title = title
|
|
11
|
+
@body = other[:body] || default_body
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create
|
|
15
|
+
link = `hub issue create -m '#{title}' -m '#{body}'`
|
|
16
|
+
link.split('/').last.to_i
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def default_body
|
|
20
|
+
'This issue was created by [rubocop_pr](https://github.com/kvokka/rubocop_pr) for ' \
|
|
21
|
+
'[rubocop](https://github.com/rubocop-hq/rubocop)'
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# The representation of the PR
|
|
26
|
+
class PullRequest
|
|
27
|
+
attr_reader :title, :body
|
|
28
|
+
|
|
29
|
+
def initialize(title:, **other)
|
|
30
|
+
@title = title
|
|
31
|
+
@body = other[:body] || ''
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def create
|
|
35
|
+
link = `hub pull-request create -m '#{title}' -m '#{body}'`
|
|
36
|
+
link.split('/').last.to_i
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class << self
|
|
41
|
+
def checks
|
|
42
|
+
super + [RubocopPr::Repositories::Github::Checks::VerifyHubVersion]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def create_issue(*args)
|
|
46
|
+
Issue.new(*args).create
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def create_pull_request(*args)
|
|
50
|
+
PullRequest.new(*args).create
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module RubocopPr
|
|
2
|
+
# abstract repository class
|
|
3
|
+
class Repository
|
|
4
|
+
class << self
|
|
5
|
+
def all
|
|
6
|
+
@all ||= ::ActiveSupport::HashWithIndifferentAccess.new
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def inherited(base)
|
|
10
|
+
all[base.name.demodulize.underscore] = base
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Array of Class which respond_to ::call and raise if check do not pass
|
|
14
|
+
def checks
|
|
15
|
+
[]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# return Integer issue number
|
|
19
|
+
def create_issue(*)
|
|
20
|
+
raise NotImplemented, 'should be implemented on sub-class'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# return Integer pull_request number
|
|
24
|
+
def create_pull_request(*)
|
|
25
|
+
raise NotImplemented, 'should be implemented on sub-class'
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module RubocopPr
|
|
2
|
+
# small helper for rubocop commands, everything should be stubbed in tests
|
|
3
|
+
class Rubocop
|
|
4
|
+
include Enumerable
|
|
5
|
+
|
|
6
|
+
TODO_FILENAME = '.rubocop_todo.yml'.freeze
|
|
7
|
+
|
|
8
|
+
attr_reader :branch, :git
|
|
9
|
+
|
|
10
|
+
def initialize(**options)
|
|
11
|
+
@branch = options.delete(:branch)
|
|
12
|
+
@git = options.delete(:git)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def todo
|
|
16
|
+
YAML.safe_load(read_or_generate_todo)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def each
|
|
20
|
+
git.checkout(branch)
|
|
21
|
+
todos_backup = todo
|
|
22
|
+
todos_backup.each_key do |cop|
|
|
23
|
+
git.checkout(branch)
|
|
24
|
+
todos = todos_backup.dup
|
|
25
|
+
todos.delete cop
|
|
26
|
+
File.open(TODO_FILENAME, 'w') { |f| f.write todos.blank? ? '' : YAML.dump(todos) }
|
|
27
|
+
yield cop
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def read_or_generate_todo
|
|
32
|
+
return File.read(TODO_FILENAME) if File.exist?(TODO_FILENAME)
|
|
33
|
+
generate_todo
|
|
34
|
+
git.commit_all('Generate initial Rubocop todo file')
|
|
35
|
+
File.read(TODO_FILENAME)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def generate_todo
|
|
39
|
+
`bundle exec rubocop --auto-gen-config`
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def corrected?
|
|
43
|
+
`bundle exec rubocop -a`
|
|
44
|
+
git.checkout TODO_FILENAME
|
|
45
|
+
!git.status.blank?
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
data/lib/rubocop_pr/version.rb
CHANGED
data/lib/rubocop_pr.rb
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'optparse'
|
|
4
|
+
require 'ostruct'
|
|
5
|
+
require 'active_support/core_ext/hash'
|
|
6
|
+
require 'yaml'
|
|
7
|
+
|
|
8
|
+
require 'pry'
|
|
9
|
+
|
|
10
|
+
require 'rubocop_pr/version'
|
|
11
|
+
require 'rubocop_pr/options'
|
|
12
|
+
require 'rubocop_pr/environment_checker'
|
|
13
|
+
require 'rubocop_pr/rubocop'
|
|
14
|
+
require 'rubocop_pr/git'
|
|
15
|
+
require 'rubocop_pr/repository'
|
|
16
|
+
require 'rubocop_pr/repositories/github'
|
|
17
|
+
require 'rubocop_pr/repositories/github/checks/verify_hub_version'
|
|
18
|
+
require 'rubocop_pr/cli'
|
|
19
|
+
|
|
20
|
+
# The entry point
|
|
3
21
|
module RubocopPr
|
|
4
22
|
class Error < StandardError; end
|
|
5
|
-
|
|
23
|
+
|
|
24
|
+
HUB_VERSION = '2.12.3'.freeze
|
|
6
25
|
end
|
data/rubocop_pr.gemspec
CHANGED
|
@@ -1,32 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
|
|
2
|
-
lib = File.expand_path(
|
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
-
require
|
|
5
|
+
require 'rubocop_pr/version'
|
|
5
6
|
|
|
6
7
|
Gem::Specification.new do |spec|
|
|
7
|
-
spec.name =
|
|
8
|
+
spec.name = 'rubocop_pr'
|
|
8
9
|
spec.version = RubocopPr::VERSION
|
|
9
|
-
spec.authors = [
|
|
10
|
-
spec.email = [
|
|
10
|
+
spec.authors = ['kvokka']
|
|
11
|
+
spec.email = ['kvokka@yahoo.com']
|
|
11
12
|
|
|
12
|
-
spec.summary =
|
|
13
|
-
spec.description =
|
|
14
|
-
spec.homepage =
|
|
15
|
-
spec.license =
|
|
13
|
+
spec.summary = 'Quick & clean Rubocop introduction.'
|
|
14
|
+
spec.description = 'Create 1 PR per 1 Rubocop linter, which allow to do review rubocop changes smoothly.'
|
|
15
|
+
spec.homepage = 'https://github.com/kvokka/rubocop_pr'
|
|
16
|
+
spec.license = 'MIT'
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
|
18
|
+
spec.required_ruby_version = '~> 2.1'
|
|
19
19
|
|
|
20
20
|
# Specify which files should be added to the gem when it is released.
|
|
21
21
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
22
|
-
spec.files
|
|
22
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
23
23
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
24
24
|
end
|
|
25
|
-
spec.bindir =
|
|
25
|
+
spec.bindir = 'exe'
|
|
26
26
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
27
|
-
spec.require_paths = [
|
|
27
|
+
spec.require_paths = ['lib']
|
|
28
28
|
|
|
29
|
-
spec.
|
|
30
|
-
spec.
|
|
31
|
-
|
|
29
|
+
spec.add_dependency 'activesupport', '>= 4.2.0', '< 6.0'
|
|
30
|
+
spec.add_dependency 'rubocop', '~> 0.57.0'
|
|
31
|
+
|
|
32
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
|
33
|
+
spec.add_development_dependency 'overcommit', '~> 0.44'
|
|
34
|
+
spec.add_development_dependency 'pry', '~> 0.12'
|
|
35
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
|
36
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
37
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 1.27'
|
|
32
38
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rubocop_pr
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- kvokka
|
|
@@ -10,20 +10,82 @@ bindir: exe
|
|
|
10
10
|
cert_chain: []
|
|
11
11
|
date: 2019-08-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: activesupport
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 4.2.0
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: '6.0'
|
|
23
|
+
type: :runtime
|
|
24
|
+
prerelease: false
|
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
26
|
+
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: 4.2.0
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '6.0'
|
|
33
|
+
- !ruby/object:Gem::Dependency
|
|
34
|
+
name: rubocop
|
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 0.57.0
|
|
40
|
+
type: :runtime
|
|
41
|
+
prerelease: false
|
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: 0.57.0
|
|
13
47
|
- !ruby/object:Gem::Dependency
|
|
14
48
|
name: bundler
|
|
15
49
|
requirement: !ruby/object:Gem::Requirement
|
|
16
50
|
requirements:
|
|
17
51
|
- - "~>"
|
|
18
52
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '1.
|
|
53
|
+
version: '1.16'
|
|
20
54
|
type: :development
|
|
21
55
|
prerelease: false
|
|
22
56
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
57
|
requirements:
|
|
24
58
|
- - "~>"
|
|
25
59
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '1.
|
|
60
|
+
version: '1.16'
|
|
61
|
+
- !ruby/object:Gem::Dependency
|
|
62
|
+
name: overcommit
|
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0.44'
|
|
68
|
+
type: :development
|
|
69
|
+
prerelease: false
|
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0.44'
|
|
75
|
+
- !ruby/object:Gem::Dependency
|
|
76
|
+
name: pry
|
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - "~>"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0.12'
|
|
82
|
+
type: :development
|
|
83
|
+
prerelease: false
|
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0.12'
|
|
27
89
|
- !ruby/object:Gem::Dependency
|
|
28
90
|
name: rake
|
|
29
91
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -52,15 +114,33 @@ dependencies:
|
|
|
52
114
|
- - "~>"
|
|
53
115
|
- !ruby/object:Gem::Version
|
|
54
116
|
version: '3.0'
|
|
55
|
-
|
|
117
|
+
- !ruby/object:Gem::Dependency
|
|
118
|
+
name: rubocop-rspec
|
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - "~>"
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '1.27'
|
|
124
|
+
type: :development
|
|
125
|
+
prerelease: false
|
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
127
|
+
requirements:
|
|
128
|
+
- - "~>"
|
|
129
|
+
- !ruby/object:Gem::Version
|
|
130
|
+
version: '1.27'
|
|
131
|
+
description: Create 1 PR per 1 Rubocop linter, which allow to do review rubocop changes
|
|
132
|
+
smoothly.
|
|
56
133
|
email:
|
|
57
134
|
- kvokka@yahoo.com
|
|
58
|
-
executables:
|
|
135
|
+
executables:
|
|
136
|
+
- rubocop_pr
|
|
59
137
|
extensions: []
|
|
60
138
|
extra_rdoc_files: []
|
|
61
139
|
files:
|
|
62
140
|
- ".gitignore"
|
|
141
|
+
- ".overcommit.yml"
|
|
63
142
|
- ".rspec"
|
|
143
|
+
- ".rubocop.yml"
|
|
64
144
|
- ".travis.yml"
|
|
65
145
|
- CODE_OF_CONDUCT.md
|
|
66
146
|
- Gemfile
|
|
@@ -69,10 +149,19 @@ files:
|
|
|
69
149
|
- Rakefile
|
|
70
150
|
- bin/console
|
|
71
151
|
- bin/setup
|
|
152
|
+
- exe/rubocop_pr
|
|
72
153
|
- lib/rubocop_pr.rb
|
|
154
|
+
- lib/rubocop_pr/cli.rb
|
|
155
|
+
- lib/rubocop_pr/environment_checker.rb
|
|
156
|
+
- lib/rubocop_pr/git.rb
|
|
157
|
+
- lib/rubocop_pr/options.rb
|
|
158
|
+
- lib/rubocop_pr/repositories/github.rb
|
|
159
|
+
- lib/rubocop_pr/repositories/github/checks/verify_hub_version.rb
|
|
160
|
+
- lib/rubocop_pr/repository.rb
|
|
161
|
+
- lib/rubocop_pr/rubocop.rb
|
|
73
162
|
- lib/rubocop_pr/version.rb
|
|
74
163
|
- rubocop_pr.gemspec
|
|
75
|
-
homepage:
|
|
164
|
+
homepage: https://github.com/kvokka/rubocop_pr
|
|
76
165
|
licenses:
|
|
77
166
|
- MIT
|
|
78
167
|
metadata: {}
|
|
@@ -82,9 +171,9 @@ require_paths:
|
|
|
82
171
|
- lib
|
|
83
172
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
173
|
requirements:
|
|
85
|
-
- - "
|
|
174
|
+
- - "~>"
|
|
86
175
|
- !ruby/object:Gem::Version
|
|
87
|
-
version: '
|
|
176
|
+
version: '2.1'
|
|
88
177
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
178
|
requirements:
|
|
90
179
|
- - ">="
|
|
@@ -94,5 +183,5 @@ requirements: []
|
|
|
94
183
|
rubygems_version: 3.0.4
|
|
95
184
|
signing_key:
|
|
96
185
|
specification_version: 4
|
|
97
|
-
summary:
|
|
186
|
+
summary: Quick & clean Rubocop introduction.
|
|
98
187
|
test_files: []
|