sequel_paper_trail_safehub 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: aa412934301fcc0f02d260c7ef473dc69bb5ca8eb3202a5b5b35de1617aa0c6d
4
+ data.tar.gz: b54c187e26c4aa92fb2c7b272de7b51b3d7029375864d680a80ff950995301bd
5
+ SHA512:
6
+ metadata.gz: f541d6bfb5fc433f732b192b128b9e54e801d201659e54fe5c8979b182eed702bf2b83218aa51f56e668e76ffc433a0402a045234e3969d27657b653541d95c4
7
+ data.tar.gz: d53503b9f9e2f922c14d123cfd135bdabe110db766e004e586ebebfc4f42ed2949e5f2bdb49765cab126fb008fc3cb53a90fb91cb3e1f756b65a8a546a78fd3e
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Vadim Lazebny
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,132 @@
1
+ Sequel plugin for Paper Trail
2
+ =============
3
+
4
+ This is a simple Sequel plugin for PaperTrail (with limited functionality).
5
+
6
+ Contributions are welcome!
7
+
8
+ [![Travis badge](https://github.com/lambwaves/sequel_paper_trail/actions/workflows/ruby.yml/badge.svg)](https://github.com/lambwaves/sequel_paper_trail/actions/workflows/ruby.yml)
9
+ [![Coverage Status](https://coveralls.io/repos/github/lambwaves/sequel_paper_trail/badge.svg)](https://coveralls.io/github/lambwaves/sequel_paper_trail)
10
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](http://opensource.org/licenses/MIT)
11
+
12
+ Features
13
+ ------------
14
+
15
+ * Track when models are created, updated, or deleted
16
+ * specify current_user as whodunnit
17
+ * can be specified info_for_paper_trail
18
+ * versioning can be disabled or enabled globally or in a block context
19
+
20
+ Limitations
21
+ ------------
22
+
23
+ * this gem doesn't create a version table
24
+ * this is forked from 7 year old code, and I may not accept PRs.
25
+ * info_for_paper_trail is global
26
+ * does not reify
27
+
28
+ Installation
29
+ ------------
30
+
31
+ Add this line to your application's Gemfile:
32
+
33
+ ```ruby
34
+ gem 'sequel_paper_trail', github: 'lambwaves/sequel_paper_trail'
35
+ ```
36
+
37
+ Documentation
38
+ -------------
39
+
40
+
41
+ Usage
42
+ -------------
43
+
44
+ Quick start:
45
+
46
+ ```ruby
47
+
48
+ require 'sequel_paper_trail'
49
+ require 'sequel'
50
+ require 'sequel/plugins/has_paper_trail'
51
+
52
+ Album.plugin :has_paper_trail, class_name: 'VersionClassName'
53
+
54
+ class AlbumsController < BaseController
55
+ before_action :set_user_for_papertrail
56
+
57
+ def set_user_for_papertrail
58
+ SequelPaperTrail.whodunnit = current_user.id
59
+ end
60
+ end
61
+ ```
62
+
63
+ Enable versioning globally:
64
+
65
+ ```ruby
66
+
67
+ SequelPaperTrail.enabled = true
68
+
69
+ ```
70
+
71
+ Enable versioning for a block of code:
72
+
73
+ ```ruby
74
+
75
+ SequelPaperTrail.with_versioning { 'code' }
76
+
77
+ ```
78
+
79
+ Disable versioning globally:
80
+
81
+ ```ruby
82
+
83
+ SequelPaperTrail.enabled = false
84
+
85
+ ```
86
+
87
+ Disable versioning for a block of code
88
+
89
+ ```ruby
90
+
91
+ SequelPaperTrail.with_versioning(false) { 'code' }
92
+
93
+ ```
94
+
95
+ Set whodunnit:
96
+
97
+ ```ruby
98
+
99
+ SequelPaperTrail.whodunnit = 'Mr. Smith'
100
+
101
+ ```
102
+
103
+ Set info_for_paper_trail - additional info (Hash) which will be attached to the versions table.
104
+
105
+ ```ruby
106
+ # If you have 'release' and 'instance' columns in a versions table you can populate them.
107
+
108
+ SequelPaperTrail.info_for_paper_trail = { release: 'asdf131234', instance: `hostname` }
109
+
110
+ ```
111
+
112
+ Development
113
+ --------------
114
+
115
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
116
+
117
+ I specify the location of this gem in my application's Gemfile.
118
+
119
+
120
+ Contributing
121
+ --------------
122
+
123
+ I have minimal functionality, so contributions might not be received applicably.
124
+
125
+ Bug reports and pull requests are welcome on GitHub at https://github.com/lazebny/sequel_paper_trail.
126
+
127
+
128
+ License
129
+ --------------
130
+
131
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
132
+
@@ -0,0 +1,160 @@
1
+ module Sequel
2
+ module Plugins
3
+ # Add Paper Trail versioning callbacks to model.
4
+ #
5
+ # Usage:
6
+ #
7
+ # # Enable versioning for all models.
8
+ # Sequel::Model.plugin :has_paper_trail
9
+ #
10
+ # # Make the Album class be able to versioning.
11
+ # Album.plugin :has_paper_trail, item_class_name: Album, class_name: 'Album::Version'
12
+ #
13
+ module HasPaperTrail
14
+ # rubocop:disable Metrics/MethodLength
15
+ def self.configure(model, opts = {})
16
+ paper_trail_item_class_name = opts.fetch(:item_class_name) do
17
+ model.name
18
+ end
19
+ paper_trail_version_class_name = opts.fetch(:class_name) do
20
+ 'SequelPaperTrail::Version'
21
+ end
22
+ paper_trail_ignore_attributes = opts.fetch(:ignore) { [] }
23
+ paper_trail_whodunnit = opts.fetch(:whodunnit) { proc { '' } }
24
+
25
+ model.plugin :dirty
26
+ binding.pry
27
+ model.one_to_many :versions,
28
+ class: paper_trail_version_class_name,
29
+ key: :item_id,
30
+ conditions: { item_type: paper_trail_item_class_name }
31
+
32
+ model.instance_eval do
33
+ @paper_trail_item_class_name = paper_trail_item_class_name
34
+ @paper_trail_version_class_name = paper_trail_version_class_name
35
+ @paper_trail_ignore_attributes = paper_trail_ignore_attributes
36
+ @paper_trail_whodunnit = paper_trail_whodunnit
37
+ end
38
+ end
39
+ # rubocop:enable Metrics/MethodLength
40
+
41
+ # rubocop:disable Style/Documentation
42
+ module ClassMethods
43
+ Sequel::Plugins.inherited_instance_variables(
44
+ self,
45
+ :@paper_trail_item_class_name => :dup,
46
+ :@paper_trail_version_class_name => :dup,
47
+ :@paper_trail_ignore_attributes => :dup,
48
+ :@paper_trail_whodunnit => :dup
49
+ )
50
+
51
+ # The class name of item for versioning
52
+ attr_reader :paper_trail_item_class_name
53
+
54
+ # The version class name
55
+ attr_reader :paper_trail_version_class_name
56
+
57
+ # Attributes to ignore in version table
58
+ attr_reader :paper_trail_ignore_attributes
59
+
60
+ # Attributes to set whodunnit
61
+ attr_reader :paper_trail_whodunnit
62
+ end
63
+ # rubocop:enable Style/Documentation
64
+
65
+ # rubocop:disable Style/Documentation
66
+ module InstanceMethods
67
+ def after_create
68
+ super
69
+
70
+ return unless SequelPaperTrail.enabled?
71
+
72
+ attrs = {
73
+ item_id: id,
74
+ event: :create,
75
+ object: nil
76
+ }
77
+
78
+ PaperTrailHelpers.create_version(model, attrs)
79
+ end
80
+
81
+ def after_update
82
+ super
83
+
84
+ return unless SequelPaperTrail.enabled?
85
+ return if column_changes.empty?
86
+ return if (column_changes.keys - model.paper_trail_ignore_attributes)
87
+ .empty?
88
+
89
+ attrs = {
90
+ item_id: id,
91
+ event: :update,
92
+ object: PaperTrailHelpers.serializer(values.merge(initial_values))
93
+ }
94
+
95
+ PaperTrailHelpers.create_version(model, attrs)
96
+ end
97
+
98
+ def after_destroy
99
+ super
100
+
101
+ return unless SequelPaperTrail.enabled?
102
+
103
+ attrs = {
104
+ item_id: id,
105
+ event: :destroy,
106
+ object: PaperTrailHelpers.serializer(values)
107
+ }
108
+
109
+ PaperTrailHelpers.create_version(model, attrs)
110
+ end
111
+
112
+ def current_version_id
113
+ versions.any? ? versions.first.id : nil
114
+ end
115
+ end
116
+ # rubocop:enable Style/Documentation
117
+
118
+ # rubocop:disable Style/Documentation
119
+ module PaperTrailHelpers
120
+ def self.create_version(model, attrs)
121
+ whodunnit = SequelPaperTrail.whodunnit.respond_to?(:call) ? SequelPaperTrail.whodunnit.call : SequelPaperTrail.whodunnit
122
+ default_attrs = {
123
+ item_type: model.paper_trail_item_class_name.to_s,
124
+ whodunnit: whodunnit,
125
+ created_at: Time.now.utc.iso8601
126
+ }
127
+
128
+ extra_params = if SequelPaperTrail.info_for_paper_trail.nil?
129
+ {}
130
+ elsif SequelPaperTrail.info_for_paper_trail.respond_to?(:call)
131
+ SequelPaperTrail.info_for_paper_trail.call
132
+ else
133
+ SequelPaperTrail.info_for_paper_trail
134
+ end
135
+
136
+ create_attrs = default_attrs
137
+ .merge(extra_params)
138
+ .merge(attrs)
139
+
140
+ version_class(model.paper_trail_version_class_name).create(create_attrs)
141
+ end
142
+
143
+ private_class_method
144
+
145
+ def self.version_class(class_name)
146
+ if class_name.is_a?(String)
147
+ Kernel.const_get(class_name)
148
+ else
149
+ class_name
150
+ end
151
+ end
152
+
153
+ def self.serializer(hash)
154
+ JSON.dump(hash)
155
+ end
156
+ end
157
+ # rubocop:enable Style/Documentation
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,21 @@
1
+ require 'singleton'
2
+
3
+ module SequelPaperTrail
4
+ # Config storage
5
+ class Config
6
+ include Singleton
7
+
8
+ def initialize
9
+ @mutex = Mutex.new
10
+ @enabled = true
11
+ end
12
+
13
+ def enabled
14
+ @mutex.synchronize { @enabled }
15
+ end
16
+
17
+ def enabled=(enable)
18
+ @mutex.synchronize { @enabled = enable }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module SequelPaperTrail
2
+ VERSION = '0.0.4'.freeze
3
+ end
@@ -0,0 +1,3 @@
1
+ module SequelPaperTrail
2
+ # Config storage
3
+ end
@@ -0,0 +1,42 @@
1
+ require 'sequel_paper_trail/version'
2
+ require 'sequel_paper_trail/config'
3
+
4
+ # Paper Trail config interface
5
+ module SequelPaperTrail
6
+ class << self
7
+ attr_accessor :whodunnit
8
+ attr_accessor :info_for_paper_trail
9
+
10
+ # Set versioning state.
11
+ #
12
+ # Boolean -> Boolean
13
+ #
14
+ def enabled=(enable)
15
+ Config.instance.enabled = enable
16
+ end
17
+
18
+ # Check if versioning enabled.
19
+ #
20
+ # Boolean
21
+ #
22
+ def enabled?
23
+ Config.instance.enabled
24
+ end
25
+
26
+ # Execute block with or without versioning.
27
+ #
28
+ # Boolean -> Proc -> Boolean
29
+ #
30
+ def with_versioning(enable = true)
31
+ was_enabled = enabled?
32
+ self.enabled = enable
33
+ yield
34
+ ensure
35
+ self.enabled = was_enabled
36
+ end
37
+ end
38
+ end
39
+
40
+ # Default Configuration
41
+ SequelPaperTrail.enabled = true
42
+ SequelPaperTrail.info_for_paper_trail = {}
@@ -0,0 +1,126 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sequel::Plugins::HasPaperTrail do
4
+ def without_fields(records, *fields)
5
+ records.map do |record|
6
+ record.to_hash.tap { |r| fields.each { |field| r.delete(field) } }
7
+ end
8
+ end
9
+
10
+ let(:paper_db) { SpecPaperDb.new }
11
+ let(:item_class) { paper_db.test_model }
12
+ let(:version_class) { paper_db.version_model }
13
+
14
+ before do
15
+ paper_db.create_test_table
16
+ paper_db.create_versions_table
17
+
18
+ item_class.plugin :has_paper_trail,
19
+ item_class_name: 'TetsClass',
20
+ class_name: version_class,
21
+ ignore: [:ignore]
22
+
23
+ SequelPaperTrail.whodunnit = 'Admin'
24
+ SequelPaperTrail.info_for_paper_trail = {
25
+ info: {
26
+ 'val' => 1
27
+ }.to_json,
28
+ other_info: '{}'
29
+ }
30
+ end
31
+
32
+ after do
33
+ paper_db.drop_all_tables
34
+ end
35
+
36
+ it 'creates versions on record create event' do
37
+ record = item_class.create(name: 'test', email: 'test@test.com')
38
+ expected = [
39
+ {
40
+ item_type: 'TetsClass',
41
+ item_id: 1,
42
+ event: 'create',
43
+ whodunnit: 'Admin',
44
+ created_at: Time.now.utc.iso8601,
45
+ transaction_id: nil,
46
+ object: nil,
47
+ info: '{"val":1}',
48
+ other_info: '{}'
49
+ }
50
+ ]
51
+ expect(without_fields(record.versions, :id)).to eq(expected)
52
+ end
53
+
54
+ it 'creates versions on record update event' do
55
+ record = item_class.create(name: 'test', email: 'test@test.com')
56
+ record.update(name: '2')
57
+ expected = {
58
+ item_type: 'TetsClass',
59
+ item_id: 1,
60
+ event: 'update',
61
+ whodunnit: 'Admin',
62
+ created_at: Time.now.utc.iso8601,
63
+ transaction_id: nil,
64
+ object: '{"id":1,"name":"test","email":"test@test.com","ignore":null}',
65
+ info: '{"val":1}',
66
+ other_info: '{}'
67
+ }
68
+ binding.pry
69
+ expect(without_fields(record.versions, :id)).to be_include(expected)
70
+ end
71
+
72
+ it 'creates versions on record destroy event' do
73
+ record = item_class.create(name: 'test', email: 'test@test.com')
74
+ record.destroy
75
+ expected = {
76
+ item_type: 'TetsClass',
77
+ item_id: 1,
78
+ event: 'destroy',
79
+ whodunnit: 'Admin',
80
+ created_at: Time.now.utc.iso8601,
81
+ transaction_id: nil,
82
+ object: '{"id":1,"name":"test","email":"test@test.com","ignore":null}',
83
+ info: '{"val":1}',
84
+ other_info: '{}'
85
+ }
86
+ expect(without_fields(record.versions, :id)).to be_include(expected)
87
+ end
88
+
89
+ it 'creates versions on record update event without ignored attrs' do
90
+ record = item_class.create(name: 'test',
91
+ email: 'test@test.com',
92
+ ignore: 'secret')
93
+ record.update(ignore: '2')
94
+ expected = {
95
+ item_type: 'TetsClass',
96
+ item_id: 1,
97
+ event: 'update',
98
+ whodunnit: 'Admin',
99
+ created_at: Time.now.utc.iso8601,
100
+ transaction_id: nil,
101
+ object: '{"id":1,"name":"test","email":"test@test.com","ignore":null}',
102
+ info: '{"val":1}',
103
+ other_info: '{}'
104
+ }
105
+ expect{ record.update(ignore: '2') }.to_not change { record.versions.count }
106
+ end
107
+
108
+ it 'current_version_id returns the latest version id' do
109
+ record = item_class.create(name: 'test', email: 'test@test.com')
110
+ record.update(name: '1')
111
+ record.update(name: '2')
112
+ expect(record.current_version_id).to eq(record.versions.first.id)
113
+ end
114
+
115
+ it 'saves join table rows' do
116
+ paper_db.create_test_join_table
117
+ test_join_model = paper_db.test_join_model
118
+ # class AlbumArtist;end;
119
+ test_join_model.plugin :has_paper_trail,
120
+ item_class_name: 'AlbumArtist',
121
+ class_name: version_class
122
+
123
+ joiner = test_join_model.create(artist_id: 1, album_id: 1)
124
+ expect(joiner.versions.count).to eq(1)
125
+ end
126
+ end
File without changes
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe SequelPaperTrail do
4
+ let(:paper_db) { SpecPaperDb.new }
5
+ let(:item_class) { paper_db.test_model }
6
+ let(:version_class) { paper_db.version_model }
7
+
8
+ before do
9
+ paper_db.create_test_table
10
+ paper_db.create_versions_table
11
+
12
+ item_class.plugin :has_paper_trail,
13
+ item_class_name: 'TestClass',
14
+ class_name: version_class
15
+ end
16
+
17
+ after do
18
+ paper_db.drop_all_tables
19
+ end
20
+
21
+ context '.with_versioning' do
22
+ it 'enabled' do
23
+ described_class.with_versioning(true) do
24
+ item = item_class.create(name: 'test')
25
+ expect(item.versions).not_to be_empty
26
+ end
27
+ end
28
+
29
+ it 'disabled' do
30
+ described_class.with_versioning(false) do
31
+ item = item_class.create(name: 'test')
32
+ expect(item.versions).to be_empty
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,22 @@
1
+ require 'bundler/setup'
2
+ require 'sequel'
3
+ # require 'jdbc-sqlite3'
4
+ require 'pry'
5
+
6
+ require 'sequel_paper_trail'
7
+ require 'sequel/plugins/has_paper_trail'
8
+
9
+ Dir['./spec/support/*'].each(&method(:require))
10
+
11
+ require 'coveralls'
12
+ Coveralls.wear!
13
+
14
+ RSpec.configure do |config|
15
+ config.order = 'random'
16
+ # Enable flags like --only-failures and --next-failure
17
+ # config.example_status_persistence_file_path = '.rspec_status'
18
+
19
+ config.expect_with :rspec do |c|
20
+ c.syntax = :expect
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ # require 'sinatra'
2
+
3
+ # class GenericSinatraApp < Sinatra::Base
4
+ # get '/' do
5
+ # binding.pry
6
+ # db = SpecPaperDb.new
7
+ # db.test_model.all[-1].update_email('fresh@example.com')
8
+ # end
9
+ # end
@@ -0,0 +1,60 @@
1
+ class SpecPaperDb
2
+ def initialize
3
+ # https://gist.github.com/studiorailsway/1561497
4
+ @db = if RUBY_PLATFORM == 'java'
5
+ Sequel.connect('jdbc:sqlite:db.sqlite3')
6
+ else
7
+ Sequel.extension(:sqlite_json_ops)
8
+ Sequel.sqlite(':memory:')
9
+ end
10
+ end
11
+
12
+ def create_test_join_table
13
+ @db.create_table!(:albums_artists) do
14
+ column :artist_id, :integer
15
+ column :album_id, :integer
16
+ end
17
+ end
18
+
19
+ def create_test_table
20
+ @db.create_table!(:test_table) do
21
+ primary_key :id
22
+ column :name, :text
23
+ column :email, :text
24
+ column :ignore, :text
25
+ end
26
+ end
27
+
28
+ def test_model
29
+ Class.new(Sequel::Model(@db[:test_table]))
30
+ end
31
+
32
+ def test_join_model
33
+ Class.new(Sequel::Model(@db[:albums_artists]))
34
+ end
35
+ # rubocop:disable Metrics/MethodLength
36
+ def create_versions_table
37
+ @db.create_table!(:versions) do
38
+ primary_key :id
39
+ column 'item_type', :text
40
+ column 'item_id', :integer
41
+ column 'event', :text
42
+ column 'whodunnit', :text
43
+ column 'created_at', :text
44
+ column 'transaction_id', :integer
45
+ column 'object', :json
46
+ column 'info', :text
47
+ column 'other_info', :text
48
+ end
49
+ end
50
+ # rubocop:enable Metrics/MethodLength
51
+
52
+ def version_model
53
+ Class.new(Sequel::Model(@db[:versions]))
54
+ end
55
+
56
+ def drop_all_tables
57
+ @db.drop_table(:test_table)
58
+ @db.drop_table(:versions)
59
+ end
60
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sequel_paper_trail_safehub
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Vadim Lazebny
8
+ - Evan Richards
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2023-03-17 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Sequel plugin for PaperTrail.
15
+ email:
16
+ - vadim.lazebny@gmail.com
17
+ - evan.richards@safehub.io
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files:
21
+ - README.md
22
+ - LICENSE.txt
23
+ files:
24
+ - LICENSE.txt
25
+ - README.md
26
+ - lib/sequel/plugins/has_paper_trail.rb
27
+ - lib/sequel_paper_trail.rb
28
+ - lib/sequel_paper_trail/config.rb
29
+ - lib/sequel_paper_trail/version.rb
30
+ - lib/sequel_paper_trail/whodunnit.rb
31
+ - spec/sequel/plugins/has_paper_trail_spec.rb
32
+ - spec/sequel/plugins/whodunnit_spec.rb
33
+ - spec/sequel_paper_trail_spec.rb
34
+ - spec/spec_helper.rb
35
+ - spec/support/generic_sinatra_app.rb
36
+ - spec/support/spec_paper_db.rb
37
+ homepage: https://github.com/lambwaves/sequel_paper_trail
38
+ licenses:
39
+ - MIT
40
+ metadata: {}
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 1.9.3
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubygems_version: 3.0.3
57
+ signing_key:
58
+ specification_version: 4
59
+ summary: Sequel plugin for PaperTrail.
60
+ test_files:
61
+ - spec/spec_helper.rb
62
+ - spec/sequel/plugins/whodunnit_spec.rb
63
+ - spec/sequel/plugins/has_paper_trail_spec.rb
64
+ - spec/sequel_paper_trail_spec.rb
65
+ - spec/support/generic_sinatra_app.rb
66
+ - spec/support/spec_paper_db.rb