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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1cc893abebb39fdce9dcf7a2d1b7659734d7e27ebc5d88b166245c1baa2991a2
4
- data.tar.gz: 51da80a1ea01bf4650831ca95cb6439120ffc881b2f909b1aab3fe44db58e9f8
3
+ metadata.gz: e12c6c589719fa574aecc86ff23ba8f3c2f9b3ae7f5d4da88bae60bbd3035735
4
+ data.tar.gz: c107e0d511e57a1cbbbb61ec62a28d3f704bb11e3dbea32851000146f3053a4c
5
5
  SHA512:
6
- metadata.gz: ef6c52fc24bab87e5d1873d40eff8425e31128cfdecb933881c7f0d51abb15c2bd588299257e324468beb1c72fe2fd7666815facbae62a5a6e30f78e5fac40b8
7
- data.tar.gz: f3f78859233ba397931dc57dd228b87e36afbeff2856e9e13da304e3af05de97ce379e1628bec0a63078a6d8a190472401d67cc6d059db6c1e529c67290f66a2
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,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "a11y/lint"
5
+ require "a11y/lint/cli"
6
+
7
+ exit A11y::Lint::CLI.new(ARGV).run
@@ -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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module A11y
4
4
  module Lint
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
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.1.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