erblint-github 0.3.1 → 0.4.0

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 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