search_lingo 2.0.0 → 3.0.0.pre1

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: d697959cb461bb00ba17b4dbd3fe71037db81c65d3253fc22c42c27b69228f2e
4
- data.tar.gz: 2a96f4b480d60d052bd1bf7f7ae02f645386144dbebccfacaa9ecfbf56fbbd30
3
+ metadata.gz: 06b21144b96415a618c188261eca38aab055ca218d294a966f96f543c41759a2
4
+ data.tar.gz: eff6897cd99f4abf444a9dd9c8c5d1d545b1da5277d507a8fb8b7a685756ca44
5
5
  SHA512:
6
- metadata.gz: aa98221d0840199c0ed21f96412f39fd82567210d8f99d1b2767a0b8f718ba2f1039f1624e7f9d04a63bd7b0c6a22d00ecbe81ddb4c8986322dfdda99da84b4f
7
- data.tar.gz: 3ecc60bea0e32cc52548bbe5999e80704bc52e89ec0218f3076473220c14f8f4b2a5214bd8dadca5490b90a2229291dea960289819f53c9689bb4f3ab8859ac7
6
+ metadata.gz: fbd45adde84bf9a73d73c15cb91545e1e46b7ddbc2b0647506a087dcf77cf1aa7777ed29e57c8329a101b98b01b647308ed5657157fc60cc9858bd5281a25ca0
7
+ data.tar.gz: a05213f9fd31a2049f649bc935ac9d5edf0e4c8cd4bc390ee423bdc660180d78fb1a9802ffe7ff428b886b70911f93c98d469edb1dfb59b5c9e43c13c4eb1a74
data/.gitignore CHANGED
@@ -8,3 +8,4 @@
8
8
  /pkg/
9
9
  /spec/reports/
10
10
  /tmp/
11
+ .tool-versions
data/.gitlab-ci.yml ADDED
@@ -0,0 +1,27 @@
1
+ before_script:
2
+ - gem install bundler --no-document -v '~> 2.3.11'
3
+ - bundle install --jobs="$(nproc)" --retry=3
4
+
5
+ build:rubocop:
6
+ stage: build
7
+ image: "ruby:3.1"
8
+ script:
9
+ - bundle exec rubocop
10
+
11
+ test:ruby-2.7:
12
+ stage: test
13
+ image: "ruby:2.7"
14
+ script:
15
+ - bundle exec rake test
16
+
17
+ test:ruby-3.0:
18
+ stage: test
19
+ image: "ruby:3.0"
20
+ script:
21
+ - bundle exec rake test
22
+
23
+ test:ruby-3.1:
24
+ stage: test
25
+ image: "ruby:3.1"
26
+ script:
27
+ - bundle exec rake test
data/.rubocop.yml CHANGED
@@ -1,14 +1,8 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.3.0
3
- Layout/AlignParameters:
4
- Enabled: false
5
- Metrics/AbcSize:
6
- Max: 25
7
- Style/AndOr:
8
- EnforcedStyle: conditionals
2
+ NewCops: enable
3
+ SuggestExtensions: false
4
+ TargetRubyVersion: 2.7.0
9
5
  Style/TrailingCommaInArrayLiteral:
10
- Enabled: false
6
+ EnforcedStyleForMultiline: consistent_comma
11
7
  Style/TrailingCommaInHashLiteral:
12
- Enabled: false
13
- Style/NumericPredicate:
14
- Enabled: false
8
+ EnforcedStyleForMultiline: consistent_comma
data/.travis.yml CHANGED
@@ -1,5 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.3.8
4
- - 2.4.5
5
- - 2.5.3
3
+ - "2.7"
4
+ - "3.0"
5
+ - "3.1"
6
+ before_install:
7
+ - gem install bundler
data/examples/complex.rb CHANGED
@@ -40,9 +40,11 @@ class JobSearch < SearchLingo::AbstractSearch # :nodoc:
40
40
  end
