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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7173dd0294a0f7645db2dde57c7fdd4dedd49643668ce2c7d59bc13d09d1d9f4
4
- data.tar.gz: 37477c3e7eb020a7112fae39b9c30bdc3b78d8b4cb526da8ecab38a17e3ecfce
3
+ metadata.gz: 15d511455e488fe8175d4b8eb85f9d7a55647515d39450d1f627254ee90571a3
4
+ data.tar.gz: 3841f4796632094f9e8b17fb3ff9bdd219e5bb2b783ba11e1ec074788185f72e
5
5
  SHA512:
6
- metadata.gz: 954a4e7a09375a52125d1db49ac0a5845ae8ef56867eb1e7c984244513ff0e801977a5f691ef181d8f7f91bb471af706fd94b04246c5bdc11a37aced5a6ffaf4
7
- data.tar.gz: 38b377026a5433b5800517076afd009222e2a903cbd0df9b324b3e3c2ccd1fbf2e5b7679d7a505f5d073ccbf54bdad6061c2da3e056f4990e5de46cae74ec555
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TypoChecker
4
- VERSION = '0.1.5'
4
+ VERSION = '0.1.6'
5
5
  end
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
- @excludes = excludes
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
- result = {}
20
- Find.find(repo_path) do |path|
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.5
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-06 00:00:00.000000000 Z
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: