ducalis 0.8.0 → 0.9.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/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
|