erblint-github 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 625ce68b5e4d109bc1ddc27921ba6fc52d0d27fab2b23b9ebed9f0af92d1a523
4
- data.tar.gz: '08302ed91e755eea56d05d7d1fb7d30403929f7cb943e7042b0ae43ecfb137f6'
3
+ metadata.gz: d329206d7b3c42304a1279e5077122c74757ce8959272c1c76bd870559becc0a
4
+ data.tar.gz: e0d34fb46bc77014dd2124fbab66af6bffe1385cd381b0c2e54a4520d5b02876
5
5
  SHA512:
6
- metadata.gz: 15b5b10a2edd73c90f01a3e803dceee6f2afccf38c2810b4e70327f5b88ffa6d0d0ee4570e5aa190fa6483fcd3d0ee34924b391b4e390ccba2b4ca86319493e4
7
- data.tar.gz: 50d4c0c8f6059ed88b66b08d6c4ccbe6e795087ffee0bc5a3fc45327ddacc750178317c355a8e742f0aa2f0d4024b3ce19c00bc9e5eed4408ef20470211f387b
6
+ metadata.gz: 2893fe01bc4fa5f16be61698646f649c5098eeefa4268be7f69ee7ef7bd3c7fbe4a6b4f5c09ecfeedbba3441c62e96ae767253d1058171b00c92c7f88992aedd
7
+ data.tar.gz: 0a3cbff707c22df4bbcb4e6da28e86ad9f2d46cbe0cc61a241a7f163e584846eaa671639a736a32efdfc90463f8abb14c45069b7f71aaea2fd3467f0812a86a2
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # erblint-github
2
+
2
3
  Template style checking for GitHub's Ruby projects
3
4
 
4
5
  ## Setup
@@ -10,49 +11,19 @@ gem "erb_lint", require: false
10
11
  gem "erblint-github"
11
12
  ```
12
13
 
13
- 2. Require the linters within the `.erb-linters` folder. This could be done by adding a file `.erb-linters/erblint-github.rb` with the following line.
14
+ 2. Require the lint rules from this library. Currently, the only supported way is to add a new file in `.erb-linters/erblint-github.rb` with the line:
14
15
 
15
16
  ```ruby
16
17
  require "erblint-github/linters"
17
18
  ```
18
19
 
19
- 3. Update the `erb-lint.yml` to configure the rule.
20
-
21
- ### .erb-lint.yml
20
+ 3. Update your `erb-lint.yml` to pull in our recommended configs. This will ensure you are up-to-date with our recommendations.
22
21
 
23
- ```yaml
22
+ ```yaml
24
23
  ---
25
- linters:
26
- GitHub::Accessibility::AriaLabelIsWellFormatted:
27
- enabled: true
28
- GitHub::Accessibility::AvoidBothDisabledAndAriaDisabled:
29
- enabled: true
30
- GitHub::Accessibility::AvoidGenericLinkText:
31
- enabled: true
32
- GitHub::Accessibility::DisabledAttribute:
33
- enabled: true
34
- GitHub::Accessibility::IframeHasTitle:
35
- enabled: true
36
- GitHub::Accessibility::ImageHasAlt:
37
- enabled: true
38
- GitHub::Accessibility::NavigationHasLabel:
39
- enabled: true
40
- GitHub::Accessibility::LinkHasHref:
41
- enabled: true
42
- GitHub::Accessibility::NestedInteractiveElements:
43
- enabled: true
44
- GitHub::Accessibility::NoAriaHiddenOnFocusable:
45
- enabled: true
46
- GitHub::Accessibility::NoAriaLabelMisuse:
47
- enabled: true
48
- GitHub::Accessibility::NoPositiveTabIndex:
49
- enabled: true
50
- GitHub::Accessibility::NoRedundantImageAlt:
51
- enabled: true
52
- GitHub::Accessibility::NoTitleAttribute:
53
- enabled: true
54
- GitHub::Accessibility::SvgHasAccessibleText:
55
- enabled: true
24
+ inherit_gem:
25
+ erblint-github:
26
+ - config/accessibility.yml
56
27
  ```
57
28
 
58
29
  ## Rules
@@ -73,34 +44,6 @@ linters:
73
44
  - [GitHub::Accessibility::NoTitleAttribute](./docs/rules/accessibility/no-title-attribute.md)
