solrb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +69 -0
  3. data/.circleci/run-with-local-config.sh +7 -0
  4. data/.gitignore +11 -0
  5. data/.rspec +3 -0
  6. data/.rubocop.yml +30 -0
  7. data/.ruby-version +1 -0
  8. data/Gemfile +6 -0
  9. data/Gemfile.lock +83 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +259 -0
  12. data/Rakefile +6 -0
  13. data/bin/console +14 -0
  14. data/bin/setup +8 -0
  15. data/lib/solr/commit/request.rb +15 -0
  16. data/lib/solr/configuration.rb +66 -0
  17. data/lib/solr/connection.rb +33 -0
  18. data/lib/solr/core_configuration/core_config.rb +44 -0
  19. data/lib/solr/core_configuration/core_config_builder.rb +51 -0
  20. data/lib/solr/core_configuration/dynamic_field.rb +17 -0
  21. data/lib/solr/core_configuration/field.rb +20 -0
  22. data/lib/solr/delete/request.rb +34 -0
  23. data/lib/solr/document.rb +26 -0
  24. data/lib/solr/document_collection.rb +55 -0
  25. data/lib/solr/errors/ambiguous_core_error.rb +9 -0
  26. data/lib/solr/errors/solr_query_error.rb +4 -0
  27. data/lib/solr/errors/solr_url_not_defined_error.rb +16 -0
  28. data/lib/solr/grouped_document_collection.rb +38 -0
  29. data/lib/solr/indexing/document.rb +25 -0
  30. data/lib/solr/indexing/request.rb +22 -0
  31. data/lib/solr/query/request/boost_magnitude.rb +9 -0
  32. data/lib/solr/query/request/boosting/dictionary_boost_function.rb +36 -0
  33. data/lib/solr/query/request/boosting/exists_boost_function.rb +27 -0
  34. data/lib/solr/query/request/boosting/field_value_less_than_boost_function.rb +25 -0
  35. data/lib/solr/query/request/boosting/field_value_match_boost_function.rb +24 -0
  36. data/lib/solr/query/request/boosting/geodist_function.rb +37 -0
  37. data/lib/solr/query/request/boosting/ln_function_boost.rb +28 -0
  38. data/lib/solr/query/request/boosting/numeric_field_value_match_boost_function.rb +13 -0
  39. data/lib/solr/query/request/boosting/phrase_proximity_boost.rb +27 -0
  40. data/lib/solr/query/request/boosting/ranking_field_boost_function.rb +20 -0
  41. data/lib/solr/query/request/boosting/recent_field_value_boost_function.rb +26 -0
  42. data/lib/solr/query/request/boosting/scale_function_boost.rb +28 -0
  43. data/lib/solr/query/request/boosting/textual_field_value_match_boost_function.rb +13 -0
  44. data/lib/solr/query/request/boosting.rb +46 -0
  45. data/lib/solr/query/request/edismax_adapter.rb +163 -0
  46. data/lib/solr/query/request/facet.rb +68 -0
  47. data/lib/solr/query/request/field_with_boost.rb +18 -0
  48. data/lib/solr/query/request/filter.rb +73 -0
  49. data/lib/solr/query/request/geo_filter.rb +26 -0
  50. data/lib/solr/query/request/grouping.rb +37 -0
  51. data/lib/solr/query/request/or_filter.rb +16 -0
  52. data/lib/solr/query/request/runner.rb +46 -0
  53. data/lib/solr/query/request/sorting/field.rb +16 -0
  54. data/lib/solr/query/request/sorting.rb +34 -0
  55. data/lib/solr/query/request/spellcheck.rb +74 -0
  56. data/lib/solr/query/request.rb +49 -0
  57. data/lib/solr/query/response/facet_value.rb +16 -0
  58. data/lib/solr/query/response/field_facets.rb +25 -0
  59. data/lib/solr/query/response/parser.rb +154 -0
  60. data/lib/solr/query/response/spellcheck.rb +42 -0
  61. data/lib/solr/query/response.rb +48 -0
  62. data/lib/solr/response/header.rb +25 -0
  63. data/lib/solr/response/http_status.rb +27 -0
  64. data/lib/solr/response/parser.rb +47 -0
  65. data/lib/solr/response/solr_error.rb +31 -0
  66. data/lib/solr/response.rb +52 -0
  67. data/lib/solr/support/connection_helper.rb +12 -0
  68. data/lib/solr/support/hash_extensions.rb +29 -0
  69. data/lib/solr/support/schema_helper.rb +11 -0
  70. data/lib/solr/support/string_extensions.rb +12 -0
  71. data/lib/solr/support/url_helper.rb +12 -0
  72. data/lib/solr/support.rb +5 -0
  73. data/lib/solr/testing.rb +19 -0
  74. data/lib/solr/version.rb +3 -0
  75. data/lib/solr.rb +65 -0
  76. data/solrb.gemspec +36 -0
  77. metadata +261 -0
