typo_checker 0.1.5 → 0.1.6
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/lib/data/typos.csv +0 -3
- data/lib/typo_checker/configuration.rb +11 -0
- data/lib/typo_checker/file_scanner.rb +81 -0
- data/lib/typo_checker/repository_scanner.rb +58 -0
- data/lib/typo_checker/typos_loader.rb +19 -0
- data/lib/typo_checker/version.rb +1 -1
- data/lib/typo_checker.rb +7 -121
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15d511455e488fe8175d4b8eb85f9d7a55647515d39450d1f627254ee90571a3
|
4
|
+
data.tar.gz: 3841f4796632094f9e8b17fb3ff9bdd219e5bb2b783ba11e1ec074788185f72e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a42eb16f7838b9e56e39a290d39682c4bb082c643526038d01b168b5f29a1a922fc8dfc6882d205684a906d0155ff96c610e4ccc9f8386b363cd560d781ef292
|
7
|
+
data.tar.gz: 7c097ec3e93767e28c12c414ec64cc439b06630c3d94983da15f8335ad53077938f3fbbcd240c89c482fd3e15cbeb8cafc077a85e8cd2428c3eba81208d13943
|
data/lib/data/typos.csv
CHANGED
@@ -44440,7 +44440,6 @@ falsde,false
|
|
44440
44440
|
falsei,false
|
44441
44441
|
falseley,falsely
|
44442
44442
|
falsemounted,false
|
44443
|
-
falsey,false
|
44444
44443
|
falsh,flash
|
44445
44444
|
falshbacks,flashbacks
|
44446
44445
|
falshed,flashed
|
@@ -112652,7 +112651,6 @@ unintuive,unintuitive
|
|
112652
112651
|
uniomus,unanimous
|
112653
112652
|
unionous,unanimous
|
112654
112653
|
unioun,union
|
112655
|
-
uniq,unique
|
112656
112654
|
uniqe,unique
|
112657
112655
|
uniqely,uniquely
|
112658
112656
|
uniqu,unique
|
@@ -114460,7 +114458,6 @@ uther,other
|
|
114460
114458
|
uthor,author
|
114461
114459
|
utiility,utility
|
114462
114460
|
utiity,utility
|
114463
|
-
util,until
|
114464
114461
|
utilaties,utilities
|
114465
114462
|
utilaty,utility
|
114466
114463
|
utiliatrian,utilitarian
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module TypoChecker
|
2
|
+
class Configuration
|
3
|
+
attr_reader :excludes, :skips, :stdoutput
|
4
|
+
|
5
|
+
def initialize(excludes = nil, skips = nil, stdoutput = true)
|
6
|
+
@excludes = excludes || []
|
7
|
+
@skips = (skips || []).map(&:downcase)
|
8
|
+
@stdoutput = stdoutput.nil? ? true : stdoutput
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module TypoChecker
|
2
|
+
class FileScanner
|
3
|
+
def initialize(typos, stdoutput)
|
4
|
+
@typos = typos
|
5
|
+
@stdoutput = stdoutput
|
6
|
+
end
|
7
|
+
|
8
|
+
def scan_file(path, result)
|
9
|
+
File.foreach(path).with_index do |line, line_number|
|
10
|
+
words = line.split(/[^a-zA-Z0-9']+/)
|
11
|
+
check_words = words.map { |word| split_function_name(word) }.flatten
|
12
|
+
check_words.each do |word|
|
13
|
+
clean_word = word.gsub(/^[^\w]+|[^\w]+$/, '')
|
14
|
+
char_index = line.index(clean_word)
|
15
|
+
check_word(clean_word, path, line_number, char_index, result)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def check_word(word, file, line_num, char_index, result)
|
23
|
+
return unless @typos.key?(word.downcase)
|
24
|
+
|
25
|
+
corrected_word = corrected_word(word, @typos[word.downcase])
|
26
|
+
typo_details = { incorrect_word: word, correct_word: corrected_word }
|
27
|
+
typo_path = "#{file}:#{line_num + 1}:#{char_index + 1}"
|
28
|
+
path = file.sub(%r{^./}, '')
|
29
|
+
|
30
|
+
result[path] ||= {}
|
31
|
+
result[path][:typos] ||= []
|
32
|
+
line_entry = result[path][:typos].find { |entry| entry[:line] == line_num + 1 }
|
33
|
+
|
34
|
+
if line_entry
|
35
|
+
line_entry[:typos] << typo_details
|
36
|
+
else
|
37
|
+
result[path][:typos] << { line: line_num + 1, typos: [typo_details] }
|
38
|
+
end
|
39
|
+
|
40
|
+
stdout(typo_path, word, corrected_word)
|
41
|
+
end
|
42
|
+
|
43
|
+
def split_function_name(name)
|
44
|
+
# Split on capital letters or digit transitions.
|
45
|
+
# This handles cases like camelCase, PascalCase, and mixed cases with digits.
|
46
|
+
name.gsub(/([a-zA-Z])(\d)/, '\1 \2') # Between letter and digit
|
47
|
+
.gsub(/(\d)([A-Z])/, '\1 \2') # Between digit and capital letter
|
48
|
+
.gsub(/([a-z])([A-Z])/, '\1 \2') # Between lowercase and uppercase
|
49
|
+
.split(/[\s_]+/) # Split on spaces and underscores
|
50
|
+
end
|
51
|
+
|
52
|
+
def corrected_word(word, typo_correct_word)
|
53
|
+
if word == word.capitalize
|
54
|
+
typo_correct_word.capitalize
|
55
|
+
elsif word == word.upcase
|
56
|
+
typo_correct_word.upcase
|
57
|
+
else
|
58
|
+
typo_correct_word
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def stdout(typo_path, word, corrected_word)
|
63
|
+
return unless @stdoutput
|
64
|
+
|
65
|
+
puts "Typo found in #{colorize_light_blue(typo_path)}: " \
|
66
|
+
"#{colorize_red(word)} -> #{colorize_green(corrected_word)}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def colorize_red(text)
|
70
|
+
"\e[31m#{text}\e[0m"
|
71
|
+
end
|
72
|
+
|
73
|
+
def colorize_green(text)
|
74
|
+
"\e[32m#{text}\e[0m"
|
75
|
+
end
|
76
|
+
|
77
|
+
def colorize_light_blue(text)
|
78
|
+
"\e[94m#{text}\e[0m"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'find'
|
2
|
+
|
3
|
+
module TypoChecker
|
4
|
+
class RepositoryScanner
|
5
|
+
def initialize(repo_path, configuration)
|
6
|
+
@repo_path = repo_path
|
7
|
+
@configuration = configuration
|
8
|
+
@file_scanner = FileScanner.new(load_typos, configuration.stdoutput)
|
9
|
+
end
|
10
|
+
|
11
|
+
def scan
|
12
|
+
result = {}
|
13
|
+
Find.find(@repo_path) do |path|
|
14
|
+
next if exclude_path?(path)
|
15
|
+
|
16
|
+
@file_scanner.scan_file(path, result) if File.file?(path) && text_file?(path)
|
17
|
+
end
|
18
|
+
result.map do |path, data|
|
19
|
+
data[:typos].map do |entry|
|
20
|
+
{ path: path, line: entry[:line], typos: entry[:typos] }
|
21
|
+
end
|
22
|
+
end.flatten
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def exclude_path?(path)
|
28
|
+
exclude_patterns.any? { |pattern| path.match?(pattern) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def exclude_patterns
|
32
|
+
@exclude_patterns ||= @configuration.excludes + [
|
33
|
+
%r{\.git/.*}, # Skip all files and directories inside .git
|
34
|
+
%r{node_modules/.*}, # Skip all files and directories inside node_modules
|
35
|
+
%r{vendor/.*}, # Skip all files and directories inside vendor
|
36
|
+
%r{tmp/.*} # Skip all files and directories inside tmp
|
37
|
+
]
|
38
|
+
end
|
39
|
+
|
40
|
+
def text_file?(path)
|
41
|
+
excluded_extensions = %w[.log]
|
42
|
+
|
43
|
+
return false if excluded_extensions.include?(File.extname(path))
|
44
|
+
|
45
|
+
%w[
|
46
|
+
.rb .txt .md .html .css .js .py .java .php .go .swift .ts .scala .c .cpp .csharp .h .lua .pl .rs .kt
|
47
|
+
.d .r .m .sh .bash .bat .json .yaml .xml .scss .tsv .vb .ps1 .clj .elixir .f# .vhdl .verilog
|
48
|
+
.ada .ml .lisp .prolog .tcl .rexx .awk .sed .coffee .groovy .dart .haxe .zig .nim .crystal .reason .ocaml
|
49
|
+
.forth .v .xhtml .julia .racket .scheme .rust .graphql
|
50
|
+
].include? File.extname(path)
|
51
|
+
end
|
52
|
+
|
53
|
+
def load_typos
|
54
|
+
csv_file = File.expand_path('../data/typos.csv', __dir__)
|
55
|
+
TyposLoader.new(@configuration.skips).load_typos(csv_file)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
module TypoChecker
|
4
|
+
class TyposLoader
|
5
|
+
def initialize(skips)
|
6
|
+
@skips = skips
|
7
|
+
end
|
8
|
+
|
9
|
+
def load_typos(file_path)
|
10
|
+
typos = {}
|
11
|
+
CSV.foreach(file_path, headers: false) do |row|
|
12
|
+
next if @skips.include?(row[0])
|
13
|
+
|
14
|
+
typos[row[0]] = row[1]
|
15
|
+
end
|
16
|
+
typos
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/typo_checker/version.rb
CHANGED
data/lib/typo_checker.rb
CHANGED
@@ -3,134 +3,20 @@
|
|
3
3
|
require 'csv'
|
4
4
|
require 'find'
|
5
5
|
require 'fileutils'
|
6
|
+
require_relative 'typo_checker/configuration'
|
7
|
+
require_relative 'typo_checker/typos_loader'
|
8
|
+
require_relative 'typo_checker/file_scanner'
|
9
|
+
require_relative 'typo_checker/repository_scanner'
|
6
10
|
|
7
11
|
module TypoChecker
|
8
12
|
class Checker
|
9
|
-
attr_reader :typos, :excludes, :skips, :stdoutput
|
10
|
-
|
11
13
|
def initialize(excludes = [], skips = [], stdoutput = true)
|
12
|
-
@
|
13
|
-
@skips = skips.map(&:downcase)
|
14
|
-
@typos = load_typos
|
15
|
-
@stdoutput = stdoutput
|
14
|
+
@configuration = Configuration.new(excludes, skips, stdoutput)
|
16
15
|
end
|
17
16
|
|
18
17
|
def scan_repo(repo_path = Dir.pwd)
|
19
|
-
|
20
|
-
|
21
|
-
next if exclude_path?(path)
|
22
|
-
|
23
|
-
scan_file(path, result) if File.file?(path) && text_file?(path)
|
24
|
-
end
|
25
|
-
|
26
|
-
result.map do |path, data|
|
27
|
-
data[:typos].map do |entry|
|
28
|
-
{ path: path, line: entry[:line], typos: entry[:typos] }
|
29
|
-
end
|
30
|
-
end.flatten
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def exclude_path?(path)
|
36
|
-
exclude_patterns.any? { |pattern| path.match?(pattern) }
|
37
|
-
end
|
38
|
-
|
39
|
-
def exclude_patterns
|
40
|
-
@exclude_patterns ||= excludes + [
|
41
|
-
%r{\.git/.*}, # Skip all files and directories inside .git
|
42
|
-
%r{node_modules/.*}, # Skip all files and directories inside node_modules
|
43
|
-
%r{vendor/.*}, # Skip all files and directories inside vendor
|
44
|
-
%r{tmp/.*} # Skip all files and directories inside tmp
|
45
|
-
]
|
46
|
-
end
|
47
|
-
|
48
|
-
def load_typos
|
49
|
-
typos = {}
|
50
|
-
csv_file = File.expand_path('data/typos.csv', __dir__)
|
51
|
-
CSV.foreach(csv_file, headers: false) do |row|
|
52
|
-
next if skips.include?(row[0])
|
53
|
-
|
54
|
-
typos[row[0]] = row[1]
|
55
|
-
end
|
56
|
-
typos
|
57
|
-
end
|
58
|
-
|
59
|
-
def text_file?(path)
|
60
|
-
excluded_extensions = %w[.log]
|
61
|
-
|
62
|
-
return false if excluded_extensions.include?(File.extname(path))
|
63
|
-
|
64
|
-
%w[
|
65
|
-
.rb .txt .md .html .css .js .py .java .php .go .swift .ts .scala .c .cpp .csharp .h .lua .pl .rs .kt
|
66
|
-
.d .r .m .sh .bash .bat .json .yaml .xml .scss .tsv .vb .ps1 .clj .elixir .f# .vhdl .verilog
|
67
|
-
.ada .ml .lisp .prolog .tcl .rexx .awk .sed .coffee .groovy .dart .haxe .zig .nim .crystal .reason .ocaml
|
68
|
-
.forth .v .xhtml .julia .racket .scheme .rust .graphql
|
69
|
-
].include? File.extname(path)
|
70
|
-
end
|
71
|
-
|
72
|
-
def scan_file(path, result)
|
73
|
-
File.foreach(path).with_index do |line, line_number|
|
74
|
-
words = line.split(/[^a-zA-Z0-9']+/)
|
75
|
-
check_words = words.map { |word| split_function_name(word) }.flatten
|
76
|
-
check_words.each do |word|
|
77
|
-
clean_word = word.gsub(/^[^\w]+|[^\w]+$/, '')
|
78
|
-
char_index = line.index(clean_word)
|
79
|
-
check_word(clean_word, path, line_number, char_index, result)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def check_word(word, file, line_num, char_index, result)
|
85
|
-
return unless typos.key?(word.downcase)
|
86
|
-
|
87
|
-
corrected_word = corrected_word(word, typos[word.downcase])
|
88
|
-
typo_details = { incorrect_word: word, correct_word: corrected_word }
|
89
|
-
typo_path = "#{file}:#{line_num + 1}:#{char_index + 1}"
|
90
|
-
path = file.sub(%r{^./}, '')
|
91
|
-
|
92
|
-
result[path] ||= {}
|
93
|
-
result[path][:typos] ||= []
|
94
|
-
line_entry = result[path][:typos].find { |entry| entry[:line] == line_num + 1 }
|
95
|
-
|
96
|
-
if line_entry
|
97
|
-
line_entry[:typos] << typo_details
|
98
|
-
else
|
99
|
-
result[path][:typos] << { line: line_num + 1, typos: [typo_details] }
|
100
|
-
end
|
101
|
-
|
102
|
-
stdout(typo_path, word, corrected_word) if stdoutput
|
103
|
-
end
|
104
|
-
|
105
|
-
def split_function_name(name)
|
106
|
-
name.gsub(/([a-z])([A-Z])/, '\1 \2').split(/[\s_]+/)
|
107
|
-
end
|
108
|
-
|
109
|
-
def corrected_word(word, typo_correct_word)
|
110
|
-
if word == word.capitalize
|
111
|
-
typo_correct_word.capitalize
|
112
|
-
elsif word == word.upcase
|
113
|
-
typo_correct_word.upcase
|
114
|
-
else
|
115
|
-
typo_correct_word
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
def stdout(typo_path, word, corrected_word)
|
120
|
-
puts "Typo found in #{colorize_light_blue(typo_path)}: " \
|
121
|
-
"#{colorize_red(word)} -> #{colorize_green(corrected_word)}"
|
122
|
-
end
|
123
|
-
|
124
|
-
def colorize_red(text)
|
125
|
-
"\e[31m#{text}\e[0m"
|
126
|
-
end
|
127
|
-
|
128
|
-
def colorize_green(text)
|
129
|
-
"\e[32m#{text}\e[0m"
|
130
|
-
end
|
131
|
-
|
132
|
-
def colorize_light_blue(text)
|
133
|
-
"\e[94m#{text}\e[0m"
|
18
|
+
repository_scanner = RepositoryScanner.new(repo_path, @configuration)
|
19
|
+
repository_scanner.scan
|
134
20
|
end
|
135
21
|
end
|
136
22
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: typo_checker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- datpmt
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-01-
|
10
|
+
date: 2025-01-08 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: thor
|
@@ -39,6 +39,10 @@ files:
|
|
39
39
|
- lib/data/typos.csv
|
40
40
|
- lib/typo_checker.rb
|
41
41
|
- lib/typo_checker/cli.rb
|
42
|
+
- lib/typo_checker/configuration.rb
|
43
|
+
- lib/typo_checker/file_scanner.rb
|
44
|
+
- lib/typo_checker/repository_scanner.rb
|
45
|
+
- lib/typo_checker/typos_loader.rb
|
42
46
|
- lib/typo_checker/version.rb
|
43
47
|
homepage: https://rubygems.org/gems/typo_checker
|
44
48
|
licenses:
|