74
45
  - [GitHub::Accessibility::SvgHasAccessibleText](./docs/rules/accessibility/svg-has-accessible-text.md)
75
46
 
76
- ## Disabling a rule (Deprecated)
77
-
78
- _This is a soon-to-be deprecated feature. Do not use. See [migration guide](./docs/counter-migration-guide.md)_
79
-
80
- `erblint` does not natively support rule disables. At GitHub, we've implemented these rules in a way to allow rules to be disabled at an offense-level via counters or disabled at a file-level because often times, we want to enable a rule but aren't able to address all offenses at once. We achieve this in one of two ways.
81
-
82
- Rules that are marked as `Counter` can be disabled by adding a comment with the offense count that matches the number of offenses within the file like:
83
-
84
- ```.html.erb
85
- <%# erblint:counter GitHub::Accessibility::LinkHasHrefCounter 1 %>
86
- ```
87
-
88
- In this comment example, when a new `LinkHasHref` offense has been added, the counter will need to be bumped up to 2. More recent rules use a `Counter` format.
89
-
90
- If you are enabling a rule for the first time and your codebase has a lot of offenses, you can use the `-a` command to automatically add these counter comments in the appropriate places.
91
-
92
- ```
93
- bundle exec erblint app/views app/components -a
94
- ```
95
-
96
- Rules that are not marked as `Counter` like `NoRedundantImageAlt` are considered to be legacy format. We are in the process of migrating these to counters. These rules can still be disabled at the file-level by adding this comment at the top of the file:
97
-
98
- ```.html.erb
99
- <%# erblint:disable GitHub::Accessibility::NoRedundantImageAlt %>
100
- ```
101
-
102
- However, unlike a counter, any subsequent offenses introduced to the file will not raise.
103
-
104
47
  ## Testing
105
48
 
