spellr 0.6.0 → 0.7.0

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/README.md +34 -15
  4. data/exe/spellr +8 -1
  5. data/lib/spellr/backports.rb +48 -21
  6. data/lib/spellr/base_reporter.rb +0 -4
  7. data/lib/spellr/check.rb +7 -47
  8. data/lib/spellr/check_dry_run.rb +14 -0
  9. data/lib/spellr/check_interactive.rb +24 -0
  10. data/lib/spellr/check_parallel.rb +23 -0
  11. data/lib/spellr/cli.rb +5 -90
  12. data/lib/spellr/cli_options.rb +98 -0
  13. data/lib/spellr/column_location.rb +2 -4
  14. data/lib/spellr/config.rb +39 -41
  15. data/lib/spellr/config_loader.rb +3 -29
  16. data/lib/spellr/config_validator.rb +63 -0
  17. data/lib/spellr/file_list.rb +7 -24
  18. data/lib/spellr/interactive.rb +80 -45
  19. data/lib/spellr/interactive_add.rb +20 -16
  20. data/lib/spellr/interactive_replacement.rb +52 -29
  21. data/lib/spellr/key_tuner/naive_bayes.rb +7 -59
  22. data/lib/spellr/key_tuner/possible_key.rb +5 -24
  23. data/lib/spellr/key_tuner/stats.rb +2 -0
  24. data/lib/spellr/language.rb +7 -8
  25. data/lib/spellr/line_location.rb +2 -7
  26. data/lib/spellr/line_tokenizer.rb +1 -9
  27. data/lib/spellr/output.rb +5 -7
  28. data/lib/spellr/output_stubbed.rb +16 -16
  29. data/lib/spellr/quiet_reporter.rb +1 -0
  30. data/lib/spellr/reporter.rb +0 -4
  31. data/lib/spellr/string_format.rb +8 -15
  32. data/lib/spellr/token.rb +13 -29
  33. data/lib/spellr/token_regexps.rb +2 -2
  34. data/lib/spellr/tokenizer.rb +0 -10
  35. data/lib/spellr/validations.rb +31 -0
  36. data/lib/spellr/version.rb +1 -1
  37. data/lib/spellr/wordlist.rb +9 -17
  38. data/lib/spellr/wordlist_reporter.rb +0 -4
  39. data/lib/spellr.rb +12 -0
  40. data/spellr.gemspec +12 -7
  41. data/wordlists/ruby.txt +1 -0
  42. metadata +59 -26
@@ -9,8 +9,13 @@ require 'yaml'
9
9
  class NaiveBayes
10
10
  YAML_PATH = File.join(__dir__, 'data.yml')
11
11
 
12
+ attr_reader :feature_set
13
+ attr_reader :num_classes
14
+ attr_reader :classes
15
+ attr_reader :features
16
+
12
17
  def initialize(path = YAML_PATH)
13
- load_from_yaml(path) if File.exist?(path)
18
+ load_from_yaml(path)
14
19
  @key = {}
15
20
  end
16
21
 
@@ -21,7 +26,7 @@ class NaiveBayes
21
26
  end
22
27
 
23
28
  def load_from_yaml(path = YAML_PATH)
24
- data = YAML.safe_load(::File.read(path), [Symbol])
29
+ data = YAML.safe_load(::File.read(path), permitted_classes: [Symbol])
25
30
 
26
31
  @feature_set = data[:feature_set]
27
32
  @num_classes = data[:num_classes]
@@ -29,63 +34,6 @@ class NaiveBayes
29
34
  @features = data[:features]
30
35
  end
31
36
 
