spellr 0.8.0 → 0.8.5

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: 4d7433ea064065687e2295575e41d3a991bad67e3ad57602ef37fbbc19dcd91d
4
- data.tar.gz: a242b9f1c85d00933a367924440d5c22ecc3c53c2f339c18e91393808d25f86d
3
+ metadata.gz: 80438eca6b5b281ceab331e0ab9886fcb9c622cfe1e91ca2762ed10628c44ee1
4
+ data.tar.gz: 434910ca88653cb6a7d4bb11dabc32e4c782b22df4e65cc488ebaf6439bb3b38
5
5
  SHA512:
6
- metadata.gz: 76ee40dd1f2c4ad6cba3a1db28966bc84e0e6910a994bcf58840135eef8d1043f14bfd0f0151ae9f770633ec8d878d2984dc3e235013766a877ca88f250d5c5d
7
- data.tar.gz: fc2fb0f38d1513a24cd2e33d5175f35eb7bdbb72f37d2c97c6e2ef6ef0ae3efc6cdbee41938c5c836a9d5af6536c057c0c5ed0b17ab4179c363781255554473d
6
+ metadata.gz: b14f3fe397b01f9a7e1742246a451e68238833c98e98b6716e36a11bb38d556463d992a0cdb8577f2dac2b65bb39eb0a9f3d050f884814c7449d0b6d2239e013
7
+ data.tar.gz: 45fe01c33fd31faafd21248751f2a85f38c3807b75eb242fa994ffbdd14735f2dde343cf397b5f14281a24107ca5532d45b4c107b720546ac4994121c5599e58
@@ -1,3 +1,22 @@
1
+ # v0.8.5
2
+ - Single line disable! use `spellr:disable-line` #25
3
+
4
+ # v0.8.4
5
+ - Update fast_ignore dependency, it's faster now (about 0.5s faster on rails codebase)
6
+
7
+ # v0.8.3
8
+ - Update fast_ignore dependency fixing symlinks to directories handling.
9
+
10
+ # v0.8.2
11
+ - Massive test refactor
12
+ - Spellr now only pays attention to Spellr.pwd. Dir.pwd can be whatever
13
+ - All output goes through Spellr.config.output. Now we can override it.
14
+ - tests are twice as fast. Fewer warnings
15
+ - upgrade fast_ignore dependency
16
+
17
+ # v0.8.1
18
+ - use refinements for backports so that RakeTask doesn't conflict with Rubocop::RakeTask
19
+
1
20
  # v0.8.0
2
21
  - add the ability to use spellr as a rake task
3
22
 
data/README.md CHANGED
@@ -175,14 +175,21 @@ Type `e` to add this word to the english wordlist and continue on through the sp
175
175
 
176
176
  ### Disabling the tokenizer
177
177
 
178
- If the tokenizer finds a word you don't want to add to the wordlist (perhaps it's an intentional example of a typo, or a non-word string not excluded by the heuristic) then place on the lines before and after
178
+ If the tokenizer finds a word you don't want to add to the wordlist (perhaps it's an intentional example of a typo, or a non-word string not excluded by the heuristic) then add any kind of comment containing `spellr:disable-line` to the line.
179
+ ```ruby
180
+ open('mispeled_filename.txt') # spellr:disable-line
181
+ ```
182
+
183
+ You can also disable multiple lines, by surrounding the offending code with `spellr:disable` and `spellr:enable`
179
184
  ```ruby
180
185
  # spellr:disable
181
- "Test typo of the: teh"
186
+ it "Test typo of the: teh" do
187
+ fill_in(field, with: "teh")
188
+ end
182
189
  # spellr:enable
183
190
  ```
184
191
 
185
- This works with any kind of comment, even in the same line
192
+ If your language supports inline comments you can also surround with `spellr:disable` and `spellr:enable` in the same line:
186
193
  ```html
187
194
  <span><!-- spellr:disable -->nonsenseword<!-- spellr:enable --></span>
188
195
  ```
@@ -257,14 +264,14 @@ To have this automatically run on travis, add `:spellr` to the default task.
257
264
  require 'spellr/rake_task'
258
265
  Spellr::RakeTask.generate_task
259
266
 
260
- task :default, :spellr
267
+ task default: :spellr
261
268
  ```
262
269
  or if you already have :default task, add :spellr to the array.
263
270
  ```ruby
264
271
  require 'spellr/rake_task'
265
272
  Spellr::RakeTask.generate_task
266
273
 