41
41
 
42
42
  class ReceiptSearch < SearchLingo::AbstractSearch # :nodoc:
43
- parser SearchLingo::Parsers::DateParser.new Receipt.arel_table[:check_date]
44
- parser SearchLingo::Parsers::DateParser.new Receipt.arel_table[:post_date],
45
- modifier: 'posted'
43
+ # You might prefer to include SearchLingo::Parsers if you you are going to
44
+ # instantiate multiple DateParsers.
45
+ include SearchLingo::Parsers
46
+ parser DateParser.new Receipt.arel_table[:check_date]
47
+ parser DateParser.new Receipt.arel_table[:post_date], modifier: 'posted'
46
48
 
47
49
  parser do |token, chain|
48
50
  token.match(/\Aamount: (\d+(?:\.\d+)?)\z/) do |m|
@@ -56,13 +56,11 @@ class TaskSearch < SearchLingo::AbstractSearch # :nodoc:
56
56
  # 7/4/17 => Tasks with due_date == Date.new(2017, 7, 4)
57
57
  parser do |token, chain|
58
58
  token.match %r{\A(?<m>\d{1,2})/(?<d>\d{1,2})/(?<y>\d{2}\d{2}?)\z} do |m|
59
- begin
60
- date = Date.parse "#{m[:y]}/#{m[:m]}/#{m[:d]}"
61
- chain.where due_date: date
62
- rescue ArgumentError
63
- # Fail if Date.parse raises an ArgumentError
64
- nil
65
- end
59
+ date = Date.parse "#{m[:y]}/#{m[:m]}/#{m[:d]}"
60
+ chain.where due_date: date
61
+ rescue ArgumentError
62
+ # Fail if Date.parse raises an ArgumentError
63
+ nil
66
64
  end
67
65
  end
68
66
 
@@ -61,8 +61,8 @@ module SearchLingo
61
61
  # responds to +#call+. The parser will be send +#call+ with a single
62
62
  # argument which will be a token from the query string.
63
63
  #
64
- # If both a callable object and a block are given, or if neither a callable
65
- # object nor a block are given, an +ArgumentError+ will be raised.
64
+ # Raises +ArgumentError+ if +parser+ does not respond to +#call+ and no
65
+ # block is given.
66
66
  #
67
67
  # class MyParser
68
68
  # def call(token)
@@ -77,11 +77,13 @@ module SearchLingo
77
77
  # end
78
78
  # end
79
79
  def self.parser(parser = nil, &block)
80
- unless block_given? ^ parser.respond_to?(:call)
81
- raise ArgumentError, 'parse must be called with callable OR block'
80
+ if parser.respond_to? :call
81
+ parsers << parser
82
+ elsif block_given?
83
+ parsers << block
84
+ else
85
+ raise ArgumentError, 'parse must be called with block or callable object'
82
86
  end
83
-
84
- parsers << (parser || block)
85
87
  end
86
88
 
87
89
  ##
@@ -161,7 +163,7 @@ module SearchLingo
161
163
  # implementation should return +chain+. (Doing so would ignore +token+.)
162
164
  def default_parse(_token, _chain)
163
165
  raise NotImplementedError,
164
- "#default_parse must be implemented by #{self.class}"
166
+ "#default_parse must be implemented by #{self.class}"
165
167
  end
166
168
  end
167
169
  end
@@ -3,9 +3,22 @@
3
3
  module SearchLingo
4
4
  ##
5
5
  # Pattern for matching modifiers within a token.
6
- MODIFIER = /[[:alnum:]]+/
6
+ MODIFIER = /[[:alnum:]]+/.freeze
7
7
 
8
8
  ##
