dm-is-revisioned 0.1.0
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.
- data/History.txt +1 -0
- data/LICENSE +20 -0
- data/Manifest.txt +12 -0
- data/README.txt +3 -0
- data/Rakefile +75 -0
- data/TODO +0 -0
- data/lib/dm-is-revisioned.rb +16 -0
- data/lib/dm-is-revisioned/is/revisioned.rb +142 -0
- data/lib/dm-is-revisioned/is/version.rb +7 -0
- data/spec/revisioned_spec.rb +199 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +28 -0
- metadata +87 -0
data/History.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2007 Timothy Bennett and David Leal
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest.txt
ADDED
data/README.txt
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
require 'spec/rake/spectask'
|
4
|
+
require 'pathname'
|
5
|
+
require 'hoe'
|
6
|
+
|
7
|
+
ROOT = Pathname(__FILE__).dirname.expand_path
|
8
|
+
require ROOT + 'lib/dm-is-revisioned/is/version'
|
9
|
+
|
10
|
+
AUTHOR = "David Leal"
|
11
|
+
EMAIL = "dgleal@gmail.com"
|
12
|
+
GEM_NAME = "dm-is-revisioned"
|
13
|
+
GEM_VERSION = DataMapper::Is::Revisioned::VERSION
|
14
|
+
GEM_DEPENDENCIES = [['dm-core', "~> 0.9.7"]]
|
15
|
+
GEM_CLEAN = ["log", "pkg"]
|
16
|
+
GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.txt LICENSE TODO ] }
|
17
|
+
|
18
|
+
PROJECT_NAME = "dm-revisioned"
|
19
|
+
PROJECT_URL = "http://github.com/david/dm-is-revisioned"
|
20
|
+
PROJECT_DESCRIPTION = PROJECT_SUMMARY = "DataMapper plugin enabling more flexible versioning of models"
|
21
|
+
|
22
|
+
hoe = Hoe.new(GEM_NAME, GEM_VERSION) do |p|
|
23
|
+
|
24
|
+
p.developer(AUTHOR, EMAIL)
|
25
|
+
|
26
|
+
p.description = PROJECT_DESCRIPTION
|
27
|
+
p.summary = PROJECT_SUMMARY
|
28
|
+
p.url = PROJECT_URL
|
29
|
+
|
30
|
+
p.rubyforge_name = PROJECT_NAME if PROJECT_NAME
|
31
|
+
|
32
|
+
p.clean_globs |= GEM_CLEAN
|
33
|
+
p.spec_extras = GEM_EXTRAS if GEM_EXTRAS
|
34
|
+
|
35
|
+
GEM_DEPENDENCIES.each do |dep|
|
36
|
+
p.extra_deps << dep
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
task :default => [ :spec ]
|
41
|
+
|
42
|
+
WIN32 = (RUBY_PLATFORM =~ /win32|mingw|cygwin/) rescue nil
|
43
|
+
SUDO = WIN32 ? '' : ('sudo' unless ENV['SUDOLESS'])
|
44
|
+
|
45
|
+
desc "Install #{GEM_NAME} #{GEM_VERSION} (default ruby)"
|
46
|
+
task :install => [ :package ] do
|
47
|
+
sh "#{SUDO} gem install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources", :verbose => false
|
48
|
+
end
|
49
|
+
|
50
|
+
desc "Uninstall #{GEM_NAME} #{GEM_VERSION} (default ruby)"
|
51
|
+
task :uninstall => [ :clobber ] do
|
52
|
+
sh "#{SUDO} gem uninstall #{GEM_NAME} -v#{GEM_VERSION} -I -x", :verbose => false
|
53
|
+
end
|
54
|
+
|
55
|
+
namespace :jruby do
|
56
|
+
desc "Install #{GEM_NAME} #{GEM_VERSION} with JRuby"
|
57
|
+
task :install => [ :package ] do
|
58
|
+
sh %{#{SUDO} jruby -S gem install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources}, :verbose => false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
desc 'Run specifications'
|
63
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
64
|
+
t.spec_opts << '--options' << 'spec/spec.opts' if File.exists?('spec/spec.opts')
|
65
|
+
t.spec_files = Pathname.glob((ROOT + 'spec/**/*_spec.rb').to_s)
|
66
|
+
|
67
|
+
begin
|
68
|
+
t.rcov = ENV.has_key?('NO_RCOV') ? ENV['NO_RCOV'] != 'true' : true
|
69
|
+
t.rcov_opts << '--exclude' << 'spec'
|
70
|
+
t.rcov_opts << '--text-summary'
|
71
|
+
t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
|
72
|
+
rescue Exception
|
73
|
+
# rcov not installed
|
74
|
+
end
|
75
|
+
end
|
data/TODO
ADDED
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
gem 'dm-core', '~>0.9.7'
|
5
|
+
require 'dm-core'
|
6
|
+
|
7
|
+
require Pathname(__FILE__).dirname.expand_path / 'dm-is-revisioned' / 'is' / 'revisioned'
|
8
|
+
|
9
|
+
# Include the plugin in Resource
|
10
|
+
module DataMapper
|
11
|
+
module Resource
|
12
|
+
module ClassMethods
|
13
|
+
include DataMapper::Is::Revisioned
|
14
|
+
end # module ClassMethods
|
15
|
+
end # module Resource
|
16
|
+
end # module DataMapper
|
@@ -0,0 +1,142 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Is
|
3
|
+
##
|
4
|
+
# = Is Revisioned
|
5
|
+
# The Revisioned module is similar to Versioned but is sufficiently
|
6
|
+
# different that it justified a fork.
|
7
|
+
#
|
8
|
+
# Just like with Versioned, there is not an incrementing 'version'
|
9
|
+
# field, but rather, any field of your choosing which will be unique
|
10
|
+
# on update. However, Revisioned will let you specify exactly when a
|
11
|
+
# new version should be created. By default, this happens when the record
|
12
|
+
# is created or whenever the field you specified changes.
|
13
|
+
#
|
14
|
+
# == Setup
|
15
|
+
# For simplicity, I will assume that you have loaded dm-timestamps to
|
16
|
+
# automatically update your :updated_at field. See versioned_spec for
|
17
|
+
# and example of updating the versioned field yourself.
|
18
|
+
#
|
19
|
+
# class Story
|
20
|
+
# include DataMapper::Resource
|
21
|
+
# property :id, Serial
|
22
|
+
# property :title, String
|
23
|
+
# property :updated_at, DateTime
|
24
|
+
#
|
25
|
+
# is_revisioned :on => :updated_at
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# == Auto Upgrading and Auto Migrating
|
29
|
+
#
|
30
|
+
# Story.auto_migrate! # => will run auto_migrate! on Story::Version, too
|
31
|
+
# Story.auto_upgrade! # => will run auto_upgrade! on Story::Version, too
|
32
|
+
#
|
33
|
+
# == Usage
|
34
|
+
#
|
35
|
+
# story = Story.crreate(:title => "A Title") # Creates a new version
|
36
|
+
# story.versions.size # => 1
|
37
|
+
# story = Story.get(1)
|
38
|
+
# story.title = "New Title"
|
39
|
+
# story.save # Saves this story and creates a new version
|
40
|
+
# story.versions.size # => 2
|
41
|
+
#
|
42
|
+
# story.title = "A Different New Title"
|
43
|
+
# story.save
|
44
|
+
# story.versions.size # => 3
|
45
|
+
#
|
46
|
+
# == Specifying when a new version should occur
|
47
|
+
# You can override the wants_new_version? method to determine exactly when
|
48
|
+
# a new version should be created. The method versioned_attribute_changed?
|
49
|
+
# is provided for your convenience, and can be used inside wants_new_version?
|
50
|
+
#
|
51
|
+
# TODO: enable replacing a current version with an old version.
|
52
|
+
module Revisioned
|
53
|
+
attr_reader :versioned_property_name
|
54
|
+
|
55
|
+
def is_revisioned(options = {})
|
56
|
+
include DataMapper::Is::Revisioned::InstanceMethods
|
57
|
+
|
58
|
+
@versioned_property_name = on = options[:on]
|
59
|
+
|
60
|
+
class << self; self end.class_eval do
|
61
|
+
define_method :const_missing do |name|
|
62
|
+
storage_name = Extlib::Inflection.tableize(self.name + "Version")
|
63
|
+
model = DataMapper::Model.new(storage_name)
|
64
|
+
|
65
|
+
if name == :Version
|
66
|
+
properties.each do |property|
|
67
|
+
options = property.options
|
68
|
+
options[:key] = true if property.name == on || options[:serial] == true
|
69
|
+
options[:serial] = false
|
70
|
+
model.property property.name, property.type, options
|
71
|
+
end
|
72
|
+
|
73
|
+
self.const_set("Version", model)
|
74
|
+
else
|
75
|
+
super(name)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
after_class_method :auto_migrate! do
|
81
|
+
self::Version.auto_migrate!
|
82
|
+
end
|
83
|
+
|
84
|
+
after_class_method :auto_upgrade! do
|
85
|
+
self::Version.auto_upgrade!
|
86
|
+
end
|
87
|
+
|
88
|
+
before :create, :check_if_wants_new_version
|
89
|
+
after :create, :save_new_version
|
90
|
+
|
91
|
+
before :update, :check_if_wants_new_version
|
92
|
+
after :update, :save_new_version
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
module InstanceMethods
|
97
|
+
##
|
98
|
+
# Returns a hash of original values to be stored in the
|
99
|
+
# versions table when a new version is created. It is
|
100
|
+
# cleared after a version model is created.
|
101
|
+
#
|
102
|
+
# --
|
103
|
+
# @return <Hash>
|
104
|
+
def pending_version_attributes
|
105
|
+
@pending_version_attributes ||= {}
|
106
|
+
end
|
107
|
+
|
108
|
+
##
|
109
|
+
# Returns a collection of other versions of this resource.
|
110
|
+
# The versions are related on the models keys, and ordered
|
111
|
+
# by the version field.
|
112
|
+
#
|
113
|
+
# --
|
114
|
+
# @return <Collection>
|
115
|
+
def versions(include_current = false)
|
116
|
+
query = {}
|
117
|
+
version = self.class.const_get("Version")
|
118
|
+
self.class.key.zip(self.key) { |property, value| query[property.name] = value }
|
119
|
+
query.merge(:order => version.key.collect { |key| key.name.desc })
|
120
|
+
result = version.all(query)
|
121
|
+
end
|
122
|
+
|
123
|
+
def versioned_attribute_changed?
|
124
|
+
dirty_attributes.has_key?(self.class.properties[self.class.versioned_property_name])
|
125
|
+
end
|
126
|
+
|
127
|
+
alias_method :wants_new_version?, :versioned_attribute_changed?
|
128
|
+
|
129
|
+
def check_if_wants_new_version
|
130
|
+
@should_save_version = wants_new_version?
|
131
|
+
end
|
132
|
+
|
133
|
+
def save_new_version(result, *args)
|
134
|
+
if result && @should_save_version
|
135
|
+
self.class::Version.create(self.attributes)
|
136
|
+
@should_save_version = false
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end # Revisioned
|
141
|
+
end # Is
|
142
|
+
end # DataMapper
|
@@ -0,0 +1,199 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/spec_helper"
|
2
|
+
|
3
|
+
if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
|
4
|
+
describe 'DataMapper::Is::Revisioned', "default behavior" do
|
5
|
+
before :all do
|
6
|
+
class Story
|
7
|
+
include DataMapper::Resource
|
8
|
+
|
9
|
+
property :id, Integer, :serial => true
|
10
|
+
property :title, String
|
11
|
+
property :updated_at, DateTime
|
12
|
+
|
13
|
+
before :save do
|
14
|
+
# For the sake of testing, make sure the updated_at is always unique
|
15
|
+
time = self.updated_at ? self.updated_at + 1 : Time.now
|
16
|
+
self.updated_at = time if self.dirty?
|
17
|
+
end
|
18
|
+
|
19
|
+
is_revisioned :on => :updated_at
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
after :all do
|
24
|
+
if defined?(:Story) then Object.send(:remove_const, :Story) end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "inner class" do
|
28
|
+
it "should be present" do
|
29
|
+
Story::Version.should be_a_kind_of(Class)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should have a default storage name" do
|
33
|
+
Story::Version.storage_name.should == "story_versions"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should have its parent's properties" do
|
37
|
+
Story.properties.each do |property|
|
38
|
+
Story::Version.properties.should have_property(property.name)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end # inner class
|
42
|
+
|
43
|
+
describe "#auto_migrate!" do
|
44
|
+
before do
|
45
|
+
Story::Version.should_receive(:auto_migrate!)
|
46
|
+
end
|
47
|
+
it "should get called on the inner class" do
|
48
|
+
Story.auto_migrate!
|
49
|
+
end
|
50
|
+
end # #auto_migrate!
|
51
|
+
|
52
|
+
describe "#auto_upgrade!" do
|
53
|
+
before do
|
54
|
+
Story::Version.should_receive(:auto_upgrade!)
|
55
|
+
end
|
56
|
+
it "should get called on the inner class" do
|
57
|
+
Story.auto_upgrade!
|
58
|
+
end
|
59
|
+
end # #auto_upgrade!
|
60
|
+
|
61
|
+
describe "#create" do
|
62
|
+
before do
|
63
|
+
Story.auto_migrate!
|
64
|
+
Story.create(:title => "A Very Interesting Article")
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should create 1 versioned copy" do
|
68
|
+
Story::Version.all.size.should == 1
|
69
|
+
end
|
70
|
+
end # #create
|
71
|
+
|
72
|
+
describe "#save" do
|
73
|
+
before do
|
74
|
+
Story.auto_migrate!
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "(with new resource)" do
|
78
|
+
before do
|
79
|
+
@story = Story.new(:title => "A Story")
|
80
|
+
@story.save
|
81
|
+
end
|
82
|
+
it "should create 1 versioned copy" do
|
83
|
+
Story::Version.all.size.should == 1
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "(with a clean existing resource)" do
|
88
|
+
before do
|
89
|
+
@story = Story.create(:title => "A Story")
|
90
|
+
@story.save
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should have only 1 versioned copy" do
|
94
|
+
Story::Version.all.size.should == 1
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "(with a dirty existing resource)" do
|
99
|
+
before do
|
100
|
+
@story = Story.create(:title => "A Story")
|
101
|
+
@story.title = "An Inner Update"
|
102
|
+
@story.title = "An Updated Story"
|
103
|
+
@story.save
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should have 2 versioned copies" do
|
107
|
+
Story::Version.all.size.should == 2
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should not have the same value for the versioned field" do
|
111
|
+
@story.updated_at.should_not == Story::Version.first.updated_at
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end # #save
|
115
|
+
|
116
|
+
describe "#versions" do
|
117
|
+
before do
|
118
|
+
Story.auto_migrate!
|
119
|
+
@story = Story.create(:title => "A Story")
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should return a collection when there are versions" do
|
123
|
+
@story.versions.should == Story::Version.all(:id => @story.id)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should not return another object's versions" do
|
127
|
+
@story2 = Story.create(:title => "A Different Story")
|
128
|
+
@story2.title = "A Different Title"
|
129
|
+
@story2.save
|
130
|
+
@story.versions.should == Story::Version.all(:id => @story.id)
|
131
|
+
end
|
132
|
+
end # #versions
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "DataMapper::Is::Versioned", "overriding wants_new_version?" do
|
136
|
+
before :all do
|
137
|
+
class Story
|
138
|
+
include DataMapper::Resource
|
139
|
+
|
140
|
+
property :id, Integer, :serial => true
|
141
|
+
property :title, String
|
142
|
+
property :updated_at, DateTime
|
143
|
+
|
144
|
+
before :save do
|
145
|
+
# For the sake of testing, make sure the updated_at is always unique
|
146
|
+
time = self.updated_at ? self.updated_at + 1 : Time.now
|
147
|
+
self.updated_at = time if self.dirty?
|
148
|
+
end
|
149
|
+
|
150
|
+
is_revisioned :on => :updated_at
|
151
|
+
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "wants a new version" do
|
156
|
+
before do
|
157
|
+
Story.class_eval do
|
158
|
+
def wants_new_version?
|
159
|
+
true # this is dangerous, the key will be the same on 2 consecutive saves, even with no changes
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
Story.auto_migrate!
|
164
|
+
@story = Story.create(:title => "A Story")
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should create 1 new version" do
|
168
|
+
Story::Version.all.size.should == 1
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "does not want a new version" do
|
173
|
+
before do
|
174
|
+
Story.class_eval do
|
175
|
+
def wants_new_version?
|
176
|
+
false
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
Story.auto_migrate!
|
181
|
+
@story = Story.create(:title => "A Story")
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should not create a new version" do
|
185
|
+
Story::Version.all.should be_empty
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should not create a new version on update" do
|
189
|
+
@story.title = "A New Hope"
|
190
|
+
@story.save
|
191
|
+
Story::Version.all.should be_empty
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
after :all do
|
196
|
+
if defined?(:Story) then Object.send(:remove_const, :Story) end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'rspec', '>=1.1.3'
|
3
|
+
require 'spec'
|
4
|
+
require 'pathname'
|
5
|
+
require Pathname(__FILE__).dirname.expand_path.parent + 'lib/dm-is-revisioned'
|
6
|
+
|
7
|
+
def load_driver(name, default_uri)
|
8
|
+
return false if ENV['ADAPTER'] != name.to_s
|
9
|
+
|
10
|
+
lib = "do_#{name}"
|
11
|
+
|
12
|
+
begin
|
13
|
+
gem lib, '~>0.9.7'
|
14
|
+
require lib
|
15
|
+
DataMapper.setup(name, ENV["#{name.to_s.upcase}_SPEC_URI"] || default_uri)
|
16
|
+
DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[name]
|
17
|
+
true
|
18
|
+
rescue Gem::LoadError => e
|
19
|
+
warn "Could not load #{lib}: #{e}"
|
20
|
+
false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
ENV['ADAPTER'] ||= 'sqlite3'
|
25
|
+
|
26
|
+
HAS_SQLITE3 = load_driver(:sqlite3, 'sqlite3::memory:')
|
27
|
+
HAS_MYSQL = load_driver(:mysql, 'mysql://localhost/dm_core_test')
|
28
|
+
HAS_POSTGRES = load_driver(:postgres, 'postgres://postgres@localhost/dm_core_test')
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dm-is-revisioned
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Leal
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-12-05 00:00:00 +00:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: dm-core
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.9.7
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: hoe
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.8.2
|
34
|
+
version:
|
35
|
+
description: DataMapper plugin enabling more flexible versioning of models
|
36
|
+
email:
|
37
|
+
- dgleal@gmail.com
|
38
|
+
executables: []
|
39
|
+
|
40
|
+
extensions: []
|
41
|
+
|
42
|
+
extra_rdoc_files:
|
43
|
+
- README.txt
|
44
|
+
- LICENSE
|
45
|
+
- TODO
|
46
|
+
files:
|
47
|
+
- History.txt
|
48
|
+
- LICENSE
|
49
|
+
- Manifest.txt
|
50
|
+
- README.txt
|
51
|
+
- Rakefile
|
52
|
+
- TODO
|
53
|
+
- lib/dm-is-revisioned.rb
|
54
|
+
- lib/dm-is-revisioned/is/version.rb
|
55
|
+
- lib/dm-is-revisioned/is/revisioned.rb
|
56
|
+
- spec/spec.opts
|
57
|
+
- spec/spec_helper.rb
|
58
|
+
- spec/revisioned_spec.rb
|
59
|
+
has_rdoc: true
|
60
|
+
homepage: http://github.com/david/dm-is-revisioned
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options:
|
63
|
+
- --main
|
64
|
+
- README.txt
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: "0"
|
72
|
+
version:
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: "0"
|
78
|
+
version:
|
79
|
+
requirements: []
|
80
|
+
|
81
|
+
rubyforge_project: dm-revisioned
|
82
|
+
rubygems_version: 1.3.1
|
83
|
+
signing_key:
|
84
|
+
specification_version: 2
|
85
|
+
summary: DataMapper plugin enabling more flexible versioning of models
|
86
|
+
test_files: []
|
87
|
+
|