spellr 0.8.1 → 0.8.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e045b4e7f76fa43573c0e28564a4f532dbcc9b35f05ca682e7302274ce0bdbc
4
- data.tar.gz: 2918d1f1c2a41c681dc7370180ead18a63a86f991032140f0dea1ac92faad3b0
3
+ metadata.gz: 31be9d119f5909486cfd46089d224e0bf1a47b815951766fc138bf1a6637dec3
4
+ data.tar.gz: b621fac32ca57cd912b0167cd02f0fb998c2366b8160247324f2f9e190638704
5
5
  SHA512:
6
- metadata.gz: d44c69a61badacc0a792f2ec60794847ea722101fc46e5fdce717562e2f3923ce6d95624af75d6c31e4cdcf2e6b017aaa7aa87c28a3f3b3761591658fcea6770
7
- data.tar.gz: a607bcdf971179b58c7a1fc4fbf433ef4312724910c74f3731dd5df1127ccc2c9059d836564f00456656d19dfad39b62707663baffd1349bb93352a20f83f9b8
6
+ metadata.gz: 7a701cb79672ac340ac8d688b1b859189647ed4e1cb0d7c0b869cf55517287330cbf3144283a25a151c36ac00ee7aa1c2da0ee322be3c2e8aabd409b0f104ec8
7
+ data.tar.gz: 88a37834530501ddfe3bd5e63c667b97a8b0b282fc71b40ab9040e06725bc235798c86d28f1f817ec332f7018bdfcef69f951ad854d93e02b797efdd62b7ef04
@@ -1,3 +1,22 @@
1
+ # v0.8.6
2
+ - `--suppress--file-rules` so you can check files that would usually be ignored
3
+
4
+ # v0.8.5
5
+ - Single line disable! use `spellr:disable-line` #25
6
+
7
+ # v0.8.4
8
+ - Update fast_ignore dependency, it's faster now (about 0.5s faster on rails codebase)
9
+
10
+ # v0.8.3
11
+ - Update fast_ignore dependency fixing symlinks to directories handling.
12
+
13
+ # v0.8.2
14
+ - Massive test refactor
15
+ - Spellr now only pays attention to Spellr.pwd. Dir.pwd can be whatever
16
+ - All output goes through Spellr.config.output. Now we can override it.
17
+ - tests are twice as fast. Fewer warnings
18
+ - upgrade fast_ignore dependency
19
+
1
20
  # v0.8.1
2
21
  - use refinements for backports so that RakeTask doesn't conflict with Rubocop::RakeTask
3
22
 
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Spellr
2
2
 
