tomafro-penknife 0.1.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/README +0 -0
- data/Rakefile +23 -0
- data/VERSION.yml +4 -0
- data/lib/penknife.rb +2 -0
- data/lib/penknife/active_record.rb +5 -0
- data/lib/penknife/active_record/column_reader.rb +28 -0
- data/lib/penknife/active_record/permalink.rb +22 -0
- data/lib/penknife/enhanced_form_builder.rb +84 -0
- data/lib/penknife/rake.rb +41 -0
- data/lib/penknife/rspec.rb +47 -0
- data/lib/penknife/spec.rb +13 -0
- data/lib/penknife/spec/controller_example_group_extensions.rb +120 -0
- data/lib/penknife/spec/doing.rb +11 -0
- data/lib/penknife/spec/pending_block.rb +0 -0
- data/lib/penknife/spec/time_travel.rb +20 -0
- data/penknife.gemspec +27 -0
- data/rails/init.rb +5 -0
- data/recipes/backup.rb +46 -0
- data/spec/extensions/active_record_spec.rb +8 -0
- data/spec/spec_helper.rb +10 -0
- data/tasks/backup.rake +46 -0
- data/tasks/penknife.rake +6 -0
- metadata +85 -0
data/README
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
folders = %w{rails lib recipes tasks spec features}.collect {|f| "#{f}/**/*"}
|
5
|
+
|
6
|
+
GEM_FILES = FileList[
|
7
|
+
*['[a-zA-Z]*', folders]
|
8
|
+
]
|
9
|
+
|
10
|
+
begin
|
11
|
+
require 'jeweler'
|
12
|
+
Jeweler::Tasks.new do |gem|
|
13
|
+
gem.name = "penknife"
|
14
|
+
gem.summary = %{All purpose toolkit for rails}
|
15
|
+
gem.email = "tom@popdog.net"
|
16
|
+
gem.homepage = "http://github.com/tomafro/penknife"
|
17
|
+
gem.authors = ["Tom Ward"]
|
18
|
+
gem.files = GEM_FILES.to_a
|
19
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
20
|
+
end
|
21
|
+
rescue LoadError
|
22
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
23
|
+
end
|
data/VERSION.yml
ADDED
data/lib/penknife.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
module Penknife::ActiveRecord::ColumnReader
|
2
|
+
def column_reader(column_name, options = {})
|
3
|
+
name = options.delete(:as) || column_name.to_s.pluralize
|
4
|
+
behaviour_module = column_reader_module(column_name)
|
5
|
+
column = columns_hash[column_name.to_s]
|
6
|
+
|
7
|
+
behaviour_module.module_eval %{
|
8
|
+
def #{name}(options = {})
|
9
|
+
connection.select_all(construct_finder_sql(options.merge(:select => '#{column_name}'))).collect do |value|
|
10
|
+
v = value.values.first
|
11
|
+
#{column.type_cast_code('v')}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
}
|
15
|
+
extend behaviour_module
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def column_reader_module(column_name)
|
21
|
+
module_name = "Raw#{column_name.to_s.camelize}Access"
|
22
|
+
if constants.include?(module_name)
|
23
|
+
const_get(module_name)
|
24
|
+
else
|
25
|
+
const_set(module_name, Module.new)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Penknife::ActiveRecord::Permalink
|
2
|
+
def has_permalink(attribute)
|
3
|
+
has_slug attribute
|
4
|
+
include Behaviour
|
5
|
+
end
|
6
|
+
|
7
|
+
module Behaviour
|
8
|
+
def self.included(base)
|
9
|
+
base.extend(ClassMethods)
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_param
|
13
|
+
self.permalink
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
def from_param(param)
|
18
|
+
self.find_by_permalink(param)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
class Penknife::EnhancedFormBuilder < ActionView::Helpers::FormBuilder
|
2
|
+
include ActionView::Helpers::TagHelper, ActionView::Helpers::FormTagHelper
|
3
|
+
|
4
|
+
(field_helpers - %w(hidden_field label check_box radio_button fields_for)).each do |selector|
|
5
|
+
src = <<-end_src
|
6
|
+
def #{selector}(method, options = {})
|
7
|
+
within_form_row(method, #{selector.inspect}, options) do
|
8
|
+
@template.send(#{selector.inspect}, @object_name, method, objectify_options(options))
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end_src
|
12
|
+
class_eval src, __FILE__, __LINE__
|
13
|
+
end
|
14
|
+
|
15
|
+
def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
|
16
|
+
within_form_row(method, 'check_box', options) do
|
17
|
+
@template.check_box(@object_name, method, objectify_options(options), checked_value, unchecked_value)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def select(method, choices, options = {}, html_options = {})
|
22
|
+
within_form_row(method, 'check_box', options) do
|
23
|
+
@template.select(@object_name, method, choices, objectify_options(options), @default_options.merge(html_options))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def radio_button(method, tag_value, options = {})
|
28
|
+
@template.radio_button(@object_name, method, tag_value, objectify_options(options))
|
29
|
+
end
|
30
|
+
|
31
|
+
def submit(value = "Save changes", options = {})
|
32
|
+
within_form_row(' ', nil, options.merge(:title => '')) do
|
33
|
+
submit_button(value, options.reverse_merge(:id => "#{object_name}_submit"))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def submit_button(value = "Save changes", options = {})
|
38
|
+
options.stringify_keys!
|
39
|
+
|
40
|
+
if disable_with = options.delete("disable_with")
|
41
|
+
disable_with = "this.value='#{disable_with}'"
|
42
|
+
disable_with << ";#{options.delete('onclick')}" if options['onclick']
|
43
|
+
|
44
|
+
options["onclick"] = [
|
45
|
+
"this.setAttribute('originalValue', this.value)",
|
46
|
+
"this.disabled=true",
|
47
|
+
disable_with,
|
48
|
+
"result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit())",
|
49
|
+
"if (result == false) { this.value = this.getAttribute('originalValue'); this.disabled = false }",
|
50
|
+
"return result;",
|
51
|
+
].join(";")
|
52
|
+
end
|
53
|
+
|
54
|
+
if confirm = options.delete("confirm")
|
55
|
+
options["onclick"] ||= ''
|
56
|
+
options["onclick"] += "return #{confirm_javascript_function(confirm)};"
|
57
|
+
end
|
58
|
+
|
59
|
+
tag(:button, { "type" => "submit", "name" => "commit" }.update(options.stringify_keys), true) + value + "</button>"
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def within_form_row(method, style, options = {}, &block)
|
65
|
+
description = options.delete(:description)
|
66
|
+
options[:class] = style
|
67
|
+
name = options[:title] || method.to_s.humanize
|
68
|
+
if options.delete(:required)
|
69
|
+
name << '*'
|
70
|
+
end
|
71
|
+
|
72
|
+
result = label(method, name) + yield
|
73
|
+
|
74
|
+
row_class = 'form-row'
|
75
|
+
if object && object.errors.on(options[:errors_from] || method)
|
76
|
+
row_class << ' errors'
|
77
|
+
result << " " << content_tag('div', object.errors.on(options[:errors_from] || method), :class => 'error')
|
78
|
+
elsif description
|
79
|
+
result << " " << content_tag('div', description, :class => 'description')
|
80
|
+
end
|
81
|
+
|
82
|
+
content_tag('div', result, :class => row_class)
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'penknife'
|
2
|
+
|
3
|
+
begin
|
4
|
+
rspec_base = File.expand_path("#{RAILS_ROOT}/vendor/plugins/rspec/lib")
|
5
|
+
$LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base) && !$LOAD_PATH.include?(rspec_base)
|
6
|
+
require 'spec/rake/spectask'
|
7
|
+
rescue Object => e
|
8
|
+
end
|
9
|
+
|
10
|
+
module Penknife::Rake
|
11
|
+
def self.define_plugin_tasks_for(plugin)
|
12
|
+
plugin = plugin.to_s
|
13
|
+
plugin_path = "#{RAILS_ROOT}/vendor/plugins/#{plugin}"
|
14
|
+
|
15
|
+
namespace plugin do
|
16
|
+
if Object.const_defined?(:Spec)
|
17
|
+
desc "Run #{plugin} specs"
|
18
|
+
Spec::Rake::SpecTask.new(:spec => "db:test:prepare") do |t|
|
19
|
+
t.spec_opts = ["-f n -c"]
|
20
|
+
t.spec_files = FileList["#{plugin_path}/spec/**/*_spec.rb"]
|
21
|
+
end
|
22
|
+
else
|
23
|
+
task :spec do
|
24
|
+
puts "To run specs for #{plugin} you must install rspec"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "#{plugin.titleize} stats"
|
29
|
+
task :stats do
|
30
|
+
require 'code_statistics'
|
31
|
+
::CodeStatistics::TEST_TYPES << "#{plugin.titleize} specs"
|
32
|
+
directories = [
|
33
|
+
[plugin.titleize + " code", "lib"],
|
34
|
+
[plugin.titleize + " specs", "spec"]
|
35
|
+
].collect { |name, dir|
|
36
|
+
[name, File.expand_path(File.join(plugin_path, dir))]}.select { |name, dir| File.directory?(dir) }
|
37
|
+
CodeStatistics.new(*directories).to_s
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'penknife'
|
2
|
+
require 'spec'
|
3
|
+
require 'spec/rails'
|
4
|
+
|
5
|
+
module Penknife::Rspec
|
6
|
+
module ExampleGroupExtensions
|
7
|
+
def doing(&block)
|
8
|
+
lambda(&block)
|
9
|
+
end
|
10
|
+
|
11
|
+
Spec::Example::ExampleMethods.module_eval do
|
12
|
+
include Penknife::Rspec::ExampleGroupExtensions
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
#
|
20
|
+
# module Spec
|
21
|
+
# module Mocks
|
22
|
+
# module SpecMethods
|
23
|
+
# def redefine_models
|
24
|
+
# redefine_classes(:SpraypaintPub, :SpraypaintCinema, :superclass => ActiveRecord::Base)
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# def redefine_classes(*classes)
|
28
|
+
# options = classes.last.is_a?(Hash) ? classes.pop : {}
|
29
|
+
# classes.each do |class_name|
|
30
|
+
# Object.remove_class(class_name.to_s.constantize) if Object.const_defined?(class_name)
|
31
|
+
# Object.const_set(class_name, Class.new(options[:superclass] || Object))
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# def tags
|
36
|
+
# @tags ||= Hash.new do |hash, key|
|
37
|
+
# tag = Tomafro::Spraypaint::SpraypaintTag.find_or_create_by_name(key)
|
38
|
+
# hash[key] = tag
|
39
|
+
# end
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# def doing(&block)
|
43
|
+
# lambda(&block)
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
# end
|
47
|
+
# end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module Penknife
|
2
|
+
module Spec
|
3
|
+
module ControllerExampleGroupExtensions
|
4
|
+
include ::ActionController::StatusCodes
|
5
|
+
|
6
|
+
def self.extended(base)
|
7
|
+
base.class_eval do
|
8
|
+
include InstanceMethods
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def describe(*args, &example_group_block)
|
13
|
+
if example_group_block
|
14
|
+
super
|
15
|
+
else
|
16
|
+
extract_action_from_args!(args)
|
17
|
+
extract_parameters_from_args(*args)
|
18
|
+
returning(clazz = super(*args, &example_group_block)) do
|
19
|
+
clazz.class_eval %{
|
20
|
+
before(:each) do
|
21
|
+
@it = @controller
|
22
|
+
params.merge!(self.class.described_action_parameters.dup)
|
23
|
+
request.env["HTTP_REFERER"] = "http://test.host/originalurl"
|
24
|
+
request.env['HTTP_USER_AGENT'] = "test"
|
25
|
+
end
|
26
|
+
|
27
|
+
def do_request
|
28
|
+
send self.class.described_action_method, self.class.described_action, params
|
29
|
+
end
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def described_action
|
36
|
+
@described_action || (superclass.respond_to?(:described_action) ? superclass.described_action : nil)
|
37
|
+
end
|
38
|
+
|
39
|
+
def described_action_method
|
40
|
+
@described_action_method || (superclass.respond_to?(:described_action_method) ? superclass.described_action_method : nil)
|
41
|
+
end
|
42
|
+
|
43
|
+
def described_action_parameters
|
44
|
+
(superclass.respond_to?(:described_action_parameters) ? superclass.described_action_parameters : {}).merge(@described_action_parameters || {})
|
45
|
+
end
|
46
|
+
|
47
|
+
def extract_action_from_args!(args)
|
48
|
+
options = args.extract_options!
|
49
|
+
args.collect! do |argument|
|
50
|
+
if @described_action.nil? && argument.is_a?(Symbol)
|
51
|
+
@described_action = args.first
|
52
|
+
@described_action_method = options[:method] || default_action_method_for(@described_action)
|
53
|
+
"doing #{@described_action_method.to_s.upcase} #{described_action}"
|
54
|
+
else
|
55
|
+
argument
|
56
|
+
end
|
57
|
+
end
|
58
|
+
args << options
|
59
|
+
end
|
60
|
+
|
61
|
+
def extract_parameters_from_args(*args)
|
62
|
+
options = args.dup.extract_options!
|
63
|
+
if (options[:with_params] || options[:params])
|
64
|
+
@described_action_parameters = (options[:with_params] || options[:params])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def description_parts
|
69
|
+
returning(super) do |parts|
|
70
|
+
parts << " with #{described_action_parameters.inspect}" unless described_action_parameters.empty?
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def default_action_method_for(action)
|
75
|
+
case action.to_sym
|
76
|
+
when :create then :post
|
77
|
+
when :update then :put
|
78
|
+
when :destroy then :delete
|
79
|
+
else :get
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def it_should_respond_with(status)
|
84
|
+
raise "Status #{status} not known" unless status = SYMBOL_TO_STATUS_CODE[status]
|
85
|
+
it "should respond with status #{status} (#{STATUS_CODES[status]})" do
|
86
|
+
do_request
|
87
|
+
response.code.to_s.should == status.to_s
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def it_should_redirect_to(*args)
|
92
|
+
path_hash = args.extract_options!
|
93
|
+
message ||= path_hash.inspect
|
94
|
+
it "should redirect to #{message}" do
|
95
|
+
do_request
|
96
|
+
@response.should redirect_to(path_hash)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
module InstanceMethods
|
101
|
+
# Yields to block, then calls request. e.g:
|
102
|
+
# during_request {@it.should_receive(:some_method)}
|
103
|
+
|
104
|
+
def during_request(&block)
|
105
|
+
yield
|
106
|
+
do_request
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
# Calls request, then yields to block. e.g:
|
111
|
+
# after_request {assigns[:organisations].should == @organisations}
|
112
|
+
|
113
|
+
def after_request(&block)
|
114
|
+
do_request
|
115
|
+
yield
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
File without changes
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class << Time
|
2
|
+
unless method_defined? :now_before_time_travel
|
3
|
+
alias_method :now_before_time_travel, :now
|
4
|
+
end
|
5
|
+
|
6
|
+
def now
|
7
|
+
@now || now_before_time_travel
|
8
|
+
end
|
9
|
+
|
10
|
+
def freeze(&block)
|
11
|
+
travel_to(Time.now, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def travel_to(time = Time.now, &block)
|
15
|
+
@now = time
|
16
|
+
block.call
|
17
|
+
ensure
|
18
|
+
@now = nil
|
19
|
+
end
|
20
|
+
end
|
data/penknife.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = %q{penknife}
|
3
|
+
s.version = "0.1.1"
|
4
|
+
|
5
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
6
|
+
s.authors = ["Tom Ward"]
|
7
|
+
s.date = %q{2009-03-24}
|
8
|
+
s.email = %q{tom@popdog.net}
|
9
|
+
s.extra_rdoc_files = ["README"]
|
10
|
+
s.files = ["lib", "penknife.gemspec", "pkg", "rails", "Rakefile", "README", "recipes", "spec", "tasks", "VERSION.yml", "rails/init.rb", "lib/penknife", "lib/penknife/active_record", "lib/penknife/active_record/column_reader.rb", "lib/penknife/active_record/permalink.rb", "lib/penknife/active_record.rb", "lib/penknife/enhanced_form_builder.rb", "lib/penknife/rake.rb", "lib/penknife/rspec.rb", "lib/penknife/spec", "lib/penknife/spec/controller_example_group_extensions.rb", "lib/penknife/spec/doing.rb", "lib/penknife/spec/pending_block.rb", "lib/penknife/spec/time_travel.rb", "lib/penknife/spec.rb", "lib/penknife.rb", "recipes/backup.rb", "tasks/backup.rake", "tasks/penknife.rake", "spec/extensions", "spec/extensions/active_record_spec.rb", "spec/spec_helper.rb"]
|
11
|
+
s.has_rdoc = true
|
12
|
+
s.homepage = %q{http://github.com/tomafro/penknife}
|
13
|
+
s.rdoc_options = ["--inline-source", "--charset=UTF-8"]
|
14
|
+
s.require_paths = ["lib"]
|
15
|
+
s.rubygems_version = %q{1.2.0}
|
16
|
+
s.summary = %q{All purpose toolkit for rails}
|
17
|
+
|
18
|
+
if s.respond_to? :specification_version then
|
19
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
20
|
+
s.specification_version = 2
|
21
|
+
|
22
|
+
if current_version >= 3 then
|
23
|
+
else
|
24
|
+
end
|
25
|
+
else
|
26
|
+
end
|
27
|
+
end
|
data/rails/init.rb
ADDED
data/recipes/backup.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Perform backups
|
2
|
+
#
|
3
|
+
# To automatically transfer backups to your local machine, add:
|
4
|
+
# after "backup:create", "backup:download"
|
5
|
+
#
|
6
|
+
|
7
|
+
_cset(:backup_path) { "#{shared_path}/backups" }
|
8
|
+
|
9
|
+
namespace :backup do
|
10
|
+
def latest
|
11
|
+
capture("cd #{current_path}; rake -s db:backup:latest BACKUP_DIR=#{backup_path}").split("\n").last.strip
|
12
|
+
end
|
13
|
+
|
14
|
+
task :link_folder, :roles => :db, :only => {:primary => true} do
|
15
|
+
run "mkdir -p #{backup_path}"
|
16
|
+
run "ln -s #{backup_path} #{latest_release}/backups"
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Create a backup on the server"
|
20
|
+
task :create, :roles => :db, :only => {:primary => true} do
|
21
|
+
rails_env = fetch(:rails_env, "production")
|
22
|
+
run "cd #{current_path}; rake db:backup:create RAILS_ENV=#{rails_env} BACKUP_DIR=#{backup_path}"
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "Retreive a backup from the server. Gets the latest by default, set :backup_version to specify which version to copy"
|
26
|
+
task :download, :roles => :db, :only => {:primary => true} do
|
27
|
+
version = fetch(:backup_version, latest)
|
28
|
+
run "tar -C #{backup_path} -czf #{backup_path}/#{version}.tar.gz #{version}"
|
29
|
+
`mkdir -p backups`
|
30
|
+
get "#{backup_path}/#{version}.tar.gz", "backups/#{version}.tar.gz"
|
31
|
+
run "rm #{backup_path}/#{version}.tar.gz"
|
32
|
+
`tar -C backups -zxf backups/#{version}.tar.gz`
|
33
|
+
`rm backups/#{version}.tar.gz`
|
34
|
+
end
|
35
|
+
|
36
|
+
desc "Creates a new remote backup and clones it to the local database"
|
37
|
+
task :mirror, :roles => :db, :only => {:primary => true} do
|
38
|
+
create
|
39
|
+
download
|
40
|
+
`rake db:backup:restore`
|
41
|
+
end
|
42
|
+
|
43
|
+
task :mirror_production, :roles => :db do
|
44
|
+
run "cd #{current_path}; cap production backup:mirror"
|
45
|
+
end
|
46
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
2
|
+
require File.expand_path(__FILE__ + "/../../../../../config/environment")
|
3
|
+
require 'penknife/rspec'
|
4
|
+
|
5
|
+
Spec::Rails::Example::ControllerExampleGroup.module_eval do
|
6
|
+
extend Penknife::Spec::ControllerExampleGroupExtensions
|
7
|
+
end
|
8
|
+
|
9
|
+
Spec::Example::ExampleGroupFactory.register(:"penknife/controllers", Spec::Rails::Example::ControllerExampleGroup)
|
10
|
+
|
data/tasks/backup.rake
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
namespace :db do
|
2
|
+
namespace :backup do
|
3
|
+
def backup_directory
|
4
|
+
ENV['BACKUP_DIR'] ||= File.join(RAILS_ROOT, 'backups')
|
5
|
+
end
|
6
|
+
|
7
|
+
def latest_backup
|
8
|
+
last = Dir["#{backup_directory}/*"].sort.last
|
9
|
+
File.basename(last) if last
|
10
|
+
end
|
11
|
+
|
12
|
+
task :latest => :environment do
|
13
|
+
if latest_backup
|
14
|
+
puts ENV['BACKUP'] = latest_backup
|
15
|
+
else
|
16
|
+
puts "No backups found in #{backup_directory}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Setup environment variables for the schema and fixtures tasks
|
21
|
+
task :setup => :environment do
|
22
|
+
ENV['BACKUP'] ||= Time.now.utc.strftime('%Y%m%d%H%M%S.sql')
|
23
|
+
FileUtils.mkdir_p backup_directory
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'Create a new backup of the database'
|
27
|
+
task :create => :setup do
|
28
|
+
config = ActiveRecord::Base.configurations[RAILS_ENV]
|
29
|
+
backup_file = File.expand_path(File.join(ENV['BACKUP_DIR'], ENV['BACKUP']))
|
30
|
+
case config["adapter"]
|
31
|
+
when "mysql" then puts `mysqldump -u #{config["username"]} #{config["database"]} > #{backup_file}`
|
32
|
+
else raise "Adapter #{config["adapter"]} not currently supported"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
task :restore => [:environment] do
|
37
|
+
ENV['BACKUP'] ||= latest_backup
|
38
|
+
config = ActiveRecord::Base.configurations[RAILS_ENV]
|
39
|
+
backup_file = File.expand_path(File.join(ENV['BACKUP_DIR'], ENV['BACKUP']))
|
40
|
+
case config["adapter"]
|
41
|
+
when "mysql" then puts `mysql -u #{config["username"]} #{config["database"]} < #{backup_file}`
|
42
|
+
else raise "Adapter #{config["adapter"]} not currently supported"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/tasks/penknife.rake
ADDED
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tomafro-penknife
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tom Ward
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-03-24 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: tom@popdog.net
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
24
|
+
files:
|
25
|
+
- lib
|
26
|
+
- penknife.gemspec
|
27
|
+
- pkg
|
28
|
+
- rails
|
29
|
+
- Rakefile
|
30
|
+
- README
|
31
|
+
- recipes
|
32
|
+
- spec
|
33
|
+
- tasks
|
34
|
+
- VERSION.yml
|
35
|
+
- rails/init.rb
|
36
|
+
- lib/penknife
|
37
|
+
- lib/penknife/active_record
|
38
|
+
- lib/penknife/active_record/column_reader.rb
|
39
|
+
- lib/penknife/active_record/permalink.rb
|
40
|
+
- lib/penknife/active_record.rb
|
41
|
+
- lib/penknife/enhanced_form_builder.rb
|
42
|
+
- lib/penknife/rake.rb
|
43
|
+
- lib/penknife/rspec.rb
|
44
|
+
- lib/penknife/spec
|
45
|
+
- lib/penknife/spec/controller_example_group_extensions.rb
|
46
|
+
- lib/penknife/spec/doing.rb
|
47
|
+
- lib/penknife/spec/pending_block.rb
|
48
|
+
- lib/penknife/spec/time_travel.rb
|
49
|
+
- lib/penknife/spec.rb
|
50
|
+
- lib/penknife.rb
|
51
|
+
- recipes/backup.rb
|
52
|
+
- tasks/backup.rake
|
53
|
+
- tasks/penknife.rake
|
54
|
+
- spec/extensions
|
55
|
+
- spec/extensions/active_record_spec.rb
|
56
|
+
- spec/spec_helper.rb
|
57
|
+
has_rdoc: true
|
58
|
+
homepage: http://github.com/tomafro/penknife
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options:
|
61
|
+
- --inline-source
|
62
|
+
- --charset=UTF-8
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: "0"
|
70
|
+
version:
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: "0"
|
76
|
+
version:
|
77
|
+
requirements: []
|
78
|
+
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.2.0
|
81
|
+
signing_key:
|
82
|
+
specification_version: 2
|
83
|
+
summary: All purpose toolkit for rails
|
84
|
+
test_files: []
|
85
|
+
|