32
- def save_to_yaml(path = YAML_PATH)
33
- write_yaml(path,
34
- feature_set: feature_set,
35
- num_classes: num_classes,
36
- classes: classes,
37
- features: features)
38
- end
39
-
40
- private
41
-
42
- def write_yaml(path = YAML_PATH, **hash)
43
- require 'yaml'
44
-
45
- File.write(path, hash.to_yaml)
46
- end
47
-
48
- def training_data
49
- @training_data ||= PossibleKey.keys.each_with_object({}) do |key, data|
50
- data[key.classification] ||= []
51
- data[key.classification] << key.features
52
- end
53
- end
54
-
55
- def num_classes
56
- @num_classes ||= training_data&.length
57
- end
58
-
59
- def classes
60
- @classes ||= training_data&.keys
61
- end
62
-
63
- def features
64
- @features ||= training_data.first.last.first.keys
65
- end
66
-
67
- def feature_set
68
- @feature_set ||= classes.each.with_object({}) do |class_name, feature_set|
69
- feature_set[class_name] = features.each.with_object({}) do |feature, feature_set_for_class|
70
- feature_set_for_class[feature] = feature_stats_for_class(class_name, feature)
71
- end
72
- end
73
- end
74
-
75
- def feature_stats_for_class(class_name, feature)
76
- values = training_data[class_name].map { |row| row[feature] }
77
-
78
- feature_stats(values)
79
- end
80
-
81
- def feature_stats(values)
82
- {
83
- standard_deviation: Stats.standard_deviation(values),
84
- mean: Stats.mean(values),
85
- variance: Stats.variance(values)
86
- }
87
- end
88
-
89
37
  # given a class, this method determines the probability
90
38
  # of a certain value occurring for a given feature
91
39
  # feature: name of the feature in consideration in the training data
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'pathname'
4
3
  require_relative 'stats'
4
+ require_relative '../backports'
5
5
 
6
6
  class PossibleKey # rubocop:disable Metrics/ClassLength
7
7
  include Stats
@@ -15,29 +15,11 @@ class PossibleKey # rubocop:disable Metrics/ClassLength
15
15
  B C D F G H J K L M N P Q R S T V W X Y Z
16
16
  }.freeze
17
17
  BASE_64 = VOWELS + CONSONANTS + %i{0 1 2 3 4 5 6 7 8 9 - _ + / =}.freeze
18
- LETTER_COUNT_HASH = BASE_64.map { |k| [k.to_sym, 0] }.to_h
18
+ letter_count_hash = BASE_64.map { |k| [k.to_sym, 0] }.to_h
19
+ letter_count_hash.default = 0
20
+ LETTER_COUNT_HASH = letter_count_hash
19
21
  FEATURE_LETTERS = %i{+ - _ / A z Z q Q X x}.freeze
20
22
 
21
- class << self
22
- def keys
23
- @keys ||= begin
24
- load_from_file('false_positives.txt', false) +
25
- load_from_file('keys.txt', true)
26
- end
27
- end
28
-
29
- private
30
-
31
- def load_from_file(filename, key)
32
- Pathname.new(__dir__).join('data', filename).each_line.map! do |line|
33
- line = line.chomp
34
- next if line.empty?
35
-
36
- PossibleKey.new(line, key)
37
- end.compact
38
- end
39
- end
40
-
41
23
  attr_reader :string
42
24
 
43
25
  def initialize(string, key = nil)
@@ -100,8 +82,6 @@ class PossibleKey # rubocop:disable Metrics/ClassLength
100
82
  when /^[a-z0-9]+$/ then :lower36
101
83
  when /^[A-Z0-9]+$/ then :upper36
102
84
  when %r{^[A-Za-z0-9\-_+/]+={0,2}$} then :base64
103
- else
104
- raise "#{string.inspect} is an unrecognised character set"
105
85
  end
106
86
  end
107
87
 
@@ -111,6 +91,7 @@ class PossibleKey # rubocop:disable Metrics/ClassLength
111
91
  when :lower36 then 36
112
92
  when :upper36 then 36
113
93
  when :base64 then 64
94
+ else 0
114
95
  end
115
96
  end
116
97
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative '../backports'
4
+
3
5
  module Stats
4
6
  module_function
5
7
 
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'wordlist'
4
+ require_relative 'file'
5
+ require 'pathname'
6
+ require 'fast_ignore'
4
7
 
