seed-fu-ndo 0.0.1
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/Rakefile +33 -0
- data/lib/seed-fu-ndo.rb +21 -0
- data/lib/seed-fu-ndo/railtie.rb +8 -0
- data/lib/seed-fu-ndo/recorder.rb +27 -0
- data/lib/seed-fu-ndo/seeder.rb +42 -0
- data/lib/seed-fu-ndo/version.rb +4 -0
- data/lib/tasks/seed_fu_ndo.rake +19 -0
- data/spec/seeder_spec.rb +80 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/test.sqlite3 +0 -0
- metadata +120 -0
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
|
8
|
+
begin
|
9
|
+
require 'rdoc/task'
|
10
|
+
rescue LoadError
|
11
|
+
require 'rdoc/rdoc'
|
12
|
+
require 'rake/rdoctask'
|
13
|
+
RDoc::Task = Rake::RDocTask
|
14
|
+
end
|
15
|
+
|
16
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = 'Seed-Fu-ndo'
|
19
|
+
rdoc.options << '--line-numbers'
|
20
|
+
rdoc.rdoc_files.include('README.rdoc')
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
Bundler::GemHelper.install_tasks
|
26
|
+
|
27
|
+
require 'rspec/core/rake_task'
|
28
|
+
|
29
|
+
RSpec::Core::RakeTask.new do |t|
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
task :default => :spec
|
data/lib/seed-fu-ndo.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'seed-fu'
|
2
|
+
require 'seed-fu-ndo/seeder'
|
3
|
+
require 'seed-fu-ndo/railtie' if defined?(Rails) && Rails.version >= "3"
|
4
|
+
|
5
|
+
module SeedFuNdo
|
6
|
+
autoload :Recorder, 'seed-fu-ndo/recorder'
|
7
|
+
|
8
|
+
mattr_reader :recorder
|
9
|
+
|
10
|
+
# Unload seed data from files. Main entry point for third-party libraries.
|
11
|
+
# [fixture_paths] The paths to look for seed files in.
|
12
|
+
# [filter] A regexp. If given, only filenames matching this expression will be loaded.
|
13
|
+
def self.unseed(fixture_paths = SeedFu.fixture_paths, filter = nil)
|
14
|
+
@@recorder = Recorder.new
|
15
|
+
SeedFu::Runner.new(fixture_paths, filter).run
|
16
|
+
@@recorder.unseed
|
17
|
+
ensure
|
18
|
+
@@recorder = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module SeedFuNdo
|
2
|
+
|
3
|
+
# Records seeder instances created by Seed Fu.
|
4
|
+
class Recorder
|
5
|
+
attr_reader :seeders
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@seeders = []
|
9
|
+
end
|
10
|
+
|
11
|
+
# Record a single seeder.
|
12
|
+
def record(seeder)
|
13
|
+
seeders << seeder
|
14
|
+
end
|
15
|
+
|
16
|
+
# Unseed the data of all the recorded seeders in reverse order.
|
17
|
+
def unseed
|
18
|
+
ActiveRecord::Base.transaction do
|
19
|
+
seeders.reverse.each do |seeder|
|
20
|
+
seeder.unseed
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module SeedFu
|
2
|
+
|
3
|
+
# Enhanced class from Seed Fu to allow for recording and destroying seed data.
|
4
|
+
class Seeder
|
5
|
+
|
6
|
+
# Record instead of inserting the data if in recording mode.
|
7
|
+
def seed_with_undo
|
8
|
+
if r = SeedFuNdo.recorder
|
9
|
+
r.record self
|
10
|
+
|
11
|
+
# return existing records in case they are processed by the caller
|
12
|
+
@data.map { |record_data| find_record(record_data) }
|
13
|
+
else
|
14
|
+
seed_without_undo
|
15
|
+
end
|
16
|
+
end
|
17
|
+
alias_method_chain :seed, :undo
|
18
|
+
|
19
|
+
# Destroy the seed data.
|
20
|
+
def unseed
|
21
|
+
@model_class.transaction do
|
22
|
+
@data.reverse.map { |record_data| unseed_record(record_data.symbolize_keys) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def unseed_record(data)
|
29
|
+
record = find_record(data)
|
30
|
+
return if record.nil?
|
31
|
+
|
32
|
+
puts " - Remove #{@model_class} #{data.inspect}" unless @options[:quiet]
|
33
|
+
|
34
|
+
record.destroy || raise(ActiveRecord::ActiveRecordError, record.errors.full_messages.join(", ").presence)
|
35
|
+
end
|
36
|
+
|
37
|
+
def find_record(data)
|
38
|
+
@model_class.where(constraint_conditions(data)).first
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'seed-fu-ndo'
|
2
|
+
|
3
|
+
namespace :db do
|
4
|
+
desc "Unloads seed data for the current environment."
|
5
|
+
task :unseed_fu => :environment do
|
6
|
+
if ENV["FILTER"]
|
7
|
+
filter = /#{ENV["FILTER"].gsub(/,/, "|")}/
|
8
|
+
end
|
9
|
+
|
10
|
+
if ENV["FIXTURE_PATH"]
|
11
|
+
fixture_paths = [ENV["FIXTURE_PATH"], ENV["FIXTURE_PATH"] + '/' + Rails.env]
|
12
|
+
end
|
13
|
+
|
14
|
+
SeedFuNdo.unseed(fixture_paths, filter)
|
15
|
+
end
|
16
|
+
|
17
|
+
# alias
|
18
|
+
task :unseed => 'db:unseed_fu'
|
19
|
+
end
|
data/spec/seeder_spec.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SeedFu::Seeder do
|
4
|
+
|
5
|
+
context "in regular seed" do
|
6
|
+
it "should run single seeds" do
|
7
|
+
SeededModel.seed(:title) do |s|
|
8
|
+
s.title = 'Foo'
|
9
|
+
s.login = 'Foo'
|
10
|
+
s.first_name = 'Bar'
|
11
|
+
end
|
12
|
+
|
13
|
+
SeededModel.count.should == 1
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should run multiple seeds" do
|
17
|
+
SeededModel.seed(:title,
|
18
|
+
{:title => 'Foo', :login => 'Foo', :first_name => 'Foo'},
|
19
|
+
{:title => 'Bar', :login => 'Bar', :first_name => 'Bar'}
|
20
|
+
)
|
21
|
+
|
22
|
+
SeededModel.count.should == 2
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "in unseed" do
|
27
|
+
|
28
|
+
before do
|
29
|
+
SeedFuNdo.send(:class_variable_set, :@@recorder, SeedFuNdo::Recorder.new)
|
30
|
+
end
|
31
|
+
|
32
|
+
context "for single seeds" do
|
33
|
+
|
34
|
+
before do
|
35
|
+
SeededModel.seed(:title) do |s|
|
36
|
+
s.title = 'Foo'
|
37
|
+
s.login = 'Foo'
|
38
|
+
s.first_name = 'Bar'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should only record" do
|
43
|
+
SeededModel.count.should == 0
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should ignore non-existing records" do
|
47
|
+
SeedFuNdo.recorder.unseed
|
48
|
+
SeededModel.count.should == 0
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should unseed existing records" do
|
52
|
+
SeededModel.create!(:title => 'Foo')
|
53
|
+
SeedFuNdo.recorder.unseed
|
54
|
+
SeededModel.count.should == 0
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "for multiple seeds" do
|
59
|
+
|
60
|
+
before do
|
61
|
+
SeededModel.seed(:title,
|
62
|
+
{:title => 'Foo', :login => 'Foo', :first_name => 'Foo'},
|
63
|
+
{:title => 'Bar', :login => 'Bar', :first_name => 'Bar'}
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should only record" do
|
68
|
+
SeededModel.count.should == 0
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should rollback if one record cannot be destroyed" do
|
72
|
+
SeededModel.create!(:title => 'Foo', :fail_to_destroy => true)
|
73
|
+
SeededModel.create!(:title => 'Bar')
|
74
|
+
expect { SeedFuNdo.recorder.unseed }.to raise_error(ActiveRecord::ActiveRecordError)
|
75
|
+
SeededModel.count.should == 2
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'seed-fu-ndo'
|
4
|
+
require 'logger'
|
5
|
+
|
6
|
+
SeedFu.quiet = true
|
7
|
+
|
8
|
+
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/../debug.log")
|
9
|
+
|
10
|
+
ActiveRecord::Base.establish_connection(
|
11
|
+
:adapter => "sqlite3",
|
12
|
+
:database => File.dirname(__FILE__) + "/test.sqlite3"
|
13
|
+
)
|
14
|
+
|
15
|
+
ActiveRecord::Schema.define :version => 0 do
|
16
|
+
create_table :seeded_models, :force => true do |t|
|
17
|
+
t.column :login, :string
|
18
|
+
t.column :first_name, :string
|
19
|
+
t.column :last_name, :string
|
20
|
+
t.column :title, :string
|
21
|
+
t.column :fail_to_destroy, :boolean, :default => false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class SeededModel < ActiveRecord::Base
|
26
|
+
validates_presence_of :title
|
27
|
+
attr_protected :first_name
|
28
|
+
|
29
|
+
before_destroy { false if fail_to_destroy }
|
30
|
+
end
|
31
|
+
|
32
|
+
RSpec.configure do |config|
|
33
|
+
config.before do
|
34
|
+
SeededModel.delete_all
|
35
|
+
end
|
36
|
+
end
|
data/spec/test.sqlite3
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: seed-fu-ndo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Pascal Zumkehr
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-06-06 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
22
|
+
none: false
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
hash: 7
|
27
|
+
segments:
|
28
|
+
- 2
|
29
|
+
- 2
|
30
|
+
- 0
|
31
|
+
version: 2.2.0
|
32
|
+
prerelease: false
|
33
|
+
requirement: *id001
|
34
|
+
name: seed-fu
|
35
|
+
type: :runtime
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
prerelease: false
|
47
|
+
requirement: *id002
|
48
|
+
name: rspec
|
49
|
+
type: :development
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
prerelease: false
|
61
|
+
requirement: *id003
|
62
|
+
name: sqlite3
|
63
|
+
type: :development
|
64
|
+
description: While Seed Fu solves the problem for inserting and maintaining seed data in a database, Seed Fu-ndo adds the possiblity to remove this data again.
|
65
|
+
email:
|
66
|
+
- spam@codez.ch
|
67
|
+
executables: []
|
68
|
+
|
69
|
+
extensions: []
|
70
|
+
|
71
|
+
extra_rdoc_files: []
|
72
|
+
|
73
|
+
files:
|
74
|
+
- lib/tasks/seed_fu_ndo.rake
|
75
|
+
- lib/seed-fu-ndo.rb
|
76
|
+
- lib/seed-fu-ndo/seeder.rb
|
77
|
+
- lib/seed-fu-ndo/recorder.rb
|
78
|
+
- lib/seed-fu-ndo/version.rb
|
79
|
+
- lib/seed-fu-ndo/railtie.rb
|
80
|
+
- Rakefile
|
81
|
+
- spec/test.sqlite3
|
82
|
+
- spec/seeder_spec.rb
|
83
|
+
- spec/spec_helper.rb
|
84
|
+
homepage: http://github.com/codez/seed-fu-ndo
|
85
|
+
licenses: []
|
86
|
+
|
87
|
+
post_install_message:
|
88
|
+
rdoc_options: []
|
89
|
+
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
hash: 3
|
98
|
+
segments:
|
99
|
+
- 0
|
100
|
+
version: "0"
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
hash: 3
|
107
|
+
segments:
|
108
|
+
- 0
|
109
|
+
version: "0"
|
110
|
+
requirements: []
|
111
|
+
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 1.8.17
|
114
|
+
signing_key:
|
115
|
+
specification_version: 3
|
116
|
+
summary: Seed Fu-ndo adds undo functionality to Seed Fu
|
117
|
+
test_files:
|
118
|
+
- spec/test.sqlite3
|
119
|
+
- spec/seeder_spec.rb
|
120
|
+
- spec/spec_helper.rb
|