search_lingo 2.0.0 → 3.0.0.pre1

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: 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.