5
8
  module Spellr
6
9
  class Language
@@ -30,7 +33,7 @@ module Spellr
30
33
 
31
34
  def project_wordlist
32
35
  @project_wordlist ||= Spellr::Wordlist.new(
33
- Pathname.pwd.join('.spellr_wordlists', "#{name}.txt"),
36
+ Spellr.config.pwd.join('.spellr_wordlists', "#{name}.txt"),
34
37
  name: name
35
38
  )
36
39
  end
@@ -49,7 +52,9 @@ module Spellr
49
52
  def matches_includes?(file)
50
53
  return @hashbangs.empty? if @includes.empty?
51
54
 
52
- @fast_ignore ||= FastIgnore.new(include_rules: @includes, gitignore: false)
55
+ @fast_ignore ||= FastIgnore.new(
56
+ include_rules: @includes, gitignore: false, root: Spellr.config.pwd_s
57
+ )
53
58
  @fast_ignore.allowed?(file.to_s)
54
59
  end
55
60
 
@@ -67,12 +72,6 @@ module Spellr
67
72
  end
68
73
  end
69
74
 
70
- def load_wordlists(name, paths)
71
- wordlists = paths + default_wordlist_paths(name)
72
-
73
- wordlists.map(&Spellr::Wordlist.method(:new))
74
- end
75
-
76
75
  def default_wordlists