9
- # Pattern for matching terms within a token.
10
- TERM = /"[^"]+"|[[:graph:]]+/
9
+ # Pattern for matching a simple token.
10
+ SIMPLE_TOKEN = /"[^"]+"|[[:graph:]]+/.freeze
11
+
12
+ ##
13
+ # Pattern for matching a simple or compound token.
14
+ SIMPLE_OR_COMPOUND_TOKEN = /(?:#{MODIFIER}:[[:space:]]*)?#{SIMPLE_TOKEN}/.freeze
15
+
16
+ ##
17
+ # Pattern for matching a simple or compound token, with regex grouping to aid
18
+ # in decomposing the token into its modifier and term components.
19
+ SIMPLE_OR_COMPOUND_TOKEN_WITH_GROUPING = /\A(?:(#{MODIFIER}):[[:space:]]*)?(#{SIMPLE_TOKEN})\z/.freeze
20
+
21
+ ##
22
+ # Pattern for matching the delimiter between tokens.
23
+ DELIMITER = /[[:space:]]*/.freeze
11
24
  end
@@ -16,7 +16,7 @@ module SearchLingo
16
16
  class DateParser
17
17
  include MDY
18
18
 
19
- attr_reader :column, :prefix, :append
19
+ attr_reader :column, :prefix, :decorator
20
20
 
21
21
  ##
22
22
  # Instantiates a new DateParser object.
@@ -26,10 +26,10 @@ module SearchLingo
26
26
  # If present, the optional argument +modifier+ will be used as the
27
27
  # token operator which precedes the date term.
28
28
  #
29
- # If a block is provided, it will be used to append additional methods to
30
- # the filter chain. (This is useful for static methods that must be
31
- # appended to the filter chain independent of the content of the token,
32
- # for example, if you need to join another table.)
29
+ # If a block is provided, it will be called with the filter chain. This
30
+ # is useful if you need to send additional messages to the filter chain
31
+ # which are independent of the content of the token, e.g., if you need to
32
+ # join another table.
33
33
  #
34
34
  # DateParser.new Model.arel_table[:date]
35
35
  # DateParser.new Model.arel_table[:date], modifier: 'contract'
@@ -39,7 +39,7 @@ module SearchLingo
39
39
  def initialize(column, modifier: nil, &block)
40
40
  @column = column
41
41
  @prefix = /#{modifier}:[[:space:]]*/ if modifier
42
- @append = block_given? ? block : ->(chain) { chain }
42
+ @decorator = block_given? ? block : ->(chain) { chain }
43
43
  end
44
44
 
45
45
  ##
@@ -57,9 +57,9 @@ module SearchLingo
57
57
 
58
58
  def inspect # :nodoc:
59
59
  format '#<%<cls>s @prefix=%<prefix>s @column=%<column>s>',
60
- cls: self.class,
61
- prefix: prefix.inspect,
62
- column: "#{column.relation.name}.#{column.name}".inspect
60
+ cls: self.class,
61
+ prefix: prefix.inspect,
62
+ column: "#{column.relation.name}.#{column.name}".inspect
63
63
  end
64
64
 
65
65
  private
@@ -67,7 +67,7 @@ module SearchLingo
67
67
  def parse_single_date(token, chain) # :nodoc:
68
68
  token.match(/\A#{prefix}(?<date>#{US_DATE})\z/) do |m|
69
69
  date = parse(m[:date]) or return nil
70
- throw :halt, append.call(chain).where(column.eq(date))
70
+ throw :halt, decorate(chain).where(column.eq(date))
71
71
  end
72
72
  end
73
73
 
@@ -75,23 +75,27 @@ module SearchLingo
75
75
  token.match(/\A#{prefix}(?<min>#{US_DATE})-(?<max>#{US_DATE})\z/) do |m|
76
76
  min = parse(m[:min]) or return nil
77
77
  max = parse(m[:max], relative_to: min.next_year) or return nil
78
- throw :halt, append.call(chain).where(column.in(min..max))
78
+ throw :halt, decorate(chain).where(column.between(min..max))
79
79
  end
80
80
  end
81
81
 
82
82
  def parse_lte_date(token, chain) # :nodoc:
83
83
  token.match(/\A#{prefix}-(?<date>#{US_DATE})\z/) do |m|
84
84
  date = parse(m[:date]) or return nil
85
- throw :halt, append.call(chain).where(column.lteq(date))
85
+ throw :halt, decorate(chain).where(column.lteq(date))
86
86
  end
87
87
  end
88
88
 
89
89
  def parse_gte_date(token, chain) # :nodoc:
90
90
  token.match(/\A#{prefix}(?<date>#{US_DATE})-\z/) do |m|
91
91
  date = parse(m[:date]) or return nil
92
- throw :halt, append.call(chain).where(column.gteq(date))
92
+ throw :halt, decorate(chain).where(column.gteq(date))
93
93
  end
94
94
  end
95
+
96
+ def decorate(chain)
97
+ decorator.call chain
98
+ end
95
99
  end
96
100
  end
97
101
  end
@@ -5,14 +5,16 @@ require 'date'
5
5
  module SearchLingo
6
6
  module Parsers # :nodoc:
7
7
  ##
8
- # MDY provides a parser for dates that adhere to the MDY format used in the
9
- # US.
8
+ # MDY provides a parser for dates that adhere to the M/D/Y format used in
9
+ # the US.
10
10
  module MDY
11
11
  ##
12
12
  # Pattern for matching US-formatted date strings.
13
13
  #
14
14
  # The year may be two or four digits, or it may be omitted.
15
- US_DATE = %r{(?<m>\d{1,2})/(?<d>\d{1,2})(?:/(?<y>\d{2}\d{2}?))?}
15
+ US_DATE = %r{(?<m>\d{1,2})/(?<d>\d{1,2})(?:/(?<y>\d{2}\d{2}?))?}.freeze
16
+
17
+ module_function
16
18
 
17
19
  ##
18
20
  # Returns a +Date+ object for the date represented by +term+. Returns
@@ -24,33 +26,32 @@ module SearchLingo
24
26
  # If the year is omitted, it will be inferred using +relative_to+ as a
25
27
  # reference date. In this scenario, the resulting date will always be
26
28
  # less than or equal to the reference date. If +relative_to+ omitted, it
27
- # defaults to today's date.
29
+ # defaults to +Date.today+.
28
30
  #
29
31
  # Available as both a class method and an instance method.
30
- # rubocop:disable Metrics/MethodLength
31
32
  def parse(term, relative_to: Date.today)
32
33
  term.match(/\A#{US_DATE}\z/) do |m|
33
- return Date.parse "#{m[:y]}/#{m[:m]}/#{m[:d]}" if m[:y]
34
-
35
- ref = relative_to
36
- month = Integer m[:m]
37
- day = Integer m[:d]
38
- year = if month < ref.month || month == ref.month && day <= ref.day
39
- ref.year
40
- else
41
- ref.year - 1
42
- end
43
- Date.new year, month, day
34
+ date = reformat_date m, relative_to
35
+ Date.parse date
44
36
  end
45
37
  rescue ArgumentError
46
38
  # Fail if Date.parse or Date.new raise ArgumentError.
47
39
  nil
48
40
  end
49
- # rubocop:enable Metrics/MethodLength
50
41
 
51
- # rubocop:disable Style/AccessModifierDeclarations:
52
- module_function :parse
53
- # rubocop:enable Style/AccessModifierDeclarations:
42
+ def reformat_date(match, today) # :nodoc:
43
+ return match.values_at(:y, :m, :d).join('/') if match[:y]
44
+
45
+ month = Integer match[:m]
46
+ day = Integer match[:d]
47
+ year = if month < today.month || (month == today.month && day <= today.day)
48
+ today.year
49
+ else
50
+ today.year - 1
51
+ end
52
+
53
+ "#{year}/#{month}/#{day}"
54
+ end
54
55
  end
55
56
  end
56
57
  end
@@ -18,18 +18,14 @@ module SearchLingo
18
18
  # Token.new('foo: bar')
19
19
  # Token.new('foo: "bar baz"')
20
20
  class Token < DelegateClass(String)
21
- ##
22
- # Pattern for decomposing a token into a modifier and a term.
23
- STRUCTURE = /\A(?:(#{MODIFIER}):[[:space:]]*)?"?(.+?)"?\z/
24
-
25
21
  ##
26
22
  # Returns the modifier portion of the token. Returns +nil+ if token does
27
23
  # not have a modifier.
28
24
  #
29
- # Token.new('foo: bar').modifier # => 'foo'
25
+ # Token.new('foo: bar').modifier # => "foo"
30
26
  # Token.new('bar').modifier # => nil
31
27
  def modifier
32
- self[STRUCTURE, 1]
28
+ self[SIMPLE_OR_COMPOUND_TOKEN_WITH_GROUPING, 1]
33
29
  end
34
30
 
35
31
  alias operator modifier
@@ -38,11 +34,12 @@ module SearchLingo
38
34
  # Returns the term portion of the token. If the term is wrapped in quotes,
39
35
  # they are removed.
40
36
  #
41
- # Token.new('foo: bar').term # => 'bar'
42
- # Token.new('bar').term # => 'bar'
43
- # Token.new('"bar baz"').term # => 'bar baz'
37
+ # Token.new('foo: bar').term # => "bar"
38
+ # Token.new('bar').term # => "bar"
39
+ # Token.new('"bar baz"').term # => "bar baz"
40
+ # Token.new('""').term # => ""
44
41
  def term
45
- self[STRUCTURE, 2]
42
+ self[SIMPLE_OR_COMPOUND_TOKEN_WITH_GROUPING, 2].delete_prefix('"').delete_suffix('"')
46
43
  end
47
44
 
48
45
  ##
@@ -56,10 +53,10 @@ module SearchLingo
56
53
 
57
54
  def inspect # :nodoc:
58
55
  format '#<%<cls>s String(%<str>s) modifier=%<mod>s term=%<term>s>',
59
- cls: self.class,
60
- str: super,
61
- mod: modifier.inspect,
62
- term: term.inspect
56
+ cls: self.class,
57
+ str: super,
58
+ mod: modifier.inspect,
59
+ term: term.inspect
63
60
  end
64
61
  end
65
62
  end
@@ -16,18 +16,6 @@ module SearchLingo
16
16
  include Enumerable
17
17
  extend Forwardable
18
18
 
19
- ##
20
- # Pattern for matching a simple token (a term without a modifier).
21
- SIMPLE_TOKEN = /#{TERM}/
22
-
23
- ##
24
- # Pattern for matching a compound token (a term with an optional modifier).
25
- COMPOUND_TOKEN = /(?:#{MODIFIER}:[[:space:]]*)?#{TERM}/
26
-
27
- ##
28
- # Pattern for matching the delimiter between tokens.
29
- DELIMITER = /[[:space:]]*/
30
-
31
19
  def initialize(query) # :nodoc:
32
20
  @scanner = StringScanner.new query.strip
33
21
  end
@@ -42,11 +30,11 @@ module SearchLingo
42
30
  end
43
31
 
44
32
  ##
45
- # Returns a Token for the next token in the query string. When the end of
33
+ # Returns a +Token+ for the next token in the query string. When the end of
46
34
  # the query string is reached raises +StopIteration+.
47
35
  def next
48
36
  scanner.skip DELIMITER
49
- token = scanner.scan COMPOUND_TOKEN
37
+ token = scanner.scan SIMPLE_OR_COMPOUND_TOKEN
50
38
  raise StopIteration unless token
51
39
 
52
40
  Token.new token
@@ -1,5 +1,5 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module SearchLingo
4
- VERSION = '2.0.0'
4
+ VERSION = '3.0.0.pre1'
5
5
  end
data/search_lingo.gemspec CHANGED
@@ -4,7 +4,6 @@ lib = File.expand_path('lib', __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require 'search_lingo/version'
6
6
 
7
- # rubocop:disable Metrics/BlockLength
8
7
  Gem::Specification.new do |spec|
9
8
  spec.name = 'search_lingo'
10
9
  spec.version = SearchLingo::VERSION
@@ -19,25 +18,26 @@ Gem::Specification.new do |spec|
19
18
  spec.homepage = 'https://github.com/jparker/search_lingo'
20
19
  spec.license = 'MIT'
21
20
 
22
- spec.files = `git ls-files -z`.split("\x0").reject { |f|
21
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
23
22
  f.match(%r{^(test|spec|features)/})
24
- }
23
+ end
25
24
  spec.bindir = 'exe'
26
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
26
  spec.require_paths = ['lib']
28
27
 
29
28
  spec.rdoc_options += ['-x', 'examples/', '-x', 'test/']
30
29
 
31
- spec.required_ruby_version = '>= 2.3'
30
+ spec.required_ruby_version = '>= 2.7'
32
31
 
33
- spec.add_development_dependency 'bundler', '~> 1.9'
32
+ spec.add_development_dependency 'bundler', '~> 2.0'
34
33
  spec.add_development_dependency 'minitest'
35
34
  spec.add_development_dependency 'minitest-focus'
36
35
  spec.add_development_dependency 'mocha'
37
36
  spec.add_development_dependency 'pry'
38
- spec.add_development_dependency 'rake', '~> 10.0'
39
- spec.add_development_dependency 'rubocop'
37
+ spec.add_development_dependency 'rake', '~> 13.0'
38
+ spec.add_development_dependency 'rubocop', '~> 1.12'
39
+ spec.add_development_dependency 'rubocop-minitest'
40
40
  spec.add_development_dependency 'sequel', '~> 5.0'
41
41
  spec.add_development_dependency 'sqlite3'
42
+ spec.metadata['rubygems_mfa_required'] = 'true'
42
43
  end
43
- # rubocop:enable Metrics/BlockLength
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: search_lingo
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 3.0.0.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Parker
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-11-25 00:00:00.000000000 Z
11
+ date: 2022-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.9'
19
+ version: '2.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.9'
26
+ version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -86,16 +86,30 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '10.0'
89
+ version: '13.0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '10.0'
96
+ version: '13.0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.12'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.12'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop-minitest
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - ">="
@@ -146,6 +160,7 @@ extensions: []
146
160
  extra_rdoc_files: []
147
161
  files:
148
162
  - ".gitignore"
163
+ - ".gitlab-ci.yml"
149
164
  - ".rubocop.yml"
150
165
  - ".travis.yml"
151
166
  - Gemfile
@@ -169,7 +184,8 @@ files:
169
184
  homepage: https://github.com/jparker/search_lingo
170
185
  licenses:
171
186
  - MIT
172
- metadata: {}
187
+ metadata:
188
+ rubygems_mfa_required: 'true'
173
189
  post_install_message:
174
190
  rdoc_options:
175
191
  - "-x"
@@ -182,15 +198,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
182
198
  requirements:
183
199
  - - ">="
184
200
  - !ruby/object:Gem::Version
185
- version: '2.3'
201
+ version: '2.7'
186
202
  required_rubygems_version: !ruby/object:Gem::Requirement
187
203
  requirements:
188
- - - ">="
204
+ - - ">"
189
205
  - !ruby/object:Gem::Version
190
- version: '0'
206
+ version: 1.3.1
191
207
  requirements: []
192
- rubyforge_project:
193
- rubygems_version: 2.7.8
208
+ rubygems_version: 3.3.7
194
209
  signing_key:
195
210
  specification_version: 4
196
211
  summary: Framework for defining and parsing search queries.