106
49
  ```
@@ -0,0 +1,32 @@
1
+ ---
2
+ linters:
3
+ GitHub::Accessibility::AriaLabelIsWellFormatted:
4
+ enabled: true
5
+ GitHub::Accessibility::AvoidBothDisabledAndAriaDisabled:
6
+ enabled: true
7
+ GitHub::Accessibility::AvoidGenericLinkText:
8
+ enabled: true
9
+ GitHub::Accessibility::DisabledAttribute:
10
+ enabled: true
11
+ GitHub::Accessibility::IframeHasTitle:
12
+ enabled: true
13
+ GitHub::Accessibility::ImageHasAlt:
14
+ enabled: true
15
+ GitHub::Accessibility::NavigationHasLabel:
16
+ enabled: true
17
+ GitHub::Accessibility::LinkHasHref:
18
+ enabled: true
19
+ GitHub::Accessibility::NestedInteractiveElements:
20
+ enabled: true
21
+ GitHub::Accessibility::NoAriaHiddenOnFocusable:
22
+ enabled: true
23
+ GitHub::Accessibility::NoAriaLabelMisuse:
24
+ enabled: true
25
+ GitHub::Accessibility::NoPositiveTabIndex:
26
+ enabled: true
27
+ GitHub::Accessibility::NoRedundantImageAlt:
28
+ enabled: true
29
+ GitHub::Accessibility::NoTitleAttribute:
30
+ enabled: true
31
+ GitHub::Accessibility::SvgHasAccessibleText:
32
+ enabled: true
@@ -8,39 +8,6 @@ module ERBLint
8
8
  module CustomHelpers
9
9
  INTERACTIVE_ELEMENTS = %w[button summary input select textarea a].freeze
10
10
 
11
- def counter_correct?(processed_source)
12
- comment_node = nil
13
- expected_count = 0
14
- rule_name = simple_class_name
15
- offenses_count = @offenses.length
16
-
17
- processed_source.parser.ast.descendants(:erb).each do |node|
18
- indicator_node, _, code_node, = *node
19
- indicator = indicator_node&.loc&.source
20
- comment = code_node&.loc&.source&.strip
21
-
22
- if indicator == "#" && comment.start_with?("erblint:counter") && comment.match(rule_name)
23
- comment_node = node
24
- expected_count = comment.match(/\s(\d+)\s?$/)[1].to_i
25
- end
26
- end
27
-
28
- if offenses_count.zero?
29
- # have to adjust to get `\n` so we delete the whole line
30
- add_offense(processed_source.to_source_range(comment_node.loc.adjust(end_pos: 1)), "Unused erblint:counter comment for #{rule_name}", "") if comment_node
31
- return
32
- end
33
-
34
- first_offense = @offenses[0]
35
-
36
- if comment_node.nil?
37
- add_offense(processed_source.to_source_range(first_offense.source_range), "#{rule_name}: If you must, add <%# erblint:disable #{rule_name} %> at the end of the offending line to bypass this check. See https://github.com/shopify/erb-lint#disable-rule-at-offense-level", "<%# erblint:disable #{rule_name} %>")
38
- else
39
- clear_offenses
40
- add_offense(processed_source.to_source_range(comment_node.loc), "Incorrect erblint:counter number for #{rule_name}. Expected: #{expected_count}, actual: #{offenses_count}.", "<%# erblint:counter #{rule_name}Counter #{offenses_count} %>") if expected_count != offenses_count
41
- end
42
- end
43
-
44
11
  def generate_offense(klass, processed_source, tag, message = nil, replacement = nil)
45
12
  message ||= klass::MESSAGE
46
13
  message += "\nLearn more at https://github.com/github/erblint-github#rules.\n"
@@ -13,11 +13,6 @@ module ERBLint
13
13
  ELEMENTS_WITH_NATIVE_DISABLED_ATTRIBUTE_SUPPORT = %w[button fieldset input optgroup option select textarea].freeze
14
14
  MESSAGE = "[aria-disabled] may be used in place of native HTML [disabled] to allow tab-focus on an otherwise ignored element. Setting both attributes is contradictory."
15
15
 
16
- class ConfigSchema < LinterConfig
17
- property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
18
- end
19
- self.config_schema = ConfigSchema
20
-
21
16
  def run(processed_source)
22
17
  tags(processed_source).each do |tag|
23
18
  next if tag.closing?
@@ -26,10 +21,6 @@ module ERBLint
26
21
 
27
22
  generate_offense(self.class, processed_source, tag)
28
23
  end
29
-
30
- if @config.counter_enabled?
31
- counter_correct?(processed_source)
32
- end
33
24
  end
34
25
  end
35
26
  end
@@ -22,11 +22,6 @@ module ERBLint
22
22
 
23
23
  MESSAGE = "Avoid using generic link text such as #{BANNED_GENERIC_TEXT.join(', ')} which do not make sense in isolation."
24
24
 
25
- class ConfigSchema < LinterConfig
26
- property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
27
- end
28
- self.config_schema = ConfigSchema
29
-
30
25
  def run(processed_source)
31
26
  processed_source.ast.children.each_with_index do |node, index|
32
27
  next unless node.methods.include?(:type) && node.type == :text
@@ -98,9 +93,6 @@ module ERBLint
98
93
  banned_text = nil
99
94
  end
100
95
  end
101
- if @config.counter_enabled?
102
- counter_correct?(processed_source)
103
- end
104
96
  end
105
97
 
106
98
  private
@@ -13,16 +13,6 @@ module ERBLint
13
13
  VALID_DISABLED_TAGS = %w[button input textarea option select fieldset optgroup task-lists].freeze
14
14
  MESSAGE = "`disabled` is only valid on #{VALID_DISABLED_TAGS.join(', ')}."
15
15
 
16
- class ConfigSchema < LinterConfig
17
- property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
18
- end
19
- self.config_schema = ConfigSchema
20
-
21
- class ConfigSchema < LinterConfig
22
- property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
23
- end
24
- self.config_schema = ConfigSchema
25
-
26
16
  def run(processed_source)
27
17
  tags(processed_source).each do |tag|
28
18
  next if tag.closing?
@@ -31,10 +21,6 @@ module ERBLint
31
21
 
32
22
  generate_offense(self.class, processed_source, tag)
33
23
  end
34
-
35
- if @config.counter_enabled?
36
- counter_correct?(processed_source)
37
- end
38
24
  end
39
25
  end
40
26
  end
@@ -13,11 +13,6 @@ module ERBLint
13
13
  MESSAGE = "`<iframe>` with meaningful content should have a title attribute that identifies the content."\
14
14
  " If `<iframe>` has no meaningful content, hide it from assistive technology with `aria-hidden='true'`."\
15
15
 
16
- class ConfigSchema < LinterConfig
17
- property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
18
- end
19
- self.config_schema = ConfigSchema
20
-
21
16
  def run(processed_source)
22
17
  tags(processed_source).each do |tag|
23
18
  next if tag.name != "iframe"
@@ -27,10 +22,6 @@ module ERBLint
27
22
 
28
23
  generate_offense(self.class, processed_source, tag) if title.empty? && !aria_hidden?(tag)
29
24
  end
30
-
31
- if @config.counter_enabled?
32
- counter_correct?(processed_source)
33
- end
34
25
  end
35
26
 
36
27
  private
@@ -12,11 +12,6 @@ module ERBLint
12
12
 
13
13
  MESSAGE = "<img> should have an alt prop with meaningful text or an empty string for decorative images"
14
14
 
15
- class ConfigSchema < LinterConfig
16
- property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
17
- end
18
- self.config_schema = ConfigSchema
19
-
20
15
  def run(processed_source)
21
16
  tags(processed_source).each do |tag|
22
17
  next if tag.name != "img"
@@ -26,10 +21,6 @@ module ERBLint
26
21
 
27
22
  generate_offense(self.class, processed_source, tag) if alt.empty?
28
23
  end
29
-
30
- if @config.counter_enabled?
31
- counter_correct?(processed_source)
32
- end
33
24
  end
34
25
  end
35
26
  end
@@ -12,11 +12,6 @@ module ERBLint
12
12
 
13
13
  MESSAGE = "Links should go somewhere, you probably want to use a `<button>` instead."
14
14
 
15
- class ConfigSchema < LinterConfig
16
- property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
17
- end
18
- self.config_schema = ConfigSchema
19
-
20
15
  def run(processed_source)
21
16
  tags(processed_source).each do |tag|
22
17
  next if tag.name != "a"
@@ -26,10 +21,6 @@ module ERBLint
26
21
  name = tag.attributes["name"]
27
22
  generate_offense(self.class, processed_source, tag) if (!name && href.empty?) || href.include?("#")
28
23
  end
29
-
30
- if @config.counter_enabled?
31
- counter_correct?(processed_source)
32
- end
33
24
  end
34
25
  end
35
26
  end
@@ -12,10 +12,6 @@ module ERBLint
12
12
 
13
13
  MESSAGE = "Nesting interactive elements produces invalid HTML, and ssistive technologies, such as screen readers, might ignore or respond unexpectedly to such nested controls."
14
14
 
15
- class ConfigSchema < LinterConfig
16
- property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
17
- end
18
- self.config_schema = ConfigSchema
19
15
  def run(processed_source)
20
16
  last_interactive_element = nil
21
17
  tags(processed_source).each do |tag|
@@ -34,10 +30,6 @@ module ERBLint
34
30
 
35
31
  last_interactive_element = tag unless tag&.name == "input"
36
32
  end
37
-
38
- if @config.counter_enabled?
39
- counter_correct?(processed_source)
40
- end
41
33
  end
42
34
  end
43
35
  end
@@ -12,20 +12,11 @@ module ERBLint
12
12
 
13
13
  MESSAGE = "Elements that are focusable should not have `aria-hidden='true' because it will cause confusion for assistive technology users."