267
- task :default, [:spec, :spellr]
274
+ task default: [:spec, :spellr]
268
275
  ```
269
276
  or etc.
270
277
 
@@ -285,7 +292,7 @@ To provide default cli arguments, the first argument is the name, and subsequent
285
292
  require 'spellr/rake_task'
286
293
  Spellr::RakeTask.generate_task(:spellr_quiet, '--quiet')
287
294
 
288
- task :default, :spellr_quiet
295
+ task default: :spellr_quiet
289
296
  ```
290
297
  or `rake spellr` will be in interactive mode unless the CI env variable is set.
291
298
  ```ruby
@@ -294,7 +301,7 @@ require 'spellr/rake_task'
294
301
  spellr_arguments = ENV['CI'] ? [] : ['--interactive']
295
302
  Spellr::RakeTask.generate_task(:spellr, **spellr_arguments)
296
303
 
297
- task :default, :spellr
304
+ task default: :spellr
298
305
  ```
299
306
 
300
307
  ## Development
data/exe/spellr CHANGED
@@ -3,4 +3,4 @@
3
3
 
4
4
  require_relative '../lib/spellr/cli'
5
5
 
6
- Spellr::CLI.new(ARGV)
6
+ exit Spellr::CLI.new(ARGV).run
@@ -44,6 +44,7 @@ languages:
44
44
  - Rakefile
45
45
  - config.ru
46
46
  - Capfile
47
+ - .simplecov
47
48
  hashbangs:
48
49
  - ruby
49
50
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative 'spellr/backports'
4
4
  require_relative 'spellr/config'
5
+ require_relative 'spellr/pwd'
5
6
 
6
7
  module Spellr
7
8
  class Error < StandardError; end
@@ -27,4 +28,8 @@ module Spellr
27
28
  def config
28
29
  @config ||= Spellr::Config.new
29
30
  end
31
+
32
+ def exit(status = 0)
33
+ throw(:spellr_exit, status)
34
+ end
30
35
  end
@@ -1,58 +1,60 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- ruby_version = Gem::Version.new(RUBY_VERSION)
4
-
5
- unless ruby_version >= Gem::Version.new('2.5')
6
- class Hash
7
- def slice!(*keys)
8
- delete_if { |k| !keys.include?(k) }
9
- end
3
+ module Spellr
4
+ ruby_version = Gem::Version.new(RUBY_VERSION)
5
+ unless ruby_version >= Gem::Version.new('2.5')
6
+ module HashSlice
7
+ refine Hash do
8
+ def slice!(*keys)
9
+ delete_if { |k| !keys.include?(k) }
10
+ end
10
11
 
11
- def slice(*keys)
12
- dup.slice!(*keys)
12
+ def slice(*keys)
13
+ dup.slice!(*keys)
14
+ end
15
+ end
13
16
  end
14
- end
15
17
 
16
- require 'yaml'
17
- module YAML
18
- class << self
19
- alias_method :safe_load_without_symbolize_names, :safe_load
20
- def safe_load(path, *args, symbolize_names: false, **kwargs)
21
- if symbolize_names
22
- symbolize_names!(safe_load_without_symbolize_names(path, *args, **kwargs))
23
- else
24
- safe_load_without_symbolize_names(path, *args, **kwargs)
18
+ require 'yaml'
19
+ module YAMLSymbolizeNames
20
+ refine YAML.singleton_class do
21
+ alias_method :safe_load_without_symbolize_names, :safe_load
22
+ def safe_load(path, *args, symbolize_names: false, **kwargs)
23
+ if symbolize_names
24
+ symbolize_names!(safe_load_without_symbolize_names(path, *args, **kwargs))
25
+ else
26
+ safe_load_without_symbolize_names(path, *args, **kwargs)
27
+ end
25
28
  end
26
- end
27
29
 
28
- private
30
+ private
29
31
 
30
- def symbolize_names!(obj) # rubocop:disable Metrics/MethodLength
31
- case obj
32
- when Hash
33
- obj.keys.each do |key| # rubocop:disable Style/HashEachMethods # each_key never finishes.
34
- obj[key.to_sym] = symbolize_names!(obj.delete(key))
32
+ def symbolize_names!(obj) # rubocop:disable Metrics/MethodLength
33
+ case obj
34
+ when Hash
35
+ obj.keys.each do |key| # rubocop:disable Style/HashEachMethods # each_key never finishes.
36
+ obj[key.to_sym] = symbolize_names!(obj.delete(key))
37
+ end
38
+ when Array
39
+ obj.map! { |ea| symbolize_names!(ea) }
35
40
  end
36
- when Array
37
- obj.map! { |ea| symbolize_names!(ea) }
41
+ obj
38
42
  end
39
- obj
40
43
  end