3
+ [![Build Status](https://travis-ci.com/robotdana/spellr.svg?branch=main)](https://travis-ci.com/robotdana/spellr)
3
4
  [![Gem Version](https://badge.fury.io/rb/spellr.svg)](https://rubygems.org/gems/spellr)
4
- [![Build Status](https://travis-ci.org/robotdana/spellr.svg?branch=master)](https://travis-ci.org/robotdana/spellr)
5
5
 
6
6
  Spell check your source code for fun and occasionally finding bugs
7
7
 
@@ -175,20 +175,27 @@ 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
  ```
189
196
  ## Configuration
190
197
 
191
- Spellr's configuration is a `.spellr.yml` file in your project root. This is combined with the gem defaults defined [here](https://github.com/robotdana/spellr/blob/master/lib/.spellr.yml).
198
+ Spellr's configuration is a `.spellr.yml` file in your project root. This is combined with the gem defaults defined [here](https://github.com/robotdana/spellr/blob/main/lib/.spellr.yml).
192
199
  There are top-level keys and per-language keys.
193
200
  ```yml
194
201
  word_minimum_length: 3 # any words shorter than this will be ignored
@@ -297,6 +304,18 @@ Spellr::RakeTask.generate_task(:spellr, **spellr_arguments)
297
304
  task default: :spellr
298
305
  ```
299
306
 
307
+ ## Ignoring the configured patterns
308
+
309
+ Sometimes you'll want to spell check something that would usually be ignored,
310
+ e.g. `.git/COMMIT_EDITMSG` even though `spellr` ignores the `.git` directory.
311
+
312
+ For this you can use the `--suppress-file-rules` command line argument.
313
+ ```bash
314
+ $ spellr --suppress-file-rules .git/COMMIT_EDITMSG
315
+ ```
316
+
317
+ **Note: This still ignores files outside of the current directory**
318
+
300
319
  ## Development
301
320
 
302
321
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
@@ -310,4 +329,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/robotd
310
329
  ## License
311
330
 
312
331
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
313
- Wordlists packaged with this gem have their own licenses, see them in https://github.com/robotdana/spellr/tree/master/wordlists
332
+ Wordlists packaged with this gem have their own licenses, see them in https://github.com/robotdana/spellr/tree/main/wordlists
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
@@ -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
 
@@ -26,6 +28,9 @@ module Spellr
26
28
  opts.separator('')
27
29
  opts.on('--[no-]parallel', 'Run in parallel or not, default --parallel', &method(:parallel_option))
28
30
  opts.on('-d', '--dry-run', 'List files to be checked', &method(:dry_run_option))
31
+ opts.on('-f', '--suppress-file-rules', <<~HELP, &method(:suppress_file_rules))
32
+ Suppress all configured, default, and gitignore include and exclude patterns
33
+ HELP
29
34
  opts.separator('')
30
35
  opts.on('-c', '--config FILENAME', String, <<~HELP, &method(:config_option))
31
36
  Path to the config file (default ./.spellr.yml)
@@ -43,7 +48,6 @@ module Spellr
43
48
  end
44
49
 
45
50
  def quiet_option(_)
46
- Spellr.config.quiet = true
47
51
  require_relative 'quiet_reporter'
48
52
  Spellr.config.reporter = Spellr::QuietReporter.new
49
53
  end
@@ -55,8 +59,12 @@ module Spellr
55
59
  Spellr.config.checker = Spellr::CheckInteractive unless @parallel_option
56
60
  end
57
61
 
62
+ def suppress_file_rules(_)
63
+ Spellr.config.suppress_file_rules = true
64
+ end
65
+
58
66
  def config_option(file)
59
- file = Pathname.pwd.join(file).expand_path
67
+ file = Spellr.pwd.join(file).expand_path
60
68
 
61
69
  unless ::File.readable?(file)
62
70
  raise Spellr::Config::NotFound, "Config error: #{file} not found or not readable"
@@ -82,15 +90,15 @@ module Spellr
82
90
 
83
91
  def version_option(_)
84
92
  require_relative 'version'
85
- puts(Spellr::VERSION)
93
+ Spellr.config.output.puts(Spellr::VERSION)
86
94
 
87
- exit
95
+ Spellr.exit
88
96
  end
89
97
 
90
98
  def options_help(_)
91
- puts options.help
99
+ Spellr.config.output.puts options.help
92
100
 
93
- exit
101
+ Spellr.exit
94
102
  end
95
103
  end
96
104
  end
@@ -4,8 +4,8 @@ require_relative 'line_location'
4
4
 
5
5
  module Spellr
6
6
  class ColumnLocation
7
- attr_reader :char_offset
8
- attr_reader :byte_offset
7
+ attr_reader :char_offset, :byte_offset
8
+
9
9
  attr_accessor :line_location
10
10
 
11
11
  def initialize(char_offset: 0, byte_offset: 0, line_location: LineLocation.new)
@@ -4,16 +4,18 @@ 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
10
12
  class Config
11
- attr_writer :reporter
12
- attr_writer :checker
13
+ attr_writer :reporter, :checker
14
+
15
+ attr_accessor :suppress_file_rules, :dry_run
16
+
13
17
  attr_reader :config_file
14
- attr_accessor :quiet
15
- alias_method :quiet?, :quiet
16
- attr_accessor :dry_run
18
+ alias_method :dry_run?, :dry_run
17
19
 
18
20
  def initialize
19
21
  @config = ConfigLoader.new
@@ -45,14 +47,6 @@ module Spellr
45
47
  end
46
48
  end
47
49
 
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
50
  def languages_for(file)
57
51
  languages.select { |l| l.matches?(file) }
58
52
  end
@@ -66,12 +60,16 @@ module Spellr
66
60
  @config = ConfigLoader.new(value)
67
61
  end
68
62
 
63
+ def output
64
+ @output ||= Spellr::Output.new
65
+ end
66
+
69
67
  def reporter
70
68
  @reporter ||= default_reporter
71
69
  end
72
70
 
73
71
  def checker
74
- return dry_run_checker if @dry_run
72
+ return dry_run_checker if dry_run?
75
73
 
76
74
  @checker ||= default_checker
77
75
  end
@@ -80,7 +78,7 @@ module Spellr
80
78
  Spellr::ConfigValidator.new.valid?
81
79
  end
82
80
 
83
- def reset! # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
81
+ def reset! # rubocop:disable Metrics/MethodLength
84
82
  @config = ConfigLoader.new
85
83
  remove_instance_variable(:@languages) if defined?(@languages)
86
84
  remove_instance_variable(:@excludes) if defined?(@excludes)
@@ -106,10 +104,5 @@ module Spellr
106
104
  require_relative 'check_parallel'
107
105
  Spellr::CheckParallel
108
106
  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
107
  end
115
108
  end
@@ -11,7 +11,7 @@ module Spellr
11
11
 
12
12
  attr_reader :config_file
13
13
 
14
- def initialize(config_file = ::File.join(Dir.pwd, '.spellr.yml'))
14
+ def initialize(config_file = ::File.join(Spellr.pwd, '.spellr.yml'))
15
15
  @config_file = config_file
16
16
  end
17
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
@@ -26,12 +26,21 @@ module Spellr
26
26
 
27
27
  private
28
28
 
29
+ def configured_rules
30
+ return { gitignore: false } if Spellr.config.suppress_file_rules
31
+
32
+ {
33
+ ignore_rules: Spellr.config.excludes,
34
+ include_rules: Spellr.config.includes
35
+ }
36
+ end
37
+
29
38
  def fast_ignore # rubocop:disable Metrics/MethodLength
30
39
  FastIgnore.new(
31
- ignore_rules: Spellr.config.excludes,
32
- include_rules: Spellr.config.includes,
40
+ **configured_rules,
33
41
  argv_rules: @patterns,
34
- root: Spellr.config.pwd_s
42
+ follow_symlinks: true,
43
+ root: Spellr.pwd_s
35
44
  )
36
45
  end
37
46
  end
@@ -58,7 +58,7 @@ module Spellr
58
58
  Process.clock_gettime(Process::CLOCK_MONOTONIC)
59
59
  end
60
60
 
61
- def stdin_getch(legal_chars) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
61
+ def stdin_getch(legal_chars) # rubocop:disable Metrics/MethodLength
62
62
  choice = output.stdin.getch
63
63
 
64
64
  if legal_chars.include?(choice)
@@ -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
@@ -13,10 +13,7 @@ class NaiveBayes
13
13
 
14
14
  YAML_PATH = File.join(__dir__, 'data.yml')
15
15
 
16
- attr_reader :feature_set
17
- attr_reader :num_classes
18
- attr_reader :classes
19
- attr_reader :features
16
+ attr_reader :feature_set, :num_classes, :classes, :features
20
17
 
21
18
  def initialize(path = YAML_PATH)
22
19
  load_from_yaml(path)
@@ -7,17 +7,12 @@ require 'fast_ignore'
7
7
 
8
8
  module Spellr
9
9
  class Language
10
- attr_reader :name
11
- attr_reader :key
10
+ attr_reader :name, :key
12
11
 
13
- def initialize(name, key: name[0], includes: [], hashbangs: [], locale: [], addable: true) # rubocop:disable Metrics/ParameterLists, Metrics/MethodLength
12
+ def initialize(name, key: name[0], includes: [], hashbangs: [], locale: [], addable: true) # rubocop:disable Metrics/ParameterLists
14
13
  @name = name
15
14
  @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
15
+ @includes = includes + hashbangs.map { |h| "#!:#{h}" }
21
16
  @locales = Array(locale)
22
17
  @addable = addable
23
18
  end
@@ -26,39 +21,29 @@ module Spellr
26
21
  @addable
27
22
  end
28
23
 
29
- def matches?(file)
30
- matches_includes?(file) || matches_hashbangs?(file)
31
- end
32
-
33
24
  def wordlists
34
25
  default_wordlists.select(&:exist?)
35
26
  end
36
27
 
37
28
  def project_wordlist
38
29
  @project_wordlist ||= Spellr::Wordlist.new(
39
- Spellr.config.pwd.join('.spellr_wordlists', "#{name}.txt"),
30
+ Spellr.pwd.join('.spellr_wordlists', "#{name}.txt"),
40
31
  name: name
41
32
  )
42
33
  end
43
34
 
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
35
+ def matches?(file)
36
+ return true if @includes.empty?
51
37
 
52
- @hashbang_pattern.match?(file.hashbang)
38
+ fast_ignore.allowed?(file.to_s, directory: false, content: file.first_line)
53
39
  end
54
40
 
55
- def matches_includes?(file)
56
- return @hashbangs.empty? if @includes.empty?
41
+ private
57
42
 
43
+ def fast_ignore
58
44
  @fast_ignore ||= FastIgnore.new(
59
- include_rules: @includes, gitignore: false, root: Spellr.config.pwd_s
45
+ include_rules: @includes, gitignore: false, root: Spellr.pwd_s
60
46
  )
61
- @fast_ignore.allowed?(file.to_s)
62
47
  end
63
48
 
64
49
  def gem_wordlist
@@ -4,27 +4,22 @@ require_relative 'file'
4
4
 
5
5
  module Spellr
6
6
  class LineLocation
7
- attr_reader :line_number
8
- attr_reader :char_offset
9
- attr_reader :byte_offset
7
+ attr_reader :line_number, :char_offset, :byte_offset, :file
10
8
 
11
- def initialize(file = '[String]', line_number = 1, char_offset: 0, byte_offset: 0)
12
- @filename = file
9
+ def initialize(
10
+ file = ::Spellr::File.new('[string]'),
11
+ line_number = 1,
12
+ char_offset: 0,
13
+ byte_offset: 0
14
+ )
15
+ @file = file
13
16
  @line_number = line_number
14
17
  @char_offset = char_offset
15
18
  @byte_offset = byte_offset
16
19
  end
17
20
 
18
21
  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)
22
+ "#{file.relative_path}:#{line_number}"
28
23
  end
29
24
  end
30
25
  end
@@ -9,17 +9,16 @@ require_relative 'token_regexps'
9
9
 
10
10
  module Spellr
11
11
  class LineTokenizer < StringScanner
12
- attr_reader :line
13
- attr_accessor :disabled
14
- alias_method :disabled?, :disabled
15
- attr_accessor :skip_key
12
+ attr_reader :line, :skip_key
13
+
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
@@ -16,7 +16,7 @@ module Spellr
16
16
  @stderr ||= StringIO.new
17
17
  end
18
18
 
19
- def marshal_dump # rubocop:disable Metrics/MethodLength
19
+ def marshal_dump # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
20
20
  l_exit_code = @exit_code if defined?(@exit_code)
21
21
  l_counts = @counts if defined?(@counts)
22
22
  l_stdin = @stdin if defined?(@stdin)
@@ -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.1'
4
+ VERSION = '0.8.6'
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)
@@ -14,6 +14,12 @@ Gem::Specification.new do |spec|
14
14
  spec.homepage = 'http://github.com/robotdana/spellr'
15
15
  spec.license = 'MIT'
16
16
 
17
+ if spec.respond_to?(:metadata)
18
+ spec.metadata['homepage_uri'] = spec.homepage
19
+ spec.metadata['source_code_uri'] = spec.homepage
20
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
21
+ end
22
+
17
23
  spec.required_ruby_version = '>= 2.4'
18
24
 
19
25
  spec.files = Dir.glob('{lib,exe,wordlists}/**/{*,.*}') + %w{
@@ -28,6 +34,7 @@ Gem::Specification.new do |spec|
28
34
  spec.require_paths = ['lib']
29
35
 
30
36
  spec.add_development_dependency 'bundler', '~> 2.0'
37
+ spec.add_development_dependency 'leftovers', '>= 0.2.2'
31
38
  spec.add_development_dependency 'mime-types', '~> 3.3.1'
32
39
  spec.add_development_dependency 'nokogiri'
33
40
  spec.add_development_dependency 'pry'
@@ -40,6 +47,6 @@ Gem::Specification.new do |spec|
40
47
  spec.add_development_dependency 'tty_string', '>= 0.2.1'
41
48
  spec.add_development_dependency 'webmock', '~> 3.8'
42
49
 
43
- spec.add_dependency 'fast_ignore', '>= 0.6.0'
50
+ spec.add_dependency 'fast_ignore', '>= 0.11.0'
44
51
  spec.add_dependency 'parallel', '~> 1.0'
45
52
  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.1
4
+ version: 0.8.6
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-08-15 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
@@ -284,7 +299,10 @@ files:
284
299
  homepage: http://github.com/robotdana/spellr
285
300
  licenses:
286
301
  - MIT
287
- metadata: {}
302
+ metadata:
303
+ homepage_uri: http://github.com/robotdana/spellr
304
+ source_code_uri: http://github.com/robotdana/spellr
305
+ changelog_uri: http://github.com/robotdana/spellr/blob/main/CHANGELOG.md
288
306
  post_install_message:
289
307
  rdoc_options: []
290
308
  require_paths:
@@ -300,7 +318,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
300
318
  - !ruby/object:Gem::Version
301
319
  version: '0'
302
320
  requirements: []
303
- rubygems_version: 3.0.3
321
+ rubygems_version: 3.0.8
304
322
  signing_key:
305
323
  specification_version: 4
306
324
  summary: Spell check your source code