14
14
 
15
- class ConfigSchema < LinterConfig
16
- property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
17
- end
18
- self.config_schema = ConfigSchema
19
-
20
15
  def run(processed_source)
21
16
  tags(processed_source).each do |tag|
22
17
  aria_hidden = possible_attribute_values(tag, "aria-hidden")
23
18
  generate_offense(self.class, processed_source, tag) if aria_hidden.include?("true") && focusable?(tag)
24
19
  end
25
-
26
- if @config.counter_enabled?
27
- counter_correct?(processed_source)
28
- end
29
20
  end
30
21
  end
31
22
  end
@@ -18,11 +18,6 @@ module ERBLint
18
18
 
19
19
  MESSAGE = "[aria-label] and [aria-labelledby] usage are only reliably supported on interactive elements and a subset of ARIA roles"
20
20
 
21
- class ConfigSchema < LinterConfig
22
- property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
23
- end
24
- self.config_schema = ConfigSchema
25
-
26
21
  def run(processed_source)
27
22
  tags(processed_source).each do |tag|
28
23
  next if tag.closing?
@@ -39,9 +34,6 @@ module ERBLint
39
34
  end
40
35
  end
41
36
  end
42
- if @config.counter_enabled?
43
- counter_correct?(processed_source)
44
- end
45
37
  end
46
38
  end
47
39
  end