77
76
  [
78
77
  gem_wordlist,
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'file'
4
+
3
5
  module Spellr
4
6
  class LineLocation
5
7
  attr_reader :line_number
@@ -24,12 +26,5 @@ module Spellr
24
26
  def file
25
27
  @file ||= Spellr::File.wrap(@filename)
26
28
  end
27
-
28
- def advance(line)
29
- LineLocation.new(@filename,
30
- line_number + 1,
31
- char_offset: char_offset + line.length,
32
- byte_offset: byte_offset + line.bytesize)
33
- end
34
29
  end
35
30
  end
@@ -48,19 +48,12 @@ module Spellr
48
48
  end
49
49
  end
50
50
 
51
- # jump to character-aware position
52
- # TODO: handle jump backward
53
- def charpos=(new_charpos)
54
- skip(/.{#{new_charpos - charpos}}/m)
55
- end
56
-
57
51
  private
58
52
 
59
53
  def column_location(term)
60
54
  ColumnLocation.new(
61
55
  byte_offset: pos - term.bytesize,
62
- char_offset: charpos - term.length,
63
- **(line.respond_to?(:location) ? { line_location: line.location.line_location } : {})
56
+ char_offset: charpos - term.length
64
57
  )
65
58
  end
66
59
 
@@ -97,7 +90,6 @@ module Spellr
97
90
  def key?(possible_key)
98
91
  # I've come across some large base64 strings by this point they're definitely base64.
99
92
  return true if possible_key.length > 200
100
- return unless possible_key.length >= Spellr.config.key_minimum_length
101
93
  return unless possible_key.match?(min_alpha_re) # or there's no point
102
94
 
103
95
  BAYES_KEY_HEURISTIC.key?(possible_key)
data/lib/spellr/output.rb CHANGED
@@ -2,10 +2,8 @@
2
2
 
3
3
  module Spellr
4
4
  class Output
5
- attr_reader :exit_code
6
-
7
- def initialize
8
- @exit_code = 0
5
+ def exit_code
6
+ @exit_code ||= 0
9
7
  end
10
8
 
11
9
  def stdin
@@ -52,10 +50,10 @@ module Spellr
52
50
  stdout.print(str)
53
51
  end
54
52
 
55
- def <<(other) # rubocop:disable Metrics/AbcSize
53
+ def <<(other)
56
54
  self.exit_code = other.exit_code
57
- stderr.puts other.stderr.string if other.stderr?
58
- stdout.puts other.stdout.string if other.stdout?
55
+ warn other.stderr.string if other.stderr?
56
+ puts other.stdout.string if other.stdout?
59
57
  counts.merge!(other.counts) { |_k, a, b| a + b }
60
58
  end
61
59
  end
@@ -4,12 +4,6 @@ require_relative 'output'
4
4
 
5
5
  module Spellr
6
6
  class OutputStubbed < Spellr::Output
7
- attr_accessor :exit_code
8
-
9
- def initialize
10
- @exit_code = 0
11
- end
12
-
13
7
  def stdin
14
8
  @stdin ||= StringIO.new
15
9
  end
@@ -23,15 +17,21 @@ module Spellr
23
17
  end
24
18
 
25
19
  def marshal_dump # rubocop:disable Metrics/MethodLength
20
+ l_exit_code = @exit_code if defined?(@exit_code)
21
+ l_counts = @counts if defined?(@counts)
22
+ l_stdin = @stdin if defined?(@stdin)
23
+ l_stdout = @stdout if defined?(@stdout)
24
+ l_stderr = @stderr if defined?(@stderr)
25
+
26
26
  {
27
- exit_code: exit_code,
28
- counts: @counts,
29
- stdin: @stdin&.string,
30
- stdin_pos: @stdin&.pos,
31
- stdout: @stdout&.string,
32
- stdout_pos: @stdout&.pos,
33
- stderr: @stderr&.string,
34
- stderr_pos: @stderr&.pos
27
+ exit_code: l_exit_code,
28
+ counts: l_counts,
29
+ stdin: l_stdin&.string,
30
+ stdin_pos: l_stdin&.pos,
31
+ stdout: l_stdout&.string,
32
+ stdout_pos: l_stdout&.pos,
33
+ stderr: l_stderr&.string,
34
+ stderr_pos: l_stderr&.pos
35
35
  }
36
36
  end
37
37
 
@@ -51,8 +51,8 @@ module Spellr
51
51
  @stderr.pos = dumped[:stderr_pos]
52
52
  end
53
53
 
54
- @exit_code = dumped[:exit_code]
55
- @counts = dumped[:counts]
54
+ @exit_code = dumped[:exit_code] if dumped[:exit_code]
55
+ @counts = dumped[:counts] if dumped[:counts]
56
56
  end
57
57
  end
58
58
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'base_reporter'
4
+ require_relative 'output_stubbed'
4
5
 
5
6
  module Spellr
6
7
  class QuietReporter < Spellr::BaseReporter
@@ -4,10 +4,6 @@ require_relative 'base_reporter'
4
4
 
5
5
  module Spellr
6
6
  class Reporter < Spellr::BaseReporter
7
- def parallel?
8
- true
9
- end
10
-
11
7
  def finish
12
8
  puts "\n"
13
9
  puts "#{pluralize 'file', counts[:checked]} checked"
@@ -8,39 +8,32 @@ module Spellr
8
8
  "#{count} #{word}#{'s' if count != 1}"
9
9
  end
10
10
 
11
- # TODO: make it work without color
12
- def color_enabled?
13
- true
14
- end
15
-
16
11
  def aqua(text)
17
- return text unless Spellr::StringFormat.color_enabled?
18
-
19
12
  "\e[36m#{text}#{normal}"
20
13
  end
21
14
 
22
15
  def normal(text = '')
23
- return text unless Spellr::StringFormat.color_enabled?
24
-
25
16
  "\e[0m#{text}"
26
17
  end
27
18
 
28
19
  def bold(text)
29
- return text unless Spellr::StringFormat.color_enabled?
30
-
31
20
  "\e[1;39m#{text}#{normal}"
32
21
  end
33
22
 
34
- def red(text)
35
- return text unless Spellr::StringFormat.color_enabled?
23
+ def lighten(text)
24
+ "\e[2;39m#{text}#{normal}"
25
+ end
36
26
 
27
+ def red(text)
37
28
  "\e[1;31m#{text}#{normal}"
38
29
  end
39
30
 
40
31
  def green(text)
41
- return text unless Spellr::StringFormat.color_enabled?
42
-
43
32
  "\e[1;32m#{text}#{normal}"
44
33
  end
34
+
35
+ def key(label)
36
+ "[#{bold label[0]}]#{label[1..-1]}"
37
+ end
45
38
  end
46
39
  end
data/lib/spellr/token.rb CHANGED
@@ -17,53 +17,41 @@ module Spellr
17
17
  class Token < String
18
18
  attr_reader :location, :line, :replacement
19
19
 
20
- def self.wrap(value)
21
- return value if value.is_a?(Spellr::Token)
22
-
23
- Spellr::Token.new(value || '')
24
- end
25
-
26
20
  def initialize(string, line: string, location: ColumnLocation.new)
27
21
  @location = location
28
22
  @line = line
29
23
  super(string)
30
24
  end
31
25
 
32
- def strip
33
- @strip ||= begin
34
- lstripped = lstrip
35
- new_column_location = lstripped_column_location(lstripped)
36
- Token.new(lstripped.rstrip, line: line, location: new_column_location)
37
- end
38
- end
39
-
40
- def lstripped_column_location(lstripped)
41
- ColumnLocation.new(
42
- byte_offset: bytesize - lstripped.bytesize,
43
- char_offset: length - lstripped.length,
44
- line_location: location.line_location
45
- )
46
- end
47
-
48
26
  def line=(new_line)
49
27
  @line = new_line
50
28
  location.line_location = new_line.location.line_location
51
29
  end
52
30
 
31
+ # :nocov:
53
32
  def inspect
54
33
  "#<#{self.class.name} #{to_s.inspect} @#{location}>"
55
34
  end
35
+ # :nocov:
56
36
 
57
37
  def char_range
58
- @char_range ||= location.char_offset...(location.char_offset + length)
38
+ @char_range ||=
39
+ location.char_offset...(location.char_offset + length)
59
40
  end
60
41
 
61
42
  def byte_range
62
- @byte_range ||= location.byte_offset...(location.byte_offset + bytesize)
43
+ @byte_range ||=
44
+ location.byte_offset...(location.byte_offset + bytesize)
63
45
  end
64
46
 
65
47
  def file_char_range
66
- @file_char_range ||= location.absolute_char_offset...(location.absolute_char_offset + length)
48
+ @file_char_range ||=
49
+ location.absolute_char_offset...(location.absolute_char_offset + length)
50
+ end
51
+
52
+ def file_byte_range
53
+ @file_byte_range ||=
54
+ location.absolute_byte_offset...(location.absolute_byte_offset + bytesize)
67
55
  end
68
56
 
69
57
  def coordinates
@@ -78,9 +66,5 @@ module Spellr
78
66
  @replacement = replacement
79
67
  location.file.insert(replacement, file_char_range)
80
68
  end
81
-
82
- def file_name
83
- location.file_name
84
- end
85
69
  end
86
70
  end
@@ -9,7 +9,7 @@ module Spellr
9
9
  # [Word], [Word]Word [Word]'s [Wordn't]
10
10
  TITLE_CASE_RE = /[[:upper:]][[:lower:]]+(?:['’][[:lower:]]+(?<!['’]s))*/.freeze
11
11
  # [WORD] [WORD]Word [WORDN'T] [WORD]'S [WORD]'s [WORD]s
12
- UPPER_CASE_RE = /[[:upper:]]+(?:['’][[:upper:]]+(?<!['’][Ss]))*(?:(?![[:lower:]])|(?=s(?![[:lower:]])))/.freeze # rubocop:disable Metrics/LineLength
12
+ UPPER_CASE_RE = /[[:upper:]]+(?:['’][[:upper:]]+(?<!['’][Ss]))*(?:(?![[:lower:]])|(?=s(?![[:lower:]])))/.freeze # rubocop:disable Layout/LineLength
13
13
  # [word] [word]'s [wordn't]
