rubomatic-html 1.1.0.pre.rc.3 → 1.1.0.pre.rc.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +10 -1
  3. data/config/default.yml +28 -0
  4. data/docs/cops/style/README.adoc +9 -0
  5. data/docs/cops/style/no_fields_for/README.adoc +28 -0
  6. data/docs/cops/style/no_form_for/README.adoc +28 -0
  7. data/docs/cops/style/no_form_tag/README.adoc +28 -0
  8. data/docs/cops/style/no_on_before_unload/README.adoc +29 -0
  9. data/docs/cops/style/no_on_click/README.adoc +29 -0
  10. data/docs/cops/style/no_on_drag/README.adoc +29 -0
  11. data/docs/cops/style/no_on_load/README.adoc +29 -0
  12. data/docs/cops/style/no_on_unload/README.adoc +29 -0
  13. data/docs/cops/style/no_on_wheel/README.adoc +29 -0
  14. data/exe/rubomatic-html +2 -3
  15. data/lib/rubomatic-html/cop/base.rb +58 -0
  16. data/lib/rubomatic-html/cop/cops.rb +19 -0
  17. data/lib/rubomatic-html/cop/layout/base.rb +17 -0
  18. data/lib/rubomatic-html/cop/layout/line_length.rb +28 -0
  19. data/lib/rubomatic-html/cop/layout/multiple_line_breaks.rb +42 -0
  20. data/lib/rubomatic-html/cop/layout/trailing_whitespace.rb +28 -0
  21. data/lib/rubomatic-html/cop/style/base.rb +17 -0
  22. data/lib/rubomatic-html/cop/style/no_fields_for.rb +28 -0
  23. data/lib/rubomatic-html/cop/style/no_form_for.rb +28 -0
  24. data/lib/rubomatic-html/cop/style/no_form_tag.rb +28 -0
  25. data/lib/rubomatic-html/cop/style/no_on_attribute.rb +31 -0
  26. data/lib/rubomatic-html/cop/style/no_on_before_unload.rb +27 -0
  27. data/lib/rubomatic-html/cop/style/no_on_click.rb +27 -0
  28. data/lib/rubomatic-html/cop/style/no_on_drag.rb +27 -0
  29. data/lib/rubomatic-html/cop/style/no_on_load.rb +27 -0
  30. data/lib/rubomatic-html/cop/style/no_on_unload.rb +27 -0
  31. data/lib/rubomatic-html/cop/style/no_on_wheel.rb +27 -0
  32. data/lib/rubomatic-html/cop/style/partial_instance_variable.rb +44 -0
  33. data/lib/rubomatic-html/generator/cop_readme_injector.rb +48 -0
  34. data/lib/rubomatic-html/generator/dept_readme_injector.rb +111 -0
  35. data/lib/rubomatic-html/generator.rb +330 -0
  36. data/lib/rubomatic-html/inject.rb +19 -0
  37. data/lib/rubomatic-html/runner.rb +129 -0
  38. data/lib/rubomatic-html/version.rb +5 -0
  39. data/lib/rubomatic-html.rb +11 -1
  40. metadata +47 -18
  41. data/lib/rubomatic/html/cop/base.rb +0 -42
  42. data/lib/rubomatic/html/cop/cops.rb +0 -9
  43. data/lib/rubomatic/html/cop/layout/base.rb +0 -19
  44. data/lib/rubomatic/html/cop/layout/line_length.rb +0 -26
  45. data/lib/rubomatic/html/cop/layout/multiple_line_breaks.rb +0 -40
  46. data/lib/rubomatic/html/cop/layout/trailing_whitespace.rb +0 -26
  47. data/lib/rubomatic/html/cop/style/base.rb +0 -19
  48. data/lib/rubomatic/html/cop/style/partial_instance_variable.rb +0 -28
  49. data/lib/rubomatic/html/version.rb +0 -7
  50. data/lib/rubomatic/html.rb +0 -115
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubomaticHtml
4
+ module Cop
5
+ module Style
6
+ class NoOnAttribute < RubomaticHtml::Cop::Style::Base
7
+ # @return [String]
8
+ attr_accessor :html_attr
9
+
10
+ # @see super
11
+ def run_for_line(line, index)
12
+ # `onclick:` or `onclick=`
13
+ has_on_click = line.match?(/#{html_attr}[:=]/i)
14
+
15
+ # `:onclick=>` or `:onclick =>`
16
+ has_on_click ||= line.match?(/:#{html_attr} ?=>/i)
17
+
18
+ # `'onclick'=>` or `'onclick' =>`
19
+ has_on_click ||= line.match?(/'#{html_attr}' ?=>/i)
20
+
21
+ # `"onclick"=>` or `"onclick" =>`
22
+ has_on_click ||= line.match?(/"#{html_attr}" ?=>/i)
23
+
24
+ return unless has_on_click
25
+
26
+ puts("#{file}:#{index}: might use an #{html_attr} attribute")
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -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