harbinger 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +48 -0
- data/app/controllers/harbinger/messages_controller.rb +2 -2
- data/app/models/harbinger/database_channel_message.rb +10 -6
- data/app/views/harbinger/messages/index.html.erb +6 -2
- data/app/views/harbinger/messages/show.html.erb +7 -5
- data/config/routes.rb +1 -0
- data/db/migrate/20140310185338_create_harbinger_database_channel_message.rb +4 -2
- data/db/migrate/20140310185339_create_harbinger_database_channel_message_elements.rb +0 -1
- data/harbinger.gemspec +3 -1
- data/lib/harbinger.rb +13 -7
- data/lib/harbinger/engine.rb +2 -0
- data/lib/harbinger/message.rb +1 -1
- data/lib/harbinger/reporters.rb +1 -1
- data/lib/harbinger/version.rb +1 -1
- data/spec/features/end_to_end_exception_handling_spec.rb +6 -10
- data/spec/lib/harbinger/message_spec.rb +1 -1
- data/spec/lib/harbinger/reporters_spec.rb +8 -0
- data/spec/lib/harbinger_spec.rb +2 -2
- data/spec/models/harbinger/database_channel_message_spec.rb +2 -2
- data/spec/views/harbinger/messages/index.html.erb_spec.rb +7 -4
- data/spec/views/harbinger/messages/show.html.erb_spec.rb +7 -4
- metadata +30 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9286ebe3e606bd4307248feb1794d0c6a4e84a44
|
4
|
+
data.tar.gz: ebe9958929959fbc584187e2afe50cae6eb0a5de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c61a8b758e5fd0e1ec0f1aa11da0048195166cc8c55e3dfedbe53fe574a1917b5a0d083bcf68a389a5105c4d9f6fd276fa022917562110748bed57fc59f41cd
|
7
|
+
data.tar.gz: 7982c7f1af6d2d912d54ed749030e6b171378bb34c106973c6967b94c9930c1b87dcd77317d2c8f1b1b5546ab41f6425e896e3c63a5d8cc0c42d5c7a612acc1f
|
data/README.md
CHANGED
@@ -8,3 +8,51 @@
|
|
8
8
|
[![APACHE 2 License](http://img.shields.io/badge/APACHE2-license-blue.svg)](./LICENSE)
|
9
9
|
|
10
10
|
A Rails engine for arbitrary message creation and delivery.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
gem 'blorg'
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
$ gem install blorg
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
class PagesController
|
30
|
+
def show
|
31
|
+
@page = Page.find(params[:id])
|
32
|
+
rescue ActiveRecord::RecordNotFound => exception
|
33
|
+
Harbinger.call(
|
34
|
+
channels: [:database, :logger],
|
35
|
+
reporters: [exception, current_user, request]
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
Given the above Rails-like code
|
42
|
+
When a user attempts to find a page that does not exist
|
43
|
+
Then an exception is raised
|
44
|
+
And the Harbinger.call code will:
|
45
|
+
|
46
|
+
* Build a message based on the three reporters:
|
47
|
+
* The raised exception
|
48
|
+
* The current user
|
49
|
+
* The request
|
50
|
+
* Deliver that message to the two channels:
|
51
|
+
* Database
|
52
|
+
* Logger
|
53
|
+
|
54
|
+
For further details I recommend delving into the [end to end exception handling spec](./spec/features/end_to_end_exception_handling_spec.rb)
|
55
|
+
|
56
|
+
### Extending Contexts and Channels
|
57
|
+
|
58
|
+
Harbinger is built to allow for easy creation of new Contexts and Channels.
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Harbinger
|
2
|
-
class MessagesController <
|
2
|
+
class MessagesController < ApplicationController
|
3
3
|
|
4
4
|
def index
|
5
5
|
messages
|
@@ -12,7 +12,7 @@ module Harbinger
|
|
12
12
|
protected
|
13
13
|
|
14
14
|
def messages
|
15
|
-
@messages ||= DatabaseChannelMessage.search(q: params[:q])
|
15
|
+
@messages ||= DatabaseChannelMessage.page(params[:page]).search(q: params[:q])
|
16
16
|
end
|
17
17
|
|
18
18
|
def message
|
@@ -6,17 +6,18 @@ module Harbinger
|
|
6
6
|
self.table_name = 'harbinger_messages'
|
7
7
|
has_many :elements, class_name: 'Harbinger::DatabaseChannelMessageElement', foreign_key: :message_id
|
8
8
|
|
9
|
-
def
|
9
|
+
def reporters=(values)
|
10
10
|
super(Array.wrap(values).join(','))
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
13
|
+
def reporters
|
14
14
|
super.split(',')
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.store_message(message, storage = new)
|
18
|
-
storage.
|
18
|
+
storage.reporters = message.reporters
|
19
19
|
storage.state = 'new'
|
20
|
+
storage.message_object_id = message.object_id
|
20
21
|
message.attributes.each do |key, value|
|
21
22
|
storage.elements.build(key: key, value: value)
|
22
23
|
end
|
@@ -33,10 +34,13 @@ module Harbinger
|
|
33
34
|
scope :search_text, lambda { |text|
|
34
35
|
if text
|
35
36
|
where(
|
36
|
-
arel_table[:
|
37
|
+
arel_table[:reporters].matches("#{text}%").
|
37
38
|
or(
|
38
|
-
arel_table[:
|
39
|
-
|
39
|
+
arel_table[:message_object_id].eq(text).
|
40
|
+
or(
|
41
|
+
arel_table[:id].
|
42
|
+
in(Arel::SqlLiteral.new(DatabaseChannelMessageElement.search_text(text).select(:message_id).to_sql))
|
43
|
+
)
|
40
44
|
)
|
41
45
|
)
|
42
46
|
else
|
@@ -17,11 +17,14 @@
|
|
17
17
|
</fieldset>
|
18
18
|
<% end %>
|
19
19
|
|
20
|
+
<%= paginate messages %>
|
21
|
+
|
20
22
|
<table>
|
21
23
|
<caption>Messages</caption>
|
22
24
|
<thead>
|
23
25
|
<tr>
|
24
26
|
<th>Created At</th>
|
27
|
+
<th>Message Object ID</th>
|
25
28
|
<th>Contexts</th>
|
26
29
|
<th>State</th>
|
27
30
|
<th>Actions</th>
|
@@ -31,9 +34,10 @@
|
|
31
34
|
<% messages.each do |message| %>
|
32
35
|
<tr class="message">
|
33
36
|
<td class="detail message-created-at-detail"><a href="<%= harbinger.message_path(message.to_param)%>"><time><%= message.created_at %></time></a></td>
|
37
|
+
<td class="detail message-object-id-detail"><%= message.message_object_id %></td>
|
34
38
|
<td>
|
35
|
-
<ul><% message.
|
36
|
-
<li class="detail message-
|
39
|
+
<ul><% message.reporters.each do |context| %>
|
40
|
+
<li class="detail message-reporters-detail"><%= context %></li>
|
37
41
|
<% end %></ul>
|
38
42
|
</td>
|
39
43
|
<td class="detail message-state-detail"><%= message.state %></td>
|
@@ -2,14 +2,16 @@
|
|
2
2
|
<header class="message-header">
|
3
3
|
<h2>Message</h2>
|
4
4
|
<dl>
|
5
|
-
<dt class="term message-
|
6
|
-
|
7
|
-
<
|
5
|
+
<dt class="term message-created-at-term">Created at</dt>
|
6
|
+
<dd class="detail message-created-at-detail"><time><%= message.created_at %></time></dd>
|
7
|
+
<dt class="term message-object-id-term">Message Object ID</dt>
|
8
|
+
<dd class="detail message-object-id-detail"><%= message.message_object_id %></dd>
|
9
|
+
<dt class="term message-reporters-term">Contexts</dt>
|
10
|
+
<% message.reporters.each do |context| %>
|
11
|
+
<dd class="detail message-reporters-detail"><%= context %></dd>
|
8
12
|
<% end %>
|
9
13
|
<dt class="term message-state-term">State</dt>
|
10
14
|
<dd class="detail message-state-detail"><%= message.state %></dd>
|
11
|
-
<dt class="term message-created-at-term">Created at</dt>
|
12
|
-
<dd class="detail message-created-at-detail"><time><%= message.created_at %></time></dd>
|
13
15
|
</dl>
|
14
16
|
</header>
|
15
17
|
<section class="message-body">
|
data/config/routes.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
class CreateHarbingerDatabaseChannelMessage < ActiveRecord::Migration
|
2
2
|
def change
|
3
3
|
create_table :harbinger_messages do |t|
|
4
|
-
t.string :
|
4
|
+
t.string :reporters
|
5
5
|
t.string :state, limit: 32
|
6
|
+
t.integer :message_object_id
|
6
7
|
t.timestamps
|
7
8
|
end
|
8
9
|
add_index :harbinger_messages, :state
|
9
|
-
add_index :harbinger_messages, :
|
10
|
+
add_index :harbinger_messages, :reporters
|
11
|
+
add_index :harbinger_messages, :message_object_id
|
10
12
|
end
|
11
13
|
end
|
@@ -9,6 +9,5 @@ class CreateHarbingerDatabaseChannelMessageElements < ActiveRecord::Migration
|
|
9
9
|
add_index :harbinger_message_elements, :message_id
|
10
10
|
add_index :harbinger_message_elements, :key
|
11
11
|
add_index :harbinger_message_elements, [:message_id, :key]
|
12
|
-
add_index :harbinger_message_elements, [:message_id, :value]
|
13
12
|
end
|
14
13
|
end
|
data/harbinger.gemspec
CHANGED
@@ -24,13 +24,15 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
25
25
|
spec.require_paths = ["lib"]
|
26
26
|
|
27
|
+
spec.add_dependency "kaminari", "~> 0.16"
|
28
|
+
spec.add_dependency "rails", "~> 4.0"
|
29
|
+
|
27
30
|
spec.add_development_dependency "bundler", "~> 1.5"
|
28
31
|
spec.add_development_dependency "rake", '~> 10.3'
|
29
32
|
spec.add_development_dependency "rspec-given", '~> 3.5'
|
30
33
|
spec.add_development_dependency 'rspec-rails', '~> 3.0'
|
31
34
|
spec.add_development_dependency 'rspec-html-matchers', '~>0.6'
|
32
35
|
spec.add_development_dependency "engine_cart", '~> 0.3'
|
33
|
-
spec.add_development_dependency "rails", "~> 4.0"
|
34
36
|
spec.add_development_dependency 'sqlite3', '~> 1.3'
|
35
37
|
spec.add_development_dependency 'database_cleaner', '~> 1.3'
|
36
38
|
spec.add_development_dependency 'capybara', '~> 2.4'
|
data/lib/harbinger.rb
CHANGED
@@ -6,21 +6,24 @@ require "harbinger/exceptions"
|
|
6
6
|
require "harbinger/configuration"
|
7
7
|
|
8
8
|
module Harbinger
|
9
|
-
module_function
|
10
9
|
class << self
|
11
10
|
attr_writer :configuration
|
12
11
|
|
12
|
+
# @see Configuration
|
13
13
|
def configuration
|
14
14
|
@configuration ||= Configuration.new
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
module_function
|
19
|
+
|
20
|
+
# @see Configuration
|
21
|
+
# @see .configuration
|
19
22
|
def configure
|
20
23
|
yield(configuration)
|
21
24
|
end
|
22
25
|
|
23
|
-
# Responsible for building a :message from the various :
|
26
|
+
# Responsible for building a :message from the various :reporters and then
|
24
27
|
# delivering the :message to the appropriate :channels.
|
25
28
|
#
|
26
29
|
# @see .build_message
|
@@ -29,7 +32,7 @@ module Harbinger
|
|
29
32
|
# @param [Hash] options
|
30
33
|
# @option options [Message] :message The message you want to amend.
|
31
34
|
# If none is provided, then one is created.
|
32
|
-
# @option options [Object, Array<Object>] :
|
35
|
+
# @option options [Object, Array<Object>] :reporters One or more Objects that
|
33
36
|
# Harbinger will visit and extract message elements from.
|
34
37
|
# @option options [Symbol, Array<Symbol>] :channels One or more channels that
|
35
38
|
# Harbinger will deliver the :message to
|
@@ -38,20 +41,20 @@ module Harbinger
|
|
38
41
|
deliver_message(message, options)
|
39
42
|
end
|
40
43
|
|
41
|
-
# Responsible for building a :message from the various :
|
44
|
+
# Responsible for building a :message from the various :reporters.
|
42
45
|
#
|
43
46
|
# @see .call
|
44
47
|
#
|
45
48
|
# @param [Hash] options
|
46
49
|
# @option options [Message] :message The message you want to amend.
|
47
50
|
# If none is provided, then one is created.
|
48
|
-
# @option options [Object, Array<Object>] :
|
51
|
+
# @option options [Object, Array<Object>] :reporters One or more Objects that
|
49
52
|
# Harbinger will visit and extract message elements from.
|
50
53
|
def build_message(options = {})
|
51
|
-
|
54
|
+
reporters = Array(options.fetch(:reporters)).flatten.compact
|
52
55
|
message = options.fetch(:message) { default_message }
|
53
56
|
|
54
|
-
|
57
|
+
reporters.each { |context| reporter_for(context).accept(message) }
|
55
58
|
message
|
56
59
|
end
|
57
60
|
|
@@ -89,14 +92,17 @@ module Harbinger
|
|
89
92
|
end
|
90
93
|
private_class_method :channel_for
|
91
94
|
|
95
|
+
# @api protected
|
92
96
|
def default_channels
|
93
97
|
configuration.default_channels
|
94
98
|
end
|
95
99
|
|
100
|
+
# @api protected
|
96
101
|
def logger
|
97
102
|
configuration.logger
|
98
103
|
end
|
99
104
|
|
105
|
+
# @api protected
|
100
106
|
def database_storage
|
101
107
|
configuration.database_storage
|
102
108
|
end
|
data/lib/harbinger/engine.rb
CHANGED
data/lib/harbinger/message.rb
CHANGED
data/lib/harbinger/reporters.rb
CHANGED
@@ -21,7 +21,7 @@ module Harbinger
|
|
21
21
|
if context.is_a?(Exception)
|
22
22
|
"ExceptionReporter"
|
23
23
|
else
|
24
|
-
context.class.to_s.gsub(/(?:^|_)([a-z])/) { $1.upcase } + "Reporter"
|
24
|
+
context.class.to_s.split('::').last.gsub(/(?:^|_)([a-z])/) { $1.upcase } + "Reporter"
|
25
25
|
end
|
26
26
|
end
|
27
27
|
private_class_method :reporter_name_for_instance
|
data/lib/harbinger/version.rb
CHANGED
@@ -4,19 +4,15 @@ require 'harbinger'
|
|
4
4
|
module Harbinger
|
5
5
|
describe 'handling a message', type: :feature do
|
6
6
|
let(:message) do
|
7
|
-
begin
|
8
|
-
{}.fetch(:missing_key)
|
9
|
-
rescue KeyError => exception
|
10
|
-
Harbinger.build_message(contexts: [exception])
|
11
|
-
end
|
12
7
|
end
|
13
8
|
|
14
9
|
it 'sends the exception message to the database channel' do
|
15
10
|
expect(Harbinger.logger).to receive(:add).at_least(:once).and_call_original
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
11
|
+
begin
|
12
|
+
{}.fetch(:missing_key)
|
13
|
+
rescue KeyError => exception
|
14
|
+
Harbinger.call(channels: [:database, :logger], reporters: [exception])
|
15
|
+
end
|
20
16
|
|
21
17
|
message = DatabaseChannelMessage.last
|
22
18
|
|
@@ -31,7 +27,7 @@ module Harbinger
|
|
31
27
|
page.find(:xpath, "//a[@href='#{harbinger.message_path(message.to_param)}']").click
|
32
28
|
|
33
29
|
expect(page.html).to have_tag('.message') do
|
34
|
-
with_tag('.message-
|
30
|
+
with_tag('.message-reporters-detail', text: 'exception')
|
35
31
|
with_tag('.message-state-detail', text: 'new')
|
36
32
|
end
|
37
33
|
end
|
@@ -9,7 +9,7 @@ module Harbinger
|
|
9
9
|
When { message.append('other_container', 'other_key', 'other_value')}
|
10
10
|
|
11
11
|
Then { expect(message.attributes).to eq({ 'container.key' => ['value'], 'other_container.other_key' => ['other_value']}) }
|
12
|
-
And { expect(message.
|
12
|
+
And { expect(message.reporters).to eq(['container', 'other_container']) }
|
13
13
|
|
14
14
|
end
|
15
15
|
end
|
@@ -2,6 +2,8 @@ require 'spec_fast_helper'
|
|
2
2
|
require 'harbinger/reporters'
|
3
3
|
|
4
4
|
module Harbinger
|
5
|
+
class Request
|
6
|
+
end
|
5
7
|
describe Reporters do
|
6
8
|
context '.find_for' do
|
7
9
|
Given(:reporter) { double('Reporter') }
|
@@ -41,6 +43,12 @@ module Harbinger
|
|
41
43
|
When(:result) { described_class.find_for(context) }
|
42
44
|
Then { expect(result).to be_an_instance_of(Reporters::NullReporter) }
|
43
45
|
end
|
46
|
+
|
47
|
+
context 'module conversion' do
|
48
|
+
Given(:context) { ::Harbinger::Request.new }
|
49
|
+
When(:result) { described_class.find_for(context) }
|
50
|
+
Then { expect(result).to be_an_instance_of(Reporters::RequestReporter) }
|
51
|
+
end
|
44
52
|
end
|
45
53
|
end
|
46
54
|
end
|
data/spec/lib/harbinger_spec.rb
CHANGED
@@ -14,7 +14,7 @@ describe Harbinger do
|
|
14
14
|
Given(:channel_name) { 'channel_double' }
|
15
15
|
Given(:channel) { double('Channel', deliver: true) }
|
16
16
|
Given(:message) { Harbinger::Message.new }
|
17
|
-
When { Harbinger.call(
|
17
|
+
When { Harbinger.call(reporters: [user, request], message: message, channels: channel_name) }
|
18
18
|
Then do expect(message.attributes).to eq(
|
19
19
|
'user.username' => [user.username],
|
20
20
|
'request.path' => [request.path],
|
@@ -27,7 +27,7 @@ describe Harbinger do
|
|
27
27
|
|
28
28
|
context '.build_message' do
|
29
29
|
Given(:message) { Harbinger::Message.new }
|
30
|
-
When { Harbinger.build_message(
|
30
|
+
When { Harbinger.build_message(reporters: [user, request], message: message) }
|
31
31
|
Then do expect(message.attributes).to eq(
|
32
32
|
'user.username' => [user.username],
|
33
33
|
'request.path' => [request.path],
|
@@ -57,10 +57,10 @@ module Harbinger
|
|
57
57
|
by(3)
|
58
58
|
end
|
59
59
|
|
60
|
-
it 'assigns :
|
60
|
+
it 'assigns :reporters' do
|
61
61
|
storage = described_class.new
|
62
62
|
expect { described_class.store_message(message, storage) }.
|
63
|
-
to change { storage.attributes.values_at('
|
63
|
+
to change { storage.attributes.values_at('reporters', 'state') }.
|
64
64
|
from([nil, nil]).to(['exception,user', 'new'])
|
65
65
|
end
|
66
66
|
end
|
@@ -8,13 +8,15 @@ describe 'harbinger/messages/index.html.erb', type: :view do
|
|
8
8
|
let(:message) do
|
9
9
|
double(
|
10
10
|
'Message',
|
11
|
-
|
11
|
+
reporters: ['Hello','World'],
|
12
12
|
state: 'new',
|
13
|
-
created_at: created_at
|
13
|
+
created_at: created_at,
|
14
|
+
message_object_id: '123456'
|
14
15
|
)
|
15
16
|
end
|
16
17
|
let(:harbinger) { double("Engine", message_path: true, messages_path: '/messages/') }
|
17
18
|
it 'renders the object and fieldsets' do
|
19
|
+
expect(view).to receive(:paginate).with([message])
|
18
20
|
expect(harbinger).to receive(:message_path).with(message.to_param).and_return("/messages/#{message.to_param}")
|
19
21
|
render template: "harbinger/messages/index.html.erb", locals: { messages: [message], harbinger: harbinger }
|
20
22
|
expect(rendered).to have_tag('.search-form') do
|
@@ -23,8 +25,9 @@ describe 'harbinger/messages/index.html.erb', type: :view do
|
|
23
25
|
|
24
26
|
expect(rendered).to have_tag('.message') do
|
25
27
|
with_tag(".detail.message-created-at-detail a time", text: created_at.to_s)
|
26
|
-
with_tag('.detail.message-
|
27
|
-
with_tag('.detail.message-
|
28
|
+
with_tag('.detail.message-object-id-detail', text: message.message_object_id)
|
29
|
+
with_tag('.detail.message-reporters-detail', text: 'Hello')
|
30
|
+
with_tag('.detail.message-reporters-detail', text: 'World')
|
28
31
|
with_tag('.detail.message-state-detail', text: 'new')
|
29
32
|
end
|
30
33
|
end
|
@@ -10,9 +10,10 @@ describe 'harbinger/messages/show.html.erb', type: :view do
|
|
10
10
|
let(:message) do
|
11
11
|
double(
|
12
12
|
'Message',
|
13
|
-
|
13
|
+
reporters: ['Hello','World'],
|
14
14
|
state: 'new',
|
15
15
|
created_at: created_at,
|
16
|
+
message_object_id: '123456',
|
16
17
|
elements: [netid_element, request_referrer_element]
|
17
18
|
)
|
18
19
|
end
|
@@ -20,9 +21,11 @@ describe 'harbinger/messages/show.html.erb', type: :view do
|
|
20
21
|
render template: 'harbinger/messages/show',
|
21
22
|
locals: { message: message }
|
22
23
|
expect(rendered).to have_tag('article.message') do
|
23
|
-
with_tag('.term.message-
|
24
|
-
with_tag('.detail.message-
|
25
|
-
with_tag('.detail.message-
|
24
|
+
with_tag('.term.message-reporters-term')
|
25
|
+
with_tag('.detail.message-reporters-detail', text: 'Hello')
|
26
|
+
with_tag('.detail.message-reporters-detail', text: 'World')
|
27
|
+
with_tag('.term.message-object-id-term')
|
28
|
+
with_tag('.detail.message-object-id-detail', text: '123456')
|
26
29
|
with_tag('.term.message-state-term')
|
27
30
|
with_tag('.detail.message-state-detail', text: 'new')
|
28
31
|
with_tag('.term.message-created-at-term')
|
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: harbinger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Friesen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: kaminari
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.16'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.16'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.0'
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: bundler
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,20 +122,6 @@ dependencies:
|
|
94
122
|
- - "~>"
|
95
123
|
- !ruby/object:Gem::Version
|
96
124
|
version: '0.3'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: rails
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '4.0'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '4.0'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: sqlite3
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|