danger-wcc 0.0.4 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +22 -15
- data/danger-wcc.gemspec +3 -3
- data/lib/version.rb +1 -1
- data/lib/wcc/commit_lint.rb +2 -1
- data/lib/wcc/commit_lint/commit_check.rb +0 -1
- data/lib/wcc/commit_lint/empty_line_check.rb +0 -1
- data/lib/wcc/commit_lint/subject_cap_check.rb +0 -1
- data/lib/wcc/commit_lint/subject_length_check.rb +0 -1
- data/lib/wcc/commit_lint/subject_period_check.rb +0 -1
- data/lib/wcc/commit_lint/subject_words_check.rb +0 -1
- data/lib/wcc/defaults.reek +8 -8
- data/lib/wcc/dependencies.rb +100 -0
- data/lib/wcc/jshint.rb +2 -2
- data/lib/wcc/plugin.rb +30 -12
- data/lib/wcc/reek.rb +2 -2
- data/lib/wcc/rubocop_exceptions.rb +13 -8
- data/lib/wcc/todos.rb +5 -4
- data/lib/wcc/util/yarn_info.rb +98 -0
- data/lib/wcc/utils.rb +18 -8
- data/lib/wcc/yarn_deduplicate.rb +71 -0
- data/spec/fixtures/dependencies/package.json +112 -0
- data/spec/fixtures/dependencies/package.json.diff +28 -0
- data/spec/fixtures/dependencies/package.json_patch_bumps_minor.diff +13 -0
- data/spec/fixtures/dependencies/package.json_patch_bumps_minor.json +112 -0
- data/spec/fixtures/dependencies/package.json_second_level_effect.diff +17 -0
- data/spec/fixtures/dependencies/package.json_second_level_effect.json +133 -0
- data/spec/fixtures/dependencies/yarn.lock +19609 -0
- data/spec/fixtures/dependencies/yarn.lock_patch_bumps_minor.lock +19614 -0
- data/spec/fixtures/dependencies/yarn.lock_second_level_effect.lock +20022 -0
- data/spec/fixtures/dependencies/yarn_list_second_level_effect.txt +1243 -0
- data/spec/fixtures/dependencies/yarn_list_second_level_effect.txt.diff +141 -0
- data/spec/fixtures/dependencies/yarn_minor_version.diff +33 -0
- data/spec/fixtures/dependencies/yarn_minor_version.txt +1151 -0
- data/spec/fixtures/dependencies/yarn_old.txt +1152 -0
- data/spec/fixtures/dependencies/yarn_patch_bumps_minor.diff +28 -0
- data/spec/fixtures/exception_inline_disabled_rule.diff +12 -0
- data/spec/fixtures/rubocop_exception.rb +3 -0
- data/spec/fixtures/yarn_deduplicate/list.a.txt +293 -0
- data/spec/fixtures/yarn_deduplicate/list.b.txt +295 -0
- data/spec/fixtures/yarn_deduplicate/list.diff +11 -0
- data/spec/fixtures/yarn_deduplicate/yarn.lock +20031 -0
- data/spec/fixtures_helper.rb +0 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/wcc/commit_lint_spec.rb +6 -10
- data/spec/wcc/dependencies_spec.rb +130 -0
- data/spec/wcc/github_spec.rb +13 -7
- data/spec/wcc/jshint_spec.rb +1 -1
- data/spec/wcc/plugin_spec.rb +22 -17
- data/spec/wcc/reek_spec.rb +1 -1
- data/spec/wcc/rubocop_exceptions_spec.rb +34 -15
- data/spec/wcc/todos_spec.rb +10 -10
- data/spec/wcc/utils_spec.rb +2 -2
- data/spec/wcc/yarn_deduplicate_spec.rb +57 -0
- data/spec/wcc_spec.rb +1 -1
- metadata +71 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5129a6e15f66a145fda1a0791144cfe4b4735150
|
4
|
+
data.tar.gz: 90d46909a0c85b829aaea23b543b99a61b2141f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a695fb8019f7d4e90dd6499ec656e579719737dbb173fc524d17bab8162d2b8438a44f6a205d38f2b10e32ff289856fc2730eec8be54a9d0aec0294fdc2cb6b
|
7
|
+
data.tar.gz: 9e30b7eadb23699642caf8c56345121b741e9d2d91f74d574c3c3365a1b38c9f487ba0b78a23c3d6544d50540abcafa964fc417943c6094935abb77c219d32f6
|
data/.rubocop.yml
CHANGED
@@ -2,6 +2,7 @@ AllCops:
|
|
2
2
|
DisplayCopNames: true
|
3
3
|
TargetRubyVersion: 2.3
|
4
4
|
Exclude:
|
5
|
+
- 'spec/fixtures/**/*'
|
5
6
|
# generated by rails/binstubs
|
6
7
|
- 'bin/**/*'
|
7
8
|
|
@@ -46,26 +47,36 @@ Metrics/ModuleLength:
|
|
46
47
|
- 'lib/wcc/utils.rb'
|
47
48
|
- 'spec/**/*.rb'
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
- 'spec/**/*.rb'
|
52
|
-
|
53
|
-
Performance/UnfreezeString:
|
54
|
-
Exclude:
|
55
|
-
- 'spec/**/*.rb'
|
50
|
+
Naming/MethodParameterName:
|
51
|
+
Enabled: false
|
56
52
|
|
57
|
-
|
53
|
+
Naming/MemoizedInstanceVariableName:
|
58
54
|
Enabled: false
|
59
55
|
|
60
56
|
Lint/AssignmentInCondition:
|
61
57
|
Enabled: false
|
62
58
|
|
59
|
+
Lint/RaiseException:
|
60
|
+
Enabled: true
|
61
|
+
|
62
|
+
Lint/StructNewOverride:
|
63
|
+
Enabled: true
|
64
|
+
|
63
65
|
Style/EmptyMethod:
|
64
66
|
EnforcedStyle: expanded
|
65
67
|
|
66
68
|
Style/Alias:
|
67
69
|
EnforcedStyle: prefer_alias_method
|
68
70
|
|
71
|
+
Style/HashEachMethods:
|
72
|
+
Enabled: true
|
73
|
+
|
74
|
+
Style/HashTransformKeys:
|
75
|
+
Enabled: true
|
76
|
+
|
77
|
+
Style/HashTransformValues:
|
78
|
+
Enabled: true
|
79
|
+
|
69
80
|
Style/NumericPredicate:
|
70
81
|
EnforcedStyle: comparison
|
71
82
|
|
@@ -76,13 +87,13 @@ Style/RegexpLiteral:
|
|
76
87
|
Style/SignalException:
|
77
88
|
Enabled: false
|
78
89
|
|
79
|
-
Layout/
|
90
|
+
Layout/ParameterAlignment:
|
80
91
|
EnforcedStyle: with_fixed_indentation
|
81
92
|
|
82
|
-
Layout/
|
93
|
+
Layout/FirstHashElementIndentation:
|
83
94
|
EnforcedStyle: consistent
|
84
95
|
|
85
|
-
Layout/
|
96
|
+
Layout/HashAlignment:
|
86
97
|
# allow coder to get around alignment rules by explicitly defining the hash param
|
87
98
|
EnforcedLastArgumentHashStyle: ignore_explicit
|
88
99
|
|
@@ -124,10 +135,6 @@ Layout/MultilineAssignmentLayout:
|
|
124
135
|
StyleGuide: '#indent-conditional-assignment'
|
125
136
|
Enabled: true
|
126
137
|
|
127
|
-
Lint/UnneededDisable:
|
128
|
-
Exclude:
|
129
|
-
- 'spec/fixtures/**/*'
|
130
|
-
|
131
138
|
Lint/MissingCopEnableDirective:
|
132
139
|
Exclude:
|
133
140
|
- 'spec/fixtures/**/*'
|
data/danger-wcc.gemspec
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
|
-
lib = File.expand_path('
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
5
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
6
5
|
require 'version'
|
7
6
|
|
@@ -20,6 +19,7 @@ Gem::Specification.new do |spec|
|
|
20
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
20
|
spec.require_paths = ['lib']
|
22
21
|
|
22
|
+
spec.add_runtime_dependency 'activesupport', '> 5'
|
23
23
|
spec.add_runtime_dependency 'brakeman'
|
24
24
|
spec.add_runtime_dependency 'danger-plugin-api', '~> 1.0'
|
25
25
|
spec.add_runtime_dependency 'flay'
|
@@ -36,7 +36,7 @@ Gem::Specification.new do |spec|
|
|
36
36
|
spec.add_development_dependency 'webmock', '~> 3.1'
|
37
37
|
|
38
38
|
# Linting code and docs
|
39
|
-
spec.add_development_dependency 'rubocop'
|
39
|
+
spec.add_development_dependency 'rubocop', '~> 0.81'
|
40
40
|
spec.add_development_dependency 'yard'
|
41
41
|
|
42
42
|
# Makes testing easy via `bundle exec guard`
|
data/lib/version.rb
CHANGED
data/lib/wcc/commit_lint.rb
CHANGED
@@ -102,7 +102,7 @@ class Danger::DangerWCC < Danger::Plugin
|
|
102
102
|
return unless c.fail?
|
103
103
|
|
104
104
|
messaging.issue([c.message, message[:sha]].join("\n"),
|
105
|
-
|
105
|
+
severity: severity)
|
106
106
|
end
|
107
107
|
|
108
108
|
def checkers
|
@@ -141,6 +141,7 @@ class Danger::DangerWCC < Danger::Plugin
|
|
141
141
|
|
142
142
|
def warning_checks
|
143
143
|
return checks if @config[:warn] == :all
|
144
|
+
|
144
145
|
@config[:warn] || []
|
145
146
|
end
|
146
147
|
|
data/lib/wcc/defaults.reek
CHANGED
@@ -23,10 +23,10 @@ DuplicateMethodCall:
|
|
23
23
|
allow_calls: []
|
24
24
|
FeatureEnvy:
|
25
25
|
enabled: true
|
26
|
-
exclude: []
|
26
|
+
exclude: ["Helper"]
|
27
27
|
InstanceVariableAssumption:
|
28
28
|
enabled: true
|
29
|
-
exclude: []
|
29
|
+
exclude: ["Controller"]
|
30
30
|
IrresponsibleModule:
|
31
31
|
enabled: false
|
32
32
|
exclude: []
|
@@ -54,7 +54,7 @@ NestedIterators:
|
|
54
54
|
ignore_iterators:
|
55
55
|
- tap
|
56
56
|
NilCheck:
|
57
|
-
enabled:
|
57
|
+
enabled: false
|
58
58
|
exclude: []
|
59
59
|
PrimaDonnaMethod:
|
60
60
|
enabled: true
|
@@ -70,15 +70,15 @@ Syntax:
|
|
70
70
|
enabled: true
|
71
71
|
exclude: []
|
72
72
|
TooManyConstants:
|
73
|
-
enabled:
|
73
|
+
enabled: true
|
74
74
|
exclude: []
|
75
75
|
max_constants: 5
|
76
76
|
TooManyInstanceVariables:
|
77
|
-
enabled:
|
77
|
+
enabled: true
|
78
78
|
exclude: []
|
79
79
|
max_instance_variables: 5
|
80
80
|
TooManyMethods:
|
81
|
-
enabled:
|
81
|
+
enabled: true
|
82
82
|
exclude: []
|
83
83
|
max_methods: 15
|
84
84
|
TooManyStatements:
|
@@ -127,5 +127,5 @@ UnusedPrivateMethod:
|
|
127
127
|
exclude: []
|
128
128
|
UtilityFunction:
|
129
129
|
enabled: true
|
130
|
-
exclude: []
|
131
|
-
public_methods_only:
|
130
|
+
exclude: ["Helper", "util"]
|
131
|
+
public_methods_only: true
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support'
|
4
|
+
require_relative 'utils'
|
5
|
+
|
6
|
+
class Danger::DangerWCC < Danger::Plugin
|
7
|
+
class Dependencies
|
8
|
+
include Utils
|
9
|
+
|
10
|
+
DEFAULT_OPTIONS = {
|
11
|
+
lockfile: 'yarn.lock',
|
12
|
+
severity: :warn
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
def yarn_info
|
16
|
+
@yarn_info ||=
|
17
|
+
Danger::DangerWCC::Util::YarnInfo.new(self, @options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(plugin, options = {})
|
21
|
+
@plugin = plugin
|
22
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def perform
|
26
|
+
return unless File.exist?(@options[:lockfile])
|
27
|
+
|
28
|
+
find_yarn_violations
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def issue_yarn_violation(package, versions)
|
34
|
+
line_index = yarn_info.find_index_in_lockfile(package, versions[1])
|
35
|
+
|
36
|
+
msg = "Dangerous change! #{package} was updated "\
|
37
|
+
"from #{versions[0]} to #{versions[1]}"\
|
38
|
+
' without a corresponding change to package.json!'
|
39
|
+
plugin.public_send(
|
40
|
+
@options[:severity],
|
41
|
+
msg,
|
42
|
+
file: @options[:lockfile],
|
43
|
+
line: line_index
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
def find_yarn_violations # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
48
|
+
# if there are any explicit major version changes in top level deps,
|
49
|
+
# say nothing about anything b/c it'll likely be noisy
|
50
|
+
has_explicit_mods =
|
51
|
+
yarn_info.modified_yarn_dependencies
|
52
|
+
.slice(*yarn_info.package_json_changes)
|
53
|
+
.any? { |_, v| major_version_change?(v[0], v[1]) }
|
54
|
+
return if has_explicit_mods
|
55
|
+
|
56
|
+
# Do say something if top level minor version change induces dangerous
|
57
|
+
# changes in other deps
|
58
|
+
|
59
|
+
mods =
|
60
|
+
yarn_info.modified_yarn_dependencies
|
61
|
+
.select { |_, versions| dangerous_change?(versions[0], versions[1]) }
|
62
|
+
|
63
|
+
has_dangerous_top_level_changes = false
|
64
|
+
mods.slice(*yarn_info.package_json_dependencies)
|
65
|
+
.each do |package, versions|
|
66
|
+
has_dangerous_top_level_changes = true
|
67
|
+
issue_yarn_violation(package, versions)
|
68
|
+
end
|
69
|
+
|
70
|
+
# issue warnings if a sub-dependency changed without a dangerous change in
|
71
|
+
# a top level dependency
|
72
|
+
return if has_dangerous_top_level_changes
|
73
|
+
|
74
|
+
mods.except(*yarn_info.package_json_dependencies)
|
75
|
+
.each do |package, versions|
|
76
|
+
issue_yarn_violation(package, versions)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def major_version_change?(old_version, new_version)
|
81
|
+
return false unless new_version
|
82
|
+
|
83
|
+
new_version.segments[0] > old_version.segments[0]
|
84
|
+
end
|
85
|
+
|
86
|
+
def dangerous_change?(old_version, new_version)
|
87
|
+
# the package was deleted
|
88
|
+
return true unless new_version
|
89
|
+
|
90
|
+
old_segments = old_version.segments
|
91
|
+
new_segments = new_version.segments
|
92
|
+
|
93
|
+
# the major or minor version changed.
|
94
|
+
new_segments[0] > old_segments[0] ||
|
95
|
+
new_segments[1] > old_segments[1]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
require_relative './util/yarn_info'
|
data/lib/wcc/jshint.rb
CHANGED
data/lib/wcc/plugin.rb
CHANGED
@@ -7,28 +7,36 @@ require_relative 'rubocop_exceptions'
|
|
7
7
|
require_relative 'commit_lint'
|
8
8
|
require_relative 'reek'
|
9
9
|
require_relative 'jshint'
|
10
|
+
require_relative 'dependencies'
|
11
|
+
require_relative 'yarn_deduplicate'
|
10
12
|
|
11
|
-
class Danger::DangerWCC < Danger::Plugin
|
13
|
+
class Danger::DangerWCC < Danger::Plugin # rubocop:disable Metrics/ClassLength
|
12
14
|
include Utils
|
13
15
|
include Github
|
14
16
|
|
15
|
-
|
16
|
-
rubocop_exceptions
|
17
|
-
todos
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
DEFAULT_OPTIONS = {
|
18
|
+
rubocop_exceptions: true,
|
19
|
+
todos: true,
|
20
|
+
brakeman: true,
|
21
|
+
dependencies: true,
|
22
|
+
yarn_deduplicate: true,
|
23
|
+
|
24
|
+
commit_lint: false,
|
25
|
+
reek: false,
|
26
|
+
jshint: false,
|
27
|
+
flay: false
|
28
|
+
}.freeze
|
24
29
|
|
25
30
|
# Runs all the included checks in the plugin
|
26
31
|
def all(options = {})
|
27
|
-
|
32
|
+
options = DEFAULT_OPTIONS.merge(options)
|
33
|
+
|
34
|
+
to_run = options.keys.reject { |check_name| options[check_name] == false }
|
28
35
|
raise ArgumentError, 'No Enabled Checks' if to_run.empty?
|
29
36
|
|
30
37
|
to_run.each do |check_name|
|
31
|
-
|
38
|
+
check_options = options.fetch(check_name, {})
|
39
|
+
public_send(check_name, check_options == true ? {} : check_options)
|
32
40
|
end
|
33
41
|
end
|
34
42
|
|
@@ -92,6 +100,16 @@ class Danger::DangerWCC < Danger::Plugin
|
|
92
100
|
Jshint.new(self, options).perform
|
93
101
|
end
|
94
102
|
|
103
|
+
def dependencies(options = {})
|
104
|
+
logger.info "dependencies: #{options}"
|
105
|
+
Dependencies.new(self, options).perform
|
106
|
+
end
|
107
|
+
|
108
|
+
def yarn_deduplicate(options = {})
|
109
|
+
logger.info "yarn_deduplicate: #{options}"
|
110
|
+
YarnDeduplicate.new(self, options).perform
|
111
|
+
end
|
112
|
+
|
95
113
|
private
|
96
114
|
|
97
115
|
def parse_flay_results
|
data/lib/wcc/reek.rb
CHANGED
@@ -49,8 +49,8 @@ class Danger::DangerWCC < Danger::Plugin
|
|
49
49
|
|
50
50
|
line_info = with_line_number.match(/^\s*([^\:]+)\:(\d+)\:/i)
|
51
51
|
plugin.warn(format_links_as_markdown(warning.captures[0]),
|
52
|
-
|
53
|
-
|
52
|
+
file: line_info.captures[0],
|
53
|
+
line: line_info.captures[1].to_i)
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
@@ -6,9 +6,9 @@ class Danger::DangerWCC < Danger::Plugin
|
|
6
6
|
class RubocopExceptions
|
7
7
|
include Utils
|
8
8
|
|
9
|
-
DISABLE_REGEX = /^(?:\+\s)?.*\#\s*rubocop\:disable\s+(\S+)/i
|
10
|
-
ENABLE_REGEX = /^(?:\+\s)?\s*\#\s*rubocop\:enable\s+(\S+)/i
|
11
|
-
COMMENT_LINE_REGEX = /^(?:\+\s)?\s*\#\s*(.+)$/i
|
9
|
+
DISABLE_REGEX = /^(?:\+\s)?.*\#\s*rubocop\:disable\s+(\S+)/i.freeze
|
10
|
+
ENABLE_REGEX = /^(?:\+\s)?\s*\#\s*rubocop\:enable\s+(\S+)/i.freeze
|
11
|
+
COMMENT_LINE_REGEX = /^(?:\+\s)?\s*\#\s*(.+)$/i.freeze
|
12
12
|
|
13
13
|
def initialize(plugin, options = {})
|
14
14
|
@plugin = plugin
|
@@ -20,7 +20,7 @@ class Danger::DangerWCC < Danger::Plugin
|
|
20
20
|
message = build_message(e)
|
21
21
|
severity = message_severity(e)
|
22
22
|
issue(message,
|
23
|
-
|
23
|
+
severity: severity, file: e[:file], line: e[:disabled_at])
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -35,7 +35,7 @@ class Danger::DangerWCC < Danger::Plugin
|
|
35
35
|
else
|
36
36
|
" \nPlease provide an explanation why this rule was disabled."
|
37
37
|
end
|
38
|
-
unless e[:reenabled]
|
38
|
+
unless e[:inline] || e[:reenabled]
|
39
39
|
message += "\n\nThe rule was not reenabled!\n"\
|
40
40
|
'Please add a `rubocop:enable` comment so the rule is disabled '\
|
41
41
|
'for the minimal scope.'
|
@@ -44,7 +44,7 @@ class Danger::DangerWCC < Danger::Plugin
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def message_severity(e)
|
47
|
-
if !e[:reenabled]
|
47
|
+
if !e[:inline] && !e[:reenabled]
|
48
48
|
'fail'
|
49
49
|
elsif e[:context_lines].empty?
|
50
50
|
'warn'
|
@@ -60,18 +60,23 @@ class Danger::DangerWCC < Danger::Plugin
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
+
# rubocop:disable Metrics/AbcSize
|
63
64
|
def make_violation(file_contents, hunk, line, rule)
|
65
|
+
is_inline_comment = !/^\s*\+?\s*\#/.match(line.content)
|
66
|
+
|
64
67
|
reenable_line_offset = find_reenable(file_contents,
|
65
|
-
|
66
|
-
|
68
|
+
line.line_number.right,
|
69
|
+
rule)
|
67
70
|
|
68
71
|
{
|
69
72
|
rule: rule,
|
70
73
|
disabled_at: line.line_number.right,
|
74
|
+
inline: is_inline_comment,
|
71
75
|
reenabled: !reenable_line_offset.nil?,
|
72
76
|
context_lines: find_context(hunk.lines.drop(hunk.lines.index(line)))
|
73
77
|
}
|
74
78
|
end
|
79
|
+
# rubocop:enable Metrics/AbcSize
|
75
80
|
|
76
81
|
def find_context(diff_lines)
|
77
82
|
# search for all non-`rubocop:` comment lines immediately
|