41
44
  end
42
45
  end
43
- end
44
46
 
45
- # all this to avoid a deprecation warning
46
- unless ruby_version >= Gem::Version.new('2.6')
47
- require 'yaml'
48
- module YAML
49
- class << self
50
- alias_method :safe_load_without_permitted_classes, :safe_load
51
- def safe_load(path, *args, permitted_classes: nil, **kwargs)
52
- if permitted_classes
53
- safe_load_without_permitted_classes(path, permitted_classes, *args, **kwargs)
54
- else
55
- safe_load_without_permitted_classes(path, *args, **kwargs)
47
+ unless ruby_version >= Gem::Version.new('2.6')
48
+ require 'yaml'
49
+ module YAMLPermittedClasses
50
+ refine YAML.singleton_class do
51
+ alias_method :safe_load_without_permitted_classes, :safe_load
52
+ def safe_load(path, *args, permitted_classes: nil, **kwargs)
53
+ if permitted_classes
54
+ safe_load_without_permitted_classes(path, permitted_classes, *args, **kwargs)
55
+ else
56
+ safe_load_without_permitted_classes(path, *args, **kwargs)
57
+ end
56
58
  end
57
59
  end
58
60
  end
@@ -40,7 +40,7 @@ module Spellr
40
40
  end
41
41
 
42
42
  def output
43
- @output ||= Spellr::Output.new
43
+ @output ||= Spellr.config.output
44
44
  end
45
45
 
46
46
  def counts
@@ -7,6 +7,7 @@ require_relative 'string_format'
7
7
  module Spellr
8
8
  class Check
9
9
  attr_reader :files, :reporter
10
+
10
11
  include StringFormat
11
12
 
12
13
  def exit_code
@@ -16,7 +17,7 @@ module Spellr
16
17
  def initialize(files: [], reporter: Spellr.config.reporter)
17
18
  @files = files
18
19
 
19
- @main_reporter = @reporter = reporter
20
+ @reporter = reporter
20
21
  end
21
22
 
22
23
  def check
@@ -7,7 +7,7 @@ module Spellr
7
7
  class CheckDryRun < Check
8
8
  def check
9
9
  files.each do |file|
10
- puts file.relative_path
10
+ @reporter.puts file.relative_path
11
11
  end
12
12
  end
13
13
  end
@@ -1,32 +1,33 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'pathname'
3
4
  require_relative '../spellr'
4
5
  require_relative 'cli_options'
5
6
  require_relative 'string_format'
6
7
 
7
8
  module Spellr
8
9
  class CLI
9
- attr_reader :argv
10
-
11
10
  def initialize(argv)
11
+ Spellr.config.reset!
12
12
  @argv = argv
13
- CLI::Options.parse(@argv)
14
- check
15
- rescue Spellr::Error => e
16
- exit_with_error(e.message)
17
13
  end
18
14
 
19
- def exit_with_error(message)
20
- warn Spellr::StringFormat.red(message)
21
- exit 1
15
+ def run
16
+ catch(:spellr_exit) { check }
17
+ rescue Spellr::Error => e
18
+ Spellr.config.output.warn(Spellr::StringFormat.red(e.message)) && 1
19
+ 1
22
20
  end
23
21
 
22
+ private
23
+
24
24
  def check
25
+ CLI::Options.parse(@argv)
25
26
  Spellr.config.valid?
26
27
  checker = Spellr.config.checker.new(files: files)
27
28
  checker.check
28
29
 
29
- exit checker.exit_code
30
+ checker.exit_code
30
31
  end
31
32
 
32
33
  def files
@@ -9,6 +9,8 @@ module Spellr
9
9
  class Options
10
10
  class << self
11
11
  def parse(argv)
12
+ @parallel_option = false
13
+
12
14
  options.parse!(argv)
13
15
  end
14
16
 
@@ -43,7 +45,6 @@ module Spellr
43
45
  end
44
46
 
45
47
  def quiet_option(_)
46
- Spellr.config.quiet = true
47
48
  require_relative 'quiet_reporter'
48
49
  Spellr.config.reporter = Spellr::QuietReporter.new
49
50
  end
@@ -56,7 +57,7 @@ module Spellr
56
57
  end
57
58
 
58
59
  def config_option(file)
59
- file = Pathname.pwd.join(file).expand_path
60
+ file = Spellr.pwd.join(file).expand_path
60
61
 
61
62
  unless ::File.readable?(file)
62
63
  raise Spellr::Config::NotFound, "Config error: #{file} not found or not readable"
@@ -82,15 +83,15 @@ module Spellr
82
83
 
83
84
  def version_option(_)
