spellr 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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