rubomatic-html 1.1.0.pre.rc.4 → 1.1.0.pre.rc.5
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/CHANGELOG.adoc +10 -1
- data/config/default.yml +28 -0
- data/docs/cops/style/README.adoc +9 -0
- data/docs/cops/style/no_fields_for/README.adoc +28 -0
- data/docs/cops/style/no_form_for/README.adoc +28 -0
- data/docs/cops/style/no_form_tag/README.adoc +28 -0
- data/docs/cops/style/no_on_before_unload/README.adoc +29 -0
- data/docs/cops/style/no_on_click/README.adoc +29 -0
- data/docs/cops/style/no_on_drag/README.adoc +29 -0
- data/docs/cops/style/no_on_load/README.adoc +29 -0
- data/docs/cops/style/no_on_unload/README.adoc +29 -0
- data/docs/cops/style/no_on_wheel/README.adoc +29 -0
- data/exe/rubomatic-html +1 -1
- data/lib/rubomatic-html/cop/base.rb +58 -0
- data/lib/rubomatic-html/cop/cops.rb +19 -0
- data/lib/rubomatic-html/cop/layout/base.rb +17 -0
- data/lib/rubomatic-html/cop/layout/line_length.rb +28 -0
- data/lib/rubomatic-html/cop/layout/multiple_line_breaks.rb +42 -0
- data/lib/rubomatic-html/cop/layout/trailing_whitespace.rb +28 -0
- data/lib/rubomatic-html/cop/style/base.rb +17 -0
- data/lib/rubomatic-html/cop/style/no_fields_for.rb +28 -0
- data/lib/rubomatic-html/cop/style/no_form_for.rb +28 -0
- data/lib/rubomatic-html/cop/style/no_form_tag.rb +28 -0
- data/lib/rubomatic-html/cop/style/no_on_attribute.rb +31 -0
- data/lib/rubomatic-html/cop/style/no_on_before_unload.rb +27 -0
- data/lib/rubomatic-html/cop/style/no_on_click.rb +27 -0
- data/lib/rubomatic-html/cop/style/no_on_drag.rb +27 -0
- data/lib/rubomatic-html/cop/style/no_on_load.rb +27 -0
- data/lib/rubomatic-html/cop/style/no_on_unload.rb +27 -0
- data/lib/rubomatic-html/cop/style/no_on_wheel.rb +27 -0
- data/lib/rubomatic-html/cop/style/partial_instance_variable.rb +44 -0
- data/lib/rubomatic-html/generator/cop_readme_injector.rb +48 -0
- data/lib/rubomatic-html/generator/dept_readme_injector.rb +111 -0
- data/lib/rubomatic-html/generator.rb +330 -0
- data/lib/rubomatic-html/inject.rb +19 -0
- data/lib/rubomatic-html/runner.rb +129 -0
- data/lib/rubomatic-html/version.rb +5 -0
- data/lib/rubomatic-html.rb +11 -1
- metadata +47 -18
- data/lib/rubomatic/html/cop/base.rb +0 -42
- data/lib/rubomatic/html/cop/cops.rb +0 -9
- data/lib/rubomatic/html/cop/layout/base.rb +0 -19
- data/lib/rubomatic/html/cop/layout/line_length.rb +0 -26
- data/lib/rubomatic/html/cop/layout/multiple_line_breaks.rb +0 -40
- data/lib/rubomatic/html/cop/layout/trailing_whitespace.rb +0 -26
- data/lib/rubomatic/html/cop/style/base.rb +0 -19
- data/lib/rubomatic/html/cop/style/partial_instance_variable.rb +0 -28
- data/lib/rubomatic/html/version.rb +0 -7
- data/lib/rubomatic/html.rb +0 -115
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubomaticHtml
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
class NoOnBeforeUnload < RubomaticHtml::Cop::Style::NoOnAttribute
|
|
7
|
+
class << self
|
|
8
|
+
# @see super
|
|
9
|
+
def abstract_cop?
|
|
10
|
+
false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @see super
|
|
14
|
+
def name
|
|
15
|
+
[department, 'NoOnBeforeUnload'].join('/')
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def initialize(...)
|
|
20
|
+
super(...)
|
|
21
|
+
|
|
22
|
+
@html_attr = 'onbeforeunload'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubomaticHtml
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
class NoOnClick < RubomaticHtml::Cop::Style::NoOnAttribute
|
|
7
|
+
class << self
|
|
8
|
+
# @see super
|
|
9
|
+
def abstract_cop?
|
|
10
|
+
false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @see super
|
|
14
|
+
def name
|
|
15
|
+
[department, 'NoOnClick'].join('/')
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def initialize(...)
|
|
20
|
+
super(...)
|
|
21
|
+
|
|
22
|
+
@html_attr = 'onclick'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubomaticHtml
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
class NoOnDrag < RubomaticHtml::Cop::Style::NoOnAttribute
|
|
7
|
+
class << self
|
|
8
|
+
# @see super
|
|
9
|
+
def abstract_cop?
|
|
10
|
+
false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @see super
|
|
14
|
+
def name
|
|
15
|
+
[department, 'NoOnDrag'].join('/')
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def initialize(...)
|
|
20
|
+
super(...)
|
|
21
|
+
|
|
22
|
+
@html_attr = 'ondrag'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubomaticHtml
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
class NoOnLoad < RubomaticHtml::Cop::Style::NoOnAttribute
|
|
7
|
+
class << self
|
|
8
|
+
# @see super
|
|
9
|
+
def abstract_cop?
|
|
10
|
+
false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @see super
|
|
14
|
+
def name
|
|
15
|
+
[department, 'NoOnLoad'].join('/')
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def initialize(...)
|
|
20
|
+
super(...)
|
|
21
|
+
|
|
22
|
+
@html_attr = 'onload'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubomaticHtml
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
class NoOnUnload < RubomaticHtml::Cop::Style::NoOnAttribute
|
|
7
|
+
class << self
|
|
8
|
+
# @see super
|
|
9
|
+
def abstract_cop?
|
|
10
|
+
false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @see super
|
|
14
|
+
def name
|
|
15
|
+
[department, 'NoOnUnload'].join('/')
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def initialize(...)
|
|
20
|
+
super(...)
|
|
21
|
+
|
|
22
|
+
@html_attr = 'onunload'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubomaticHtml
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
class NoOnWheel < RubomaticHtml::Cop::Style::NoOnAttribute
|
|
7
|
+
class << self
|
|
8
|
+
# @see super
|
|
9
|
+
def abstract_cop?
|
|
10
|
+
false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @see super
|
|
14
|
+
def name
|
|
15
|
+
[department, 'NoOnWheel'].join('/')
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def initialize(...)
|
|
20
|
+
super(...)
|
|
21
|
+
|
|
22
|
+
@html_attr = 'onwheel'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubomaticHtml
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
class PartialInstanceVariable < RubomaticHtml::Cop::Style::Base
|
|
7
|
+
class << self
|
|
8
|
+
# @see super
|
|
9
|
+
def abstract_cop?
|
|
10
|
+
false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @see super
|
|
14
|
+
def name
|
|
15
|
+
[department, 'PartialInstanceVariable'].join('/')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @see super
|
|
19
|
+
def allowed_config_transform
|
|
20
|
+
super.merge({ 'AllowedIdentifiers' => :allowed_identifiers }).freeze
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @see super
|
|
25
|
+
def run_for_line(line, index)
|
|
26
|
+
return unless File.basename(file).match?(/^_/i)
|
|
27
|
+
|
|
28
|
+
return unless line.match?(/@/i)
|
|
29
|
+
|
|
30
|
+
return if allowed_identifiers.any? { |ai| line[/@.+/].start_with?(ai) }
|
|
31
|
+
|
|
32
|
+
puts("#{file}:#{index}: uses an instance variable")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
# @return [Array<String>]
|
|
38
|
+
def allowed_identifiers
|
|
39
|
+
@allowed_identifiers ||= Array(config.dig(:allowed_identifiers))
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubomaticHtml
|
|
4
|
+
class Generator
|
|
5
|
+
class CopReadmeInjector < DeptReadmeInjector
|
|
6
|
+
TEMPLATE =
|
|
7
|
+
'* xref:./%{cop_folder}/README.adoc[``%{department}/%{cop}``]'
|
|
8
|
+
|
|
9
|
+
# :nodoc:
|
|
10
|
+
def initialize(badge:, **kwargs)
|
|
11
|
+
super(badge: badge, **kwargs)
|
|
12
|
+
|
|
13
|
+
@cop = badge.cop_name
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
# @return [String]
|
|
19
|
+
attr_reader :cop
|
|
20
|
+
|
|
21
|
+
# @see super
|
|
22
|
+
def new_readme_entry
|
|
23
|
+
format(TEMPLATE, {
|
|
24
|
+
department_folder: snake_case(department),
|
|
25
|
+
cop_folder: snake_case(cop),
|
|
26
|
+
department: department,
|
|
27
|
+
cop: cop
|
|
28
|
+
})
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @see super
|
|
32
|
+
def line_is_good?(line)
|
|
33
|
+
return true if super
|
|
34
|
+
|
|
35
|
+
matches = line.match(target_regex)
|
|
36
|
+
|
|
37
|
+
return false if matches.nil?
|
|
38
|
+
|
|
39
|
+
department == matches[:department] && cop < matches[:cop]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @see super
|
|
43
|
+
def target_regex
|
|
44
|
+
%r{\* xref:\./[a-z_]+/README\.adoc\[``(?<department>[a-zA-Z_]+)/(?<cop>[a-zA-Z_]+)``\]}
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubomaticHtml
|
|
4
|
+
class Generator
|
|
5
|
+
class DeptReadmeInjector
|
|
6
|
+
TEMPLATE = '* xref:./docs/cops/%{department_folder}/README.adoc[``%{department}``]'
|
|
7
|
+
|
|
8
|
+
# :nodoc:
|
|
9
|
+
def initialize(readme_file_path:, badge:, department:)
|
|
10
|
+
@readme_file_path = readme_file_path
|
|
11
|
+
@badge = badge
|
|
12
|
+
@department = department
|
|
13
|
+
@output = output
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Performs the actual string injection into the file
|
|
17
|
+
# modified version of `inject` from RuboCop::Cop::Generator::ConfigurationInjector
|
|
18
|
+
# Named `inject_string` becuase rubocop thought when called it was `Array#inject`
|
|
19
|
+
#
|
|
20
|
+
# @return [void]
|
|
21
|
+
#
|
|
22
|
+
def inject_string
|
|
23
|
+
if readme_entries.none?("#{new_readme_entry}\n")
|
|
24
|
+
target_line = find_target_line
|
|
25
|
+
|
|
26
|
+
if target_line
|
|
27
|
+
readme_entries.insert(target_line, "#{new_readme_entry}\n")
|
|
28
|
+
else
|
|
29
|
+
readme_entries.push(new_readme_entry)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
File.write(readme_file_path, readme_entries.join(''))
|
|
34
|
+
|
|
35
|
+
yield if block_given?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
# @return [String]
|
|
41
|
+
attr_reader :readme_file_path
|
|
42
|
+
# @return [RuboCop::Cop::Badge]
|
|
43
|
+
attr_reader :badge
|
|
44
|
+
# @return [String]
|
|
45
|
+
attr_reader :department
|
|
46
|
+
# @return [*] Default $stdout
|
|
47
|
+
attr_reader :output
|
|
48
|
+
|
|
49
|
+
# Lines in <department>/README.adoc
|
|
50
|
+
#
|
|
51
|
+
# @return [Array<String>]
|
|
52
|
+
#
|
|
53
|
+
def readme_entries
|
|
54
|
+
@readme_entries ||= File.readlines(readme_file_path)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Modified version from Rubocop::Cop::Generator::ConfigurationInjector
|
|
58
|
+
#
|
|
59
|
+
# @return [String]
|
|
60
|
+
#
|
|
61
|
+
def new_readme_entry
|
|
62
|
+
format(TEMPLATE, {
|
|
63
|
+
department_folder: snake_case(department),
|
|
64
|
+
department: department
|
|
65
|
+
})
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Modified version from Rubocop::Cop::Generator::ConfigurationInjector
|
|
69
|
+
#
|
|
70
|
+
# @return [Integer, Nil]
|
|
71
|
+
#
|
|
72
|
+
def find_target_line
|
|
73
|
+
readme_entries.find_index do |line|
|
|
74
|
+
line_is_good?(line)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Determines if the given line is the same type we're trying to add and if it's alphabetically before
|
|
79
|
+
#
|
|
80
|
+
# @return [Boolean]
|
|
81
|
+
#
|
|
82
|
+
def line_is_good?(line)
|
|
83
|
+
matches = line.match(target_regex)
|
|
84
|
+
|
|
85
|
+
return false if matches.nil?
|
|
86
|
+
|
|
87
|
+
department < line.match(target_regex)[:department]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Regex to look for in the readme
|
|
91
|
+
#
|
|
92
|
+
# @return [Regexp]
|
|
93
|
+
#
|
|
94
|
+
def target_regex
|
|
95
|
+
%r{\* xref:\./docs/cops/[a-z_]+/README\.adoc\[``(?<department>[a-zA-Z_]+)``\]}
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Copied from Rubocop::Cop::Generator
|
|
99
|
+
#
|
|
100
|
+
# @return [String]
|
|
101
|
+
#
|
|
102
|
+
def snake_case(camel_case_string)
|
|
103
|
+
camel_case_string
|
|
104
|
+
.gsub('RSpec', 'Rspec')
|
|
105
|
+
.gsub(%r{([^A-Z/])([A-Z]+)}, '\1_\2')
|
|
106
|
+
.gsub(%r{([A-Z])([A-Z][^A-Z\d/]+)}, '\1_\2')
|
|
107
|
+
.downcase
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'generator/dept_readme_injector'
|
|
4
|
+
# require_relative 'generator/require_file_injector'
|
|
5
|
+
|
|
6
|
+
require_relative 'generator/cop_readme_injector'
|
|
7
|
+
|
|
8
|
+
module RubomaticHtml
|
|
9
|
+
class Generator
|
|
10
|
+
COP_DOC = <<~RUBY
|
|
11
|
+
# TODO: Write cop description and example of bad / good code. For every
|
|
12
|
+
# `SupportedStyle` and unique configuration, there needs to be examples.
|
|
13
|
+
# Examples must have valid Ruby syntax. Do not use upticks.
|
|
14
|
+
#
|
|
15
|
+
# @safety
|
|
16
|
+
# Delete this section if the cop is not unsafe (`Safe: false` or
|
|
17
|
+
# `SafeAutoCorrect: false`), or use it to explain how the cop is
|
|
18
|
+
# unsafe.
|
|
19
|
+
#
|
|
20
|
+
# @example EnforcedStyle: bar (default)
|
|
21
|
+
# # Description of the `bar` style.
|
|
22
|
+
#
|
|
23
|
+
# # bad
|
|
24
|
+
# bad_bar_method
|
|
25
|
+
#
|
|
26
|
+
# # bad
|
|
27
|
+
# bad_bar_method(args)
|
|
28
|
+
#
|
|
29
|
+
# # good
|
|
30
|
+
# good_bar_method
|
|
31
|
+
#
|
|
32
|
+
# # good
|
|
33
|
+
# good_bar_method(args)
|
|
34
|
+
#
|
|
35
|
+
# @example EnforcedStyle: foo
|
|
36
|
+
# # Description of the `foo` style.
|
|
37
|
+
#
|
|
38
|
+
# # bad
|
|
39
|
+
# bad_foo_method
|
|
40
|
+
#
|
|
41
|
+
# # bad
|
|
42
|
+
# bad_foo_method(args)
|
|
43
|
+
#
|
|
44
|
+
# # good
|
|
45
|
+
# good_foo_method
|
|
46
|
+
#
|
|
47
|
+
# # good
|
|
48
|
+
# good_foo_method(args)
|
|
49
|
+
#
|
|
50
|
+
RUBY
|
|
51
|
+
SOURCE_TEMPLATE = <<~RUBY
|
|
52
|
+
# frozen_string_literal: true
|
|
53
|
+
|
|
54
|
+
module RubomaticHtml
|
|
55
|
+
module Cop
|
|
56
|
+
module %{department}
|
|
57
|
+
class %{cop_name} < RubomaticHtml::Cop::%{department}::Base
|
|
58
|
+
class << self
|
|
59
|
+
# @see super
|
|
60
|
+
def abstract_cop?
|
|
61
|
+
false
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# @see super
|
|
65
|
+
def name
|
|
66
|
+
[department, '%{cop_name}'].join('/')
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# @see super
|
|
71
|
+
def run_for_line(line, index)
|
|
72
|
+
# TODO: Implement the cop in here.
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
RUBY
|
|
79
|
+
SPEC_TEMPLATE = <<~SPEC
|
|
80
|
+
# frozen_string_literal: true
|
|
81
|
+
|
|
82
|
+
RSpec.describe RubomaticHtml::Cop::%{department}::%{cop_name}, :config do
|
|
83
|
+
let(:config) { RubomaticHtml::Config.new }
|
|
84
|
+
|
|
85
|
+
# TODO: Write test code
|
|
86
|
+
#
|
|
87
|
+
# For example
|
|
88
|
+
it 'registers an offense when using `#bad_method`' do
|
|
89
|
+
expect_offense(<<~RHTML)
|
|
90
|
+
bad_method
|
|
91
|
+
^^^^^^^^^^ Use `#good_method` instead of `#bad_method`.
|
|
92
|
+
RHTML
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it 'does not register an offense when using `#good_method`' do
|
|
96
|
+
expect_no_offenses(<<~RHTML)
|
|
97
|
+
good_method
|
|
98
|
+
RHTML
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
SPEC
|
|
102
|
+
README_ADDED_MESSAGE = '[modify] A link for the %{dept_vs_cop} has been added into %{readme_file_path}.'
|
|
103
|
+
|
|
104
|
+
DEPT_README_TEMPLATE = <<~ADOC
|
|
105
|
+
= %{department}
|
|
106
|
+
|
|
107
|
+
Describe the department here
|
|
108
|
+
|
|
109
|
+
== Cops
|
|
110
|
+
|
|
111
|
+
ADOC
|
|
112
|
+
COP_README_TEMPLATE = <<~ADOC
|
|
113
|
+
= ``%{department}/%{cop_name}``
|
|
114
|
+
|
|
115
|
+
== Description
|
|
116
|
+
|
|
117
|
+
Add a description here
|
|
118
|
+
|
|
119
|
+
== Examples
|
|
120
|
+
|
|
121
|
+
[source,rhtml]
|
|
122
|
+
----
|
|
123
|
+
<!-- Bad -->
|
|
124
|
+
<!-- Add a bad example here -->
|
|
125
|
+
|
|
126
|
+
<!-- Good -->
|
|
127
|
+
<!-- Add a good example here -->
|
|
128
|
+
----
|
|
129
|
+
|
|
130
|
+
== Configurable Attributes
|
|
131
|
+
|
|
132
|
+
|===
|
|
133
|
+
|Name |Default value |Configurable values
|
|
134
|
+
|
|
135
|
+
|Max
|
|
136
|
+
|120
|
|
137
|
+
|Integer
|
|
138
|
+
|
|
139
|
+
|===
|
|
140
|
+
|
|
141
|
+
== References
|
|
142
|
+
|
|
143
|
+
https://github.com/BrandsInsurance/expert-chainsaw/issues
|
|
144
|
+
ADOC
|
|
145
|
+
|
|
146
|
+
# :nodoc:
|
|
147
|
+
def initialize(name, output: $stdout)
|
|
148
|
+
@base_gen = RuboCop::Cop::Generator.new(name, output: output)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# @see RuboCop::Cop::generator method
|
|
152
|
+
def write_source
|
|
153
|
+
write_unless_file_exists(source_path, generated_source)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# @see RuboCop::Cop::generator method
|
|
157
|
+
def write_spec
|
|
158
|
+
write_unless_file_exists(spec_path, generated_spec)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# @see RuboCop::Cop::generator method
|
|
162
|
+
def generated_source
|
|
163
|
+
generate(SOURCE_TEMPLATE)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# @see RuboCop::Cop::generator method
|
|
167
|
+
def generated_spec
|
|
168
|
+
generate(SPEC_TEMPLATE)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# @see RuboCop::Cop::generator method
|
|
172
|
+
def source_path
|
|
173
|
+
File.join(
|
|
174
|
+
'lib',
|
|
175
|
+
'rubomatic-html',
|
|
176
|
+
'cop',
|
|
177
|
+
snake_case(badge.department.to_s),
|
|
178
|
+
"#{snake_case(badge.cop_name.to_s)}.rb"
|
|
179
|
+
)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# @see RuboCop::Cop::generator method
|
|
183
|
+
def spec_path
|
|
184
|
+
File.join(
|
|
185
|
+
'spec',
|
|
186
|
+
'rubomatic-html',
|
|
187
|
+
'cop',
|
|
188
|
+
snake_case(badge.department.to_s),
|
|
189
|
+
"#{snake_case(badge.cop_name.to_s)}_spec.rb"
|
|
190
|
+
)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# @see RuboCop::Cop::generator method
|
|
194
|
+
def inject_require(root_file_path:)
|
|
195
|
+
RuboCop::Cop::Generator::RequireFileInjector.new(source_path: source_path, root_file_path: root_file_path).inject
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Calls methods in the base class
|
|
199
|
+
#
|
|
200
|
+
# @return [*]
|
|
201
|
+
#
|
|
202
|
+
def method_missing(...)
|
|
203
|
+
@base_gen.__send__(...)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# `self` responds to `method_name` if `@base_gen` does
|
|
207
|
+
#
|
|
208
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
209
|
+
@base_gen.respond_to?(method_name, include_private)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# Creates the department readme if it doesn't exist
|
|
213
|
+
# Modified version of `wirte_source` from RuboCop::Cop::Generator
|
|
214
|
+
#
|
|
215
|
+
# @return [void]
|
|
216
|
+
#
|
|
217
|
+
def write_dept_readme
|
|
218
|
+
return if File.exist?(dept_docs_path)
|
|
219
|
+
|
|
220
|
+
write_unless_file_exists(dept_docs_path, generated_dept_docs)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Creates the cop readme if it doesn't exist
|
|
224
|
+
# Modified version of `wirte_source` from RuboCop::Cop::Generator
|
|
225
|
+
#
|
|
226
|
+
# @return [void]
|
|
227
|
+
#
|
|
228
|
+
def write_cop_readme
|
|
229
|
+
write_unless_file_exists(docs_path, generated_cop_docs)
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# Injects the, possibly new, department readme link into the base readme
|
|
233
|
+
# Modified version of `inject_config` from RuboCop::Cop::Generator
|
|
234
|
+
#
|
|
235
|
+
# @return [void]
|
|
236
|
+
#
|
|
237
|
+
def inject_dept_readme(readme_file_path: 'README.adoc')
|
|
238
|
+
# Add this dept to base readme if not already there
|
|
239
|
+
injector = DeptReadmeInjector.new(
|
|
240
|
+
readme_file_path: readme_file_path,
|
|
241
|
+
badge: badge,
|
|
242
|
+
department: department
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
injector.inject_string do
|
|
246
|
+
output.puts(format(README_ADDED_MESSAGE, readme_file_path: readme_file_path, dept_vs_cop: 'department'))
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Injects the new cop readme link into the department readme
|
|
251
|
+
# Modified version of `inject_config` from RuboCop::Cop::Generator
|
|
252
|
+
#
|
|
253
|
+
# @return [void]
|
|
254
|
+
#
|
|
255
|
+
def inject_cop_readme(readme_file_path: dept_docs_path)
|
|
256
|
+
# Add this cop to the dept readme
|
|
257
|
+
injector = CopReadmeInjector.new(
|
|
258
|
+
readme_file_path: readme_file_path,
|
|
259
|
+
badge: badge,
|
|
260
|
+
department: department
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
injector.inject_string do
|
|
264
|
+
output.puts(format(README_ADDED_MESSAGE, readme_file_path: readme_file_path, dept_vs_cop: 'cop'))
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
private
|
|
269
|
+
|
|
270
|
+
# @return [String]
|
|
271
|
+
def department
|
|
272
|
+
badge.department_name
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
# Modified version of `generated_source` from Rubocop::Cop::Generator
|
|
276
|
+
#
|
|
277
|
+
# @return [String]
|
|
278
|
+
#
|
|
279
|
+
def generated_dept_docs
|
|
280
|
+
generate_readme(DEPT_README_TEMPLATE)
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
# Modified version of `generated_source` from Rubocop::Cop::Generator
|
|
284
|
+
#
|
|
285
|
+
# @return [String]
|
|
286
|
+
#
|
|
287
|
+
def generated_cop_docs
|
|
288
|
+
generate_readme(COP_README_TEMPLATE)
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
# Modified version from Rubocop::Cop::Generator
|
|
292
|
+
#
|
|
293
|
+
# @return [String]
|
|
294
|
+
#
|
|
295
|
+
def generate_readme(template)
|
|
296
|
+
format(template, {
|
|
297
|
+
department: department,
|
|
298
|
+
cop_name: badge.cop_name,
|
|
299
|
+
cop_folder: snake_case(badge.cop_name.to_s)
|
|
300
|
+
})
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
# Path to <department>/README.adoc
|
|
304
|
+
#
|
|
305
|
+
# @return [String]
|
|
306
|
+
#
|
|
307
|
+
def dept_docs_path
|
|
308
|
+
File.join(
|
|
309
|
+
'docs',
|
|
310
|
+
'cops',
|
|
311
|
+
snake_case(department),
|
|
312
|
+
'README.adoc'
|
|
313
|
+
)
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
# Path to <department>/<cop>/README.adoc
|
|
317
|
+
#
|
|
318
|
+
# @return [String]
|
|
319
|
+
#
|
|
320
|
+
def docs_path
|
|
321
|
+
File.join(
|
|
322
|
+
'docs',
|
|
323
|
+
'cops',
|
|
324
|
+
snake_case(department),
|
|
325
|
+
snake_case(badge.cop_name.to_s),
|
|
326
|
+
'README.adoc'
|
|
327
|
+
)
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
end
|