@@ -12,11 +12,6 @@ module ERBLint
12
12
 
13
13
  MESSAGE = "Do not use positive tabindex as it is error prone and can severely disrupt navigation experience for keyboard users"
14
14
 
15
- class ConfigSchema < LinterConfig
16
- property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
17
- end
18
- self.config_schema = ConfigSchema
19
-
20
15
  def run(processed_source)
21
16
  tags(processed_source).each do |tag|
22
17
  next if tag.closing?
@@ -24,10 +19,6 @@ module ERBLint
24
19
 
25
20
  generate_offense(self.class, processed_source, tag)
26
21
  end
27
-
28
- if @config.counter_enabled?
29
- counter_correct?(processed_source)
30
- end
31
22
  end
32
23
  end
33
24
  end
@@ -13,11 +13,6 @@ module ERBLint
13
13
  MESSAGE = "<img> alt prop should not contain `image` or `picture` as screen readers already announce the element as an image"
14
14
  REDUNDANT_ALT_WORDS = %w[image picture].freeze
15
15
 
16
- class ConfigSchema < LinterConfig
17
- property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
18
- end
19
- self.config_schema = ConfigSchema
20
-
21
16
  def run(processed_source)
22
17
  tags(processed_source).each do |tag|
23
18
  next if tag.name != "img"
@@ -28,10 +23,6 @@ module ERBLint
28
23
 
29
24
  generate_offense(self.class, processed_source, tag) if (alt.downcase.split & REDUNDANT_ALT_WORDS).any?
30
25
  end
31
-
32
- if @config.counter_enabled?
33
- counter_correct?(processed_source)
34
- end
35
26
  end
36
27
  end
37
28
  end
@@ -12,11 +12,6 @@ module ERBLint
12
12
 
13
13
  MESSAGE = "The title attribute should never be used unless for an `<iframe>` as it is inaccessible for several groups of users."
14
14
 
15
- class ConfigSchema < LinterConfig
16
- property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
17
- end
18
- self.config_schema = ConfigSchema
19
-
20
15
  def run(processed_source)
21
16
  tags(processed_source).each do |tag|
22
17
  next if tag.name == "iframe"
@@ -25,10 +20,6 @@ module ERBLint
25
20
  title = possible_attribute_values(tag, "title")
26
21
  generate_offense(self.class, processed_source, tag) if title.present?
27
22
  end
28
-
29
- if @config.counter_enabled?
30
- counter_correct?(processed_source)
31
- end
32
23
  end
33
24
  end
34
25
  end
@@ -12,11 +12,6 @@ module ERBLint
12
12
 
13
13
  MESSAGE = "`<svg>` must have accessible text. Set `aria-label`, or `aria-labelledby`, or nest a `<title>` element. However, if the `<svg>` is purely decorative, hide it with `aria-hidden='true'.\nFor more info, see https://css-tricks.com/accessible-svgs/."
14
14
 
15
- class ConfigSchema < LinterConfig
16
- property :counter_enabled, accepts: [true, false], default: false, reader: :counter_enabled?
17
- end
18
- self.config_schema = ConfigSchema
19
-
20
15
  def run(processed_source)
21
16
  current_svg = nil
22
17
  has_accessible_label = false
@@ -41,10 +36,6 @@ module ERBLint
41
36
  has_accessible_label = aria_label.present? || aria_labelledby.present?
42
37
  end
43
38
  end
44
-
45
- if @config.counter_enabled?
46
- counter_correct?(processed_source)
47
- end
48
39
  end
49
40
  end
50
41
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: erblint-github
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub Open Source
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-18 00:00:00.000000000 Z
11
+ date: 2023-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: erb_lint
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.3.0
19
+ version: 0.4.0
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.3.0
26
+ version: 0.4.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - '='
74
74
  - !ruby/object:Gem::Version
75
- version: 1.49.0
75
+ version: 1.52.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
- version: 1.49.0
82
+ version: 1.52.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rubocop-github
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -103,6 +103,7 @@ extra_rdoc_files: []
103
103
  files:
104
104
  - LICENSE
105
105
  - README.md
106
+ - config/accessibility.yml
106
107
  - lib/erblint-github/linters.rb
107
108
  - lib/erblint-github/linters/custom_helpers.rb
108
109
  - lib/erblint-github/linters/github/accessibility/aria_label_is_well_formatted.rb