danger-wcc 0.0.4 → 0.1.2
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/.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
|