@@ -0,0 +1,16 @@
1
+ module Solr
2
+ module Query
3
+ class Response
4
+ class FacetValue
5
+ attr_reader :text, :count, :subfacets
6
+
7
+ def initialize(text:, count:, subfacets: [])
8
+ @text = text
9
+ @count = count
10
+ @subfacets = subfacets
11
+ freeze
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ module Solr
2
+ module Query
3
+ class Response
4
+ class FieldFacets
5
+ include Enumerable
6
+
7
+ attr_reader :field, :facet_values, :count, :subfacets
8
+
9
+ def initialize(field:, facet_values:, count:, subfacets: [])
10
+ @field = field
11
+ @facet_values = facet_values
12
+ @count = count
13
+ @subfacets = subfacets
14
+
15
+ freeze
16
+ end
17
+
18
+ def each(&b)
19
+ return enum_for(:each) unless block_given?
20
+ facet_values.each(&b)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,154 @@
1
+ module Solr
2
+ module Query
3
+ class Response
4
+ class Parser
5
+ SOLR_INFINITY = '*'.freeze # for cases like [100000 TO *]
6
+
7
+ include Solr::Support::SchemaHelper
8
+
9
+ attr_reader :request, :solr_response
10
+
11
+ def initialize(request:, solr_response:)
12
+ @request = request
13
+ @solr_response = solr_response
14
+ end
15
+
16
+ def to_response
17
+ documents = parse_documents
18
+ total_count = parse_total_count
19
+ if !request.grouping.empty?
20
+ group_counts = parse_group_counts
21
+ document_collection = Solr::GroupedDocumentCollection.new(documents: documents,
22
+ total_count: total_count,
23
+ group_counts: group_counts)
24
+ else
25
+ document_collection = Solr::DocumentCollection.new(documents: documents, total_count: total_count)
26
+ end
27
+ Solr::Query::Response.new(
28
+ documents: document_collection,
29
+ available_facets: field_facet_collection,
30
+ spellcheck: spellcheck
31
+ )
32
+ end
33
+
34
+ private
35
+
36
+ def parse_total_count
37
+ if !request.grouping.empty?
38
+ parse_grouped_total_count(solr_grouping_field)
39
+ else
40
+ parse_regular_total_count
41
+ end
42
+ end
43
+
44
+ def parse_grouped_total_count(solr_grouping_field)
45
+ solr_response['grouped'][solr_grouping_field]['groups'].reduce(0) do |acc, group|
46
+ acc + group['doclist']['numFound'].to_i
47
+ end
48
+ end
49
+
50
+ def parse_regular_total_count
51
+ solr_response.dig('response', 'numFound').to_i
52
+ end
53
+
54
+ def parse_group_counts
55
+ group_counts = {}
56
+ unless request.grouping.empty?
57
+ Array(solr_response.dig('grouped', solr_grouping_field, 'groups')).each do |group|
58
+ group_counts[group['groupValue']] = group['doclist']['numFound']
59
+ end
60
+ end
61
+ group_counts
62
+ end
63
+
64
+ def parse_documents
65
+ if !request.grouping.empty?
66
+ parse_grouped_documents(solr_grouping_field)
67
+ else
68
+ parse_regular_documents
69
+ end
70
+ end
71
+
72
+ def parse_regular_documents
73
+ solr_response['response']['docs'].map do |d|
74
+ debug_info = solr_response.dig('debug', 'explain', d['id'])
75
+ Document.new(id: d['id'], score: d['score'], debug_info: debug_info)
76
+ end
77
+ end
78
+
79
+ def parse_grouped_documents(solr_grouping_field)
80
+ Array(solr_response.dig('grouped', solr_grouping_field, 'groups')).map do |group|
81
+ Array(group.dig('doclist', 'docs')).map do |doc|
82
+ next unless doc
83
+ debug_info = solr_response.dig('debug', 'explain', doc['id'])
84
+ group_information = Document::GroupInformation.new(key: solr_grouping_field, value: group['groupValue'])
85
+ Document.new(id: doc['id'], score: doc['score'],
86
+ debug_info: debug_info, group: group_information)
87
+ end
88
+ end.flatten.compact
89
+ end
90
+
91
+ def solr_grouping_field
92
+ grouping_field = request.grouping.field
93
+ solarize_field(grouping_field)
94
+ end
95
+
96
+ def field_facet_collection
97
+ return [] unless solr_response_has_facet_data?
98
+
99
+ raw_facet_data = solr_response['facets'].except('count')
100
+
101
+ parse_facets(raw_facet_data)
102
+ end
103
+
104
+ # Each facet could contain subfacets.
105
+ # We need to parse them recursively and store in subfacets array.
106
+ def parse_facets(raw_facet_data)
107
+ raw_facet_data.map do |field_name, facet_data|
108
+ # We need to handle use case when facet_data is not a hash
109
+ # (e.g. query facet request with aggregate function)
110
+ if facet_data.is_a?(Hash)
111
+ parse_facet_hash(field_name, facet_data)
112
+ else
113
+ parse_facet_count(field_name, facet_data)
114
+ end
115
+ end
116
+ end
117
+
118
+ def parse_facet_hash(field_name, facet_data)
119
+ count = facet_data.delete('count')
120
+ facets = facet_data.delete('buckets')
121
+
122
+ facet_values =
123
+ Array(facets).map do |facet|
124
+ text = facet.delete('val')
125
+ count = facet.delete('count')
126
+
127
+ Solr::Query::Response::FacetValue.new(text: text, count: count, subfacets: parse_facets(facet))
128
+ end
129
+
130
+ Solr::Query::Response::FieldFacets.new(field: field_name,
131
+ facet_values: facet_values,
132
+ count: count.to_i,
133
+ subfacets: parse_facets(facet_data))
134
+ end
135
+
136
+ def parse_facet_count(field_name, count)
137
+ Solr::Query::Response::FieldFacets.new(field: field_name,
138
+ facet_values: [],
139
+ count: count.to_i,
140
+ subfacets: [])
141
+ end
142
+
143
+ def solr_response_has_facet_data?
144
+ solr_response['facets']
145
+ end
146
+
147
+ def spellcheck
148
+ return Solr::Query::Response::Spellcheck.empty unless solr_response['spellcheck']
149
+ Solr::Query::Response::Spellcheck.new(solr_response['spellcheck'])
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,42 @@
1
+ module Solr
2
+ module Query
3
+ class Response
4
+ class Spellcheck
5
+ attr_reader :response
6
+
7
+ class Collation
8
+ def initialize(data)
9
+ @data = data
10
+ end
11
+
12
+ def collation_query
13
+ @data['collationQuery']
14
+ end
15
+
16
+ def hits
17
+ @data['hits']
18
+ end
19
+
20
+ def misspellings_and_corrections
21
+ return {} unless @data['misspellingsAndCorrections']
22
+ @data['misspellingsAndCorrections'].in_groups_of(2).to_h
23
+ end
24
+ end
25
+
26
+ def self.empty
27
+ new({})
28
+ end
29
+
30
+ def initialize(response)
31
+ @response = response || {}
32
+ end
33
+
34
+ def collations
35
+ Array(response['collations']).flatten(1).in_groups_of(2).map do |_, collation|
36
+ Collation.new(collation)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,48 @@
1
+ require 'solr/query/response/facet_value'
2
+ require 'solr/query/response/field_facets'
3
+ require 'solr/query/response/parser'
4
+ require 'solr/query/response/spellcheck'
5
+
6
+ module Solr
7
+ module Query
8
+ class Response
9
+ attr_reader :documents, :available_facets, :spellcheck
10
+
11
+ class << self
12
+ def empty
13
+ new(documents: Solr::DocumentCollection.empty)
14
+ end
15
+
16
+ def empty_grouped
17
+ new(documents: Solr::GroupedDocumentCollection.empty)
18
+ end
19
+
20
+ def manual_grouped_documents(ids)
21
+ documents = ids.map { |id| Solr::Document.new(id: id) }
22
+ group_counts = ids.each_with_object({}) do |id, acc|
23
+ acc[id] = 1
24
+ end
25
+ new(documents: Solr::GroupedDocumentCollection.new(
26
+ documents: documents,
27
+ total_count: ids.count,
28
+ group_counts: group_counts
29
+ ))
30
+ end
31
+ end
32
+
33
+ def initialize(documents:, available_facets: [], spellcheck: Solr::Query::Response::Spellcheck.empty)
34
+ @documents = documents
35
+ @available_facets = available_facets
36
+ @spellcheck = spellcheck
37
+ end
38
+
39
+ def total_count
40
+ @documents.total_count
41
+ end
42
+
43
+ def empty?
44
+ total_count.zero?
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,25 @@
1
+ module Solr
2
+ class Response
3
+ class Header
4
+ attr_reader :status, :time
5
+
6
+ def initialize(status:, time: 0)
7
+ @status = status
8
+ @time = time
9
+ freeze
10
+ end
11
+
12
+ def ok?
13
+ status.zero?
14
+ end
15
+
16
+ def inspect
17
+ if ok?
18
+ 'OK'
19
+ else
20
+ status.to_s
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,27 @@
1
+ module Solr
2
+ class Response
3
+ class HttpStatus
4
+ class << self
5
+ def ok
6
+ new(status: 200, message: 'OK')
7
+ end
8
+
9
+ def not_found
10
+ new(status: 404, message: 'Not Found')
11
+ end
12
+ end
13
+
14
+ attr_reader :status, :message
15
+
16
+ def initialize(status:, message:)
17
+ @status = status
18
+ @message = message
19
+ freeze
20
+ end
21
+
22
+ def inspect
23
+ "#{status} (#{message})"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,47 @@
1
+ module Solr
2
+ class Response
3
+ class Parser
4
+ def initialize(raw_response)
5
+ @raw_response = raw_response
6
+ end
7
+
8
+ def parse
9
+ # 404 is a special case, it didn't hit Solr (more likely than not)
10
+ return not_found_response if @raw_response.status == 404
11
+ parsed_body = JSON.parse(@raw_response.body).freeze
12
+ http_status = parse_http_status
13
+ header = parse_header(parsed_body)
14
+ solr_error = parse_solr_error(parsed_body)
15
+ Solr::Response.new(header: header, http_status: http_status, solr_error: solr_error, body: parsed_body)
16
+ end
17
+
18
+ private
19
+
20
+ def not_found_response
21
+ Solr::Response.new(
22
+ header: Solr::Response::Header.new(status: 404),
23
+ http_status: Solr::Response::HttpStatus.not_found,
24
+ solr_error: nil
25
+ )
26
+ end
27
+
28
+ def parse_header(parsed_body)
29
+ parsed_header = parsed_body['responseHeader']
30
+ status = parsed_header['status'].to_i
31
+ time = parsed_header['QTime'].to_i
32
+ Solr::Response::Header.new(status: status, time: time)
33
+ end
34
+
35
+ def parse_http_status
36
+ HttpStatus.new(status: @raw_response.status, message: @raw_response.reason_phrase)
37
+ end
38
+
39
+ def parse_solr_error(parsed_body)
40
+ return Solr::Response::SolrError.none unless parsed_body['error']
41
+ code = parsed_body['error']['code'].to_i
42
+ message = parsed_body['error']['msg']
43
+ Solr::Response::SolrError.new(code: code, message: message)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,31 @@
1
+ module Solr
2
+ class Response
3
+ class SolrError
4
+ class None < SolrError
5
+ def initialize
6
+ super(code: nil, message: nil)
7
+ freeze
8
+ end
9
+
10
+ def inspect
11
+ 'SolrError: None'
12
+ end
13
+ end
14
+
15
+ def self.none
16
+ None.new
17
+ end
18
+
19
+ attr_reader :code, :message
20
+ def initialize(code:, message:)
21
+ @code = code
22
+ @message = message
23
+ freeze
24
+ end
25
+
26
+ def inspect
27
+ "#{message} (#{code})"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,52 @@
1
+ require 'solr/response/header'
2
+ require 'solr/response/http_status'
3
+ require 'solr/response/solr_error'
4
+ require 'solr/response/parser'
5
+
6
+ module Solr
7
+ class Response
8
+ OK = 'OK'.freeze
9
+
10
+ def self.from_raw_response(response)
11
+ Solr::Response::Parser.new(response).parse
12
+ end
13
+
14
+ attr_reader :header, :http_status, :solr_error, :body
15
+
16
+ def initialize(header:, http_status: HttpStatus.ok, solr_error: SolrError.none, body: {})
17
+ @header = header
18
+ @http_status = http_status
19
+ @solr_error = solr_error
20
+ @body = body
21
+ freeze
22
+ end
23
+
24
+ def ok?
25
+ header.ok?
26
+ end
27
+
28
+ def error?
29
+ !ok?
30
+ end
31
+
32
+ def status
33
+ if header.status.zero?
34
+ OK
35
+ else
36
+ header.status
37
+ end
38
+ end
39
+
40
+ def error_message
41
+ return if ok?
42
+ solr_error ? solr_error.message : http_status.inspect
43
+ end
44
+
45
+ def inspect
46
+ return OK if ok?
47
+ str = "Error: #{http_status.inspect}"
48
+ str << "\n#{solr_error.inspect}" if solr_error
49
+ str
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,12 @@
1
+ module Solr
2
+ module Support
3
+ module ConnectionHelper
4
+ def connection(path, commit: false)
5
+ url_params = {}
6
+ url_params[:commit] = true if commit
7
+ url = Solr::Support::UrlHelper.solr_url(path, url_params: url_params)
8
+ Solr::Connection.new(url)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,29 @@
1
+ module Solr
2
+ module Support
3
+ module HashExtensions
4
+ extend self
5
+
6
+ def symbolize_recursive(hash)
7
+ {}.tap do |h|
8
+ hash.each { |key, value| h[key.to_sym] = transform(value) }
9
+ end
10
+ end
11
+
12
+ private
13
+
14
+ def transform(thing)
15
+ case thing
16
+ when Hash then symbolize_recursive(thing)
17
+ when Array then thing.map { |v| transform(v) }
18
+ else; thing
19
+ end
20
+ end
21
+
22
+ refine Hash do
23
+ def deep_symbolize_keys
24
+ HashExtensions.symbolize_recursive(self)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,11 @@
1
+ module Solr
2
+ module Support
3
+ module SchemaHelper
4
+ def solarize_field(field)
5
+ core = Solr.current_core_config
6
+ field_config = core.field_by_name(field.to_sym) if core
7
+ field_config ? field_config.solr_field_name : field.to_s
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module Solr
2
+ module Support
3
+ module StringExtensions
4
+ refine String do
5
+ # REVIEW: this escape
6
+ def solr_escape
7
+ gsub(%r(([+\-&|!\(\)\{\}\[\]\^"~\*\?:\\/])), '\\\\\1')
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module Solr
2
+ module Support
3
+ module UrlHelper
4
+ def self.solr_url(path, url_params: {})
5
+ full_url = File.join(Solr.current_core_config.uri, path)
6
+ full_uri = Addressable::URI.parse(full_url)
7
+ full_uri.query_values = url_params if url_params.any?
8
+ full_uri
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ require 'solr/support/hash_extensions'
2
+ require 'solr/support/string_extensions'
3
+ require 'solr/support/url_helper'
4
+ require 'solr/support/connection_helper'
5
+ require 'solr/support/schema_helper'
@@ -0,0 +1,19 @@
1
+ module Solr
2
+ module Testing
3
+ class << self
4
+ attr_reader :last_solr_request_params, :last_solr_response
5
+
6
+ def subscribe_to_events
7
+ if defined? ActiveSupport::Notifications
8
+ ActiveSupport::Notifications.subscribe('solrb.request_response_cycle') do |*args|
9
+ event = ActiveSupport::Notifications::Event.new(*args)
10
+ @last_solr_request_params = event.payload[:request][:params]
11
+ @last_solr_response = event.payload[:response]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ Solr::Testing.subscribe_to_events
@@ -0,0 +1,3 @@
1
+ module Solr
2
+ VERSION = '0.1.0'.freeze
3
+ end
data/lib/solr.rb ADDED
@@ -0,0 +1,65 @@
1
+ require 'json'
2
+ require 'faraday'
3
+ require 'addressable/uri'
4
+ require 'solr/support'
5
+ require 'solr/configuration'
6
+ require 'solr/version'
7
+ require 'solr/connection'
8
+ require 'solr/document'
9
+ require 'solr/document_collection'
10
+ require 'solr/grouped_document_collection'
11
+ require 'solr/response'
12
+ require 'solr/query/request'
13
+ require 'solr/indexing/document'
14
+ require 'solr/indexing/request'
15
+ require 'solr/delete/request'
16
+ require 'solr/commit/request'
17
+
18
+ module Solr
19
+ class << self
20
+ CURRENT_CORE_CONFIG_VARIABLE_NAME = :solrb_current_core_config
21
+
22
+ attr_accessor :configuration
23
+
24
+ Solr.configuration = Configuration.new
25
+
26
+ def configure
27
+ yield configuration
28
+ end
29
+
30
+ def current_core_config
31
+ Thread.current[CURRENT_CORE_CONFIG_VARIABLE_NAME] || Solr.configuration.default_core_config
32
+ end
33
+
34
+ def commit
35
+ Solr::Commit::Request.new.run
36
+ end
37
+
38
+ def delete_by_id(id, commit: false)
39
+ Solr::Delete::Request.new(id: id).run(commit: commit)
40
+ end
41
+
42
+ def delete_by_query(query, commit: false)
43
+ Solr::Delete::Request.new(query: query).run(commit: commit)
44
+ end
45
+
46
+ def with_core(core)
47
+ core_config = Solr.configuration.core_config_by_name(core)
48
+ old_core_config = Thread.current[CURRENT_CORE_CONFIG_VARIABLE_NAME]
49
+ Thread.current[CURRENT_CORE_CONFIG_VARIABLE_NAME] = core_config
50
+ yield
51
+ ensure
52
+ Thread.current[CURRENT_CORE_CONFIG_VARIABLE_NAME] = old_core_config
53
+ end
54
+
55
+ def instrument(name:, data: {})
56
+ if defined? ActiveSupport::Notifications
57
+ ActiveSupport::Notifications.instrument(name, data) do
58
+ yield if block_given?
59
+ end
60
+ else
61
+ yield if block_given?
62
+ end
63
+ end
64
+ end
65
+ end
data/solrb.gemspec ADDED
@@ -0,0 +1,36 @@
1
+ lib = File.expand_path('lib', __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'solr/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'solrb'
7
+ spec.version = Solr::VERSION
8
+ spec.authors = ['Adriano Luz', 'Valentin Vasilyev']
9
+ spec.email = ['adriano.luz@machinio.com', 'valentin@machinio.com']
10
+
11
+ spec.summary = 'Solr Ruby client with a nice object-oriented API'
12
+ spec.homepage = 'https://github.com/machinio/solrb'
13
+ spec.license = 'MIT'
14
+
15
+ # Specify which files should be added to the gem when it is released.
16
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
17
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
18
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ end
20
+
21
+ spec.bindir = 'exe'
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ['lib']
24
+
25
+ spec.add_runtime_dependency 'addressable'
26
+ spec.add_runtime_dependency 'faraday'
27
+
28
+ spec.add_development_dependency 'bundler', '~> 1.16'
29
+ spec.add_development_dependency 'pry'
30
+ spec.add_development_dependency 'pry-byebug'
31
+ spec.add_development_dependency 'rake', '~> 10.0'
32
+ spec.add_development_dependency 'rspec', '~> 3.0'
33
+ spec.add_development_dependency 'rspec_junit_formatter'
34
+ spec.add_development_dependency 'rubocop'
35
+ spec.add_development_dependency 'simplecov'
36
+ end