danger-wcc 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +46 -0
  3. data/.gitignore +6 -0
  4. data/.rubocop.yml +219 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +12 -0
  7. data/Dangerfile +5 -0
  8. data/Gemfile +6 -0
  9. data/Guardfile +35 -0
  10. data/LICENSE +201 -0
  11. data/README.md +2 -0
  12. data/Rakefile +25 -0
  13. data/danger-wcc.gemspec +58 -0
  14. data/lib/danger_plugin.rb +3 -0
  15. data/lib/version.rb +5 -0
  16. data/lib/wcc/commit_lint.rb +158 -0
  17. data/lib/wcc/commit_lint/README.md +3 -0
  18. data/lib/wcc/commit_lint/commit_check.rb +19 -0
  19. data/lib/wcc/commit_lint/empty_line_check.rb +22 -0
  20. data/lib/wcc/commit_lint/subject_cap_check.rb +22 -0
  21. data/lib/wcc/commit_lint/subject_length_check.rb +28 -0
  22. data/lib/wcc/commit_lint/subject_period_check.rb +22 -0
  23. data/lib/wcc/commit_lint/subject_words_check.rb +22 -0
  24. data/lib/wcc/default.jshintrc +5 -0
  25. data/lib/wcc/defaults.reek +131 -0
  26. data/lib/wcc/github.rb +24 -0
  27. data/lib/wcc/jshint.rb +63 -0
  28. data/lib/wcc/plugin.rb +128 -0
  29. data/lib/wcc/reek.rb +56 -0
  30. data/lib/wcc/rubocop_exceptions.rb +99 -0
  31. data/lib/wcc/todos.rb +78 -0
  32. data/lib/wcc/utils.rb +136 -0
  33. data/spec/fixtures/brakeman/a.tmp +13 -0
  34. data/spec/fixtures/brakeman/b.tmp +14 -0
  35. data/spec/fixtures/brakeman/brakeman.diff +20 -0
  36. data/spec/fixtures/brakeman/brakeman.out +14 -0
  37. data/spec/fixtures/exception_context.diff +15 -0
  38. data/spec/fixtures/exception_insert_context.diff +14 -0
  39. data/spec/fixtures/exception_misspelled.diff +14 -0
  40. data/spec/fixtures/exception_multiline_context.diff +20 -0
  41. data/spec/fixtures/exception_reenabled.diff +13 -0
  42. data/spec/fixtures/find_in_diff.rb +21 -0
  43. data/spec/fixtures/find_in_diff_2_chunks.diff +24 -0
  44. data/spec/fixtures/flay.diff +17 -0
  45. data/spec/fixtures/flay.txt +18 -0
  46. data/spec/fixtures/github/labels.json +72 -0
  47. data/spec/fixtures/github_pr.json +325 -0
  48. data/spec/fixtures/jshint/a.tmp +5 -0
  49. data/spec/fixtures/jshint/b.tmp +7 -0
  50. data/spec/fixtures/jshint/jshint.diff +13 -0
  51. data/spec/fixtures/jshint/out.jshint +7 -0
  52. data/spec/fixtures/no_exception.diff +10 -0
  53. data/spec/fixtures/no_todo.diff +13 -0
  54. data/spec/fixtures/reek/line_numbers.reek +121 -0
  55. data/spec/fixtures/reek/reek.diff +50 -0
  56. data/spec/fixtures/rubocop_exception.rb +39 -0
  57. data/spec/fixtures/todo.rb +21 -0
  58. data/spec/fixtures/todo_link_next_line.diff +14 -0
  59. data/spec/fixtures/todo_link_same_line.diff +13 -0
  60. data/spec/fixtures/todo_no_link.diff +13 -0
  61. data/spec/fixtures/todo_removed.diff +13 -0
  62. data/spec/fixtures_helper.rb +19 -0
  63. data/spec/spec_helper.rb +73 -0
  64. data/spec/wcc/commit_lint_spec.rb +392 -0
  65. data/spec/wcc/github_spec.rb +67 -0
  66. data/spec/wcc/jshint_spec.rb +68 -0
  67. data/spec/wcc/plugin_spec.rb +134 -0
  68. data/spec/wcc/reek_spec.rb +71 -0
  69. data/spec/wcc/rubocop_exceptions_spec.rb +136 -0
  70. data/spec/wcc/todos_spec.rb +96 -0
  71. data/spec/wcc/utils_spec.rb +134 -0
  72. data/spec/wcc_spec.rb +21 -0
  73. metadata +393 -0
