search_lingo 2.0.0.pre2 → 2.0.0.pre3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
- - ">"
|