database_resetter 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/Gemfile +11 -0
- data/HISTORY.markdown +5 -0
- data/LICENCE.markdown +31 -0
- data/README.markdown +177 -0
- data/Rakefile +27 -0
- data/VERSION +1 -0
- data/config/cucumber.yml +9 -0
- data/config/darcs.boring +118 -0
- data/features/descriptions/change_environment.feature +17 -0
- data/features/descriptions/database_resetter.feature +24 -0
- data/features/descriptions/different_web_frameworks.feature +24 -0
- data/features/descriptions/no_migrations.feature +19 -0
- data/features/step_definitions/database_resetter_steps.rb +125 -0
- data/features/support/env.rb +8 -0
- data/lib/database_resetter.rb +86 -0
- metadata +86 -0
data/Gemfile
ADDED
data/HISTORY.markdown
ADDED
data/LICENCE.markdown
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Licence
|
2
|
+
|
3
|
+
This software is released under the Simplified BSD Licence.
|
4
|
+
|
5
|
+
## database\_resetter licence
|
6
|
+
|
7
|
+
Copyright 2010 PatchSpace Ltd. All rights reserved.
|
8
|
+
|
9
|
+
Redistribution and use in source and binary forms, with or without modification, are
|
10
|
+
permitted provided that the following conditions are met:
|
11
|
+
|
12
|
+
1. Redistributions of source code must retain the above copyright notice, this list of
|
13
|
+
conditions and the following disclaimer.
|
14
|
+
|
15
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
16
|
+
of conditions and the following disclaimer in the documentation and/or other materials
|
17
|
+
provided with the distribution.
|
18
|
+
|
19
|
+
THIS SOFTWARE IS PROVIDED BY PATCHSPACE LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
20
|
+
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PATCHSPACE LTD OR
|
22
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
23
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
25
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
26
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
27
|
+
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
|
29
|
+
The views and conclusions contained in the software and documentation are those of the
|
30
|
+
authors and should not be interpreted as representing official policies, either expressed
|
31
|
+
or implied, of PatchSpace Ltd.
|
data/README.markdown
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
# database\_resetter
|
2
|
+
|
3
|
+
## Introduction
|
4
|
+
|
5
|
+
### What does it do?
|
6
|
+
|
7
|
+
database\_resetter is a small gem to handle automatically resetting
|
8
|
+
your test databases when developing a Ruby web app.
|
9
|
+
|
10
|
+
### Why do I want it?
|
11
|
+
|
12
|
+
Because you're sick of seeing "No column XXX in table YYY" or some such,
|
13
|
+
because your test database is out of sync with your migrations. If you're
|
14
|
+
making a lot of database changes, this can save you a fair bit of time.
|
15
|
+
|
16
|
+
I've used this code almost unmodified in all of my clients' projects over
|
17
|
+
the last year or two. Pretty much everyone that's seen it has said
|
18
|
+
it looked pretty handy, so I've bundled it up as a gem.
|
19
|
+
|
20
|
+
### How does it work?
|
21
|
+
|
22
|
+
database\_resetter writes timestamp files into _log/database\_resetter_
|
23
|
+
that track when the database was last reset. It tracks them:
|
24
|
+
|
25
|
+
* per environment (eg test, cucumber)
|
26
|
+
* per hostname
|
27
|
+
|
28
|
+
Per-hostname tracking is done in case you use Dropbox/JungleDisk etc to sync
|
29
|
+
code between machines. (Note: there are no features/specs to prove this works.)
|
30
|
+
|
31
|
+
What _isn't_ tracked is what directory / SCM branch you're in. So if you switch
|
32
|
+
to a different working copy folder, or change eg Git branch, database\_resetter
|
33
|
+
may not run the migrations. If you'd like this feature please contact me.
|
34
|
+
|
35
|
+
_The easiest way to make database\_resetter run is to touch a migration file._
|
36
|
+
|
37
|
+
### How is database\_resetter different from database\_cleaner?
|
38
|
+
|
39
|
+
Ben Mabey wrote [database\_cleaner](http://github.com/bmabey/database_cleaner) to
|
40
|
+
help with emptying a database between individual test cases. database\_resetter is
|
41
|
+
designed to get the initial schema of a database in place before any test cases run.
|
42
|
+
|
43
|
+
Basically, you want both :-)
|
44
|
+
|
45
|
+
|
46
|
+
## Instructions
|
47
|
+
|
48
|
+
If you're working on a Rails app, and your tests are good to go after a
|
49
|
+
`rake db:reset`, then place the following code somewhere that
|
50
|
+
will get executed once per test run:
|
51
|
+
|
52
|
+
DatabaseResetter.new.reset_if_required
|
53
|
+
|
54
|
+
Note: there are no features to prove this default call actually works :) I've
|
55
|
+
always specified the options explicitly myself. But the defaults should work with
|
56
|
+
Rails. If not, let me know.
|
57
|
+
|
58
|
+
For instructions on specifying the options, see below.
|
59
|
+
|
60
|
+
### Changing the Rake task
|
61
|
+
|
62
|
+
If (like me), you don't use _schema.rb_ to regenerate databases,
|
63
|
+
you'll need your own Rake task. I use one called `rake db:rebuild`,
|
64
|
+
which is currently:
|
65
|
+
|
66
|
+
desc "Reset and re-migrate the database"
|
67
|
+
task :rebuild do
|
68
|
+
Rake::Task["db:drop"].invoke
|
69
|
+
Rake::Task["db:create"].invoke
|
70
|
+
Rake::Task["db:migrate"].invoke
|
71
|
+
end
|
72
|
+
|
73
|
+
To override the default command, specify the `:command_pattern` option:
|
74
|
+
|
75
|
+
DatabaseResetter.new(
|
76
|
+
:command_pattern => "rake db:rebuild RAILS_ENV=%ENV%"
|
77
|
+
).reset_if_required
|
78
|
+
|
79
|
+
See below for a description of `%ENV%`.
|
80
|
+
|
81
|
+
### Using a different framework
|
82
|
+
|
83
|
+
If you use a different web framework, you may have to specify a different
|
84
|
+
environment variable to switch the framework environment (eg `MERB_ENV`
|
85
|
+
or `RACK_ENV`). To override this, specify both `:command_pattern` and
|
86
|
+
`:environment`, eg:
|
87
|
+
|
88
|
+
DatabaseResetter.new(
|
89
|
+
:environment => ENV["MERB_ENV"],
|
90
|
+
:command_pattern => "rake db:reset MERB_ENV=%ENV%"
|
91
|
+
).reset_if_required
|
92
|
+
|
93
|
+
You may also need to specify a different migration file directory to watch, eg:
|
94
|
+
|
95
|
+
DatabaseResetter.new(
|
96
|
+
:migration_directory => "schema/migrations"
|
97
|
+
).reset_if_required
|
98
|
+
|
99
|
+
(You can, of course, combine all three.)
|
100
|
+
|
101
|
+
### RSpec
|
102
|
+
|
103
|
+
Put the call to `DatabaseResetter#reset_if_required` in _spec/spec\_helper.rb_.
|
104
|
+
|
105
|
+
### Cucumber
|
106
|
+
|
107
|
+
Put the call to `DatabaseResetter#reset_if_required` in
|
108
|
+
_features/support/env.rb_.
|
109
|
+
|
110
|
+
### Spork
|
111
|
+
|
112
|
+
If you use Spork, you want to call `DatabaseResetter#reset_if_required` in the
|
113
|
+
`each_run` block, eg:
|
114
|
+
|
115
|
+
Spork.each_run do
|
116
|
+
# ...
|
117
|
+
DatabaseResetter.new.reset_if_required
|
118
|
+
# ...
|
119
|
+
end
|
120
|
+
|
121
|
+
### PostgreSQL
|
122
|
+
|
123
|
+
If you use PostgreSQL, and your Rake task attempts to drop the database,
|
124
|
+
Postgres will stop you if there is a connection in place. You need to work
|
125
|
+
around this somehow. If you're using Spork, you need to divert Postgres's
|
126
|
+
eyes, eg in Rails:
|
127
|
+
|
128
|
+
Spork.each_run do
|
129
|
+
# ...
|
130
|
+
|
131
|
+
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
|
132
|
+
DatabaseResetter.new.reset_if_required
|
133
|
+
ActiveRecord::Base.establish_connection(config)
|
134
|
+
|
135
|
+
# ...
|
136
|
+
end
|
137
|
+
|
138
|
+
If you're not using Spork, you still need to make sure you call
|
139
|
+
`DatabaseResetter#reset_if_required` before connecting to the database.
|
140
|
+
One way of doing this with Bundler is to define a Bundler group just
|
141
|
+
for database\_resetter in your Gemfile:
|
142
|
+
|
143
|
+
group :database_resetter do
|
144
|
+
gem "database_resetter"
|
145
|
+
end
|
146
|
+
|
147
|
+
And then use this to load and run database\_resetter before anything connects
|
148
|
+
to the database. eg with Rails and Cucumber, in _env.rb_:
|
149
|
+
|
150
|
+
# ...
|
151
|
+
|
152
|
+
require 'bundler'
|
153
|
+
Bundler.setup(:database_resetter)
|
154
|
+
require 'database_resetter'
|
155
|
+
DatabaseResetter.new.reset_if_required
|
156
|
+
|
157
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
|
158
|
+
|
159
|
+
# ...
|
160
|
+
|
161
|
+
|
162
|
+
## Bugs / Feedback
|
163
|
+
|
164
|
+
There is currently no project page for database\_resetter. If you want to report
|
165
|
+
bugs in the code or documentation, or request features, please contact me:
|
166
|
+
|
167
|
+
[ashley.moran@patchspace.co.uk](mailto:ashley.moran@patchspace.co.uk)
|
168
|
+
|
169
|
+
[PatchSpace Ltd](http://www.patchspace.co.uk/)
|
170
|
+
|
171
|
+
|
172
|
+
## Source code
|
173
|
+
|
174
|
+
database\_resetter is maintained in a darcs repository, and is currently hosted
|
175
|
+
on Patch-Tag:
|
176
|
+
|
177
|
+
[Official darcs repository](https://patch-tag.com/r/ashleymoran/database_resetter/)
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require "bundler"
|
2
|
+
Bundler.setup(:default)
|
3
|
+
|
4
|
+
require "jeweler"
|
5
|
+
|
6
|
+
Jeweler::Tasks.new do |gemspec|
|
7
|
+
gemspec.name = "database_resetter"
|
8
|
+
gemspec.summary = "Automatically resets your database when migrations change"
|
9
|
+
gemspec.email = "ashley.moran@patchspace.co.uk"
|
10
|
+
gemspec.homepage = "https://patch-tag.com/repo/ashleymoran/database_resetter/"
|
11
|
+
gemspec.authors = ["Ashley Moran"]
|
12
|
+
|
13
|
+
gemspec.files.include %w[
|
14
|
+
config/**/*
|
15
|
+
lib/**/*
|
16
|
+
*.markdown
|
17
|
+
Gemfile
|
18
|
+
Rakefile
|
19
|
+
VERSION
|
20
|
+
]
|
21
|
+
gemspec.test_files.include %w[
|
22
|
+
features/**/*
|
23
|
+
spec/**/*
|
24
|
+
]
|
25
|
+
end
|
26
|
+
|
27
|
+
Jeweler::GemcutterTasks.new
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/config/cucumber.yml
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
<%
|
2
|
+
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
|
3
|
+
rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
|
4
|
+
requires = "--require features/support --require features/step_definitions"
|
5
|
+
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --strict --tags ~@wip #{requires}"
|
6
|
+
%>
|
7
|
+
default: <%= std_opts %> features
|
8
|
+
wip: --tags @wip:3 --wip <%= requires %> features
|
9
|
+
rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
|
data/config/darcs.boring
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
# Boring file regexps:
|
2
|
+
|
3
|
+
### compiler and interpreter intermediate files
|
4
|
+
# haskell (ghc) interfaces
|
5
|
+
\.hi$
|
6
|
+
\.hi-boot$
|
7
|
+
\.o-boot$
|
8
|
+
# object files
|
9
|
+
\.o$
|
10
|
+
\.o\.cmd$
|
11
|
+
# profiling haskell
|
12
|
+
\.p_hi$
|
13
|
+
\.p_o$
|
14
|
+
# haskell program coverage resp. profiling info
|
15
|
+
\.tix$
|
16
|
+
\.prof$
|
17
|
+
# fortran module files
|
18
|
+
\.mod$
|
19
|
+
# linux kernel
|
20
|
+
\.ko\.cmd$
|
21
|
+
\.mod\.c$
|
22
|
+
(^|/)\.tmp_versions($|/)
|
23
|
+
# *.ko files aren't boring by default because they might
|
24
|
+
# be Korean translations rather than kernel modules
|
25
|
+
# \.ko$
|
26
|
+
# python, emacs, java byte code
|
27
|
+
\.py[co]$
|
28
|
+
\.elc$
|
29
|
+
\.class$
|
30
|
+
# objects and libraries; lo and la are libtool things
|
31
|
+
\.(obj|a|exe|so|lo|la)$
|
32
|
+
# compiled zsh configuration files
|
33
|
+
\.zwc$
|
34
|
+
# Common LISP output files for CLISP and CMUCL
|
35
|
+
\.(fas|fasl|sparcf|x86f)$
|
36
|
+
|
37
|
+
### build and packaging systems
|
38
|
+
# cabal intermediates
|
39
|
+
\.installed-pkg-config
|
40
|
+
\.setup-config
|
41
|
+
# standard cabal build dir, might not be boring for everybody
|
42
|
+
# ^dist(/|$)
|
43
|
+
# autotools
|
44
|
+
(^|/)autom4te\.cache($|/)
|
45
|
+
(^|/)config\.(log|status)$
|
46
|
+
# microsoft web expression, visual studio metadata directories
|
47
|
+
\_vti_cnf$
|
48
|
+
\_vti_pvt$
|
49
|
+
# gentoo tools
|
50
|
+
\.revdep-rebuild.*
|
51
|
+
# generated dependencies
|
52
|
+
^\.depend$
|
53
|
+
|
54
|
+
### version control systems
|
55
|
+
# cvs
|
56
|
+
(^|/)CVS($|/)
|
57
|
+
\.cvsignore$
|
58
|
+
# cvs, emacs locks
|
59
|
+
^\.#
|
60
|
+
# rcs
|
61
|
+
(^|/)RCS($|/)
|
62
|
+
,v$
|
63
|
+
# subversion
|
64
|
+
(^|/)\.svn($|/)
|
65
|
+
# mercurial
|
66
|
+
(^|/)\.hg($|/)
|
67
|
+
# git
|
68
|
+
(^|/)\.git($|/)
|
69
|
+
# bzr
|
70
|
+
\.bzr$
|
71
|
+
# sccs
|
72
|
+
(^|/)SCCS($|/)
|
73
|
+
# darcs
|
74
|
+
(^|/)_darcs($|/)
|
75
|
+
(^|/)\.darcsrepo($|/)
|
76
|
+
^\.darcs-temp-mail$
|
77
|
+
-darcs-backup[[:digit:]]+$
|
78
|
+
# gnu arch
|
79
|
+
(^|/)(\+|,)
|
80
|
+
(^|/)vssver\.scc$
|
81
|
+
\.swp$
|
82
|
+
(^|/)MT($|/)
|
83
|
+
(^|/)\{arch\}($|/)
|
84
|
+
(^|/).arch-ids($|/)
|
85
|
+
# bitkeeper
|
86
|
+
(^|/)BitKeeper($|/)
|
87
|
+
(^|/)ChangeSet($|/)
|
88
|
+
|
89
|
+
### miscellaneous
|
90
|
+
# backup files
|
91
|
+
~$
|
92
|
+
\.bak$
|
93
|
+
\.BAK$
|
94
|
+
# patch originals and rejects
|
95
|
+
\.orig$
|
96
|
+
\.rej$
|
97
|
+
# X server
|
98
|
+
\..serverauth.*
|
99
|
+
# image spam
|
100
|
+
\#
|
101
|
+
(^|/)Thumbs\.db$
|
102
|
+
# vi, emacs tags
|
103
|
+
(^|/)(tags|TAGS)$
|
104
|
+
#(^|/)\.[^/]
|
105
|
+
# core dumps
|
106
|
+
(^|/|\.)core$
|
107
|
+
# partial broken files (KIO copy operations)
|
108
|
+
\.part$
|
109
|
+
# waf files, see http://code.google.com/p/waf/
|
110
|
+
(^|/)\.waf-[[:digit:].]+-[[:digit:]]+($|/)
|
111
|
+
(^|/)\.lock-wscript$
|
112
|
+
# mac os finder
|
113
|
+
(^|/)\.DS_Store$
|
114
|
+
|
115
|
+
### database_resetter
|
116
|
+
(^|/)tmp($|/)
|
117
|
+
(^|/).bundle($|/)
|
118
|
+
(^|/)pkg($|/)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Feature: Change environment
|
2
|
+
So that I don't obliterate my Cucumber database when running RSpec
|
3
|
+
As a wise developer who maintains separate testing environments
|
4
|
+
I want to specify the environment that gets reset
|
5
|
+
|
6
|
+
Scenario: Using environment "test"
|
7
|
+
Given a Rails-type project
|
8
|
+
And a fake test case for the "test" environment
|
9
|
+
When I run a test case
|
10
|
+
Then the database should be reset for the "test" environment
|
11
|
+
|
12
|
+
Scenario: Using environment "cucumber"
|
13
|
+
Given a Rails-type project
|
14
|
+
And a fake test case for the "cucumber" environment
|
15
|
+
When I run a test case
|
16
|
+
Then the database should be reset for the "cucumber" environment
|
17
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
Feature: Reset a database
|
2
|
+
In order to reduce time wasted manually running migrations
|
3
|
+
As a database-backed app developer
|
4
|
+
I want my databases rebuilt when I change the migrations
|
5
|
+
|
6
|
+
Scenario: Initial run
|
7
|
+
Given a Rails-type project
|
8
|
+
When I run a test case
|
9
|
+
Then the database should be reset
|
10
|
+
|
11
|
+
Scenario: Clean re-run
|
12
|
+
Given a Rails-type project
|
13
|
+
When I run a test case
|
14
|
+
And I run a test case again
|
15
|
+
Then the database should not be reset
|
16
|
+
|
17
|
+
Scenario: Dirty re-run
|
18
|
+
Given a Rails-type project
|
19
|
+
When I run a test case
|
20
|
+
And I touch a migration
|
21
|
+
And I run a test case again
|
22
|
+
Then the database should be reset
|
23
|
+
|
24
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
Feature: Different web frameworks
|
2
|
+
In order to enjoy the magic of an automatically-reset database on all my projects
|
3
|
+
As a promiscuous web framework fly-by-night
|
4
|
+
I want to reset databases in Rails, Merb, Sinatra and all that crazy shit
|
5
|
+
|
6
|
+
Scenario: Rails-type project
|
7
|
+
Given a Rails-type project
|
8
|
+
|
9
|
+
When I run a test case
|
10
|
+
Then the database should be reset
|
11
|
+
|
12
|
+
When I touch a migration
|
13
|
+
And I run a test case again
|
14
|
+
Then the database should be reset
|
15
|
+
|
16
|
+
Scenario: Merb-type project
|
17
|
+
Given a Merb-type project
|
18
|
+
|
19
|
+
When I run a test case
|
20
|
+
Then the database should be reset for the current Merb environment
|
21
|
+
|
22
|
+
When I touch a migration
|
23
|
+
And I run a test case again
|
24
|
+
Then the database should be reset for the current Merb environment
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Feature: No migrations
|
2
|
+
So that I don't have to decipher an incomprehensible backtrace
|
3
|
+
As a bone idle and/or forgetful database-backed app developer
|
4
|
+
I want database_resetter to tell me when I forgot to make any migrations
|
5
|
+
|
6
|
+
# TODO Rails-specific issues need highlighting
|
7
|
+
|
8
|
+
Scenario: No migrations directory
|
9
|
+
Given an empty project called "empty-project"
|
10
|
+
When I run a test case
|
11
|
+
Then I should see "No migrations"
|
12
|
+
|
13
|
+
Scenario: No migrations in migration directory
|
14
|
+
Given an empty project called "empty-project"
|
15
|
+
And an empty Rails migration directory
|
16
|
+
When I run a test case
|
17
|
+
Then I should see "No migrations"
|
18
|
+
|
19
|
+
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module DatabaseResetterHelpers
|
2
|
+
def create_project
|
3
|
+
create_dir(@project_name)
|
4
|
+
cd(@project_name)
|
5
|
+
create_fake_test_case
|
6
|
+
end
|
7
|
+
|
8
|
+
def create_fake_test_case(options = {})
|
9
|
+
options = {
|
10
|
+
:environment => "unimportant_env",
|
11
|
+
:migration_directory => "db/migrate",
|
12
|
+
:command_pattern => "rake db:reset RAILS_ENV=%ENV%"
|
13
|
+
}.merge(options)
|
14
|
+
|
15
|
+
create_file(
|
16
|
+
"fake_test_case.rb", <<-RUBY
|
17
|
+
require "rubygems"
|
18
|
+
require "database_resetter"
|
19
|
+
DatabaseResetter.new(
|
20
|
+
:environment => "#{options[:environment]}",
|
21
|
+
:migration_directory => "#{options[:migration_directory]}",
|
22
|
+
:command_pattern => "#{options[:command_pattern]}"
|
23
|
+
).reset_if_required
|
24
|
+
RUBY
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
World(DatabaseResetterHelpers)
|
29
|
+
|
30
|
+
Given /^an empty project called "([^"]*)"$/ do |project_name|
|
31
|
+
@project_name = project_name
|
32
|
+
create_project
|
33
|
+
end
|
34
|
+
|
35
|
+
Given /^an empty Rails migration directory$/ do
|
36
|
+
create_dir("db/migrate")
|
37
|
+
end
|
38
|
+
|
39
|
+
Given /^a Rails-type project$/ do
|
40
|
+
@project_name = "rails-project"
|
41
|
+
create_project
|
42
|
+
|
43
|
+
@migration_dir = "db/migrate"
|
44
|
+
create_dir(@migration_dir)
|
45
|
+
create_file(
|
46
|
+
"#{@migration_dir}/001_first_migration.rb", <<-RUBY
|
47
|
+
# This is just a dummy migration file
|
48
|
+
RUBY
|
49
|
+
)
|
50
|
+
|
51
|
+
create_file(
|
52
|
+
"Rakefile", <<-RUBY
|
53
|
+
namespace :db do
|
54
|
+
task :reset do
|
55
|
+
puts "Invoked: rake db:reset RAILS_ENV=\#{ENV['RAILS_ENV']}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
RUBY
|
59
|
+
)
|
60
|
+
|
61
|
+
create_fake_test_case
|
62
|
+
end
|
63
|
+
|
64
|
+
Given /^a Merb-type project$/ do
|
65
|
+
@project_name = "merb-project"
|
66
|
+
create_project
|
67
|
+
|
68
|
+
@migration_dir = "schema/migrations"
|
69
|
+
create_dir(@migration_dir)
|
70
|
+
|
71
|
+
create_file(
|
72
|
+
"#{@migration_dir}/001_first_migration.rb", <<-RUBY
|
73
|
+
# This is just a dummy migration file
|
74
|
+
RUBY
|
75
|
+
)
|
76
|
+
|
77
|
+
create_file(
|
78
|
+
"Rakefile", <<-RUBY
|
79
|
+
namespace :db do
|
80
|
+
task :imaginary_merb_reset_task do
|
81
|
+
puts "Invoked: rake db:imaginary_merb_reset_task MERB_ENV=\#{ENV['MERB_ENV']}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
RUBY
|
85
|
+
)
|
86
|
+
|
87
|
+
create_fake_test_case(
|
88
|
+
:migration_directory => @migration_dir,
|
89
|
+
:command_pattern => "rake db:imaginary_merb_reset_task MERB_ENV=%ENV%",
|
90
|
+
:environment => "my_merb_env"
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
Given /^a fake test case for the "([^"]*)" environment$/ do |environment|
|
95
|
+
create_fake_test_case(:environment => environment)
|
96
|
+
end
|
97
|
+
|
98
|
+
Then /^the database should be reset$/ do
|
99
|
+
Then %'I should see "Invoked: rake db:reset"'
|
100
|
+
end
|
101
|
+
|
102
|
+
Then /^the database should not be reset$/ do
|
103
|
+
Then %'I should see "Skipping database reset"'
|
104
|
+
end
|
105
|
+
|
106
|
+
Then /^the database should be reset for the "([^"]*)" environment$/ do |environment|
|
107
|
+
Then %'I should see "Invoked: rake db:reset RAILS_ENV=#{environment}"'
|
108
|
+
end
|
109
|
+
|
110
|
+
Then /^the database should be reset for the current Merb environment$/ do
|
111
|
+
Then %'I should see "Invoked: rake db:imaginary_merb_reset_task MERB_ENV=my_merb_env"'
|
112
|
+
end
|
113
|
+
|
114
|
+
When /^I run a test case(?: again)?$/ do
|
115
|
+
run("ruby fake_test_case.rb")
|
116
|
+
end
|
117
|
+
|
118
|
+
When /^I touch a migration$/ do
|
119
|
+
sleep 1
|
120
|
+
create_file(
|
121
|
+
"#{@migration_dir}/001_first_migration.rb", <<-RUBY
|
122
|
+
# Modified migration file
|
123
|
+
RUBY
|
124
|
+
)
|
125
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
class DatabaseResetter
|
4
|
+
def initialize(options)
|
5
|
+
# NOTE There are no features/specs to prove the defaults are present
|
6
|
+
@environment = options[:environment] || ENV["RAILS_ENV"]
|
7
|
+
@command_pattern = options[:command_pattern] || "rake db:reset RAILS_ENV=%ENV%"
|
8
|
+
@files_to_watch = "#{options[:migration_directory] || "db/migrate"}/**/*.rb"
|
9
|
+
end
|
10
|
+
|
11
|
+
def reset_if_required
|
12
|
+
if migration_dir.empty?
|
13
|
+
puts "*** No migrations"
|
14
|
+
return
|
15
|
+
end
|
16
|
+
|
17
|
+
if migrations_changed_since_last_database_reset?
|
18
|
+
reset
|
19
|
+
else
|
20
|
+
puts "*** Skipping database reset (migrations not changed since last run)"
|
21
|
+
puts "*** Run `#{reset_command}` if necessary, or touch a migration"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def database_reset_time_file
|
28
|
+
"#{database_reset_dir}/#{@environment}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def database_reset_dir
|
32
|
+
"log/database_resetter/#{`hostname`}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def ensure_database_reset_dir
|
36
|
+
system "mkdir -p '#{database_reset_dir}'"
|
37
|
+
end
|
38
|
+
|
39
|
+
def reset
|
40
|
+
puts "*** Resetting #{@environment} database"
|
41
|
+
run_reset_command_or_raise
|
42
|
+
log_database_reset_time
|
43
|
+
puts "*** #{@environment.capitalize} database reset"
|
44
|
+
end
|
45
|
+
|
46
|
+
def migrations_changed_since_last_database_reset?
|
47
|
+
most_recent_migration_file_change_timestamp > last_database_reset_timestamp
|
48
|
+
end
|
49
|
+
|
50
|
+
def most_recent_migration_file_change_timestamp
|
51
|
+
migration_dir.map { |filename|
|
52
|
+
File.mtime(filename)
|
53
|
+
}.max
|
54
|
+
end
|
55
|
+
|
56
|
+
def last_database_reset_timestamp
|
57
|
+
File.open(database_reset_time_file) do |file|
|
58
|
+
Time.parse(file.readline)
|
59
|
+
end
|
60
|
+
rescue Errno::ENOENT
|
61
|
+
Time.at(0)
|
62
|
+
end
|
63
|
+
|
64
|
+
def log_database_reset_time
|
65
|
+
ensure_database_reset_dir
|
66
|
+
File.open(database_reset_time_file, "w") do |file|
|
67
|
+
file.puts(Time.new)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def run_reset_command_or_raise
|
72
|
+
raise "Command failed: #{reset_command}" unless run_reset_command
|
73
|
+
end
|
74
|
+
|
75
|
+
def run_reset_command
|
76
|
+
system(reset_command)
|
77
|
+
end
|
78
|
+
|
79
|
+
def reset_command
|
80
|
+
@command_pattern.gsub("%ENV%", @environment)
|
81
|
+
end
|
82
|
+
|
83
|
+
def migration_dir
|
84
|
+
Dir[@files_to_watch]
|
85
|
+
end
|
86
|
+
end
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: database_resetter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Ashley Moran
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-07-04 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description:
|
23
|
+
email: ashley.moran@patchspace.co.uk
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files:
|
29
|
+
- README.markdown
|
30
|
+
files:
|
31
|
+
- Gemfile
|
32
|
+
- HISTORY.markdown
|
33
|
+
- LICENCE.markdown
|
34
|
+
- README.markdown
|
35
|
+
- Rakefile
|
36
|
+
- VERSION
|
37
|
+
- config/cucumber.yml
|
38
|
+
- config/darcs.boring
|
39
|
+
- lib/database_resetter.rb
|
40
|
+
- features/descriptions/change_environment.feature
|
41
|
+
- features/descriptions/database_resetter.feature
|
42
|
+
- features/descriptions/different_web_frameworks.feature
|
43
|
+
- features/descriptions/no_migrations.feature
|
44
|
+
- features/step_definitions/database_resetter_steps.rb
|
45
|
+
- features/support/env.rb
|
46
|
+
has_rdoc: true
|
47
|
+
homepage: https://patch-tag.com/repo/ashleymoran/database_resetter/
|
48
|
+
licenses: []
|
49
|
+
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options:
|
52
|
+
- --charset=UTF-8
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 3
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
version: "0"
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
hash: 3
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
version: "0"
|
73
|
+
requirements: []
|
74
|
+
|
75
|
+
rubyforge_project:
|
76
|
+
rubygems_version: 1.3.7
|
77
|
+
signing_key:
|
78
|
+
specification_version: 3
|
79
|
+
summary: Automatically resets your database when migrations change
|
80
|
+
test_files:
|
81
|
+
- features/descriptions/change_environment.feature
|
82
|
+
- features/descriptions/database_resetter.feature
|
83
|
+
- features/descriptions/different_web_frameworks.feature
|
84
|
+
- features/descriptions/no_migrations.feature
|
85
|
+
- features/step_definitions/database_resetter_steps.rb
|
86
|
+
- features/support/env.rb
|