14
14
  LOWER_CASE_RE = /[[:lower:]]+(?:['’][[:lower:]]+(?<!['’]s))*/.freeze
15
15
  # for characters in [:alpha:] that aren't in [:lower:] or [:upper:] e.g. Arabic
@@ -30,7 +30,7 @@ module Spellr
30
30
  REPEATED_SINGLE_LETTERS_RE = /(?:([[:alpha:]])\1+)(?![[:alpha:]])/.freeze # e.g. xxxxxxxx
31
31
  URL_ENCODED_ENTITIES_RE = /%[0-8A-F]{2}/.freeze
32
32
  # There's got to be a better way of writing this
33
- SEQUENTIAL_LETTERS_RE = /a(?:b(?:c(?:d(?:e(?:f(?:g(?:h(?:i(?:j(?:k(?:l(?:m(?:n(?:o(?:p(?:q(?:r(?:s(?:t(?:u(?:v(?:w(?:x(?:yz?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?(?![[:alpha:]])/i.freeze # rubocop:disable Metrics/LineLength
33
+ SEQUENTIAL_LETTERS_RE = /a(?:b(?:c(?:d(?:e(?:f(?:g(?:h(?:i(?:j(?:k(?:l(?:m(?:n(?:o(?:p(?:q(?:r(?:s(?:t(?:u(?:v(?:w(?:x(?:yz?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?(?![[:alpha:]])/i.freeze # rubocop:disable Layout/LineLength
34
34
 
35
35
  # I didn't want to do this myself
36
36
  # BUT i need something to heuristically match on, and it's difficult
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../spellr'
4
3
  require_relative 'token'
5
4
  require_relative 'column_location'
6
5
  require_relative 'line_location'
@@ -78,15 +77,6 @@ module Spellr
78
77
 
79
78
  attr_reader :line_tokenizer
80
79
 
81
- def each_line_token
82
- line_location = @start_at.line_location
83
-
84
- file.each_line do |line|
85
- yield Token.new(line, location: ColumnLocation.new(line_location: line_location))
86
- line_location = line_location.advance(line)
87
- end
88
- end
89
-
90
80
  def prepare_tokenizer_for_line(line)
91
81
  line_tokenizer.string = line
92
82
  line_tokenizer.pos = 0
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spellr
4
+ module Validations
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ def validations
11
+ @validations ||= []
12
+ end
13
+
14
+ def validate(method)
15
+ validations << method
16
+ end
17
+ end
18
+
19
+ def valid?
20
+ self.class.validations.each do |validation|
21
+ send(validation)
22
+ end
23
+
24
+ errors.empty?
25
+ end
26
+
27
+ def errors
28
+ @errors ||= []
29
+ end
30
+ end
31
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spellr
4
- VERSION = '0.6.0'
4
+ VERSION = '0.7.0'
5
5
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'pathname'
4
4
  require_relative '../spellr'
5
- require_relative 'token'
5
+ require_relative 'token' # for spellr_normalize
6
6
 
7
7
  module Spellr
8
8
  class Wordlist
@@ -12,20 +12,20 @@ module Spellr
12
12
 
13
13
  def initialize(file, name: file)
14
14
  path = @file = file
15
- @path = Pathname.pwd.join('.spellr_wordlists').join(path).expand_path
15
+ @path = Spellr.config.pwd.join('.spellr_wordlists').join(path).expand_path
16
16
  @name = name
17
17
  @include = {}
18
18
  end
19
19
 
20
20
  def each(&block)
21
- raise_unless_exists?
22
-
23
- @path.each_line(&block)
21
+ words.each(&block)
24
22
  end
25
23
 
24
+ # :nocov:
26
25
  def inspect
27
26
  "#<#{self.class.name}:#{@path}>"
28
27
  end
28
+ # :nocov:
29
29
 
30
30
  # significantly faster than default Enumerable#include?
31
31
  # requires terms to have been sorted
@@ -60,12 +60,6 @@ module Spellr
60
60
  clear_cache
61
61
  end
62
62
 
63
- def read
64
- raise_unless_exists?
65
-
66
- @path.read
67
- end
68
-
69
63
  def exist?
70
64
  return @exist if defined?(@exist)
71
65
 
@@ -80,6 +74,10 @@ module Spellr
80
74
  clear_cache
81
75
  end
82
76
 
77
+ def length
78
+ to_a.length
79
+ end
80
+
83
81
  private
84
82
 
85
83
  def insert_sorted(term)
@@ -92,11 +90,5 @@ module Spellr
92
90
  @include = {}
93
91
  remove_instance_variable(:@exist) if defined?(@exist)
94
92
  end
95
-
96
- def raise_unless_exists?
97
- return if exist?
98
-
99
- raise Spellr::Wordlist::NotFound, "Wordlist file #{@file} doesn't exist at #{@path}"
100
- end
101
93
  end
102
94
  end
@@ -5,10 +5,6 @@ require_relative 'base_reporter'
5
5
 
6
6
  module Spellr
7
7
  class WordlistReporter < Spellr::BaseReporter
8
- def parallel?
9
- true
10
- end
11
-
12
8
  def finish
13
9
  output.puts words.sort.join
14
10
  end
data/lib/spellr.rb CHANGED
@@ -10,6 +10,18 @@ module Spellr
10
10
  class NotFound < Spellr::Error; end
11
11
  end
12
12
 
13
+ class Config
14
+ class NotFound < Spellr::Error; end
15
+ class Invalid < Spellr::Error; end
16
+ end
17
+
18
+ class InvalidByteSequence < ArgumentError
19
+ RE = /invalid byte sequence/.freeze
20
+ def self.===(error)
21
+ error.is_a?(ArgumentError) && error.message.match?(RE)
22
+ end
23
+ end
24
+
13
25
  module_function
14
26
 
15
27
  def config
data/spellr.gemspec CHANGED
@@ -14,7 +14,9 @@ Gem::Specification.new do |spec|
14
14
  spec.homepage = 'http://github.com/robotdana/spellr'
15
15
  spec.license = 'MIT'
16
16
 
17
- spec.files = Dir.glob('{lib,exe,bin/fetch_wordlist,wordlists}/**/{*,.*}') + %w{
17
+ spec.required_ruby_version = '>= 2.4'
18
+
19
+ spec.files = Dir.glob('{lib,exe,wordlists}/**/{*,.*}') + %w{
18
20
  CHANGELOG.md
19
21
  Gemfile
20
22
  LICENSE.txt
@@ -26,15 +28,18 @@ Gem::Specification.new do |spec|
26
28
  spec.require_paths = ['lib']
27
29
 
28
30
  spec.add_development_dependency 'bundler', '~> 2.0'
31
+ spec.add_development_dependency 'mime-types', '~> 3.3.1'
32
+ spec.add_development_dependency 'nokogiri'
29
33
  spec.add_development_dependency 'pry'
30
- spec.add_development_dependency 'rake', '~> 10.0'
34
+ spec.add_development_dependency 'rake', '>= 12.3.3'
31
35
  spec.add_development_dependency 'rspec', '~> 3.0'
32
- spec.add_development_dependency 'rspec-eventually'
33
36
  spec.add_development_dependency 'rubocop'
34
37
  spec.add_development_dependency 'rubocop-rspec'
35
- spec.add_development_dependency 'terminal-table'
36
- spec.add_development_dependency 'tty_string'
37
- spec.add_development_dependency 'nokogiri'
38
- spec.add_dependency 'fast_ignore', '~> 0.5.2'
38
+ spec.add_development_dependency 'simplecov', '~> 0.18.5'
39
+ spec.add_development_dependency 'simplecov-console'
40
+ spec.add_development_dependency 'tty_string', '>= 0.2.1'
41
+ spec.add_development_dependency 'webmock', '~> 3.8'
42
+
43
+ spec.add_dependency 'fast_ignore', '~> 0.6.0'
39
44
  spec.add_dependency 'parallel', '~> 1.0'
40
45
  end