84
85
  require_relative 'version'
85
- puts(Spellr::VERSION)
86
+ Spellr.config.output.puts(Spellr::VERSION)
86
87
 
87
- exit
88
+ Spellr.exit
88
89
  end
89
90
 
90
91
  def options_help(_)
91
- puts options.help
92
+ Spellr.config.output.puts options.help
92
93
 
93
- exit
94
+ Spellr.exit
94
95
  end
95
96
  end
96
97
  end
@@ -4,6 +4,8 @@ require_relative '../spellr'
4
4
  require_relative 'config_loader'
5
5
  require_relative 'language'
6
6
  require_relative 'config_validator'
7
+ require_relative 'output'
8
+
7
9
  require 'pathname'
8
10
 
9
11
  module Spellr
@@ -11,9 +13,8 @@ module Spellr
11
13
  attr_writer :reporter
12
14
  attr_writer :checker
13
15
  attr_reader :config_file
14
- attr_accessor :quiet
15
- alias_method :quiet?, :quiet
16
16
  attr_accessor :dry_run
17
+ alias_method :dry_run?, :dry_run
17
18
 
18
19
  def initialize
19
20
  @config = ConfigLoader.new
@@ -45,14 +46,6 @@ module Spellr
45
46
  end
46
47
  end
47
48
 
48
- def pwd
49
- @pwd ||= Pathname.new(ENV['SPELLR_TEST_PWD'] || Dir.pwd)
50
- end
51
-
52
- def pwd_s
53
- @pwd_s ||= pwd.to_s
54
- end
55
-
56
49
  def languages_for(file)
57
50
  languages.select { |l| l.matches?(file) }
58
51
  end
@@ -66,12 +59,16 @@ module Spellr
66
59
  @config = ConfigLoader.new(value)
67
60
  end
68
61
 
62
+ def output
63
+ @output ||= Spellr::Output.new
64
+ end
65
+
69
66
  def reporter
70
67
  @reporter ||= default_reporter
71
68
  end
72
69
 
73
70
  def checker
74
- return dry_run_checker if @dry_run
71
+ return dry_run_checker if dry_run?
75
72
 
76
73
  @checker ||= default_checker
77
74
  end
@@ -106,10 +103,5 @@ module Spellr
106
103
  require_relative 'check_parallel'
107
104
  Spellr::CheckParallel
108
105
  end
109
-
110
- def clear_pwd
111
- remove_instance_variable(:@pwd) if defined?(@pwd)
112
- remove_instance_variable(:@pwd_s) if defined?(@pwd_s)
113
- end
114
106
  end
115
107
  end
@@ -5,9 +5,13 @@ require_relative 'backports'
5
5
 
6
6
  module Spellr
7
7
  class ConfigLoader
8
+ # :nocov:
9
+ using ::Spellr::YAMLSymbolizeNames if defined?(::Spellr::YAMLSymbolizeNames)
10
+ # :nocov:
11
+
8
12
  attr_reader :config_file
9
13
 
10
- def initialize(config_file = ::File.join(Dir.pwd, '.spellr.yml'))
14
+ def initialize(config_file = ::File.join(Spellr.pwd, '.spellr.yml'))
11
15
  @config_file = config_file
12
16
  end
13
17
 
@@ -23,9 +23,9 @@ module Spellr
23
23
 
24
24
  # I have no idea how to check for this other than call it
25
25
  Timeout.timeout(0.0000000000001) do
26
- $stdin.getch
26
+ Spellr.config.output.stdin.getch
27
27
  end
28
- rescue Errno::ENOTTY, Errno::ENODEV
28
+ rescue Errno::ENOTTY, Errno::ENODEV, IOError
29
29
  errors << 'CLI error: --interactive is unavailable in a non-interactive terminal'
30
30
  rescue Timeout::Error
31
31
  nil
@@ -4,27 +4,8 @@ require 'pathname'
4
4
 
5
5
  module Spellr
6
6
  class File < Pathname
7
- def self.wrap(file)
8
- file.is_a?(Spellr::File) ? file : Spellr::File.new(file)
9
- end
10
-
11
- # don't use FastIgnore shebang handling
12
- # because i use lots of different FastIgnore instances and each would to open the files.
13
- def hashbang
14
- @hashbang ||= begin
15
- return if extname != ''
16
- return unless first_line&.start_with?('#!')
17
-
18
- first_line
19
- end
20
- end
21
-
22
- def first_line
23
- @first_line ||= each_line.first
24
- end
25
-
26
7
  def relative_path
