ducalis 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -25
- data/README.md +13 -18
- data/bin/ducalis +18 -18
- data/ducalis.gemspec +1 -1
- data/lib/ducalis.rb +19 -24
- data/lib/ducalis/adapters/circle_ci.rb +25 -15
- data/lib/ducalis/adapters/default.rb +17 -0
- data/lib/ducalis/cli_arguments.rb +55 -0
- data/lib/ducalis/commentators/github.rb +27 -22
- data/lib/ducalis/diffs.rb +40 -0
- data/lib/ducalis/errors.rb +19 -0
- data/lib/ducalis/git_access.rb +61 -0
- data/lib/ducalis/github_formatter.rb +20 -0
- data/lib/ducalis/patch.rb +74 -0
- data/lib/ducalis/patched_rubocop/cop_cast.rb +13 -0
- data/lib/ducalis/patched_rubocop/git_runner.rb +1 -1
- data/lib/ducalis/patched_rubocop/git_turget_finder.rb +2 -2
- data/lib/ducalis/patched_rubocop/inject.rb +16 -0
- data/lib/ducalis/{patched_rubocop/rubo_cop.rb → rubo_cop.rb} +7 -13
- data/lib/ducalis/utils.rb +6 -1
- data/lib/ducalis/version.rb +1 -1
- metadata +17 -18
- data/lib/ducalis/adapters/base.rb +0 -17
- data/lib/ducalis/adapters/custom.rb +0 -21
- data/lib/ducalis/adapters/pull_request.rb +0 -26
- data/lib/ducalis/cli.rb +0 -96
- data/lib/ducalis/commentators/console.rb +0 -59
- data/lib/ducalis/cops/extensions/rubocop_cast.rb +0 -13
- data/lib/ducalis/passed_args.rb +0 -24
- data/lib/ducalis/patched_rubocop/diffs.rb +0 -30
- data/lib/ducalis/patched_rubocop/git_files_access.rb +0 -42
- data/lib/ducalis/runner.rb +0 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4558fbf8708c836a3ed1b13c07831f92f02f60a3e428996df38002ba68540440
|
4
|
+
data.tar.gz: b8423308b7ad62219226f0db48bebbcd9bde088f7ba3a938e93c078e914c08ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c91904bc9d0a53b0d626e642d4cc86b0436457e20e4d623c530116869dcd34c6df8e41f9447ab3688f3e2c0b4f7866ca300c83f91e5a67587379f1e7676cb14d
|
7
|
+
data.tar.gz: 45307edbf9c217bf7f757b59f3d98e5fec1902a60bb8079c043a4a846d3d653ce301a8de146cd911b74603c80c08a64db524292046b5f0dfdf0fc66567fc3148
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ducalis (0.
|
4
|
+
ducalis (0.9.0)
|
5
5
|
git (~> 1.3, >= 1.3.0)
|
6
|
-
|
6
|
+
octokit (>= 4.1.0)
|
7
7
|
regexp-examples (~> 1.3, >= 1.3.2)
|
8
8
|
rubocop (>= 0.45.0)
|
9
9
|
|
@@ -14,37 +14,17 @@ GEM
|
|
14
14
|
public_suffix (>= 2.0.2, < 4.0)
|
15
15
|
ast (2.4.0)
|
16
16
|
coderay (1.1.2)
|
17
|
-
coffee-script (2.4.1)
|
18
|
-
coffee-script-source
|
19
|
-
execjs
|
20
|
-
coffee-script-source (1.12.2)
|
21
|
-
coffeelint (1.16.1)
|
22
|
-
coffee-script
|
23
|
-
execjs
|
24
|
-
json
|
25
17
|
diff-lcs (1.3)
|
26
|
-
|
27
|
-
execjs
|
28
|
-
multi_json (>= 1.3)
|
29
|
-
rake
|
30
|
-
execjs (2.7.0)
|
31
|
-
faraday (0.14.0)
|
18
|
+
faraday (0.15.0)
|
32
19
|
multipart-post (>= 1.2, < 3)
|
33
20
|
git (1.3.0)
|
34
|
-
json (2.1.0)
|
35
21
|
method_source (0.9.0)
|
36
|
-
multi_json (1.13.1)
|
37
22
|
multipart-post (2.0.0)
|
38
|
-
octokit (4.
|
23
|
+
octokit (4.6.0)
|
39
24
|
sawyer (~> 0.8.0, >= 0.5.3)
|
40
25
|
parallel (1.12.1)
|
41
26
|
parser (2.5.0.0)
|
42
27
|
ast (~> 2.4.0)
|
43
|
-
policial (0.0.4)
|
44
|
-
coffeelint (~> 1.14)
|
45
|
-
eslintrb (~> 2.0)
|
46
|
-
octokit (~> 4.3)
|
47
|
-
rubocop (~> 0.39)
|
48
28
|
powerpack (0.1.1)
|
49
29
|
pry (0.11.3)
|
50
30
|
coderay (~> 1.1.0)
|
@@ -77,7 +57,7 @@ GEM
|
|
77
57
|
sawyer (0.8.1)
|
78
58
|
addressable (>= 2.3.5, < 2.6)
|
79
59
|
faraday (~> 0.8, < 1.0)
|
80
|
-
unicode-display_width (1.3.
|
60
|
+
unicode-display_width (1.3.2)
|
81
61
|
|
82
62
|
PLATFORMS
|
83
63
|
ruby
|
data/README.md
CHANGED
@@ -20,37 +20,32 @@ Add this line to your application's `Gemfile`:
|
|
20
20
|
gem 'ducalis'
|
21
21
|
```
|
22
22
|
|
23
|
-
|
23
|
+
__Ducalis__ is CLI application. By defaukt it will notify you about any possible
|
24
|
+
violations in CLI.
|
24
25
|
|
25
|
-
1. As CLI application. In this mode __Ducalis__ will notify you about any
|
26
|
-
possible violations in CLI.
|
27
26
|
```
|
28
27
|
ducalis
|
29
28
|
ducalis app/controllers/
|
30
29
|
```
|
31
|
-
|
30
|
+
|
31
|
+
__Ducalis__ allows to pass build even with violations it's make sense to run
|
32
32
|
__Ducalis__ across current branch or index:
|
33
|
+
|
33
34
|
```
|
34
35
|
ducalis --branch
|
35
36
|
ducalis --index
|
36
37
|
```
|
37
38
|
|
38
|
-
|
39
|
-
|
39
|
+
Additionally you can pass `--reporter` argument to notify about found violations
|
40
|
+
in boundaries of PR:
|
41
|
+
|
40
42
|
```
|
41
|
-
ducalis --
|
42
|
-
ducalis --
|
43
|
-
ducalis --ci --adapter=circle # mode for running on CircleCI
|
43
|
+
ducalis --reporter "author/repo#42"
|
44
|
+
ducalis --reporter "circleci"
|
44
45
|
```
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
code and write review comments.
|
49
|
-
|
50
|
-
3. As stand-alone server mode: In this mode __Ducalis__ will work as server,
|
51
|
-
listen webhooks from GitHub, and notify about any violations in PR. There is a
|
52
|
-
`Dockerfile` which you could use to run server for this or run it manually like
|
53
|
-
rack application. All related files are located in the `client/` directory.
|
46
|
+
|
47
|
+
_N.B._ You should provide `GITHUB_TOKEN` Env to allow __Ducalis__ download your
|
48
|
+
PR code and write review comments.
|
54
49
|
|
55
50
|
In CLI modes you can provide yours `.ducalis.yml` file based on
|
56
51
|
[default](https://github.com/ignat-z/ducalis/blob/master/config/.ducalis.yml) by
|
data/bin/ducalis
CHANGED
@@ -6,38 +6,38 @@ $LOAD_PATH.unshift("#{__dir__}/../lib")
|
|
6
6
|
require 'ducalis'
|
7
7
|
require 'benchmark'
|
8
8
|
|
9
|
-
|
9
|
+
cli_arguments = Ducalis::CliArguments.new
|
10
|
+
|
11
|
+
if cli_arguments.help_command?
|
10
12
|
puts 'You can start Ducalis in the next modes:'
|
11
|
-
puts " --ci check files from remote PR. \
|
12
|
-
Env `GITHUB_TOKEN` should be available to receive PRs files."
|
13
13
|
puts ' --branch check files in RuboCop style against branch.'
|
14
14
|
puts ' --index check files in RuboCop style against index.'
|
15
15
|
puts ' --all [default] check all files in RuboCop style.'
|
16
|
-
puts
|
16
|
+
puts
|
17
|
+
puts 'Use --reporter flag to pass how to report violations'
|
18
|
+
puts ' Ex: ducalis --reporter "user/repo#42"'
|
19
|
+
puts ' ducalis --reporter "circleci"'
|
17
20
|
|
18
|
-
Ducalis::CLI.new(ARGV).start
|
19
21
|
exit 0
|
20
22
|
end
|
21
23
|
|
22
|
-
if
|
24
|
+
if cli_arguments.docs_command?
|
23
25
|
require 'ducalis/documentation'
|
26
|
+
|
24
27
|
File.write(ARGV[1] || 'DOCUMENTATION.md', Documentation.new.call)
|
28
|
+
|
25
29
|
exit 0
|
26
30
|
end
|
27
31
|
|
28
|
-
|
29
|
-
Ducalis::CLI.new(ARGV - %w[--ci]).start
|
30
|
-
else
|
31
|
-
Ducalis::PassedArgs.process_args!
|
32
|
+
cli_arguments.process!
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
puts "Finished in #{time} seconds" if cli.options[:debug]
|
40
|
-
puts "\033[42mBuild still green. Nothing to worry about\033[0m" if result == 1
|
34
|
+
result = 0
|
35
|
+
cli = RuboCop::CLI.new
|
36
|
+
time = Benchmark.realtime do
|
37
|
+
result = cli.run
|
41
38
|
end
|
42
39
|
|
40
|
+
puts "Finished in #{time} seconds" if cli.options[:debug]
|
41
|
+
puts "\033[32mBuild still green. Nothing to worry about\033[0m" if result == 1
|
42
|
+
|
43
43
|
exit 0
|
data/ducalis.gemspec
CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
30
30
|
|
31
31
|
spec.add_dependency 'git', '~> 1.3', '>= 1.3.0'
|
32
|
-
spec.add_dependency '
|
32
|
+
spec.add_dependency 'octokit', '>= 4.1.0'
|
33
33
|
spec.add_dependency 'regexp-examples', '~> 1.3', '>= 1.3.2'
|
34
34
|
spec.add_dependency 'rubocop', '>= 0.45.0'
|
35
35
|
end
|
data/lib/ducalis.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'policial'
|
3
|
+
require 'rubocop'
|
5
4
|
|
6
5
|
module Ducalis
|
7
6
|
DOTFILE = '.ducalis.yml'.freeze
|
@@ -10,41 +9,41 @@ module Ducalis
|
|
10
9
|
end
|
11
10
|
|
12
11
|
require 'ducalis/version'
|
12
|
+
require 'ducalis/errors'
|
13
13
|
|
14
|
-
require 'ducalis/adapters/base'
|
15
14
|
require 'ducalis/adapters/circle_ci'
|
16
|
-
require 'ducalis/adapters/
|
17
|
-
require 'ducalis/adapters/pull_request'
|
15
|
+
require 'ducalis/adapters/default'
|
18
16
|
|
19
|
-
require 'ducalis/commentators/console'
|
20
|
-
require 'ducalis/commentators/github'
|
21
|
-
|
22
|
-
require 'ducalis/cli'
|
23
|
-
require 'ducalis/passed_args'
|
24
|
-
require 'ducalis/runner'
|
25
|
-
require 'ducalis/utils'
|
26
|
-
|
27
|
-
require 'ducalis/patched_rubocop/diffs'
|
28
17
|
require 'ducalis/patched_rubocop/ducalis_config_loader'
|
29
|
-
require 'ducalis/patched_rubocop/git_files_access'
|
30
18
|
require 'ducalis/patched_rubocop/git_runner'
|
31
19
|
require 'ducalis/patched_rubocop/git_turget_finder'
|
32
|
-
require 'ducalis/patched_rubocop/
|
20
|
+
require 'ducalis/patched_rubocop/inject'
|
21
|
+
require 'ducalis/patched_rubocop/cop_cast'
|
22
|
+
|
23
|
+
require 'ducalis/commentators/github'
|
24
|
+
require 'ducalis/github_formatter'
|
25
|
+
|
26
|
+
require 'ducalis/utils'
|
27
|
+
require 'ducalis/diffs'
|
28
|
+
require 'ducalis/rubo_cop'
|
29
|
+
require 'ducalis/cli_arguments'
|
30
|
+
require 'ducalis/patch'
|
31
|
+
require 'ducalis/git_access'
|
33
32
|
|
34
|
-
require 'ducalis/cops/extensions/type_resolving'
|
35
33
|
require 'ducalis/cops/black_list_suffix'
|
36
34
|
require 'ducalis/cops/callbacks_activerecord'
|
37
35
|
require 'ducalis/cops/case_mapping'
|
38
36
|
require 'ducalis/cops/controllers_except'
|
39
37
|
require 'ducalis/cops/data_access_objects'
|
40
38
|
require 'ducalis/cops/descriptive_block_names'
|
39
|
+
require 'ducalis/cops/enforce_namespace'
|
40
|
+
require 'ducalis/cops/evlis_overusing'
|
41
|
+
require 'ducalis/cops/extensions/type_resolving'
|
41
42
|
require 'ducalis/cops/fetch_expression'
|
42
|
-
require 'ducalis/cops/only_defs'
|
43
43
|
require 'ducalis/cops/keyword_defaults'
|
44
44
|
require 'ducalis/cops/module_like_class'
|
45
45
|
require 'ducalis/cops/multiple_times'
|
46
|
-
require 'ducalis/cops/
|
47
|
-
require 'ducalis/cops/enforce_namespace'
|
46
|
+
require 'ducalis/cops/only_defs'
|
48
47
|
require 'ducalis/cops/options_argument'
|
49
48
|
require 'ducalis/cops/params_passing'
|
50
49
|
require 'ducalis/cops/possible_tap'
|
@@ -62,7 +61,3 @@ require 'ducalis/cops/too_long_workers'
|
|
62
61
|
require 'ducalis/cops/uncommented_gem'
|
63
62
|
require 'ducalis/cops/unlocked_gem'
|
64
63
|
require 'ducalis/cops/useless_only'
|
65
|
-
|
66
|
-
require 'ducalis/cops/extensions/rubocop_cast'
|
67
|
-
|
68
|
-
RuboCop::Cop::Cop.prepend(RubocopCast)
|
@@ -1,22 +1,32 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
4
|
-
|
5
|
-
|
6
|
-
def repo
|
7
|
-
@repo ||= ENV.fetch('CIRCLE_REPOSITORY_URL')
|
8
|
-
.sub('https://github.com/', '')
|
9
|
-
.sub('git@github.com:', '')
|
10
|
-
.sub('.git', '')
|
11
|
-
end
|
3
|
+
module Adapters
|
4
|
+
class CircleCI
|
5
|
+
CODE = 'circleci'.freeze
|
12
6
|
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
def self.suitable_for?(value)
|
8
|
+
value == CODE
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(_value); end
|
12
|
+
|
13
|
+
def call
|
14
|
+
[repo, id]
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def repo
|
20
|
+
@repo ||= ENV.fetch('CIRCLE_REPOSITORY_URL')
|
21
|
+
.sub('https://github.com/', '')
|
22
|
+
.sub('git@github.com:', '')
|
23
|
+
.sub('.git', '')
|
24
|
+
end
|
16
25
|
|
17
|
-
|
18
|
-
|
19
|
-
|
26
|
+
def id
|
27
|
+
@id ||= ENV.fetch('CI_PULL_REQUEST')
|
28
|
+
.split('/')
|
29
|
+
.last
|
20
30
|
end
|
21
31
|
end
|
22
32
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ducalis
|
4
|
+
class CliArguments
|
5
|
+
ADAPTERS = [
|
6
|
+
Adapters::CircleCI,
|
7
|
+
Adapters::Default
|
8
|
+
].freeze
|
9
|
+
|
10
|
+
HELP_FLAGS = %w[-h -? --help].freeze
|
11
|
+
FORMATTER = %w[--format GithubFormatter].freeze
|
12
|
+
DOCS_ARG = :docs
|
13
|
+
REPORTER_ARG = :reporter
|
14
|
+
|
15
|
+
def docs_command?
|
16
|
+
ARGV.any? { |arg| arg == to_key(DOCS_ARG) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def help_command?
|
20
|
+
ARGV.any? { |arg| HELP_FLAGS.include?(arg) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def process!
|
24
|
+
detect_git_mode!
|
25
|
+
detect_reporter!
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def detect_reporter!
|
31
|
+
reporter_index = ARGV.index(to_key(REPORTER_ARG)) || return
|
32
|
+
reporter = ARGV[reporter_index + 1]
|
33
|
+
[to_key(REPORTER_ARG), reporter].each { |arg| ARGV.delete(arg) }
|
34
|
+
ARGV.push(*FORMATTER)
|
35
|
+
GitAccess.instance.store_pull_request!(find_pull_request(reporter))
|
36
|
+
end
|
37
|
+
|
38
|
+
def detect_git_mode!
|
39
|
+
git_mode = GitAccess::MODES.keys.find do |mode|
|
40
|
+
ARGV.include?(to_key(mode))
|
41
|
+
end
|
42
|
+
return unless git_mode
|
43
|
+
ARGV.delete(to_key(git_mode))
|
44
|
+
GitAccess.instance.flag = git_mode
|
45
|
+
end
|
46
|
+
|
47
|
+
def find_pull_request(value)
|
48
|
+
ADAPTERS.find { |adapter| adapter.suitable_for?(value) }.new(value).call
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_key(key)
|
52
|
+
"--#{key}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -6,29 +6,31 @@ module Ducalis
|
|
6
6
|
STATUS = 'COMMENT'.freeze
|
7
7
|
SIMILARITY_THRESHOLD = 0.8
|
8
8
|
|
9
|
-
def initialize(
|
10
|
-
@
|
9
|
+
def initialize(repo, id)
|
10
|
+
@repo = repo
|
11
|
+
@id = id
|
11
12
|
end
|
12
13
|
|
13
|
-
def call(
|
14
|
-
comments =
|
15
|
-
|
16
|
-
|
17
|
-
end.compact
|
14
|
+
def call(offenses)
|
15
|
+
comments = offenses.reject { |offense| already_commented?(offense) }
|
16
|
+
.map { |offense| present_offense(offense) }
|
17
|
+
|
18
18
|
return if comments.empty?
|
19
|
+
|
19
20
|
Utils.octokit
|
20
|
-
.create_pull_request_review(@
|
21
|
+
.create_pull_request_review(@repo, @id,
|
21
22
|
event: STATUS, comments: comments)
|
22
23
|
end
|
23
24
|
|
24
25
|
private
|
25
26
|
|
26
|
-
def
|
27
|
-
|
27
|
+
def already_commented?(offense)
|
28
|
+
current_offence = present_offense(offense)
|
29
|
+
commented_offenses.find do |commented_offense|
|
28
30
|
[
|
29
|
-
|
30
|
-
|
31
|
-
similar_messages?(
|
31
|
+
current_offence[:path] == commented_offense[:path],
|
32
|
+
current_offence[:position] == commented_offense[:position],
|
33
|
+
similar_messages?(current_offence[:body], commented_offense[:body])
|
32
34
|
].all?
|
33
35
|
end
|
34
36
|
end
|
@@ -38,18 +40,21 @@ module Ducalis
|
|
38
40
|
Utils.similarity(message, body) > SIMILARITY_THRESHOLD
|
39
41
|
end
|
40
42
|
|
41
|
-
def
|
42
|
-
@commented_violations ||=
|
43
|
-
Utils.octokit.pull_request_comments(@config.repo, @config.id)
|
44
|
-
end
|
45
|
-
|
46
|
-
def generate_comment(violation)
|
43
|
+
def present_offense(offense)
|
47
44
|
{
|
48
|
-
body:
|
49
|
-
path:
|
50
|
-
position:
|
45
|
+
body: offense.message,
|
46
|
+
path: diff_for(offense).path,
|
47
|
+
position: diff_for(offense).patch_line(offense.line)
|
51
48
|
}
|
52
49
|
end
|
50
|
+
|
51
|
+
def diff_for(offense)
|
52
|
+
GitAccess.instance.for(offense.location.source_buffer.name)
|
53
|
+
end
|
54
|
+
|
55
|
+
def commented_offenses
|
56
|
+
@_commented_offenses ||= Utils.octokit.pull_request_comments(@repo, @id)
|
57
|
+
end
|
53
58
|
end
|
54
59
|
end
|
55
60
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Diffs
|
4
|
+
class BaseDiff
|
5
|
+
attr_reader :diff, :path
|
6
|
+
|
7
|
+
def initialize(diff, path)
|
8
|
+
@diff = diff
|
9
|
+
@path = path
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class NilDiff < BaseDiff
|
14
|
+
def changed?(*)
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
def patch_line(*)
|
19
|
+
-1
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class GitDiff < BaseDiff
|
24
|
+
def changed?(changed_line)
|
25
|
+
patch.line_for(changed_line).changed?
|
26
|
+
end
|
27
|
+
|
28
|
+
def patch_line(changed_line)
|
29
|
+
patch.line_for(changed_line).patch_position
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def patch
|
35
|
+
Ducalis::Patch.new(diff.patch)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private_constant :BaseDiff, :NilDiff, :GitDiff
|
40
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ducalis
|
4
|
+
class MissingGit < ::StandardError
|
5
|
+
MESSAGE = "Can't find .git folder.".freeze
|
6
|
+
|
7
|
+
def initialize(msg = MESSAGE)
|
8
|
+
super
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class MissingToken < ::StandardError
|
13
|
+
MESSAGE = 'You should provide token in order to interact with GitHub'.freeze
|
14
|
+
|
15
|
+
def initialize(msg = MESSAGE)
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'git'
|
4
|
+
require 'singleton'
|
5
|
+
|
6
|
+
class GitAccess
|
7
|
+
DELETED = 'deleted'.freeze
|
8
|
+
GIT_DIR = '.git'.freeze
|
9
|
+
|
10
|
+
MODES = {
|
11
|
+
branch: ->(git) { git.diff('origin/master') },
|
12
|
+
index: ->(git) { git.diff('HEAD') }
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
include Diffs
|
16
|
+
include Singleton
|
17
|
+
|
18
|
+
attr_accessor :flag, :repo, :id
|
19
|
+
|
20
|
+
def store_pull_request!(repo, id)
|
21
|
+
self.repo = repo
|
22
|
+
self.id = id
|
23
|
+
end
|
24
|
+
|
25
|
+
def changed_files
|
26
|
+
changes.map(&:path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def for(path)
|
30
|
+
find(path)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def under_git?
|
36
|
+
@_under_git ||= Dir.exist?(File.join(Dir.pwd, GIT_DIR))
|
37
|
+
end
|
38
|
+
|
39
|
+
def changes
|
40
|
+
return default_value if flag.nil? || !under_git?
|
41
|
+
@_changes ||= patch_diffs
|
42
|
+
end
|
43
|
+
|
44
|
+
def patch_diffs
|
45
|
+
MODES.fetch(flag)
|
46
|
+
.call(Git.open(Dir.pwd))
|
47
|
+
.reject { |diff| diff.type == DELETED }
|
48
|
+
.select { |diff| File.exist?(diff.path) }
|
49
|
+
.map { |diff| GitDiff.new(diff, diff.path) }
|
50
|
+
end
|
51
|
+
|
52
|
+
def default_value
|
53
|
+
raise MissingGit unless flag.nil?
|
54
|
+
[]
|
55
|
+
end
|
56
|
+
|
57
|
+
def find(path)
|
58
|
+
return NilDiff.new(nil, path) if changes.empty?
|
59
|
+
changes.find { |diff| diff.path == path }
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class GithubFormatter < RuboCop::Formatter::BaseFormatter
|
4
|
+
def started(_target_files)
|
5
|
+
@all = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def file_finished(_file, offenses)
|
9
|
+
print '.'
|
10
|
+
@all << offenses unless offenses.empty?
|
11
|
+
end
|
12
|
+
|
13
|
+
def finished(_inspected_files)
|
14
|
+
print "\n"
|
15
|
+
Ducalis::Commentators::Github.new(
|
16
|
+
GitAccess.instance.repo,
|
17
|
+
GitAccess.instance.id
|
18
|
+
).call(@all.flatten)
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ducalis
|
4
|
+
class Patch
|
5
|
+
RANGE_LINE = /^@@ .+\+(?<line_number>\d+),/
|
6
|
+
MODIFIED_LINE = /^\+(?!\+|\+)/
|
7
|
+
NOT_REMOVED_LINE = /^[^-]/
|
8
|
+
ANY_LINE = /.*/
|
9
|
+
|
10
|
+
DIFF_LINES = {
|
11
|
+
RANGE_LINE => lambda do |lines, _line_number, line, _position|
|
12
|
+
[lines, line.match(RANGE_LINE)[:line_number].to_i]
|
13
|
+
end,
|
14
|
+
MODIFIED_LINE => lambda do |lines, line_number, line, position|
|
15
|
+
[lines + [Line.new(line_number, line, position)], line_number + 1]
|
16
|
+
end,
|
17
|
+
NOT_REMOVED_LINE => lambda do |lines, line_number, _line, _position|
|
18
|
+
[lines, line_number + 1]
|
19
|
+
end,
|
20
|
+
ANY_LINE => lambda do |lines, line_number, _line, _position|
|
21
|
+
[lines, line_number]
|
22
|
+
end
|
23
|
+
}.freeze
|
24
|
+
|
25
|
+
def initialize(patch)
|
26
|
+
diff_only = patch[patch.match(RANGE_LINE).begin(0)..-1]
|
27
|
+
@patch_lines = diff_only.lines.to_enum.with_index
|
28
|
+
end
|
29
|
+
|
30
|
+
def line_for(line_number)
|
31
|
+
changed_lines.detect do |line|
|
32
|
+
line.number == line_number
|
33
|
+
end || UnchangedLine.new
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
attr_reader :patch_lines
|
39
|
+
|
40
|
+
def changed_lines
|
41
|
+
patch_lines.inject([[], 0]) do |(lines, line_number), (line, position)|
|
42
|
+
_regex, action = DIFF_LINES.find { |regex, _action| line =~ regex }
|
43
|
+
action.call(lines, line_number, line, position)
|
44
|
+
end.first
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class UnchangedLine
|
49
|
+
def initialize(*); end
|
50
|
+
|
51
|
+
def patch_position
|
52
|
+
-1
|
53
|
+
end
|
54
|
+
|
55
|
+
def changed?
|
56
|
+
false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class Line
|
61
|
+
attr_reader :number, :content, :patch_position
|
62
|
+
|
63
|
+
def initialize(number, content, patch_position)
|
64
|
+
@number = number
|
65
|
+
@content = content
|
66
|
+
@patch_position = patch_position
|
67
|
+
end
|
68
|
+
|
69
|
+
def changed?
|
70
|
+
true
|
71
|
+
end
|
72
|
+
end
|
73
|
+
private_constant :Line, :UnchangedLine
|
74
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PatchedRubocop
|
4
|
+
module CopCast
|
5
|
+
def add_offense(node, loc, message = nil, severity = nil)
|
6
|
+
if PatchedRubocop::CURRENT_VERSION > PatchedRubocop::ADAPTED_VERSION
|
7
|
+
super(node, location: loc, message: message, severity: severity)
|
8
|
+
else
|
9
|
+
super(node, loc, message, severity)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -5,7 +5,7 @@ module PatchedRubocop
|
|
5
5
|
def inspect_file(file)
|
6
6
|
offenses, updated = super
|
7
7
|
offenses = offenses.select do |offense|
|
8
|
-
|
8
|
+
GitAccess.instance.for(file.path).changed?(offense.line)
|
9
9
|
end
|
10
10
|
|
11
11
|
[offenses, updated]
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module PatchedRubocop
|
4
4
|
module GitTurgetFinder
|
5
5
|
def find_files(base_dir, flags)
|
6
|
-
replacement =
|
7
|
-
return replacement
|
6
|
+
replacement = GitAccess.instance.changed_files
|
7
|
+
return replacement unless replacement.empty?
|
8
8
|
super
|
9
9
|
end
|
10
10
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PatchedRubocop
|
4
|
+
module Inject
|
5
|
+
PATH = Ducalis::DEFAULT_FILE.to_s
|
6
|
+
|
7
|
+
def self.defaults!
|
8
|
+
hash = RuboCop::ConfigLoader.send(:load_yaml_configuration, PATH)
|
9
|
+
config = RuboCop::Config.new(hash, PATH)
|
10
|
+
puts "configuration from #{PATH}" if RuboCop::ConfigLoader.debug?
|
11
|
+
config = RuboCop::ConfigLoader.merge_with_default(config, PATH)
|
12
|
+
RuboCop::ConfigLoader
|
13
|
+
.instance_variable_set(:@default_configuration, config)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,5 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module PatchedRubocop
|
4
|
+
CURRENT_VERSION = Gem::Version.new(RuboCop::Version.version)
|
5
|
+
ADAPTED_VERSION = Gem::Version.new('0.46.0')
|
6
|
+
end
|
7
|
+
|
3
8
|
module RuboCop
|
4
9
|
class ConfigLoader
|
5
10
|
::Ducalis::Utils.silence_warnings { DOTFILE = ::Ducalis::DOTFILE }
|
@@ -25,16 +30,5 @@ module RuboCop
|
|
25
30
|
end
|
26
31
|
end
|
27
32
|
|
28
|
-
|
29
|
-
|
30
|
-
branch: ->(git) { git.diff('origin/master') },
|
31
|
-
index: ->(git) { git.diff('HEAD') },
|
32
|
-
all: ->(_git) { [] }
|
33
|
-
}.freeze
|
34
|
-
|
35
|
-
module_function
|
36
|
-
|
37
|
-
def configure!(flag)
|
38
|
-
GitFilesAccess.instance.flag = flag
|
39
|
-
end
|
40
|
-
end
|
33
|
+
RuboCop::Cop::Cop.prepend(PatchedRubocop::CopCast)
|
34
|
+
PatchedRubocop::Inject.defaults!
|
data/lib/ducalis/utils.rb
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'octokit'
|
4
|
+
|
3
5
|
module Ducalis
|
4
6
|
module Utils
|
5
7
|
module_function
|
6
8
|
|
7
9
|
def octokit
|
8
|
-
@octokit ||=
|
10
|
+
@octokit ||= begin
|
11
|
+
token = ENV.fetch('GITHUB_TOKEN') { raise MissingToken }
|
12
|
+
Octokit::Client.new(access_token: token)
|
13
|
+
end
|
9
14
|
end
|
10
15
|
|
11
16
|
def similarity(string1, string2)
|
data/lib/ducalis/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ducalis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ignat Zakrevsky
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: git
|
@@ -31,19 +31,19 @@ dependencies:
|
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 1.3.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
|
-
name:
|
34
|
+
name: octokit
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
|
-
- -
|
37
|
+
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
39
|
+
version: 4.1.0
|
40
40
|
type: :runtime
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
|
-
- -
|
44
|
+
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version:
|
46
|
+
version: 4.1.0
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: regexp-examples
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -104,12 +104,9 @@ files:
|
|
104
104
|
- config/.ducalis.yml
|
105
105
|
- ducalis.gemspec
|
106
106
|
- lib/ducalis.rb
|
107
|
-
- lib/ducalis/adapters/base.rb
|
108
107
|
- lib/ducalis/adapters/circle_ci.rb
|
109
|
-
- lib/ducalis/adapters/
|
110
|
-
- lib/ducalis/
|
111
|
-
- lib/ducalis/cli.rb
|
112
|
-
- lib/ducalis/commentators/console.rb
|
108
|
+
- lib/ducalis/adapters/default.rb
|
109
|
+
- lib/ducalis/cli_arguments.rb
|
113
110
|
- lib/ducalis/commentators/github.rb
|
114
111
|
- lib/ducalis/cops/black_list_suffix.rb
|
115
112
|
- lib/ducalis/cops/callbacks_activerecord.rb
|
@@ -119,7 +116,6 @@ files:
|
|
119
116
|
- lib/ducalis/cops/descriptive_block_names.rb
|
120
117
|
- lib/ducalis/cops/enforce_namespace.rb
|
121
118
|
- lib/ducalis/cops/evlis_overusing.rb
|
122
|
-
- lib/ducalis/cops/extensions/rubocop_cast.rb
|
123
119
|
- lib/ducalis/cops/extensions/type_resolving.rb
|
124
120
|
- lib/ducalis/cops/fetch_expression.rb
|
125
121
|
- lib/ducalis/cops/keyword_defaults.rb
|
@@ -143,15 +139,18 @@ files:
|
|
143
139
|
- lib/ducalis/cops/uncommented_gem.rb
|
144
140
|
- lib/ducalis/cops/unlocked_gem.rb
|
145
141
|
- lib/ducalis/cops/useless_only.rb
|
142
|
+
- lib/ducalis/diffs.rb
|
146
143
|
- lib/ducalis/documentation.rb
|
147
|
-
- lib/ducalis/
|
148
|
-
- lib/ducalis/
|
144
|
+
- lib/ducalis/errors.rb
|
145
|
+
- lib/ducalis/git_access.rb
|
146
|
+
- lib/ducalis/github_formatter.rb
|
147
|
+
- lib/ducalis/patch.rb
|
148
|
+
- lib/ducalis/patched_rubocop/cop_cast.rb
|
149
149
|
- lib/ducalis/patched_rubocop/ducalis_config_loader.rb
|
150
|
-
- lib/ducalis/patched_rubocop/git_files_access.rb
|
151
150
|
- lib/ducalis/patched_rubocop/git_runner.rb
|
152
151
|
- lib/ducalis/patched_rubocop/git_turget_finder.rb
|
153
|
-
- lib/ducalis/patched_rubocop/
|
154
|
-
- lib/ducalis/
|
152
|
+
- lib/ducalis/patched_rubocop/inject.rb
|
153
|
+
- lib/ducalis/rubo_cop.rb
|
155
154
|
- lib/ducalis/utils.rb
|
156
155
|
- lib/ducalis/version.rb
|
157
156
|
homepage: https://github.com/ignat-z/ducalis
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Ducalis
|
4
|
-
module Adapters
|
5
|
-
class Custom < Base
|
6
|
-
def repo
|
7
|
-
@repo ||= options.fetch(:repo)
|
8
|
-
end
|
9
|
-
|
10
|
-
def id
|
11
|
-
@id ||= options.fetch(:id)
|
12
|
-
end
|
13
|
-
|
14
|
-
def sha
|
15
|
-
@sha ||= options.fetch(:sha) do
|
16
|
-
Utils.octokit.pull_request(repo, id).head.sha
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Ducalis
|
4
|
-
module Adapters
|
5
|
-
class PullRequest < Base
|
6
|
-
def repo
|
7
|
-
@repo ||= attributes[:repo]
|
8
|
-
end
|
9
|
-
|
10
|
-
def id
|
11
|
-
@id ||= attributes[:number]
|
12
|
-
end
|
13
|
-
|
14
|
-
def sha
|
15
|
-
@sha ||= attributes[:head_sha]
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def attributes
|
21
|
-
@attributes ||= Policial::PullRequestEvent.new(options)
|
22
|
-
.pull_request_attributes
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
data/lib/ducalis/cli.rb
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'optparse'
|
4
|
-
|
5
|
-
module Ducalis
|
6
|
-
class CLI
|
7
|
-
ADAPTERS = {
|
8
|
-
circle: Adapters::CircleCi,
|
9
|
-
custom: Adapters::Custom
|
10
|
-
}.freeze
|
11
|
-
DEFAULT_ADAPTER = ADAPTERS.keys.last
|
12
|
-
|
13
|
-
def initialize(arguments)
|
14
|
-
@arguments = arguments
|
15
|
-
@options = {}
|
16
|
-
@parser = OptionParser.new
|
17
|
-
configure_parser!
|
18
|
-
end
|
19
|
-
|
20
|
-
def start
|
21
|
-
@parser.parse(@arguments)
|
22
|
-
Runner.new(adapter.new(@options)).call
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def adapter
|
28
|
-
ADAPTERS.fetch(@options.fetch(:adapter, DEFAULT_ADAPTER)) do
|
29
|
-
raise "Unsupported adapter #{@options[:adapter]}"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def configure_parser!
|
34
|
-
@parser.banner = 'Usage: ducalis --ci --adapter=ADAPTER'
|
35
|
-
adapter_option_parsing
|
36
|
-
id_option_parsing
|
37
|
-
repo_option_parsing
|
38
|
-
sha_option_parsing
|
39
|
-
dry_option_parsing
|
40
|
-
help_command
|
41
|
-
end
|
42
|
-
|
43
|
-
def help_command
|
44
|
-
@parser.on_tail('--help', 'Show this message') do
|
45
|
-
puts @parser
|
46
|
-
RuboCop::CLI.new.run(@arguments)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def adapter_option_parsing
|
51
|
-
@parser.on(
|
52
|
-
'--adapter=ADAPTER',
|
53
|
-
'Describes how Ducalis will receive PR information. Default: custom'
|
54
|
-
) do |adapter|
|
55
|
-
@options[:adapter] = adapter.to_sym
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def id_option_parsing
|
60
|
-
@parser.on(
|
61
|
-
'--id=N',
|
62
|
-
'PR id, ex: 2347'
|
63
|
-
) do |id|
|
64
|
-
@options[:id] = id
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def repo_option_parsing
|
69
|
-
@parser.on(
|
70
|
-
'--repo=REPO',
|
71
|
-
'PR repository, ex: author/repo'
|
72
|
-
) do |repo|
|
73
|
-
@options[:repo] = repo
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def sha_option_parsing
|
78
|
-
@parser.on(
|
79
|
-
'--sha=SHA',
|
80
|
-
'Starting commit, can be omitted'
|
81
|
-
) do |sha|
|
82
|
-
@options[:sha] = sha
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def dry_option_parsing
|
87
|
-
@options[:dry] = false # default
|
88
|
-
@parser.on(
|
89
|
-
'--dry',
|
90
|
-
'Allows user to run dry mode, default: false'
|
91
|
-
) do |_dry|
|
92
|
-
@options[:dry] = true
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'logger'
|
4
|
-
|
5
|
-
module Ducalis
|
6
|
-
module Commentators
|
7
|
-
class Console
|
8
|
-
DOCUMENTATION_PATH = 'https://ducalis-rb.github.io/'.freeze
|
9
|
-
|
10
|
-
def initialize(config)
|
11
|
-
@config = config
|
12
|
-
end
|
13
|
-
|
14
|
-
def call(violations)
|
15
|
-
violations.each do |violation|
|
16
|
-
logger.info(generate_message(violation))
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def generate_message(violation)
|
23
|
-
[
|
24
|
-
[cyan(violation.filename), violation.line.patch_position].join(':'),
|
25
|
-
brown(violation.linter),
|
26
|
-
bold(ancor(violation))
|
27
|
-
].join(' ')
|
28
|
-
end
|
29
|
-
|
30
|
-
def logger
|
31
|
-
@logger ||= Logger.new(STDOUT).tap do |logger|
|
32
|
-
logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
33
|
-
"#{msg}\n"
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def ancor(violation)
|
39
|
-
[
|
40
|
-
DOCUMENTATION_PATH,
|
41
|
-
'#',
|
42
|
-
violation.linter.downcase.gsub(/[^[:alpha:]]/, '')
|
43
|
-
].join
|
44
|
-
end
|
45
|
-
|
46
|
-
def bold(text)
|
47
|
-
"\e[1m#{text}\e[22m"
|
48
|
-
end
|
49
|
-
|
50
|
-
def brown(text)
|
51
|
-
"\e[33m#{text}\e[0m"
|
52
|
-
end
|
53
|
-
|
54
|
-
def cyan(text)
|
55
|
-
"\e[36m#{text}\e[0m"
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RubocopCast
|
4
|
-
OLD_RUBOCOP_VERSION = Gem::Version.new('0.46.0')
|
5
|
-
|
6
|
-
def add_offense(node, loc, message = nil, severity = nil)
|
7
|
-
if Gem::Version.new(RuboCop::Version.version) > OLD_RUBOCOP_VERSION
|
8
|
-
super(node, location: loc, message: message, severity: severity)
|
9
|
-
else
|
10
|
-
super(node, loc, message, severity)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
data/lib/ducalis/passed_args.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Ducalis
|
4
|
-
module PassedArgs
|
5
|
-
module_function
|
6
|
-
|
7
|
-
HELP_FLAGS = ['-h', '-?', '--help'].freeze
|
8
|
-
|
9
|
-
def help_command?
|
10
|
-
ARGV.any? { |arg| HELP_FLAGS.include?(arg) }
|
11
|
-
end
|
12
|
-
|
13
|
-
def ci_mode?
|
14
|
-
ARGV.any? { |arg| arg == '--ci' }
|
15
|
-
end
|
16
|
-
|
17
|
-
def process_args!
|
18
|
-
flag = PatchedRubocop::MODES.keys
|
19
|
-
.map { |key| key if ARGV.delete("--#{key}") }
|
20
|
-
.find { |possible_flag| !possible_flag.nil? }
|
21
|
-
PatchedRubocop.configure!(flag || :all)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module PatchedRubocop
|
4
|
-
module Diffs
|
5
|
-
class BaseDiff
|
6
|
-
attr_reader :full_path, :diff
|
7
|
-
|
8
|
-
def initialize(full_path, diff)
|
9
|
-
@full_path = full_path
|
10
|
-
@diff = diff
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
class NilDiff < BaseDiff
|
15
|
-
def changed?(*)
|
16
|
-
true
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
class GitDiff < BaseDiff
|
21
|
-
def changed?(changed_line)
|
22
|
-
(Policial::Patch.new(diff.patch).changed_lines.detect do |line|
|
23
|
-
line.number == changed_line
|
24
|
-
end || Policial::UnchangedLine.new).changed?
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
private_constant :BaseDiff, :NilDiff, :GitDiff
|
29
|
-
end
|
30
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'git'
|
4
|
-
require 'singleton'
|
5
|
-
|
6
|
-
module PatchedRubocop
|
7
|
-
class GitFilesAccess
|
8
|
-
DELETED = 'deleted'.freeze
|
9
|
-
|
10
|
-
include PatchedRubocop::Diffs
|
11
|
-
include Singleton
|
12
|
-
|
13
|
-
attr_accessor :flag
|
14
|
-
|
15
|
-
def initialize
|
16
|
-
@dir = Dir.pwd
|
17
|
-
@git = Git.open(@dir)
|
18
|
-
end
|
19
|
-
|
20
|
-
def changes
|
21
|
-
@changes ||= MODES.fetch(@flag)
|
22
|
-
.call(@git)
|
23
|
-
.map { |diff| GitDiff.new(full_path(diff.path), diff) }
|
24
|
-
.reject { |diff| diff.diff.type == DELETED }
|
25
|
-
end
|
26
|
-
|
27
|
-
def changed?(path, line)
|
28
|
-
find(path).changed?(line)
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def full_path(path)
|
34
|
-
[@dir, path].join('/')
|
35
|
-
end
|
36
|
-
|
37
|
-
def find(path)
|
38
|
-
return NilDiff.new(full_path(path), nil) if changes.empty?
|
39
|
-
changes.find { |x| x.full_path == path }
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
data/lib/ducalis/runner.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Policial
|
4
|
-
class ConfigLoader
|
5
|
-
def raw(filename)
|
6
|
-
File.read(filename)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
module Ducalis
|
12
|
-
class Runner
|
13
|
-
def initialize(config)
|
14
|
-
@config = config
|
15
|
-
configure
|
16
|
-
end
|
17
|
-
|
18
|
-
def call
|
19
|
-
detective = Policial::Detective.new(Utils.octokit)
|
20
|
-
detective.brief(commit_info)
|
21
|
-
detective.investigate(ruby: { config_file: Ducalis::DEFAULT_FILE })
|
22
|
-
commentator.new(config).call(detective.violations)
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
attr_reader :config
|
28
|
-
|
29
|
-
def commit_info
|
30
|
-
{ repo: config.repo, number: config.id, head_sha: config.sha }
|
31
|
-
end
|
32
|
-
|
33
|
-
def configure
|
34
|
-
Octokit.auto_paginate = true
|
35
|
-
# Style guides were changed to linters in `policial` upstream
|
36
|
-
if Policial.respond_to?(:linters)
|
37
|
-
Policial.linters = [Policial::Linters::Ruby]
|
38
|
-
else
|
39
|
-
Policial.style_guides = [Policial::StyleGuides::Ruby]
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def commentator
|
44
|
-
@commentator ||=
|
45
|
-
config.dry? ? Commentators::Console : Commentators::Github
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|