heckler 0.0.1
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 +7 -0
- data/.standard.yml +3 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +44 -0
- data/Rakefile +16 -0
- data/exe/heckler +6 -0
- data/heckler.json +10 -0
- data/lib/heckler/aspell.rb +47 -0
- data/lib/heckler/checker/file_system.rb +91 -0
- data/lib/heckler/cli.rb +50 -0
- data/lib/heckler/config.rb +86 -0
- data/lib/heckler/personn.rb +0 -0
- data/lib/heckler/preset.rb +20 -0
- data/lib/heckler/presets/base.stub +98 -0
- data/lib/heckler/version.rb +5 -0
- data/lib/heckler.rb +11 -0
- data/sig/heckler.rbs +4 -0
- metadata +66 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 605da338e5d75dfc3615fd7255390559228de9223cea8c4696a7781f64b7d33f
|
4
|
+
data.tar.gz: 067dfae307730437b0d5bae6a90e06f9033ab0f479469234d11da2dde64bff92
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0e84e49df096985d552c49bd91d9bae548904174d743c5ca6288884e9494ce4be5e5a4601f900b967334500b376e113c719888fbaa91ace5a02ef405b955d8bc
|
7
|
+
data.tar.gz: 3b1f705402cb5e522ee4f47d8652947ac1cb56b6e1d2ff539e2fd9d616b15e55a497f173295acbc917d58464fa79e9ab37e35fb03426b8871fad9cb4facfa12e
|
data/.standard.yml
ADDED
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2025 Stanislav (Stas) Katkov
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Heckler
|
2
|
+
|
3
|
+
**Heckler** is a tool to identify wording or spelling mistakes in ruby codebase: filenames, class names, method names, property names and more. Spelling correction is powered by [GNU Aspell](https://en.wikipedia.org/wiki/GNU_Aspell) and originally started as a ruby port of [Peck](https://github.com/peckphp/peck).
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
```bash
|
8
|
+
bundle add heckler
|
9
|
+
```
|
10
|
+
|
11
|
+
If bundler is not being used to manage dependencies, install the gem by executing:
|
12
|
+
|
13
|
+
```bash
|
14
|
+
gem install heckler
|
15
|
+
```
|
16
|
+
|
17
|
+
## Dependencies
|
18
|
+
Heckler requires Aspell to be present on a system to function.
|
19
|
+
|
20
|
+
### MacOS
|
21
|
+
`brew install aspell`
|
22
|
+
|
23
|
+
### Linux
|
24
|
+
- Debian/Ubuntu: `sudo apt-get install aspell aspell-en`
|
25
|
+
- Fedora: `sudo dnf install aspell aspell-en`
|
26
|
+
- Arch Linux: `sudo pacman -S aspell aspell-en`
|
27
|
+
- openSUSE: `sudo zypper install aspell aspell-en`
|
28
|
+
- Alpine: `sudo apk add aspell aspell-en`
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
Start off by creating a configuration file, by running:
|
33
|
+
`heckler init`
|
34
|
+
|
35
|
+
Run spelling check with `heckler`
|
36
|
+
|
37
|
+
|
38
|
+
## Contributing
|
39
|
+
|
40
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/skatkov/heckler.
|
41
|
+
|
42
|
+
## License
|
43
|
+
|
44
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "minitest/test_task"
|
5
|
+
|
6
|
+
Minitest::TestTask.create
|
7
|
+
|
8
|
+
require "standard/rake"
|
9
|
+
|
10
|
+
task default: %i[test standard]
|
11
|
+
|
12
|
+
desc "Build and install gem locally"
|
13
|
+
task :local_install do
|
14
|
+
system "gem build heckler.gemspec"
|
15
|
+
system "gem install ./heckler-#{Heckler::VERSION}.gem"
|
16
|
+
end
|
data/exe/heckler
ADDED
data/heckler.json
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require "open3"
|
2
|
+
require_relative "config"
|
3
|
+
|
4
|
+
Misspelling = Data.define(:word, :suggestions)
|
5
|
+
|
6
|
+
module Heckler
|
7
|
+
class Aspell
|
8
|
+
@process = nil
|
9
|
+
|
10
|
+
def initialize(config)
|
11
|
+
@config = config
|
12
|
+
end
|
13
|
+
|
14
|
+
def check(text)
|
15
|
+
misspellings = get_misspellings(text)
|
16
|
+
misspellings.reject { |misspelling| @config.word_ignored?(misspelling.word) }
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def get_misspellings(text)
|
22
|
+
misspellings = run(text)
|
23
|
+
misspellings
|
24
|
+
end
|
25
|
+
|
26
|
+
def take_suggestions(suggestions)
|
27
|
+
suggestions = suggestions.select { |suggestion| suggestion.match(/[^a-zA-Z]/).nil? }
|
28
|
+
suggestions.uniq
|
29
|
+
end
|
30
|
+
|
31
|
+
def run(text)
|
32
|
+
stdin, stdout, stderr, wait_thr = Open3.popen3("aspell", "--encoding", "utf-8", "-a", "--ignore-case", "--lang=en_US", "--sug-mode=ultra")
|
33
|
+
stdin.puts text
|
34
|
+
stdin.close
|
35
|
+
output = stdout.read
|
36
|
+
stdout.close
|
37
|
+
stderr.close
|
38
|
+
|
39
|
+
output.lines.select { |line| line.start_with?("&") }.map do |line|
|
40
|
+
word_metadata, suggestions = line.strip.split(":")
|
41
|
+
word = word_metadata.split(" ")[1]
|
42
|
+
suggestions = suggestions.strip.split(", ")
|
43
|
+
Misspelling.new(word, take_suggestions(suggestions))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require_relative "../aspell"
|
2
|
+
|
3
|
+
require "find"
|
4
|
+
|
5
|
+
# The Checker::FileSystem class provides functionality to check spelling in file and directory names within a given directory structure.
|
6
|
+
#
|
7
|
+
# Usage:
|
8
|
+
# checker = Checker::FileSystem.new
|
9
|
+
# issues = checker.check("/path/to/directory")
|
10
|
+
#
|
11
|
+
# The check method:
|
12
|
+
# - Recursively traverses the given directory
|
13
|
+
# - Skips hidden files/directories (starting with .)
|
14
|
+
# - Skips .git directories
|
15
|
+
# - Checks spelling of each file/directory name
|
16
|
+
# - Returns an array of Issue objects containing any misspellings found
|
17
|
+
#
|
18
|
+
# Each Issue object contains:
|
19
|
+
# - The misspelling that was found
|
20
|
+
# - The full path to the file/directory
|
21
|
+
# - The line number (always 0 for filenames)
|
22
|
+
module Heckler
|
23
|
+
class Checker
|
24
|
+
class FileSystem
|
25
|
+
def initialize(config, spellchecker)
|
26
|
+
@config = config
|
27
|
+
@spellchecker = spellchecker
|
28
|
+
end
|
29
|
+
|
30
|
+
def check(directory)
|
31
|
+
files_or_directories = []
|
32
|
+
Find.find(directory) do |path|
|
33
|
+
next if File.basename(path).start_with?(".")
|
34
|
+
next if File.fnmatch("*/.git/*", path)
|
35
|
+
|
36
|
+
files_or_directories << path
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
files_or_directories.sort_by! { |path| File.realpath(path) }
|
41
|
+
|
42
|
+
puts files_or_directories
|
43
|
+
|
44
|
+
issues = []
|
45
|
+
|
46
|
+
files_or_directories.each do |file_or_directory|
|
47
|
+
name = SpellcheckFormatter.format(File.basename(file_or_directory, ".*"))
|
48
|
+
new_issues = @spellchecker.check(name).map do |misspelling|
|
49
|
+
Issue.new(misspelling, File.realpath(file_or_directory), 0)
|
50
|
+
end
|
51
|
+
|
52
|
+
issues.concat(new_issues)
|
53
|
+
end
|
54
|
+
|
55
|
+
issues
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class SpellcheckFormatter
|
61
|
+
def self.format(input)
|
62
|
+
# Remove leading underscores
|
63
|
+
input = input.gsub(/^_+/, "")
|
64
|
+
|
65
|
+
# Replace underscores and dashes with spaces
|
66
|
+
input = input.tr("_-", " ")
|
67
|
+
|
68
|
+
# Insert spaces between lowercase and uppercase letters (camelCase or PascalCase)
|
69
|
+
input = input.gsub(/([a-z])([A-Z])/, '\1 \2')
|
70
|
+
|
71
|
+
# Split sequences of uppercase letters, ensuring the last uppercase letter starts a new word
|
72
|
+
input = input.gsub(/([A-Z]+)([A-Z][a-z])/, '\1 \2')
|
73
|
+
|
74
|
+
# Replace multiple spaces with a single space
|
75
|
+
input = input.gsub(/\s+/, " ")
|
76
|
+
|
77
|
+
# Convert the final result to lowercase
|
78
|
+
input.downcase
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class Issue
|
83
|
+
attr_reader :misspelling, :file, :line
|
84
|
+
|
85
|
+
def initialize(misspelling, file, line)
|
86
|
+
@misspelling = misspelling
|
87
|
+
@file = file
|
88
|
+
@line = line
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/heckler/cli.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
require_relative "config"
|
4
|
+
require_relative "aspell"
|
5
|
+
require_relative "preset"
|
6
|
+
require_relative "checker/file_system"
|
7
|
+
|
8
|
+
|
9
|
+
module Heckler
|
10
|
+
class Runner
|
11
|
+
attr_reader :checkers
|
12
|
+
|
13
|
+
def initialize(checkers)
|
14
|
+
@checkers = checkers
|
15
|
+
end
|
16
|
+
|
17
|
+
def run(directory)
|
18
|
+
issues = []
|
19
|
+
|
20
|
+
puts directory
|
21
|
+
|
22
|
+
@checkers.each do |checker|
|
23
|
+
issues.concat(checker.check(directory))
|
24
|
+
end
|
25
|
+
|
26
|
+
issues
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class CLI
|
31
|
+
def self.start(args)
|
32
|
+
command = args.shift
|
33
|
+
|
34
|
+
case command
|
35
|
+
when 'init'
|
36
|
+
Config.init
|
37
|
+
when nil
|
38
|
+
config = Config.instance
|
39
|
+
aspell = Aspell.new(config)
|
40
|
+
|
41
|
+
Runner.new([
|
42
|
+
Heckler::Checker::FileSystem.new(config, aspell)
|
43
|
+
]).run(Dir.pwd)
|
44
|
+
else
|
45
|
+
puts "Unknown command: #{command}"
|
46
|
+
puts "Available commands: init, or no command for default behavior"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require "json"
|
2
|
+
require "singleton"
|
3
|
+
require_relative "preset"
|
4
|
+
|
5
|
+
module Heckler
|
6
|
+
class Config
|
7
|
+
include Singleton
|
8
|
+
|
9
|
+
JSON_CONFIGURATION_NAME = "heckler.json".freeze
|
10
|
+
|
11
|
+
attr_accessor :whitelisted_words, :whitelisted_paths, :preset
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@whitelisted_words = []
|
15
|
+
@whitelisted_paths = []
|
16
|
+
@preset = nil
|
17
|
+
load_config
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.flush
|
21
|
+
instance.whitelisted_words = []
|
22
|
+
instance.whitelisted_paths = []
|
23
|
+
instance.preset = nil
|
24
|
+
@resolve_config_file_path_using = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.exists?
|
28
|
+
File.exist?(Dir.pwd + "/" + JSON_CONFIGURATION_NAME)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.init
|
32
|
+
file_path = Dir.pwd + "/" + JSON_CONFIGURATION_NAME
|
33
|
+
|
34
|
+
return false if File.exist?(file_path)
|
35
|
+
|
36
|
+
configuration = {
|
37
|
+
preset: "base",
|
38
|
+
ignore: {
|
39
|
+
words: [],
|
40
|
+
paths: ["tmp/", "log/"]
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
File.write(file_path, JSON.pretty_generate(configuration))
|
45
|
+
true
|
46
|
+
end
|
47
|
+
|
48
|
+
def ignore_words(words)
|
49
|
+
@whitelisted_words.concat(words.map(&:downcase)).uniq!
|
50
|
+
persist
|
51
|
+
end
|
52
|
+
|
53
|
+
def word_ignored?(word)
|
54
|
+
@whitelisted_words.include?(word.downcase) ||
|
55
|
+
Preset.whitelisted_words(@preset).include?(word.downcase)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def load_config
|
61
|
+
base_path = Dir.pwd
|
62
|
+
file_path = base_path + "/" + (self.class.instance_variable_get(:@resolve_config_file_path_using)&.call || JSON_CONFIGURATION_NAME)
|
63
|
+
|
64
|
+
contents = File.exist?(file_path) ? File.read(file_path) : "{}"
|
65
|
+
json_as_array = JSON.parse(contents, symbolize_names: true) rescue {}
|
66
|
+
|
67
|
+
@whitelisted_words = (json_as_array.dig(:ignore, :words) || []).map(&:downcase)
|
68
|
+
@whitelisted_paths = json_as_array.dig(:ignore, :paths) || []
|
69
|
+
@preset = json_as_array[:preset]
|
70
|
+
end
|
71
|
+
|
72
|
+
def persist
|
73
|
+
file_path = Dir.pwd + "/" + JSON_CONFIGURATION_NAME
|
74
|
+
|
75
|
+
configuration = {
|
76
|
+
preset: @preset,
|
77
|
+
ignore: {
|
78
|
+
words: @whitelisted_words,
|
79
|
+
paths: @whitelisted_paths
|
80
|
+
}
|
81
|
+
}.compact
|
82
|
+
|
83
|
+
File.write(file_path, JSON.pretty_generate(configuration))
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
File without changes
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Heckler
|
2
|
+
class Preset
|
3
|
+
PRESET_STUBS_DIRECTORY = File.join(__dir__, "/presets")
|
4
|
+
|
5
|
+
def self.whitelisted_words(preset)
|
6
|
+
return [] if preset.nil? || !stub_exists?(preset)
|
7
|
+
|
8
|
+
get_words_from_stub("base") + get_words_from_stub(preset)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.get_words_from_stub(preset)
|
12
|
+
path = File.join(PRESET_STUBS_DIRECTORY, "#{preset}.stub")
|
13
|
+
File.read(path).lines.map(&:strip).reject(&:empty?)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.stub_exists?(preset)
|
17
|
+
File.exist?(File.join(PRESET_STUBS_DIRECTORY, "#{preset}.stub"))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
backfill
|
2
|
+
cancelled
|
3
|
+
propable
|
4
|
+
dns
|
5
|
+
verifier
|
6
|
+
enum
|
7
|
+
backend
|
8
|
+
formatter
|
9
|
+
init
|
10
|
+
enums
|
11
|
+
env
|
12
|
+
misconfigured
|
13
|
+
webhook
|
14
|
+
auth
|
15
|
+
webhooks
|
16
|
+
middleware
|
17
|
+
json
|
18
|
+
fakeable
|
19
|
+
fillable
|
20
|
+
verifiers
|
21
|
+
slugifier
|
22
|
+
txt
|
23
|
+
namespace
|
24
|
+
truncatable
|
25
|
+
unformatted
|
26
|
+
finishable
|
27
|
+
gitlab
|
28
|
+
gitfake
|
29
|
+
uri
|
30
|
+
authenticatable
|
31
|
+
hmac
|
32
|
+
callables
|
33
|
+
validator
|
34
|
+
hostname
|
35
|
+
ssl
|
36
|
+
backoff
|
37
|
+
bool
|
38
|
+
schemas
|
39
|
+
pre
|
40
|
+
accessors
|
41
|
+
unsuspend
|
42
|
+
frontend
|
43
|
+
repo
|
44
|
+
src
|
45
|
+
jwt
|
46
|
+
nano
|
47
|
+
slugify
|
48
|
+
config
|
49
|
+
ecr
|
50
|
+
cloudflare
|
51
|
+
bitbucket
|
52
|
+
serverless
|
53
|
+
postgres
|
54
|
+
dev
|
55
|
+
ui
|
56
|
+
vite
|
57
|
+
tls
|
58
|
+
acl
|
59
|
+
http
|
60
|
+
parsable
|
61
|
+
confirmable
|
62
|
+
changelog
|
63
|
+
livewire
|
64
|
+
autocomplete
|
65
|
+
followable
|
66
|
+
recaptcha
|
67
|
+
stringable
|
68
|
+
viewables
|
69
|
+
resizer
|
70
|
+
params
|
71
|
+
unfollow
|
72
|
+
unfollows
|
73
|
+
datetime
|
74
|
+
otp
|
75
|
+
lifecycle
|
76
|
+
unbookmark
|
77
|
+
pinnable
|
78
|
+
mailables
|
79
|
+
sharable
|
80
|
+
blocklist
|
81
|
+
conf
|
82
|
+
timezones
|
83
|
+
autocompletion
|
84
|
+
arrayable
|
85
|
+
pinkary
|
86
|
+
sponsorship
|
87
|
+
sponsorships
|
88
|
+
iframe
|
89
|
+
tokenize
|
90
|
+
pwa
|
91
|
+
stylesheets
|
92
|
+
rubygems
|
93
|
+
gemfile
|
94
|
+
rakefile
|
95
|
+
cli
|
96
|
+
exe
|
97
|
+
readme
|
98
|
+
sig
|
data/lib/heckler.rb
ADDED
data/sig/heckler.rbs
ADDED
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: heckler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stanislav (Stas) Katkov
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-01-16 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: "**Heckler** is a tool to identify wording or spelling mistakes in ruby
|
14
|
+
codebase: filenames, class names, method names, property names and more. Spelling
|
15
|
+
correction is powered by **GNU Aspell**."
|
16
|
+
email:
|
17
|
+
- github@skatkov.com
|
18
|
+
executables:
|
19
|
+
- heckler
|
20
|
+
extensions: []
|
21
|
+
extra_rdoc_files: []
|
22
|
+
files:
|
23
|
+
- ".standard.yml"
|
24
|
+
- CHANGELOG.md
|
25
|
+
- LICENSE.txt
|
26
|
+
- README.md
|
27
|
+
- Rakefile
|
28
|
+
- exe/heckler
|
29
|
+
- heckler.json
|
30
|
+
- lib/heckler.rb
|
31
|
+
- lib/heckler/aspell.rb
|
32
|
+
- lib/heckler/checker/file_system.rb
|
33
|
+
- lib/heckler/cli.rb
|
34
|
+
- lib/heckler/config.rb
|
35
|
+
- lib/heckler/personn.rb
|
36
|
+
- lib/heckler/preset.rb
|
37
|
+
- lib/heckler/presets/base.stub
|
38
|
+
- lib/heckler/version.rb
|
39
|
+
- sig/heckler.rbs
|
40
|
+
homepage: https://github.com/skatkov/heckler
|
41
|
+
licenses:
|
42
|
+
- MIT
|
43
|
+
metadata:
|
44
|
+
homepage_uri: https://github.com/skatkov/heckler
|
45
|
+
source_code_uri: https://github.com/skatkov/heckler
|
46
|
+
changelog_uri: https://github.com/skatkov/heckler/CHANGELOG.md
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options: []
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 3.1.0
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
requirements: []
|
62
|
+
rubygems_version: 3.5.22
|
63
|
+
signing_key:
|
64
|
+
specification_version: 4
|
65
|
+
summary: tool to identify wording or spelling mistakes in ruby codebase
|
66
|
+
test_files: []
|