a11y-lint 0.1.0 → 0.2.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 +4 -4
- data/CHANGELOG.md +9 -0
- data/CLAUDE.md +2 -0
- data/README.md +25 -0
- data/exe/a11y-lint +7 -0
- data/lib/a11y/lint/cli.rb +103 -0
- data/lib/a11y/lint/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e12c6c589719fa574aecc86ff23ba8f3c2f9b3ae7f5d4da88bae60bbd3035735
|
|
4
|
+
data.tar.gz: c107e0d511e57a1cbbbb61ec62a28d3f704bb11e3dbea32851000146f3053a4c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 81a64d2d5a348f5341636124859d31a61f65d6e4fce0d4712bafae17092d7749d5b629aa7f2a7e4269bc54f6e5ce3ff4cbf60225b1ccbcf7f44375104eaa773c
|
|
7
|
+
data.tar.gz: bda106347b59bb146e5acc02937eae5d54c0649833c86e86982f6759b128c5fc7b8885b632ee00d6d0848c3746d8d7eb5e4a041b74e1916cc39e6921a57d3ab3
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.0] - 2026-03-27
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Command-line interface (`exe/a11y-lint`) for running the linter from the terminal
|
|
15
|
+
- Accepts file paths and directories as arguments
|
|
16
|
+
- Recursively scans for `.slim` files when given a directory (defaults to current directory)
|
|
17
|
+
- Supports `--version` and `--help` flags
|
|
18
|
+
|
|
10
19
|
## [0.1.0] - 2026-03-27
|
|
11
20
|
|
|
12
21
|
### Added
|
data/CLAUDE.md
CHANGED
|
@@ -14,10 +14,12 @@ a11y-lint is a Ruby gem (v0.1.0) for accessibility linting. It uses the `A11y::L
|
|
|
14
14
|
- **Run a single test file:** `bundle exec ruby -Ilib:test test/a11y/test_lint.rb`
|
|
15
15
|
- **Run a single test by name:** `bundle exec ruby -Ilib:test test/a11y/test_lint.rb -n test_name`
|
|
16
16
|
- **Run linter:** `bundle exec rake rubocop`
|
|
17
|
+
- **Run a11y-lint on files:** `bundle exec a11y-lint [file_or_directory ...]`
|
|
17
18
|
- **Interactive console with gem loaded:** `bin/console`
|
|
18
19
|
|
|
19
20
|
## Architecture
|
|
20
21
|
|
|
22
|
+
- **CLI:** `lib/a11y/lint/cli.rb` — command-line interface; executable at `exe/a11y-lint`
|
|
21
23
|
- **Entry point:** `lib/a11y/lint.rb` — defines the `A11y::Lint` module and `A11y::Lint::Error` exception
|
|
22
24
|
- **Version:** `lib/a11y/lint/version.rb`
|
|
23
25
|
- **Type signatures (RBS):** `sig/a11y/lint.rbs`
|
data/README.md
CHANGED
|
@@ -24,8 +24,33 @@ gem install a11y-lint
|
|
|
24
24
|
|
|
25
25
|
## Usage
|
|
26
26
|
|
|
27
|
+
### Command Line
|
|
28
|
+
|
|
29
|
+
Run the linter on specific files or directories:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
a11y-lint app/views/
|
|
33
|
+
a11y-lint app/views/home.html.slim app/views/about.html.slim
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
With no arguments, it scans the current directory recursively for `.slim` files:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
a11y-lint
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Ruby API
|
|
43
|
+
|
|
27
44
|
```ruby
|
|
28
45
|
require "a11y/lint"
|
|
46
|
+
|
|
47
|
+
source = File.read("app/views/home.html.slim")
|
|
48
|
+
runner = A11y::Lint::Runner.new([A11y::Lint::Rules::ImgMissingAlt.new])
|
|
49
|
+
offenses = runner.run(source, filename: "app/views/home.html.slim")
|
|
50
|
+
|
|
51
|
+
offenses.each do |offense|
|
|
52
|
+
puts "#{offense.filename}:#{offense.line} [#{offense.rule}] #{offense.message}"
|
|
53
|
+
end
|
|
29
54
|
```
|
|
30
55
|
|
|
31
56
|
## Requirements
|
data/exe/a11y-lint
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "optparse"
|
|
4
|
+
|
|
5
|
+
module A11y
|
|
6
|
+
module Lint
|
|
7
|
+
# Command-line interface for running accessibility linting on Slim templates.
|
|
8
|
+
class CLI
|
|
9
|
+
def initialize(argv, stdout: $stdout, stderr: $stderr)
|
|
10
|
+
@argv = argv
|
|
11
|
+
@stdout = stdout
|
|
12
|
+
@stderr = stderr
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def run
|
|
16
|
+
parse_options!
|
|
17
|
+
files = resolve_files(@argv)
|
|
18
|
+
|
|
19
|
+
if files.empty?
|
|
20
|
+
@stderr.puts("No .slim files found")
|
|
21
|
+
return 0
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
offenses = lint_files(files)
|
|
25
|
+
print_results(offenses)
|
|
26
|
+
|
|
27
|
+
offenses.empty? ? 0 : 1
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def parse_options!
|
|
33
|
+
option_parser.parse!(@argv)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def option_parser # rubocop:disable Metrics/MethodLength
|
|
37
|
+
OptionParser.new do |opts|
|
|
38
|
+
opts.banner = "Usage: a11y-lint [options] [file_or_directory ...]"
|
|
39
|
+
|
|
40
|
+
opts.on("-v", "--version", "Show version") do
|
|
41
|
+
@stdout.puts(A11y::Lint::VERSION)
|
|
42
|
+
exit 0
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
opts.on("-h", "--help", "Show help") do
|
|
46
|
+
@stdout.puts(opts)
|
|
47
|
+
exit 0
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def resolve_files(paths)
|
|
53
|
+
paths = ["."] if paths.empty?
|
|
54
|
+
paths.flat_map { |path| expand_path(path) }.sort
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def expand_path(path)
|
|
58
|
+
if File.directory?(path)
|
|
59
|
+
Dir.glob(File.join(path, "**", "*.slim"))
|
|
60
|
+
elsif File.file?(path)
|
|
61
|
+
[path]
|
|
62
|
+
else
|
|
63
|
+
@stderr.puts("Warning: #{path} not found, skipping")
|
|
64
|
+
[]
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def lint_files(files)
|
|
69
|
+
runner = Runner.new(all_rules)
|
|
70
|
+
|
|
71
|
+
files.flat_map do |file|
|
|
72
|
+
source = File.read(file)
|
|
73
|
+
runner.run(source, filename: file)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def all_rules
|
|
78
|
+
Rules.constants.filter_map do |name|
|
|
79
|
+
klass = Rules.const_get(name)
|
|
80
|
+
klass.new if klass.is_a?(Class) && klass < Rule
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def print_results(offenses)
|
|
85
|
+
offenses.each { |offense| print_offense(offense) }
|
|
86
|
+
@stdout.puts(summary_message(offenses.length))
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def print_offense(offense)
|
|
90
|
+
@stdout.puts(
|
|
91
|
+
"#{offense.filename}:#{offense.line} " \
|
|
92
|
+
"[#{offense.rule}] #{offense.message}"
|
|
93
|
+
)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def summary_message(count)
|
|
97
|
+
return "No offenses found" if count.zero?
|
|
98
|
+
|
|
99
|
+
"#{count} offense#{"s" unless count == 1} found"
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
data/lib/a11y/lint/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: a11y-lint
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Abdullah Hashim
|
|
@@ -26,7 +26,8 @@ dependencies:
|
|
|
26
26
|
description: A linter for checking accessibility issues in your code
|
|
27
27
|
email:
|
|
28
28
|
- abdul@hey.com
|
|
29
|
-
executables:
|
|
29
|
+
executables:
|
|
30
|
+
- a11y-lint
|
|
30
31
|
extensions: []
|
|
31
32
|
extra_rdoc_files: []
|
|
32
33
|
files:
|
|
@@ -38,7 +39,9 @@ files:
|
|
|
38
39
|
- LICENSE.txt
|
|
39
40
|
- README.md
|
|
40
41
|
- Rakefile
|
|
42
|
+
- exe/a11y-lint
|
|
41
43
|
- lib/a11y/lint.rb
|
|
44
|
+
- lib/a11y/lint/cli.rb
|
|
42
45
|
- lib/a11y/lint/node.rb
|
|
43
46
|
- lib/a11y/lint/offense.rb
|
|
44
47
|
- lib/a11y/lint/rule.rb
|