search_lingo 2.0.0.pre2 → 2.0.0.pre3
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 +4 -4
- data/.rubocop.yml +14 -0
- data/.travis.yml +1 -0
- data/Gemfile +2 -0
- data/Rakefile +8 -2
- data/bin/console +4 -3
- data/examples/complex.rb +13 -3
- data/examples/sequel_example.rb +11 -7
- data/lib/search_lingo.rb +2 -0
- data/lib/search_lingo/abstract_search.rb +36 -2
- data/lib/search_lingo/constants.rb +2 -0
- data/lib/search_lingo/parsers.rb +2 -0
- data/lib/search_lingo/parsers/date_parser.rb +47 -24
- data/lib/search_lingo/parsers/mdy.rb +14 -4
- data/lib/search_lingo/token.rb +22 -4
- data/lib/search_lingo/tokenizer.rb +10 -3
- data/lib/search_lingo/version.rb +3 -1
- data/search_lingo.gemspec +24 -15
- metadata +30 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a72223dbfe08f7309fc060e7bb30afd3e4941810ba9f52fcf50340d6573db74
|
4
|
+
data.tar.gz: c560f79d14abbf7daa9a570ac0594184afb0aca4f69acf66ed86f4af15c6d5be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 343f682d46cf9ea34fafa75499790e0e0a0474e812c8c00cce81fe75b3f2f1b5de66975d0e2d975f4eca8e12deeedf2e9b927ebcce425fef9871d5405b686023
|
7
|
+
data.tar.gz: 725c8dca98f88dd630475c200e7b2ecb0347cb191df5d10e7e0dae9ac0c3e3d815e2830966f2bf18c6bd5448842a78a946a5ec6e60a6e58acaf83aa586adc6d8
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,14 @@
|
|
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
|
9
|
+
Style/TrailingCommaInArrayLiteral:
|
10
|
+
Enabled: false
|
11
|
+
Style/TrailingCommaInHashLiteral:
|
12
|
+
Enabled: false
|
13
|
+
Style/NumericPredicate:
|
14
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
2
4
|
require 'rake/testtask'
|
3
5
|
|
4
6
|
Rake::TestTask.new do |t|
|
5
7
|
t.libs << 'test'
|
6
|
-
t.pattern = 'test
|
8
|
+
t.pattern = 'test/**/*_test.rb'
|
7
9
|
end
|
8
10
|
|
9
11
|
task default: :test
|
12
|
+
|
13
|
+
task :rubocop do
|
14
|
+
system 'rubocop'
|
15
|
+
end
|
data/bin/console
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen-string-literal: true
|
2
3
|
|
3
|
-
require
|
4
|
-
require
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'search_lingo'
|
5
6
|
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
8
9
|
|
9
10
|
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
require
|
11
|
+
require 'pry'
|
11
12
|
Pry.start
|
12
13
|
|
13
14
|
# require "irb"
|
data/examples/complex.rb
CHANGED
@@ -1,9 +1,19 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
1
3
|
class Job < ActiveRecord::Base # :nodoc:
|
2
|
-
#
|
4
|
+
# Attributes:
|
5
|
+
# :id
|
6
|
+
# :date
|
7
|
+
# :name
|
3
8
|
end
|
4
9
|
|
5
10
|
class Receipt < ActiveRecord::Base # :nodoc:
|
6
|
-
#
|
11
|
+
# Attributes:
|
12
|
+
# :id
|
13
|
+
# :check_no
|
14
|
+
# :check_date
|
15
|
+
# :post_date
|
16
|
+
# :amount
|
7
17
|
end
|
8
18
|
|
9
19
|
module Parsers # :nodoc:
|
@@ -13,7 +23,7 @@ module Parsers # :nodoc:
|
|
13
23
|
end
|
14
24
|
|
15
25
|
def call(token, chain)
|
16
|
-
token.match
|
26
|
+
token.match(/\Aid:\s*([[:digit:]]+)\z/) do |m|
|
17
27
|
chain.where @table => { id: m[1] }
|
18
28
|
end
|
19
29
|
end
|
data/examples/sequel_example.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
1
3
|
require 'sequel'
|
2
4
|
require 'sqlite3'
|
3
5
|
|
@@ -17,12 +19,13 @@ require 'sqlite3'
|
|
17
19
|
|
18
20
|
class CategoryParser # :nodoc:
|
19
21
|
def call(token, chain)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
return nil unless token.modifier == 'cat'
|
23
|
+
|
24
|
+
# This is not an ideal example. Sequel will join the categories table for
|
25
|
+
# each token that matches. I'm ignoring the problem since this is only an
|
26
|
+
# example.
|
27
|
+
category_name = Sequel.qualify :categories, :name
|
28
|
+
chain.join(:categories, id: :category_id).where category_name => token.term
|
26
29
|
end
|
27
30
|
end
|
28
31
|
|
@@ -57,7 +60,8 @@ class TaskSearch < SearchLingo::AbstractSearch # :nodoc:
|
|
57
60
|
date = Date.parse "#{m[:y]}/#{m[:m]}/#{m[:d]}"
|
58
61
|
chain.where due_date: date
|
59
62
|
rescue ArgumentError
|
60
|
-
# Date.parse
|
63
|
+
# Fail if Date.parse raises an ArgumentError
|
64
|
+
nil
|
61
65
|
end
|
62
66
|
end
|
63
67
|
end
|
data/lib/search_lingo.rb
CHANGED
@@ -1,6 +1,37 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
1
3
|
require 'search_lingo/tokenizer'
|
2
4
|
|
3
5
|
module SearchLingo
|
6
|
+
##
|
7
|
+
# AbstractSearch is an abstract implementation from which search classes
|
8
|
+
# should inherit.
|
9
|
+
#
|
10
|
+
# Search classes are instantiated with a query string and a default scope on
|
11
|
+
# which to perform the search.
|
12
|
+
#
|
13
|
+
# Child classes must implement the #default_parse instance method, and they
|
14
|
+
# may optionally register one or more parsers.
|
15
|
+
#
|
16
|
+
# class MySearch < SearchLingo::AbstractSearch
|
17
|
+
# def default_parse(token, chain)
|
18
|
+
# chain.where attribute: token.term
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# class MyOtherSearch < SearchLingo::AbstractSearch
|
23
|
+
# parser SearchLingo::Parsers::DateParser.new Job.arel_table[:date]
|
24
|
+
#
|
25
|
+
# parser do |token, chain|
|
26
|
+
# token.match(/\Aid: [[:space:]]* (?<id>[[:digit:]]+)\z/x) do |m|
|
27
|
+
# chain.where id: m[:id]
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# def default_parse(token, chain)
|
32
|
+
# chain.where Job.arel_table[:name].matches "%#{token.term}%"
|
33
|
+
# end
|
34
|
+
# end
|
4
35
|
class AbstractSearch
|
5
36
|
attr_reader :query, :scope
|
6
37
|
|
@@ -8,7 +39,9 @@ module SearchLingo
|
|
8
39
|
# Instantiates a new search object. +query+ is the string that is to be
|
9
40
|
# parsed and compiled into an actual query. If +query+ is falsey, an empty
|
10
41
|
# string will be used. +scope+ is the object to which the compiled query
|
11
|
-
# should be sent, e.g., an +ActiveRecord
|
42
|
+
# should be sent, e.g., an +ActiveRecord::Relation+.
|
43
|
+
#
|
44
|
+
# MySearchClass.new 'foo bar: baz "froz quux"', Task.all
|
12
45
|
def initialize(query, scope)
|
13
46
|
@query = query || ''
|
14
47
|
@scope = scope
|
@@ -46,6 +79,7 @@ module SearchLingo
|
|
46
79
|
unless block_given? ^ parser.respond_to?(:call)
|
47
80
|
raise ArgumentError, 'parse must be called with callable OR block'
|
48
81
|
end
|
82
|
+
|
49
83
|
parsers << (parser || block)
|
50
84
|
end
|
51
85
|
|
@@ -115,7 +149,7 @@ module SearchLingo
|
|
115
149
|
# This is a skeletal implementation that raises +NotImplementedError+.
|
116
150
|
# Child classes should provide their own implementation. At a minimum, that
|
117
151
|
# implementation should return +chain+. (Doing so would ignore +token+.)
|
118
|
-
def default_parse(
|
152
|
+
def default_parse(_token, _chain)
|
119
153
|
raise NotImplementedError,
|
120
154
|
"#default_parse must be implemented by #{self.class}"
|
121
155
|
end
|
data/lib/search_lingo/parsers.rb
CHANGED
@@ -1,36 +1,57 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
1
3
|
require 'search_lingo/parsers/mdy'
|
2
4
|
|
3
5
|
module SearchLingo
|
4
6
|
module Parsers # :nodoc:
|
7
|
+
##
|
8
|
+
# DateParser is an example parser which handles dates that adhere to the
|
9
|
+
# MDY format used in the US. It uses `SearchLingo::Parsers::MDY.parse` to
|
10
|
+
# parse the date. It handles simple dates as well as closed and open-ended
|
11
|
+
# date ranges.
|
12
|
+
#
|
13
|
+
# Examples of single dates are 7/14, 7/14/17, and 7/14/2017.
|
14
|
+
# Examples of closed date ranges are 1/1-6/30 and 7/1/16-6/30/18.
|
15
|
+
# Examples of open date ranges are -6/30 and 7/1/17-.
|
5
16
|
class DateParser
|
6
17
|
include MDY
|
7
18
|
|
19
|
+
attr_reader :column, :prefix, :append
|
20
|
+
|
8
21
|
##
|
9
22
|
# Instantiates a new DateParser object.
|
10
23
|
#
|
11
24
|
# The required argument +column+ should be an Arel attribute.
|
12
25
|
#
|
13
26
|
# If present, the optional argument +modifier+ will be used as the
|
14
|
-
# operator which precedes the date term.
|
27
|
+
# token operator which precedes the date term.
|
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.)
|
15
33
|
#
|
16
|
-
# DateParser.new
|
17
|
-
# DateParser.new
|
18
|
-
|
34
|
+
# DateParser.new Model.arel_table[:date]
|
35
|
+
# DateParser.new Model.arel_table[:date], modifier: 'contract'
|
36
|
+
# DateParser.new Model.arel_table[:date] do |chain|
|
37
|
+
# chain.joins(:relation)
|
38
|
+
# end
|
39
|
+
def initialize(column, modifier: nil, &block)
|
19
40
|
@column = column
|
20
|
-
@prefix =
|
41
|
+
@prefix = /#{modifier}:[[:space:]]*/ if modifier
|
42
|
+
@append = if block_given?
|
43
|
+
block
|
44
|
+
else
|
45
|
+
->(chain) { chain }
|
46
|
+
end
|
21
47
|
end
|
22
48
|
|
23
|
-
attr_reader :column, :prefix
|
24
|
-
|
25
49
|
##
|
26
|
-
# Attempts to parse
|
27
|
-
# range.
|
28
|
-
#
|
29
|
-
# Examples of single dates are 7/14, 7/14/17, and 7/14/2017.
|
30
|
-
# Examples of closed date ranges are 1/1-6/30 and 7/1/16-6/30/18.
|
31
|
-
# Examples of open date ranges are -6/30 and 7/1/17-.
|
50
|
+
# Attempts to parse +token+ as a single date, closed date range, or open
|
51
|
+
# date range. If parsing succeeds, the parser sends #where to +chain+
|
52
|
+
# with the appropriate Arel node and returns the result.
|
32
53
|
def call(token, chain)
|
33
|
-
catch :
|
54
|
+
catch :halt do
|
34
55
|
parse_single_date token, chain
|
35
56
|
parse_date_range token, chain
|
36
57
|
parse_lte_date token, chain
|
@@ -39,38 +60,40 @@ module SearchLingo
|
|
39
60
|
end
|
40
61
|
|
41
62
|
def inspect # :nodoc:
|
42
|
-
'
|
43
|
-
|
63
|
+
format '#<%<cls>s @prefix=%<prefix>s @column=%<column>s>',
|
64
|
+
cls: self.class,
|
65
|
+
prefix: prefix.inspect,
|
66
|
+
column: column.inspect
|
44
67
|
end
|
45
68
|
|
46
69
|
private
|
47
70
|
|
48
|
-
def parse_single_date(token, chain)
|
71
|
+
def parse_single_date(token, chain) # :nodoc:
|
49
72
|
token.match(/\A#{prefix}(?<date>#{US_DATE})\z/) do |m|
|
50
73
|
date = parse(m[:date]) or return nil
|
51
|
-
throw :
|
74
|
+
throw :halt, append.call(chain).where(column.eq(date))
|
52
75
|
end
|
53
76
|
end
|
54
77
|
|
55
|
-
def parse_date_range(token, chain)
|
78
|
+
def parse_date_range(token, chain) # :nodoc:
|
56
79
|
token.match(/\A#{prefix}(?<min>#{US_DATE})-(?<max>#{US_DATE})\z/) do |m|
|
57
80
|
min = parse(m[:min]) or return nil
|
58
81
|
max = parse(m[:max], relative_to: min.next_year) or return nil
|
59
|
-
throw :
|
82
|
+
throw :halt, append.call(chain).where(column.in(min..max))
|
60
83
|
end
|
61
84
|
end
|
62
85
|
|
63
|
-
def parse_lte_date(token, chain)
|
86
|
+
def parse_lte_date(token, chain) # :nodoc:
|
64
87
|
token.match(/\A#{prefix}-(?<date>#{US_DATE})\z/) do |m|
|
65
88
|
date = parse(m[:date]) or return nil
|
66
|
-
throw :
|
89
|
+
throw :halt, append.call(chain).where(column.lteq(date))
|
67
90
|
end
|
68
91
|
end
|
69
92
|
|
70
|
-
def parse_gte_date(token, chain)
|
93
|
+
def parse_gte_date(token, chain) # :nodoc:
|
71
94
|
token.match(/\A#{prefix}(?<date>#{US_DATE})-\z/) do |m|
|
72
95
|
date = parse(m[:date]) or return nil
|
73
|
-
throw :
|
96
|
+
throw :halt, append.call(chain).where(column.gteq(date))
|
74
97
|
end
|
75
98
|
end
|
76
99
|
end
|
@@ -1,7 +1,12 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
1
3
|
require 'date'
|
2
4
|
|
3
5
|
module SearchLingo
|
4
6
|
module Parsers # :nodoc:
|
7
|
+
##
|
8
|
+
# MDY provides a parser for dates that adhere to the MDY format used in the
|
9
|
+
# US.
|
5
10
|
module MDY
|
6
11
|
##
|
7
12
|
# Pattern for matching US-formatted date strings.
|
@@ -22,25 +27,30 @@ module SearchLingo
|
|
22
27
|
# defaults to today's date.
|
23
28
|
#
|
24
29
|
# Available as both a class method and an instance method.
|
30
|
+
# rubocop:disable Metrics/MethodLength
|
25
31
|
def parse(term, relative_to: Date.today)
|
26
|
-
term.match
|
32
|
+
term.match(/\A#{US_DATE}\z/) do |m|
|
27
33
|
return Date.parse "#{m[:y]}/#{m[:m]}/#{m[:d]}" if m[:y]
|
28
34
|
|
29
35
|
ref = relative_to
|
30
|
-
|
31
|
-
|
36
|
+
month = Integer m[:m]
|
37
|
+
day = Integer m[:d]
|
32
38
|
year = if month < ref.month || month == ref.month && day <= ref.day
|
33
39
|
ref.year
|
34
40
|
else
|
35
41
|
ref.year - 1
|
36
42
|
end
|
37
|
-
|
38
43
|
Date.new year, month, day
|
39
44
|
end
|
40
45
|
rescue ArgumentError
|
46
|
+
# Fail if Date.parse or Date.new raise ArgumentError.
|
47
|
+
nil
|
41
48
|
end
|
49
|
+
# rubocop:enable Metrics/MethodLength
|
42
50
|
|
51
|
+
# rubocop:disable Style/AccessModifierDeclarations:
|
43
52
|
module_function :parse
|
53
|
+
# rubocop:enable Style/AccessModifierDeclarations:
|
44
54
|
end
|
45
55
|
end
|
46
56
|
end
|
data/lib/search_lingo/token.rb
CHANGED
@@ -1,7 +1,22 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
1
3
|
require 'delegate'
|
2
4
|
require 'search_lingo/constants'
|
3
5
|
|
4
6
|
module SearchLingo
|
7
|
+
##
|
8
|
+
# Single token from a query string. A token consists of a term an an optional
|
9
|
+
# modifier. The term may be a word or multiple words contained within double
|
10
|
+
# quotes. The modifier is one or more alphanumeric characters. The modifier
|
11
|
+
# and term and separated by a colon followed by zero or more whitespace
|
12
|
+
# characters.
|
13
|
+
#
|
14
|
+
# The following are examples of tokens:
|
15
|
+
#
|
16
|
+
# Token.new('foo')
|
17
|
+
# Token.new('"foo bar"')
|
18
|
+
# Token.new('foo: bar')
|
19
|
+
# Token.new('foo: "bar baz"')
|
5
20
|
class Token < DelegateClass(String)
|
6
21
|
##
|
7
22
|
# Pattern for decomposing a token into a modifier and a term.
|
@@ -17,7 +32,7 @@ module SearchLingo
|
|
17
32
|
self[STRUCTURE, 1]
|
18
33
|
end
|
19
34
|
|
20
|
-
|
35
|
+
alias operator modifier
|
21
36
|
|
22
37
|
##
|
23
38
|
# Returns the term portion of the token. If the term is wrapped in quotes,
|
@@ -36,12 +51,15 @@ module SearchLingo
|
|
36
51
|
# Token.new('foo: bar').compound? # => true
|
37
52
|
# Token.new('bar').compound? # => false
|
38
53
|
def compound?
|
39
|
-
|
54
|
+
!modifier.nil? && !modifier.empty?
|
40
55
|
end
|
41
56
|
|
42
57
|
def inspect # :nodoc:
|
43
|
-
'
|
44
|
-
|
58
|
+
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
|
45
63
|
end
|
46
64
|
end
|
47
65
|
end
|
@@ -1,9 +1,17 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
1
3
|
require 'forwardable'
|
2
4
|
require 'strscan'
|
3
5
|
require 'search_lingo/constants'
|
4
6
|
require 'search_lingo/token'
|
5
7
|
|
6
8
|
module SearchLingo
|
9
|
+
##
|
10
|
+
# Tokenizer breaks down a query string into individual tokens.
|
11
|
+
#
|
12
|
+
# Tokenizer.new 'foo'
|
13
|
+
# Tokenizer.foo 'foo "bar baz"'
|
14
|
+
# Tokenizer.foo 'foo "bar baz" froz: quux'
|
7
15
|
class Tokenizer
|
8
16
|
include Enumerable
|
9
17
|
extend Forwardable
|
@@ -30,9 +38,7 @@ module SearchLingo
|
|
30
38
|
def each
|
31
39
|
return to_enum(__callee__) unless block_given?
|
32
40
|
|
33
|
-
until scanner.eos?
|
34
|
-
yield self.next
|
35
|
-
end
|
41
|
+
yield self.next until scanner.eos?
|
36
42
|
end
|
37
43
|
|
38
44
|
##
|
@@ -42,6 +48,7 @@ module SearchLingo
|
|
42
48
|
scanner.skip DELIMITER
|
43
49
|
token = scanner.scan COMPOUND_TOKEN
|
44
50
|
raise StopIteration unless token
|
51
|
+
|
45
52
|
Token.new token
|
46
53
|
end
|
47
54
|
|
data/lib/search_lingo/version.rb
CHANGED
data/search_lingo.gemspec
CHANGED
@@ -1,34 +1,43 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'search_lingo/version'
|
5
6
|
|
7
|
+
# rubocop:disable Metrics/BlockLength
|
6
8
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
9
|
+
spec.name = 'search_lingo'
|
8
10
|
spec.version = SearchLingo::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
+
spec.authors = ['John Parker']
|
12
|
+
spec.email = ['jparker@urgetopunt.com']
|
11
13
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
14
|
-
|
15
|
-
|
14
|
+
spec.summary = 'Framework for defining and parsing search queries.'
|
15
|
+
spec.description = <<~DESCRIPTION
|
16
|
+
SearchLingo is a simple framework for defining simple query languages and
|
17
|
+
translating them into application-specific queries.
|
18
|
+
DESCRIPTION
|
19
|
+
spec.homepage = 'https://github.com/jparker/search_lingo'
|
20
|
+
spec.license = 'MIT'
|
16
21
|
|
17
|
-
spec.files = `git ls-files -z`.split("\x0").reject { |f|
|
18
|
-
|
22
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f|
|
23
|
+
f.match(%r{^(test|spec|features)/})
|
24
|
+
}
|
25
|
+
spec.bindir = 'exe'
|
19
26
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
-
spec.require_paths = [
|
27
|
+
spec.require_paths = ['lib']
|
21
28
|
|
22
29
|
spec.rdoc_options += ['-x', 'examples/', '-x', 'test/']
|
23
30
|
|
24
|
-
spec.required_ruby_version = '>= 2.
|
31
|
+
spec.required_ruby_version = '>= 2.3'
|
25
32
|
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
33
|
+
spec.add_development_dependency 'bundler', '~> 1.9'
|
28
34
|
spec.add_development_dependency 'minitest'
|
29
35
|
spec.add_development_dependency 'minitest-focus'
|
30
36
|
spec.add_development_dependency 'mocha'
|
31
37
|
spec.add_development_dependency 'pry'
|
38
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
39
|
+
spec.add_development_dependency 'rubocop'
|
32
40
|
spec.add_development_dependency 'sequel', '~> 5.0'
|
33
41
|
spec.add_development_dependency 'sqlite3'
|
34
42
|
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: 2.0.0.pre3
|
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-10-
|
11
|
+
date: 2018-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -25,21 +25,21 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.9'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name: minitest
|
42
|
+
name: minitest-focus
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: mocha
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: pry
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -81,7 +81,21 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '10.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '10.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
101
|
- - ">="
|
@@ -122,8 +136,9 @@ dependencies:
|
|
122
136
|
- - ">="
|
123
137
|
- !ruby/object:Gem::Version
|
124
138
|
version: '0'
|
125
|
-
description:
|
126
|
-
|
139
|
+
description: |
|
140
|
+
SearchLingo is a simple framework for defining simple query languages and
|
141
|
+
translating them into application-specific queries.
|
127
142
|
email:
|
128
143
|
- jparker@urgetopunt.com
|
129
144
|
executables: []
|
@@ -131,6 +146,7 @@ extensions: []
|
|
131
146
|
extra_rdoc_files: []
|
132
147
|
files:
|
133
148
|
- ".gitignore"
|
149
|
+
- ".rubocop.yml"
|
134
150
|
- ".travis.yml"
|
135
151
|
- Gemfile
|
136
152
|
- LICENSE.txt
|
@@ -166,7 +182,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
166
182
|
requirements:
|
167
183
|
- - ">="
|
168
184
|
- !ruby/object:Gem::Version
|
169
|
-
version: '2.
|
185
|
+
version: '2.3'
|
170
186
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
171
187
|
requirements:
|
172
188
|
- - ">"
|