27
- @relative_path ||= relative_path_from(Spellr.config.pwd)
8
+ @relative_path ||= relative_path_from(Spellr.pwd)
28
9
  end
29
10
 
30
11
  def insert(string, range)
@@ -34,6 +15,24 @@ module Spellr
34
15
  end
35
16
  end
36
17
 
18
+ # the bulk of this method is copied from fast_ignore
19
+ def first_line # rubocop:disable Metrics/MethodLength
20
+ return @first_line if defined?(@first_line)
21
+
22
+ @first_line = nil
23
+
24
+ file = ::File.new(to_s)
25
+ @first_line = file.sysread(25)
26
+ @first_line += file.sysread(50) until @first_line.include?("\n")
27
+ file.close
28
+ @first_line
29
+ rescue ::EOFError, ::SystemCallError
30
+ # :nocov:
31
+ file&.close
32
+ # :nocov:
33
+ @first_line
34
+ end
35
+
37
36
  def read_write
38
37
  write(yield read)
39
38
  end
@@ -31,7 +31,8 @@ module Spellr
31
31
  ignore_rules: Spellr.config.excludes,
32
32
  include_rules: Spellr.config.includes,
33
33
  argv_rules: @patterns,
34
- root: Spellr.config.pwd_s
34
+ follow_symlinks: true,
35
+ root: Spellr.pwd_s
35
36
  )
36
37
  end
37
38
  end
@@ -126,7 +126,7 @@ module Spellr
126
126
  case stdin_getch("qaAsSrR?h\u0003\u0004")
127
127
  # :nocov:
128
128
  when 'q', "\u0003" # ctrl c
129
- exit 1
129
+ Spellr.exit 1
130
130
  when 'a', 'A'
131
131
  Spellr::InteractiveAdd.new(token, self)
132
132
  when 's', "\u0004" # ctrl d
@@ -18,7 +18,7 @@ module Spellr
18
18
  end
19
19
 
20
20
  def languages
21
- @languages ||= Spellr.config.languages_for(token.location.file.to_path)
21
+ @languages ||= Spellr.config.languages_for(token.location.file)
22
22
  end
23
23
 
24
24
  def addable_languages
@@ -7,6 +7,10 @@ require 'yaml'
7
7
  # https://www.sitepoint.com/machine-learning-ruby-naive-bayes-theorem/
8
8
 
9
9
  class NaiveBayes
10
+ # :nocov:
11
+ using ::Spellr::YAMLPermittedClasses if defined?(::Spellr::YAMLPermittedClasses)
12
+ # :nocov:
13
+
10
14
  YAML_PATH = File.join(__dir__, 'data.yml')
11
15
 
12
16
  attr_reader :feature_set
@@ -4,6 +4,9 @@ require_relative 'stats'
4
4
  require_relative '../backports'
5
5
 
6
6
  class PossibleKey # rubocop:disable Metrics/ClassLength
7
+ # :nocov:
8
+ using ::Spellr::HashSlice if defined?(::Spellr::HashSlice)
9
+ # :nocov:
7
10
  include Stats
8
11
 
