rubocop-neeto 0.1.19 → 0.1.20
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/README.md +6 -0
- data/config/default.yml +63 -0
- data/lib/rubocop/cop/neeto/direct_liquid_render.rb +47 -0
- data/lib/rubocop/cop/neeto/html_in_string_literal.rb +77 -0
- data/lib/rubocop/cop/neeto/html_safe_on_dynamic_string.rb +75 -0
- data/lib/rubocop/cop/neeto/html_translation_interpolation.rb +93 -0
- data/lib/rubocop/cop/neeto_cops.rb +4 -0
- data/lib/rubocop/neeto/version.rb +1 -1
- metadata +8 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a80cf5441b3f2e8a557f1ab80f1c33f234fd0964051e0c4ba3082ed6ad4ec038
|
|
4
|
+
data.tar.gz: ed16bab4d596c2741d0205e1a3904c9207574564df4481b7aae7fac5541427f1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f34434c7395250edfac2c36e73f719bbcf80f37443945e9a6e1fc31958dc1736aba5c3705eeea4f5fd455e72022e2f1e7465ce9810fc72e32a757840aaed0840
|
|
7
|
+
data.tar.gz: 4c4e0f22d50814ceb614509f44218e0733a3466eccb7674d29cc200fed15e9bed465e99c1e8f0d91d2f0a548cccb5c060b3ab65cbf98011e0d7f6aed01f73869
|
data/README.md
CHANGED
|
@@ -7,6 +7,12 @@
|
|
|
7
7
|
3. [Neeto/DirectEnvAccess](https://rubocop-neeto.neetodeployapp.com/docs/RuboCop/Cop/Neeto/DirectEnvAccess)
|
|
8
8
|
4. [Neeto/DeprecatedJobBaseClass](https://rubocop-neeto.neetodeployapp.com/docs/RuboCop/Cop/Neeto/DeprecatedJobBaseClass)
|
|
9
9
|
5. [Neeto/FaradayOverHttparty](https://rubocop-neeto.neetodeployapp.com/docs/RuboCop/Cop/Neeto/FaradayOverHttparty)
|
|
10
|
+
6. [Neeto/HtmlSafeOnDynamicString](https://rubocop-neeto.neetodeployapp.com/docs/RuboCop/Cop/Neeto/HtmlSafeOnDynamicString)
|
|
11
|
+
7. [Neeto/HtmlInStringLiteral](https://rubocop-neeto.neetodeployapp.com/docs/RuboCop/Cop/Neeto/HtmlInStringLiteral)
|
|
12
|
+
8. [Neeto/DirectLiquidRender](https://rubocop-neeto.neetodeployapp.com/docs/RuboCop/Cop/Neeto/DirectLiquidRender)
|
|
13
|
+
9. [Neeto/HtmlTranslationInterpolation](https://rubocop-neeto.neetodeployapp.com/docs/RuboCop/Cop/Neeto/HtmlTranslationInterpolation)
|
|
14
|
+
|
|
15
|
+
The HTML-safety cops (6 to 9) report at `Severity: info` while products migrate, so they show in editors and CI output without failing the build. They move to `Severity: error` once every product is migrated.
|
|
10
16
|
|
|
11
17
|
## Installation
|
|
12
18
|
|
data/config/default.yml
CHANGED
|
@@ -64,3 +64,66 @@ Neeto/FaradayOverHttparty:
|
|
|
64
64
|
Include:
|
|
65
65
|
- '**/Gemfile'
|
|
66
66
|
- '**/Gemfile.common.rb'
|
|
67
|
+
|
|
68
|
+
Neeto/HtmlSafeOnDynamicString:
|
|
69
|
+
Description: >-
|
|
70
|
+
`html_safe`, `raw` and `safe_concat` mark a string as already safe, so
|
|
71
|
+
Rails emits it without escaping. Calling them on dynamic values
|
|
72
|
+
(interpolation, method results, variables) turns off output escaping for
|
|
73
|
+
that value. Build markup with `tag`, `content_tag`, `link_to`, `mail_to`
|
|
74
|
+
or `safe_join` instead, or annotate a reviewed call with
|
|
75
|
+
`# neeto:html-safe-reviewed <reason>`.
|
|
76
|
+
Enabled: true
|
|
77
|
+
Severity: info
|
|
78
|
+
VersionAdded: '0.1'
|
|
79
|
+
Include:
|
|
80
|
+
- app/**/*.rb
|
|
81
|
+
- lib/**/*.rb
|
|
82
|
+
- app/views/**/*.erb
|
|
83
|
+
- app/views/**/*.inky
|
|
84
|
+
|
|
85
|
+
Neeto/HtmlInStringLiteral:
|
|
86
|
+
Description: >-
|
|
87
|
+
Plain Ruby strings never escape what is interpolated into them. Build
|
|
88
|
+
markup outside views with `tag`, `content_tag`, `link_to`, `mail_to`,
|
|
89
|
+
`safe_join` or a partial instead of string literals and heredocs.
|
|
90
|
+
Enabled: true
|
|
91
|
+
Severity: info
|
|
92
|
+
VersionAdded: '0.1'
|
|
93
|
+
Include:
|
|
94
|
+
- app/**/*.rb
|
|
95
|
+
- lib/**/*.rb
|
|
96
|
+
Exclude:
|
|
97
|
+
- app/views/**/*
|
|
98
|
+
- lib/tasks/**/*
|
|
99
|
+
|
|
100
|
+
Neeto/DirectLiquidRender:
|
|
101
|
+
Description: >-
|
|
102
|
+
`Liquid::Template#render` does not escape its output. Build and render
|
|
103
|
+
Liquid templates only through `NeetoCommonsBackend::LiquidRenderer`, which
|
|
104
|
+
escapes every output and requires an explicit format (`:html` or `:text`).
|
|
105
|
+
Check a template's syntax with `NeetoCommonsBackend::LiquidRenderer.validate!`.
|
|
106
|
+
Enabled: true
|
|
107
|
+
Severity: info
|
|
108
|
+
VersionAdded: '0.1'
|
|
109
|
+
Include:
|
|
110
|
+
- app/**/*.rb
|
|
111
|
+
- lib/**/*.rb
|
|
112
|
+
|
|
113
|
+
Neeto/HtmlTranslationInterpolation:
|
|
114
|
+
Description: >-
|
|
115
|
+
`I18n.t` does not escape interpolated values, even for `_html` keys. A
|
|
116
|
+
translation that contains HTML must not interpolate unescaped values.
|
|
117
|
+
Escape each value with `ERB::Util.html_escape`, or keep the markup out of
|
|
118
|
+
the translation and build it with `tag` or `content_tag`.
|
|
119
|
+
Enabled: true
|
|
120
|
+
Severity: info
|
|
121
|
+
VersionAdded: '0.1'
|
|
122
|
+
LocaleFiles:
|
|
123
|
+
- config/locales/en.yml
|
|
124
|
+
Include:
|
|
125
|
+
- app/**/*.rb
|
|
126
|
+
- lib/**/*.rb
|
|
127
|
+
Exclude:
|
|
128
|
+
- app/views/**/*
|
|
129
|
+
- lib/tasks/**/*
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Neeto
|
|
6
|
+
# `Liquid::Template#render` does not escape its output, so every variable
|
|
7
|
+
# reaches the page or email as-is. Render Liquid through the shared
|
|
8
|
+
# renderer, which escapes every output and requires an explicit format.
|
|
9
|
+
# Code that only checks a template's syntax uses `validate!`, which raises
|
|
10
|
+
# `Liquid::SyntaxError` like `Liquid::Template.parse` does.
|
|
11
|
+
#
|
|
12
|
+
# @example DirectLiquidRender: true (default)
|
|
13
|
+
# # bad
|
|
14
|
+
# Liquid::Template.parse(template.body).render(variables)
|
|
15
|
+
#
|
|
16
|
+
# # good
|
|
17
|
+
# NeetoCommonsBackend::LiquidRenderer.render(template.body, variables, format: :html)
|
|
18
|
+
#
|
|
19
|
+
# # good
|
|
20
|
+
# NeetoCommonsBackend::LiquidRenderer.render(template.subject, variables, format: :text)
|
|
21
|
+
#
|
|
22
|
+
# # bad
|
|
23
|
+
# Liquid::Template.parse(metadata["body"])
|
|
24
|
+
#
|
|
25
|
+
# # good
|
|
26
|
+
# NeetoCommonsBackend::LiquidRenderer.validate!(metadata["body"])
|
|
27
|
+
#
|
|
28
|
+
class DirectLiquidRender < Base
|
|
29
|
+
MSG = "Do not use `Liquid::Template.%<method>s` directly. Render with " \
|
|
30
|
+
"`NeetoCommonsBackend::LiquidRenderer.render(template, variables, format: :html)`, which escapes " \
|
|
31
|
+
"every output, or check syntax with `NeetoCommonsBackend::LiquidRenderer.validate!(template)`."
|
|
32
|
+
|
|
33
|
+
RESTRICT_ON_SEND = %i[parse new].freeze
|
|
34
|
+
|
|
35
|
+
def_node_matcher :liquid_template_build?, <<~PATTERN
|
|
36
|
+
(send (const (const {nil? cbase} :Liquid) :Template) {:parse :new} ...)
|
|
37
|
+
PATTERN
|
|
38
|
+
|
|
39
|
+
def on_send(node)
|
|
40
|
+
return unless liquid_template_build?(node)
|
|
41
|
+
|
|
42
|
+
add_offense(node, message: format(MSG, method: node.method_name))
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Neeto
|
|
6
|
+
# Ruby strings never escape what is interpolated into them, so HTML built
|
|
7
|
+
# in a string or heredoc outside views is one missed escape away from an
|
|
8
|
+
# injection. Build markup with `tag`, `content_tag`, `link_to`,
|
|
9
|
+
# `mail_to`, `safe_join` or a partial, which escape their arguments.
|
|
10
|
+
#
|
|
11
|
+
# @example HtmlInStringLiteral: true (default)
|
|
12
|
+
# # bad
|
|
13
|
+
# "<a href='#{url}'>#{name}</a>"
|
|
14
|
+
#
|
|
15
|
+
# # bad
|
|
16
|
+
# <<~HTML
|
|
17
|
+
# <p>#{description}</p>
|
|
18
|
+
# HTML
|
|
19
|
+
#
|
|
20
|
+
# # good
|
|
21
|
+
# link_to(name, url)
|
|
22
|
+
#
|
|
23
|
+
# # good
|
|
24
|
+
# tag.p(description)
|
|
25
|
+
#
|
|
26
|
+
# # good (searching for markup is not building it)
|
|
27
|
+
# body.include?("<table")
|
|
28
|
+
#
|
|
29
|
+
class HtmlInStringLiteral < Base
|
|
30
|
+
MSG = "Do not build HTML in Ruby strings. Use `tag`, `content_tag`, `link_to`, `mail_to`, `safe_join` " \
|
|
31
|
+
"or a partial, which escape their arguments."
|
|
32
|
+
|
|
33
|
+
HTML_TAG = %r{<(?:[a-z][a-z0-9]*[\s/>]|/[a-z][a-z0-9]*\s*>)}i
|
|
34
|
+
FORMAT_REFERENCE = /%<\w+>/
|
|
35
|
+
|
|
36
|
+
ENCLOSING_LITERAL_TYPES = %i[dstr dsym xstr regexp].freeze
|
|
37
|
+
|
|
38
|
+
SEARCH_METHODS = %i[
|
|
39
|
+
include? start_with? end_with? index rindex match match? split scan count delete
|
|
40
|
+
gsub gsub! sub sub! == != eql?
|
|
41
|
+
].freeze
|
|
42
|
+
|
|
43
|
+
def on_str(node)
|
|
44
|
+
return if part_of_another_literal?(node)
|
|
45
|
+
|
|
46
|
+
check(node, node.value)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def on_dstr(node)
|
|
50
|
+
return if part_of_another_literal?(node)
|
|
51
|
+
|
|
52
|
+
check(node, node.each_child_node(:str).map(&:value).join)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def check(node, value)
|
|
58
|
+
return unless value.valid_encoding? && HTML_TAG.match?(value.gsub(FORMAT_REFERENCE, ""))
|
|
59
|
+
return if search_argument?(node)
|
|
60
|
+
|
|
61
|
+
add_offense(node)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def part_of_another_literal?(node)
|
|
65
|
+
ENCLOSING_LITERAL_TYPES.include?(node.parent&.type)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def search_argument?(node)
|
|
69
|
+
parent = node.parent
|
|
70
|
+
return false unless parent&.call_type? && SEARCH_METHODS.include?(parent.method_name)
|
|
71
|
+
|
|
72
|
+
parent.first_argument.equal?(node) || (parent.comparison_method? && parent.receiver.equal?(node))
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Neeto
|
|
6
|
+
# `html_safe`, `raw` and `safe_concat` mark a string as already safe, so
|
|
7
|
+
# Rails prints it without escaping. Calling them on a dynamic value
|
|
8
|
+
# (interpolation, a method result, a variable) turns escaping off for
|
|
9
|
+
# whatever that value holds, which lets user input inject markup. Build
|
|
10
|
+
# markup with `tag`, `content_tag`, `link_to`, `mail_to` or `safe_join`
|
|
11
|
+
# instead. A call that has been reviewed can be kept by adding
|
|
12
|
+
# `# neeto:html-safe-reviewed <reason>` on or above it.
|
|
13
|
+
#
|
|
14
|
+
# @example HtmlSafeOnDynamicString: true (default)
|
|
15
|
+
# # bad
|
|
16
|
+
# "<b>#{booking.name}</b>".html_safe
|
|
17
|
+
#
|
|
18
|
+
# # bad
|
|
19
|
+
# raw(message.body)
|
|
20
|
+
#
|
|
21
|
+
# # good
|
|
22
|
+
# tag.b(booking.name)
|
|
23
|
+
#
|
|
24
|
+
# # good
|
|
25
|
+
# "<br>".html_safe
|
|
26
|
+
#
|
|
27
|
+
# # good
|
|
28
|
+
# # neeto:html-safe-reviewed admin-authored rich text
|
|
29
|
+
# meeting.cancellation_policy.html_safe
|
|
30
|
+
#
|
|
31
|
+
class HtmlSafeOnDynamicString < Base
|
|
32
|
+
MSG = "Do not call `%<method>s` on a dynamic value. Build the markup with `tag`, `content_tag`, " \
|
|
33
|
+
"`link_to`, `mail_to` or `safe_join`, or add `# neeto:html-safe-reviewed <reason>` if the value " \
|
|
34
|
+
"is known to be safe."
|
|
35
|
+
|
|
36
|
+
REVIEWED_ANNOTATION = /#\s*neeto:html-safe-reviewed\s+\S/
|
|
37
|
+
|
|
38
|
+
RESTRICT_ON_SEND = %i[html_safe raw safe_concat].freeze
|
|
39
|
+
|
|
40
|
+
def on_send(node)
|
|
41
|
+
value = trusted_value(node)
|
|
42
|
+
return if value.nil? || static_string?(value) || reviewed?(node)
|
|
43
|
+
|
|
44
|
+
add_offense(node.loc.selector, message: format(MSG, method: node.method_name))
|
|
45
|
+
end
|
|
46
|
+
alias on_csend on_send
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def trusted_value(node)
|
|
51
|
+
case node.method_name
|
|
52
|
+
when :html_safe
|
|
53
|
+
node.receiver if node.arguments.none?
|
|
54
|
+
when :raw
|
|
55
|
+
node.first_argument if node.receiver.nil? && node.arguments.one?
|
|
56
|
+
when :safe_concat
|
|
57
|
+
node.first_argument if node.arguments.one?
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def static_string?(node)
|
|
62
|
+
node.str_type? || (node.dstr_type? && node.children.all? { |child| static_string?(child) })
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def reviewed?(node)
|
|
66
|
+
lines = (node.first_line - 1)..node.last_line
|
|
67
|
+
|
|
68
|
+
processed_source.comments.any? do |comment|
|
|
69
|
+
lines.cover?(comment.loc.line) && REVIEWED_ANNOTATION.match?(comment.text)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "yaml"
|
|
4
|
+
|
|
5
|
+
module RuboCop
|
|
6
|
+
module Cop
|
|
7
|
+
module Neeto
|
|
8
|
+
# `I18n.t` does not escape interpolated values, even for `_html` keys
|
|
9
|
+
# (only the view helper `t` does). A translation that contains HTML and
|
|
10
|
+
# interpolates an unescaped value outside a view lets that value inject
|
|
11
|
+
# markup. The cop reads the translations from `LocaleFiles`.
|
|
12
|
+
#
|
|
13
|
+
# @example HtmlTranslationInterpolation: true (default)
|
|
14
|
+
# # en.yml
|
|
15
|
+
# # seed:
|
|
16
|
+
# # description: "<p>Schedule a meeting with %{name}</p>"
|
|
17
|
+
#
|
|
18
|
+
# # bad
|
|
19
|
+
# I18n.t("seed.description", name: user.name)
|
|
20
|
+
#
|
|
21
|
+
# # good
|
|
22
|
+
# I18n.t("seed.description", name: ERB::Util.html_escape(user.name))
|
|
23
|
+
#
|
|
24
|
+
# # good
|
|
25
|
+
# tag.p(I18n.t("seed.description_text", name: user.name))
|
|
26
|
+
#
|
|
27
|
+
class HtmlTranslationInterpolation < Base
|
|
28
|
+
MSG = "Translation `%<key>s` contains HTML and interpolates %<variables>s, which `I18n.t` does not " \
|
|
29
|
+
"escape. Escape each value with `ERB::Util.html_escape`, or keep the markup out of the translation " \
|
|
30
|
+
"and build it with `tag` or `content_tag`."
|
|
31
|
+
|
|
32
|
+
RESTRICT_ON_SEND = %i[t translate].freeze
|
|
33
|
+
OPTIONS = %i[locale scope default raise throw count].freeze
|
|
34
|
+
|
|
35
|
+
def_node_matcher :translation_call, <<~PATTERN
|
|
36
|
+
(send {nil? (const {nil? cbase} :I18n)} {:t :translate} (str $_) $...)
|
|
37
|
+
PATTERN
|
|
38
|
+
|
|
39
|
+
def_node_matcher :escaped_value?, <<~PATTERN
|
|
40
|
+
(send {nil? (const (const {nil? cbase} :ERB) :Util)} {:html_escape :h} _)
|
|
41
|
+
PATTERN
|
|
42
|
+
|
|
43
|
+
def self.translations_cache
|
|
44
|
+
@_translations_cache ||= {}
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def on_send(node)
|
|
48
|
+
translation_call(node) do |key, arguments|
|
|
49
|
+
options = arguments.last
|
|
50
|
+
next unless options&.hash_type?
|
|
51
|
+
|
|
52
|
+
translation = translations[key]
|
|
53
|
+
next unless translation.is_a?(String) && HtmlInStringLiteral::HTML_TAG.match?(translation)
|
|
54
|
+
|
|
55
|
+
variables = unescaped_variables(options).select { |name| translation.include?("%{#{name}}") }
|
|
56
|
+
next if variables.empty?
|
|
57
|
+
|
|
58
|
+
add_offense(node, message: format(MSG, key:, variables: variables.map { |name| "%{#{name}}" }.join(", ")))
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
def unescaped_variables(options)
|
|
65
|
+
options.pairs.filter_map do |pair|
|
|
66
|
+
next unless pair.key.sym_type?
|
|
67
|
+
next if OPTIONS.include?(pair.key.value) || escaped_value?(pair.value)
|
|
68
|
+
|
|
69
|
+
pair.key.value.to_s
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def translations
|
|
74
|
+
self.class.translations_cache[locale_files] ||= locale_files.each_with_object({}) do |path, result|
|
|
75
|
+
next unless File.exist?(path)
|
|
76
|
+
|
|
77
|
+
YAML.safe_load_file(path, aliases: true)&.each_value { |tree| flatten(tree, nil, result) }
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def locale_files
|
|
82
|
+
Array(cop_config["LocaleFiles"]).map { |path| File.expand_path(path, config.base_dir_for_path_parameters) }
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def flatten(tree, prefix, result)
|
|
86
|
+
return result[prefix] = tree unless tree.is_a?(Hash)
|
|
87
|
+
|
|
88
|
+
tree.each { |key, value| flatten(value, [prefix, key].compact.join("."), result) }
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -5,3 +5,7 @@ require_relative "neeto/unsafe_column_deletion"
|
|
|
5
5
|
require_relative "neeto/direct_env_access"
|
|
6
6
|
require_relative "neeto/deprecated_job_base_class"
|
|
7
7
|
require_relative "neeto/faraday_over_httparty"
|
|
8
|
+
require_relative "neeto/html_safe_on_dynamic_string"
|
|
9
|
+
require_relative "neeto/html_in_string_literal"
|
|
10
|
+
require_relative "neeto/direct_liquid_render"
|
|
11
|
+
require_relative "neeto/html_translation_interpolation"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rubocop-neeto
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.20
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
7
|
+
- Neeraj Singh
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-10-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rubocop
|
|
@@ -26,7 +26,7 @@ dependencies:
|
|
|
26
26
|
version: '0'
|
|
27
27
|
description:
|
|
28
28
|
email:
|
|
29
|
-
-
|
|
29
|
+
- neeraj@neeto.com
|
|
30
30
|
executables: []
|
|
31
31
|
extensions: []
|
|
32
32
|
extra_rdoc_files: []
|
|
@@ -37,7 +37,11 @@ files:
|
|
|
37
37
|
- lib/rubocop-neeto.rb
|
|
38
38
|
- lib/rubocop/cop/neeto/deprecated_job_base_class.rb
|
|
39
39
|
- lib/rubocop/cop/neeto/direct_env_access.rb
|
|
40
|
+
- lib/rubocop/cop/neeto/direct_liquid_render.rb
|
|
40
41
|
- lib/rubocop/cop/neeto/faraday_over_httparty.rb
|
|
42
|
+
- lib/rubocop/cop/neeto/html_in_string_literal.rb
|
|
43
|
+
- lib/rubocop/cop/neeto/html_safe_on_dynamic_string.rb
|
|
44
|
+
- lib/rubocop/cop/neeto/html_translation_interpolation.rb
|
|
41
45
|
- lib/rubocop/cop/neeto/unsafe_column_deletion.rb
|
|
42
46
|
- lib/rubocop/cop/neeto/unsafe_table_deletion.rb
|
|
43
47
|
- lib/rubocop/cop/neeto_cops.rb
|