@@ -0,0 +1,2 @@
1
+ Copyright (c) 2018 Watermark Community Church
2
+ all rights reserved
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+ require 'rubocop/rake_task'
6
+
7
+ RSpec::Core::RakeTask.new(:specs)
8
+
9
+ task default: :specs
10
+
11
+ task :spec do
12
+ Rake::Task['specs'].invoke
13
+ Rake::Task['rubocop'].invoke
14
+ Rake::Task['spec_docs'].invoke
15
+ end
16
+
17
+ desc 'Run RuboCop on the lib/specs directory'
18
+ RuboCop::RakeTask.new(:rubocop) do |task|
19
+ task.patterns = ['lib/**/*.rb', 'spec/**/*.rb']
20
+ end
21
+
22
+ desc 'Ensure that the plugin passes `danger plugins lint`'
23
+ task :spec_docs do
24
+ sh 'bundle exec danger plugins lint'
25
+ end
@@ -0,0 +1,58 @@
1
+
2
+ # frozen_string_literal: true
3
+
4
+ lib = File.expand_path('../lib', __FILE__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+ require 'version'
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = 'danger-wcc'
10
+ spec.version = DangerWCC::VERSION
11
+ spec.authors = ['Watermark Dev']
12
+ spec.email = ['dev@watermark.org']
13
+ spec.description = 'A Danger plugin for Watermark Church custom rules.'
14
+ spec.summary = 'A Danger plugin for Watermark Church custom rules.'
15
+ spec.homepage = 'https://github.com/watermarkchurch/danger-wcc'
16
+ spec.license = 'Apache-2.0'
17
+
18
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.add_runtime_dependency 'brakeman'
24
+ spec.add_runtime_dependency 'danger-plugin-api', '~> 1.0'
25
+ spec.add_runtime_dependency 'flay'
26
+ spec.add_runtime_dependency 'git_diff', '~> 0.3'
27
+ spec.add_runtime_dependency 'reek'
28
+
29
+ # General ruby development
30
+ spec.add_development_dependency 'bundler', '~> 1.3'
31
+ spec.add_development_dependency 'rake', '~> 10.0'
32
+
33
+ # Testing support
34
+ spec.add_development_dependency 'rspec', '~> 3.4'
35
+ spec.add_development_dependency 'rspec_junit_formatter', '~> 0.3.0'
36
+ spec.add_development_dependency 'webmock', '~> 3.1'
37
+
38
+ # Linting code and docs
39
+ spec.add_development_dependency 'rubocop'
40
+ spec.add_development_dependency 'yard'
41
+
42
+ # Makes testing easy via `bundle exec guard`
43
+ spec.add_development_dependency 'guard', '~> 2.14'
44
+ spec.add_development_dependency 'guard-rspec', '~> 4.7'
45
+ spec.add_development_dependency 'guard-rubocop', '~> 1.3.0'
46
+
47
+ # If you want to work on older builds of ruby
48
+ spec.add_development_dependency 'listen', '3.0.7'
49
+
50
+ # This gives you the chance to run a REPL inside your tests
51
+ # via:
52
+ #
53
+ # require 'pry'
54
+ # binding.pry
55
+ #
56
+ # This will stop test execution and let you inspect the results
57
+ spec.add_development_dependency 'pry'
58
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'wcc/plugin'
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DangerWCC
4
+ VERSION = '0.0.2'
5
+ end
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'commit_lint/commit_check'
4
+ require_relative 'commit_lint/subject_cap_check'
5
+ require_relative 'commit_lint/subject_words_check'
6
+ require_relative 'commit_lint/subject_length_check'
7
+ require_relative 'commit_lint/subject_period_check'
8
+ require_relative 'commit_lint/empty_line_check'
9
+
10
+ class Danger::DangerWCC < Danger::Plugin
11
+ # Run each commit in the PR through a message linting.
12
+ #
13
+ # Commit lint will check each commit in the PR to ensure the following is
14
+ # true:
15
+ #
16
+ # * Commit subject begins with a capital letter (`subject_cap`)
17
+ # * Commit subject is more than one word (`subject_word`)
18
+ # * Commit subject is no longer than 50 characters (`subject_length`)
19
+ # * Commit subject does not end in a period (`subject_period`)
20
+ # * Commit subject and body are separated by an empty line (`empty_line`)
21
+ #
22
+ # By default, Commit Lint fails, but you can configure this behavior.
23
+ #
24
+ #
25
+ # @example Lint all commits using defaults
26
+ #
27
+ # commit_lint.check
28
+ #
29
+ # @example Warn instead of fail
30
+ #
31
+ # commit_lint.check warn: :all
32
+ #
33
+ # @example Disable a particular check
34
+ #
35
+ # commit_lint.check disable: [:subject_period]
36
+ #
37
+ # @see danger/danger
38
+ # @tags commit linting
39
+ #
40
+ class CommitLint
41
+ NOOP_MESSAGE = 'All checks were disabled, nothing to do.'
42
+
43
+ def initialize(plugin, config = {})
44
+ @plugin = plugin
45
+ @config = config
46
+ end
47
+
48
+ def git
49
+ @plugin.git
50
+ end
51
+
52
+ def messaging
53
+ @plugin
54
+ end
55
+
56
+ # Checks the commits with whatever config the user passes.
57
+ #
58
+ # Passing in a hash which contain the following keys:
59
+ #
60
+ # * `disable` - array of checks to skip
61
+ # * `fail` - array of checks to fail on
62
+ # * `warn` - array of checks to warn on
63
+ #
64
+ # The current check types are:
65
+ #
66
+ # * `subject_cap`
67
+ # * `subject_word`
68
+ # * `subject_length`
69
+ # * `subject_period`
70
+ # * `empty_line`
71
+ #
72
+ # Note: you can pass :all instead of an array to target all checks.
73
+ #
74
+ # @param [Hash] config
75
+ #
76
+ # @return [void]
77
+ #
78
+ def perform
79
+ if all_checks_disabled?
80
+ messaging.warn NOOP_MESSAGE
81
+ else
82
+ check_messages
83
+ end
84
+ end
85
+
86
+ private
87
+
88
+ def check_messages
89
+ messages.each do |message|
90
+ warning_checkers.each do |klass|
91
+ check_and_issue(klass, message, 'warn')
92
+ end
93
+
94
+ failing_checkers.each do |klass|
95
+ check_and_issue(klass, message, 'fail')
96
+ end
97
+ end
98
+ end
99
+
100
+ def check_and_issue(klass, message, severity)
101
+ c = klass.new(message, @config.fetch(klass.type, {}))
102
+ return unless c.fail?
103
+
104
+ messaging.issue([c.message, message[:sha]].join("\n"),
105
+ severity: severity)
106
+ end
107
+
108
+ def checkers
109
+ [
110
+ SubjectCapCheck,
111
+ SubjectWordsCheck,
112
+ SubjectLengthCheck,
113
+ SubjectPeriodCheck,
114
+ EmptyLineCheck
115
+ ]
116
+ end
117
+
118
+ def checks
119
+ checkers.map(&:type)
120
+ end
121
+
122
+ def enabled_checkers
123
+ checkers.reject { |klass| disabled_checks.include? klass.type }
124
+ end
125
+
126
+ def warning_checkers
127
+ enabled_checkers.select { |klass| warning_checks.include? klass.type }
128
+ end
129
+
130
+ def failing_checkers
131
+ enabled_checkers - warning_checkers
132
+ end
133
+
134
+ def all_checks_disabled?
135
+ @config[:disable] == :all || disabled_checks.count == checkers.count
136
+ end
137
+
138
+ def disabled_checks
139
+ @config[:disable] || []
140
+ end
141
+
142
+ def warning_checks
143
+ return checks if @config[:warn] == :all
144
+ @config[:warn] || []
145
+ end
146
+
147
+ def messages
148
+ git.commits.map do |commit|
149
+ (subject, empty_line) = commit.message.split("\n")
150
+ {
151
+ subject: subject,
152
+ empty_line: empty_line,
153
+ sha: commit.sha
154
+ }
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,3 @@
1
+ This folder copied and modified from
2
+ https://github.com/jonallured/danger-commit_lint
3
+ which is licensed under the MIT License
@@ -0,0 +1,19 @@
1
+
2
+ # frozen_string_literal: true
3
+
4
+ class CommitCheck
5
+ def self.fail?(message, options)
6
+ new(message, options || {}).fail?
7
+ end
8
+
9
+ def initialize(message, options = {})
10
+ end
11
+
12
+ def message
13
+ raise NotImplementedError, 'implement in subclass'
14
+ end
15
+
16
+ def fail?
17
+ raise NotImplementedError, 'implement in subclass'
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+
2
+ # frozen_string_literal: true
3
+
4
+ class EmptyLineCheck < CommitCheck
5
+ MESSAGE = 'Please separate subject from body with newline.'
6
+
7
+ def self.type
8
+ :empty_line
9
+ end
10
+
11
+ def initialize(message, _options = {})
12
+ @empty_line = message[:empty_line]
13
+ end
14
+
15
+ def message
16
+ MESSAGE
17
+ end
18
+
19
+ def fail?
20
+ @empty_line && !@empty_line.empty?
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+
2
+ # frozen_string_literal: true
3
+
4
+ class SubjectCapCheck < CommitCheck
5
+ MESSAGE = 'Please start subject with capital letter.'
6
+
7
+ def self.type
8
+ :subject_cap
9
+ end
10
+
11
+ def initialize(message, _options = {})
12
+ @first_character = message[:subject].split('').first
13
+ end
14
+
15
+ def message
16
+ MESSAGE
17
+ end
18
+
19
+ def fail?
20
+ @first_character != @first_character.upcase
21
+ end
22
+ end
@@ -0,0 +1,28 @@
1
+
2
+ # frozen_string_literal: true
3
+
4
+ class SubjectLengthCheck < CommitCheck
5
+ def self.type
6
+ :subject_length
7
+ end
8
+
9
+ def initialize(message, options = {})
10
+ @subject = message[:subject]
11
+ @max_length = options.fetch(:max, 50)
12
+ @min_length = options.fetch(:min, 1)
13
+ end
14
+
15
+ def message
16
+ if @subject.length > @max_length
17
+ "Please limit commit subject line to #{@max_length} characters."
18
+ else
19
+ "Please write a commit subject line of at least #{@min_length} "\
20
+ 'characters.'
21
+ end
22
+ end
23
+
24
+ def fail?
25
+ @subject.length > @max_length ||
26
+ @subject.length < @min_length
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+
2
+ # frozen_string_literal: true
3
+
4
+ class SubjectPeriodCheck < CommitCheck
5
+ MESSAGE = 'Please remove period from end of commit subject line.'
6
+
7
+ def self.type
8
+ :subject_period
9
+ end
10
+
11
+ def initialize(message, _options = {})
12
+ @subject = message[:subject]
13
+ end
14
+
15
+ def message
16
+ MESSAGE
17
+ end
18
+
19
+ def fail?
20
+ @subject.split('').last == '.'
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+
2
+ # frozen_string_literal: true
3
+
4
+ class SubjectWordsCheck < CommitCheck
5
+ MESSAGE = 'Please use more than one word.'
6
+
7
+ def self.type
8
+ :subject_words
9
+ end
10
+
11
+ def initialize(message, _options = {})
12
+ @subject = message[:subject]
13
+ end
14
+
15
+ def message
16
+ MESSAGE
17
+ end
18
+
19
+ def fail?
20
+ @subject.split.count < 2
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ {
2
+ "asi": true,
3
+ "expr": true,
4
+ "maxerr": 100
5
+ }
@@ -0,0 +1,131 @@
1
+ ---
2
+ Attribute:
3
+ enabled: true
4
+ exclude: []
5
+ BooleanParameter:
6
+ enabled: true
7
+ exclude: []
8
+ ClassVariable:
9
+ enabled: true
10
+ exclude: []
11
+ ControlParameter:
12
+ enabled: true
13
+ exclude: []
14
+ DataClump:
15
+ enabled: true
16
+ exclude: []
17
+ max_copies: 2
18
+ min_clump_size: 2
19
+ DuplicateMethodCall:
20
+ enabled: true
21
+ exclude: []
22
+ max_calls: 2
23
+ allow_calls: []
24
+ FeatureEnvy:
25
+ enabled: true
26
+ exclude: []
27
+ InstanceVariableAssumption:
28
+ enabled: true
29
+ exclude: []
30
+ IrresponsibleModule:
31
+ enabled: false
32
+ exclude: []
33
+ LongParameterList:
34
+ enabled: true
35
+ exclude: []
36
+ max_params: 3
37
+ overrides:
38
+ initialize:
39
+ max_params: 5
40
+ LongYieldList:
41
+ enabled: true
42
+ exclude: []
43
+ max_params: 3
44
+ ManualDispatch:
45
+ enabled: true
46
+ exclude: []
47
+ ModuleInitialize:
48
+ enabled: true
49
+ exclude: []
50
+ NestedIterators:
51
+ enabled: true
52
+ exclude: []
53
+ max_allowed_nesting: 1
54
+ ignore_iterators:
55
+ - tap
56
+ NilCheck:
57
+ enabled: true
58
+ exclude: []
59
+ PrimaDonnaMethod:
60
+ enabled: true
61
+ exclude: []
62
+ RepeatedConditional:
63
+ enabled: true
64
+ exclude: []
65
+ max_ifs: 2
66
+ SubclassedFromCoreClass:
67
+ enabled: true
68
+ exclude: []
69
+ Syntax:
70
+ enabled: true
71
+ exclude: []
72
+ TooManyConstants:
73
+ enabled: false
74
+ exclude: []
75
+ max_constants: 5
76
+ TooManyInstanceVariables:
77
+ enabled: false
78
+ exclude: []
79
+ max_instance_variables: 5
80
+ TooManyMethods:
81
+ enabled: false
82
+ exclude: []
83
+ max_methods: 15
84
+ TooManyStatements:
85
+ enabled: false
86
+ exclude:
87
+ - initialize
88
+ max_statements: 40
89
+ UncommunicativeMethodName:
90
+ enabled: true
91
+ exclude: []
92
+ reject:
93
+ - !ruby/regexp /^[a-z]$/
94
+ - !ruby/regexp /[0-9]$/
95
+ - !ruby/regexp /[A-Z]/
96
+ accept: []
97
+ UncommunicativeModuleName:
98
+ enabled: true
99
+ exclude: []
100
+ reject:
101
+ - !ruby/regexp /^.$/
102
+ - !ruby/regexp /[0-9]$/
103
+ accept: []
104
+ UncommunicativeParameterName:
105
+ enabled: true
106
+ exclude: []
107
+ reject:
108
+ - !ruby/regexp /^.$/
109
+ - !ruby/regexp /[0-9]$/
110
+ - !ruby/regexp /[A-Z]/
111
+ - !ruby/regexp /^_/
112
+ accept: []
113
+ UncommunicativeVariableName:
114
+ enabled: false
115
+ exclude: []
116
+ reject:
117
+ - !ruby/regexp /^.$/
118
+ - !ruby/regexp /[0-9]$/
119
+ - !ruby/regexp /[A-Z]/
120
+ accept:
121
+ - !ruby/regexp /^_$/
122
+ UnusedParameters:
123
+ enabled: true
124
+ exclude: []
125
+ UnusedPrivateMethod:
126
+ enabled: false
127
+ exclude: []
128
+ UtilityFunction:
129
+ enabled: true
130
+ exclude: []
131
+ public_methods_only: false