9
12
  VOWELS = %i{
@@ -10,14 +10,10 @@ module Spellr
10
10
  attr_reader :name
11
11
  attr_reader :key
12
12
 
13
- def initialize(name, key: name[0], includes: [], hashbangs: [], locale: [], addable: true) # rubocop:disable Metrics/ParameterLists, Metrics/MethodLength
13
+ def initialize(name, key: name[0], includes: [], hashbangs: [], locale: [], addable: true) # rubocop:disable Metrics/ParameterLists
14
14
  @name = name
15
15
  @key = key
16
- @includes = includes
17
- @hashbangs = hashbangs
18
- unless hashbangs.empty?
19
- @hashbang_pattern = /\A#!.*\b(?:#{hashbangs.map { |s| Regexp.escape(s) }.join('|')})\b/
20
- end
16
+ @includes = includes + hashbangs.map { |h| "#!:#{h}" }
21
17
  @locales = Array(locale)
22
18
  @addable = addable
23
19
  end
@@ -26,39 +22,29 @@ module Spellr
26
22
  @addable
27
23
  end
28
24
 
29
- def matches?(file)
30
- matches_includes?(file) || matches_hashbangs?(file)
31
- end
32
-
33
25
  def wordlists
34
26
  default_wordlists.select(&:exist?)
35
27
  end
36
28
 
37
29
  def project_wordlist
38
30
  @project_wordlist ||= Spellr::Wordlist.new(
39
- Spellr.config.pwd.join('.spellr_wordlists', "#{name}.txt"),
31
+ Spellr.pwd.join('.spellr_wordlists', "#{name}.txt"),
40
32
  name: name
41
33
  )
42
34
  end
43
35
 
44
- private
45
-
46
- def matches_hashbangs?(file)
47
- return @includes.empty? unless @hashbang_pattern
48
-
49
- file = Spellr::File.wrap(file)
50
- return unless file.hashbang
36
+ def matches?(file)
37
+ return true if @includes.empty?
51
38
 
52
- @hashbang_pattern.match?(file.hashbang)
39
+ fast_ignore.allowed?(file.to_s, directory: false, content: file.first_line)
53
40
  end
54
41
 
55
- def matches_includes?(file)
56
- return @hashbangs.empty? if @includes.empty?
42
+ private
57
43
 
44
+ def fast_ignore
58
45
  @fast_ignore ||= FastIgnore.new(
59
- include_rules: @includes, gitignore: false, root: Spellr.config.pwd_s
46
+ include_rules: @includes, gitignore: false, root: Spellr.pwd_s
60
47
  )
61
- @fast_ignore.allowed?(file.to_s)
62
48
  end
63
49
 
64
50
  def gem_wordlist
@@ -7,24 +7,22 @@ module Spellr
7
7
  attr_reader :line_number
8
8
  attr_reader :char_offset
9
9
  attr_reader :byte_offset
10
+ attr_reader :file
10
11
 
11
- def initialize(file = '[String]', line_number = 1, char_offset: 0, byte_offset: 0)
12
- @filename = file
12
+ def initialize(
13
+ file = ::Spellr::File.new('[string]'),
14
+ line_number = 1,
15
+ char_offset: 0,
16
+ byte_offset: 0
17
+ )
18
+ @file = file
13
19
  @line_number = line_number
14
20
  @char_offset = char_offset
15
21
  @byte_offset = byte_offset
16
22
  end
17
23
 
18
24
  def to_s
19
- "#{file_relative_path}:#{line_number}"
20
- end
21
-
22
- def file_relative_path
23
- file.relative_path
24
- end
25
-
26
- def file
27
- @file ||= Spellr::File.wrap(@filename)
25
+ "#{file.relative_path}:#{line_number}"
28
26
  end
29
27
  end
30
28
  end
@@ -10,16 +10,15 @@ require_relative 'token_regexps'
10
10
  module Spellr
11
11
  class LineTokenizer < StringScanner
12
12
  attr_reader :line
13
- attr_accessor :disabled
14
- alias_method :disabled?, :disabled
15
- attr_accessor :skip_key
13
+ attr_reader :skip_key
16
14
  alias_method :skip_key?, :skip_key
17
15
 
18
16
  include TokenRegexps
19
17
 
20
- def initialize(line, skip_key: true)
18
+ def initialize(line, skip_key: false)
21
19
  @line = line
22
20
  @skip_key = skip_key
21
+ @disabled = false
23
22
 
24
23
  super(@line.to_s)
25
24
  end
@@ -32,7 +31,7 @@ module Spellr
32
31
  def each_term
33
32
  until eos?
34
33
  term = next_term
35
- next if !term || disabled?
34
+ next if !term || @disabled
36
35
 
37
36
  yield term
38
37
  end
@@ -42,7 +41,7 @@ module Spellr
42
41
  until eos?
43
42
  term = next_term
44
43
  next unless term
45
- next if disabled? || skip_term_proc&.call(term)
44
+ next if @disabled || skip_term_proc&.call(term)
46
45
 
47
46
  yield Token.new(term, line: line, location: column_location(term))
48
47
  end
@@ -78,6 +77,8 @@ module Spellr
78
77
  end
79
78
 
80
79
  def skip_key_heuristically
80
+ return unless skip_key?
81
+
81
82
  possible_key = check(POSSIBLE_KEY_RE)
82
83
 
83
84
  return unless possible_key
@@ -88,6 +89,7 @@ module Spellr
88
89
 
89
90
  BAYES_KEY_HEURISTIC = NaiveBayes.new
90
91
  def key?(possible_key)
92
+ return unless possible_key.length >= Spellr.config.key_minimum_length
91
93
  # I've come across some large base64 strings by this point they're definitely base64.
92
94
  return true if possible_key.length > 200
93
95
  return unless possible_key.match?(min_alpha_re) # or there's no point
@@ -96,15 +98,15 @@ module Spellr
96
98
  end
97
99
 
98
100
  def skip_and_track_disable
99
- return if disabled?
101
+ return if @disabled
100
102
 
101
- skip(SPELLR_DISABLE_RE) && self.disabled = true
103
+ skip(SPELLR_DISABLE_RE) && @disabled = true
102
104
  end
103
105
 
104
106
  def skip_and_track_enable
105
- return unless disabled?
107
+ return unless @disabled
106
108
 
107
- skip(SPELLR_ENABLE_RE) && self.disabled = false
109
+ skip(SPELLR_ENABLE_RE) && @disabled = false
108
110
  end
109
111
  end
110
112
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+
5
+ module Spellr
6
+ module_function
7
+
8
+ def pwd
9
+ @pwd ||= Pathname.pwd
10
+ end
11
+
12
+ def pwd_s
13
+ @pwd_s ||= pwd.to_s
14
+ end
15
+ end
@@ -49,9 +49,8 @@ module Spellr
49
49
  end
50
50
 
51
51
  def run(argv)
52
- Spellr::CLI.new(argv)
53
- rescue SystemExit => e
54
- raise unless e.status == 0
52
+ status = Spellr::CLI.new(argv).run
53
+ exit 1 unless status == 0
55
54
  end
56
55
 
57
56
  def argv_or_default(task_argv)
@@ -39,7 +39,7 @@ module Spellr
39
39
  location.char_offset...(location.char_offset + length)
40
40
  end
41
41
 
42
- def byte_range
42
+ def byte_range # leftovers:allow i don't want to delete this
43
43
  @byte_range ||=
44
44
  location.byte_offset...(location.byte_offset + bytesize)
45
45
  end
@@ -49,7 +49,7 @@ module Spellr
49
49
  location.absolute_char_offset...(location.absolute_char_offset + length)
50
50
  end
51
51
 
52
- def file_byte_range
52
+ def file_byte_range # leftovers:allow i don't want to delete this
53
53
  @file_byte_range ||=
54
54
  location.absolute_byte_offset...(location.absolute_byte_offset + bytesize)
55
55
  end
@@ -23,7 +23,6 @@ module Spellr
23
23
  LEFTOVER_NON_WORD_BITS_RE = %r{[/%#\\]|\d+}.freeze # e.g. a / not starting //a-url.com
24
24
  HEX_RE = /(?:#(?:\h{6}|\h{3})|0x\h+)(?![[:alpha:]])/.freeze
25
25
  SHELL_COLOR_ESCAPE_RE = /\\(?:e|0?33)\[\d+(;\d+)*m/.freeze
26
- PUNYCODE_RE = /xn--[a-v0-9\-]+(?:[[:alpha:]])/.freeze
27
26
  # TODO: hex escapes e.g. \xAA.
28
27
  # TODO: language aware escapes
29
28
  BACKSLASH_ESCAPE_RE = /\\[a-zA-Z]/.freeze
@@ -99,5 +98,6 @@ module Spellr
99
98
 
100
99
  SPELLR_DISABLE_RE = /spellr:disable/.freeze
101
100
  SPELLR_ENABLE_RE = /spellr:enable/.freeze
101
+ SPELLR_LINE_DISABLE_RE = /spellr:disable[-:]line/.freeze
102
102
  end
103
103
  end
@@ -7,13 +7,10 @@ require_relative 'line_tokenizer'
7
7
 
8
8
  module Spellr
9
9
  class Tokenizer
10
- attr_reader :file
11
- attr_reader :start_at
12
-
13
- attr_accessor :disabled
14
- alias_method :disabled?, :disabled
10
+ attr_reader :file, :filename
15
11
 
16
12
  def initialize(file, start_at: nil, skip_key: true)
13
+ @filename = file
17
14
  @start_at = start_at || ColumnLocation.new(line_location: LineLocation.new(file))
18
15
  @file = file.is_a?(StringIO) || file.is_a?(IO) ? file : ::File.new(file)
19
16
  @file.pos = @start_at.line_location.byte_offset
@@ -21,7 +18,7 @@ module Spellr
21
18
  @line_tokenizer = LineTokenizer.new('', skip_key: skip_key)
22
19
  end
23
20
 
24
- def terms
21
+ def terms # leftovers:test
25
22
  enum_for(:each_term).to_a
26
23
  end
27
24
 
@@ -31,7 +28,7 @@ module Spellr
31
28
 
32
29
  def each_term(&block)
33
30
  file.each_line do |line|
34
- prepare_tokenizer_for_line(line).each_term(&block)
31
+ prepare_tokenizer_for_line(line)&.each_term(&block)
35
32
  end
36
33
  ensure
37
34
  file.close
@@ -39,7 +36,7 @@ module Spellr
39
36
 
40
37
  def each_token(skip_term_proc: nil) # rubocop:disable Metrics/MethodLength
41
38
  each_line_with_stats do |line, line_number, char_offset, byte_offset|
42
- prepare_tokenizer_for_line(line).each_token(skip_term_proc: skip_term_proc) do |token|
39
+ prepare_tokenizer_for_line(line)&.each_token(skip_term_proc: skip_term_proc) do |token|
43
40
  token.line = prepare_line(line, line_number, char_offset, byte_offset)
44
41
 
45
42
  yield token
@@ -49,7 +46,7 @@ module Spellr
49
46
 
50
47
  def prepare_line(line, line_number, char_offset, byte_offset)
51
48
  line_location = LineLocation.new(
52
- file, line_number, char_offset: char_offset, byte_offset: byte_offset
49
+ filename, line_number, char_offset: char_offset, byte_offset: byte_offset
53
50
  )
54
51
  column_location = ColumnLocation.new(line_location: line_location)
55
52
  Token.new(line, location: column_location)
@@ -78,6 +75,8 @@ module Spellr
78
75
  attr_reader :line_tokenizer
79
76
 
80
77
  def prepare_tokenizer_for_line(line)
78
+ return if line.match?(Spellr::TokenRegexps::SPELLR_LINE_DISABLE_RE)
79
+
81
80
  line_tokenizer.string = line
82
81
  line_tokenizer.pos = 0
83
82
  line_tokenizer
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spellr
4
- VERSION = '0.8.0'
4
+ VERSION = '0.8.5'
5
5
  end
@@ -12,7 +12,7 @@ module Spellr
12
12
 
13
13
  def initialize(file, name: file)
14
14
  path = @file = file
15
- @path = Spellr.config.pwd.join('.spellr_wordlists').join(path).expand_path
15
+ @path = Spellr.pwd.join('.spellr_wordlists').join(path).expand_path
16
16
  @name = name
17
17
  @include = {}
18
18
  end
@@ -6,7 +6,7 @@ require_relative 'base_reporter'
6
6
  module Spellr
7
7
  class WordlistReporter < Spellr::BaseReporter
8
8
  def finish
9
- output.puts words.sort.join
9
+ puts words.sort.join unless words.empty?
10
10
  end
11
11
 
12
12
  def call(token)
@@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.require_paths = ['lib']
29
29
 
30
30
  spec.add_development_dependency 'bundler', '~> 2.0'
31
+ spec.add_development_dependency 'leftovers', '>= 0.2.2'
31
32
  spec.add_development_dependency 'mime-types', '~> 3.3.1'
32
33
  spec.add_development_dependency 'nokogiri'
33
34
  spec.add_development_dependency 'pry'
@@ -40,6 +41,6 @@ Gem::Specification.new do |spec|
40
41
  spec.add_development_dependency 'tty_string', '>= 0.2.1'
41
42
  spec.add_development_dependency 'webmock', '~> 3.8'
42
43
 
43
- spec.add_dependency 'fast_ignore', '>= 0.6.0'
44
+ spec.add_dependency 'fast_ignore', '>= 0.11.0'
44
45
  spec.add_dependency 'parallel', '~> 1.0'
45
46
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spellr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dana Sherson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-04-18 00:00:00.000000000 Z
11
+ date: 2020-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: leftovers
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.2
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.2.2
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: mime-types
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -184,14 +198,14 @@ dependencies:
184
198
  requirements:
185
199
  - - ">="
186
200
  - !ruby/object:Gem::Version
187
- version: 0.6.0
201
+ version: 0.11.0
188
202
  type: :runtime
189
203
  prerelease: false
190
204
  version_requirements: !ruby/object:Gem::Requirement
191
205
  requirements:
192
206
  - - ">="
193
207
  - !ruby/object:Gem::Version
194
- version: 0.6.0
208
+ version: 0.11.0
195
209
  - !ruby/object:Gem::Dependency
196
210
  name: parallel
197
211
  requirement: !ruby/object:Gem::Requirement
@@ -247,6 +261,7 @@ files:
247
261
  - lib/spellr/line_tokenizer.rb
248
262
  - lib/spellr/output.rb
249
263
  - lib/spellr/output_stubbed.rb
264
+ - lib/spellr/pwd.rb
250
265
  - lib/spellr/quiet_reporter.rb
251
266
  - lib/spellr/rake_task.rb
252
267
  - lib/spellr/reporter.rb
@@ -300,7 +315,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
300
315
  - !ruby/object:Gem::Version
301
316
  version: '0'
302
317
  requirements: []
303
- rubygems_version: 3.0.3
318
+ rubygems_version: 3.0.8
304
319
  signing_key:
305
320
  specification_version: 4
306
321
  summary: Spell check your source code