gigantron 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +22 -0
- data/License.txt +20 -0
- data/Manifest.txt +65 -0
- data/PostInstall.txt +4 -0
- data/README.txt +77 -0
- data/Rakefile +4 -0
- data/app_generators/gigantron/USAGE +7 -0
- data/app_generators/gigantron/gigantron_generator.rb +87 -0
- data/app_generators/gigantron/templates/Rakefile +12 -0
- data/app_generators/gigantron/templates/database.yml.example +9 -0
- data/app_generators/gigantron/templates/initialize.rb +34 -0
- data/app_generators/gigantron/templates/lib/shoulda/active_record_helpers.rb +604 -0
- data/app_generators/gigantron/templates/lib/shoulda/general.rb +118 -0
- data/app_generators/gigantron/templates/lib/shoulda/private_helpers.rb +22 -0
- data/app_generators/gigantron/templates/tasks/import.rake +10 -0
- data/app_generators/gigantron/templates/test/tasks/test_import.rb +23 -0
- data/app_generators/gigantron/templates/test/test_helper.rb +22 -0
- data/bin/gigantron +15 -0
- data/config/hoe.rb +82 -0
- data/config/requirements.rb +15 -0
- data/gigantron_generators/mapreduce_task/USAGE +5 -0
- data/gigantron_generators/mapreduce_task/mapreduce_task_generator.rb +54 -0
- data/gigantron_generators/mapreduce_task/templates/mapreduce/mr_task.rb +22 -0
- data/gigantron_generators/mapreduce_task/templates/tasks/task.rake +5 -0
- data/gigantron_generators/mapreduce_task/templates/test/tasks/test_task.rb +22 -0
- data/gigantron_generators/migration/USAGE +5 -0
- data/gigantron_generators/migration/migration_generator.rb +61 -0
- data/gigantron_generators/migration/templates/db/migrate/migration.rb +7 -0
- data/gigantron_generators/model/USAGE +11 -0
- data/gigantron_generators/model/model_generator.rb +54 -0
- data/gigantron_generators/model/templates/models/model.rb +3 -0
- data/gigantron_generators/model/templates/test/models/test_model.rb +13 -0
- data/gigantron_generators/task/USAGE +10 -0
- data/gigantron_generators/task/task_generator.rb +51 -0
- data/gigantron_generators/task/templates/tasks/task.rake +4 -0
- data/gigantron_generators/task/templates/test/tasks/test_task.rb +22 -0
- data/lib/gigantron.rb +0 -0
- data/lib/gigantron/migrator.rb +10 -0
- data/lib/gigantron/tasks/db.rb +11 -0
- data/lib/gigantron/tasks/test.rb +30 -0
- data/lib/gigantron/version.rb +9 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +82 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/test/template_database.yml +3 -0
- data/test/template_database.yml.example +9 -0
- data/test/template_migration.rb +16 -0
- data/test/test_generator_helper.rb +29 -29
- data/test/test_gigantron.rb +11 -11
- data/test/test_gigantron_generator.rb +118 -118
- data/test/test_helper.rb +4 -4
- data/test/test_mapreduce_task_generator.rb +50 -50
- data/test/test_migration_generator.rb +49 -49
- data/test/test_model_generator.rb +53 -53
- data/test/test_task_generator.rb +48 -48
- data/website/index.html +224 -0
- data/website/index.txt +154 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +138 -0
- data/website/template.html.erb +48 -0
- metadata +152 -46
@@ -0,0 +1,118 @@
|
|
1
|
+
module ThoughtBot # :nodoc:
|
2
|
+
module Shoulda # :nodoc:
|
3
|
+
module General
|
4
|
+
def self.included(other) # :nodoc:
|
5
|
+
other.class_eval do
|
6
|
+
extend ThoughtBot::Shoulda::General::ClassMethods
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
# Loads all fixture files (<tt>test/fixtures/*.yml</tt>)
|
12
|
+
def load_all_fixtures
|
13
|
+
all_fixtures = Dir.glob(File.join(Test::Unit::TestCase.fixture_path, "*.yml")).collect do |f|
|
14
|
+
File.basename(f, '.yml').to_sym
|
15
|
+
end
|
16
|
+
fixtures *all_fixtures
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Prints a message to stdout, tagged with the name of the calling method.
|
21
|
+
def report!(msg = "")
|
22
|
+
puts("#{caller.first}: #{msg}")
|
23
|
+
end
|
24
|
+
|
25
|
+
# Asserts that two arrays contain the same elements, the same number of times. Essentially ==, but unordered.
|
26
|
+
#
|
27
|
+
# assert_same_elements([:a, :b, :c], [:c, :a, :b]) => passes
|
28
|
+
def assert_same_elements(a1, a2, msg = nil)
|
29
|
+
[:select, :inject, :size].each do |m|
|
30
|
+
[a1, a2].each {|a| assert_respond_to(a, m, "Are you sure that #{a.inspect} is an array? It doesn't respond to #{m}.") }
|
31
|
+
end
|
32
|
+
|
33
|
+
assert a1h = a1.inject({}) { |h,e| h[e] = a1.select { |i| i == e }.size; h }
|
34
|
+
assert a2h = a2.inject({}) { |h,e| h[e] = a2.select { |i| i == e }.size; h }
|
35
|
+
|
36
|
+
assert_equal(a1h, a2h, msg)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Asserts that the given collection contains item x. If x is a regular expression, ensure that
|
40
|
+
# at least one element from the collection matches x. +extra_msg+ is appended to the error message if the assertion fails.
|
41
|
+
#
|
42
|
+
# assert_contains(['a', '1'], /\d/) => passes
|
43
|
+
# assert_contains(['a', '1'], 'a') => passes
|
44
|
+
# assert_contains(['a', '1'], /not there/) => fails
|
45
|
+
def assert_contains(collection, x, extra_msg = "")
|
46
|
+
collection = [collection] unless collection.is_a?(Array)
|
47
|
+
msg = "#{x.inspect} not found in #{collection.to_a.inspect} #{extra_msg}"
|
48
|
+
case x
|
49
|
+
when Regexp: assert(collection.detect { |e| e =~ x }, msg)
|
50
|
+
else assert(collection.include?(x), msg)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Asserts that the given collection does not contain item x. If x is a regular expression, ensure that
|
55
|
+
# none of the elements from the collection match x.
|
56
|
+
def assert_does_not_contain(collection, x, extra_msg = "")
|
57
|
+
collection = [collection] unless collection.is_a?(Array)
|
58
|
+
msg = "#{x.inspect} found in #{collection.to_a.inspect} " + extra_msg
|
59
|
+
case x
|
60
|
+
when Regexp: assert(!collection.detect { |e| e =~ x }, msg)
|
61
|
+
else assert(!collection.include?(x), msg)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Asserts that the given object can be saved
|
66
|
+
#
|
67
|
+
# assert_save User.new(params)
|
68
|
+
def assert_save(obj)
|
69
|
+
assert obj.save, "Errors: #{pretty_error_messages obj}"
|
70
|
+
obj.reload
|
71
|
+
end
|
72
|
+
|
73
|
+
# Asserts that the given object is valid
|
74
|
+
#
|
75
|
+
# assert_valid User.new(params)
|
76
|
+
def assert_valid(obj)
|
77
|
+
assert obj.valid?, "Errors: #{pretty_error_messages obj}"
|
78
|
+
end
|
79
|
+
|
80
|
+
# Asserts that an email was delivered. Can take a block that can further
|
81
|
+
# narrow down the types of emails you're expecting.
|
82
|
+
#
|
83
|
+
# assert_sent_email
|
84
|
+
#
|
85
|
+
# Passes if ActionMailer::Base.deliveries has an email
|
86
|
+
#
|
87
|
+
# assert_sent_email do |email|
|
88
|
+
# email.subject =~ /hi there/ && email.to.include?('none@none.com')
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# Passes if there is an email with subject containing 'hi there' and
|
92
|
+
# 'none@none.com' as one of the recipients.
|
93
|
+
#
|
94
|
+
def assert_sent_email
|
95
|
+
emails = ActionMailer::Base.deliveries
|
96
|
+
assert !emails.empty?, "No emails were sent"
|
97
|
+
if block_given?
|
98
|
+
matching_emails = emails.select {|email| yield email }
|
99
|
+
assert !matching_emails.empty?, "None of the emails matched."
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Asserts that no ActionMailer mails were delivered
|
104
|
+
#
|
105
|
+
# assert_did_not_send_email
|
106
|
+
def assert_did_not_send_email
|
107
|
+
msg = "Sent #{ActionMailer::Base.deliveries.size} emails.\n"
|
108
|
+
ActionMailer::Base.deliveries.each { |m| msg << " '#{m.subject}' sent to #{m.to.to_sentence}\n" }
|
109
|
+
assert ActionMailer::Base.deliveries.empty?, msg
|
110
|
+
end
|
111
|
+
|
112
|
+
def pretty_error_messages(obj)
|
113
|
+
obj.errors.map { |a, m| "#{a} #{m} (#{obj.send(a).inspect})" }
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ThoughtBot # :nodoc:
|
2
|
+
module Shoulda # :nodoc:
|
3
|
+
module Private # :nodoc:
|
4
|
+
# Returns the values for the entries in the args hash who's keys are listed in the wanted array.
|
5
|
+
# Will raise if there are keys in the args hash that aren't listed.
|
6
|
+
def get_options!(args, *wanted)
|
7
|
+
ret = []
|
8
|
+
opts = (args.last.is_a?(Hash) ? args.pop : {})
|
9
|
+
wanted.each {|w| ret << opts.delete(w)}
|
10
|
+
raise ArgumentError, "Unsupported options given: #{opts.keys.join(', ')}" unless opts.keys.empty?
|
11
|
+
return *ret
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns the model class constant, as determined by the test class name.
|
15
|
+
#
|
16
|
+
# class TestUser; model_class; end => User
|
17
|
+
def model_class
|
18
|
+
self.name.gsub(/^Test/, '').constantize
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
desc "Import data into the database"
|
2
|
+
task :import do
|
3
|
+
# Acquire your data (e.g. from input/ or something) and parse it into
|
4
|
+
# your database. Your models should probably be the ones doing the heavy
|
5
|
+
# lifting on this one.
|
6
|
+
#
|
7
|
+
# Ex:
|
8
|
+
# Foo.import_yaml(FileList["input/*.yml"].to_a)
|
9
|
+
get_db_conn(ENV["GTRON_ENV"] || GTRON_ENV)
|
10
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper.rb'
|
2
|
+
|
3
|
+
class TestImport < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
get_db_conn(GTRON_ENV)
|
6
|
+
@rake = Rake::Application.new
|
7
|
+
Rake.application = @rake
|
8
|
+
load File.dirname(__FILE__) + '/../../tasks/import.rake'
|
9
|
+
end
|
10
|
+
|
11
|
+
should "import data" do
|
12
|
+
# Testing rake is a bit different
|
13
|
+
# http://blog.nicksieger.com/articles/2007/06/11/test-your-rake-tasks
|
14
|
+
# Example:
|
15
|
+
# @rake["task_name"].invoke
|
16
|
+
@rake["import"].invoke
|
17
|
+
assert true
|
18
|
+
end
|
19
|
+
|
20
|
+
def teardown
|
21
|
+
Rake.application = nil
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
require 'gigantron/migrator'
|
5
|
+
require File.dirname(__FILE__) + '/../initialize'
|
6
|
+
silence_warnings { GTRON_ENV = :test }
|
7
|
+
ENV['GTRON_ENV'] = 'test'
|
8
|
+
|
9
|
+
require 'shoulda'
|
10
|
+
require 'shoulda/private_helpers'
|
11
|
+
require 'shoulda/general'
|
12
|
+
require 'shoulda_active_record_helpers'
|
13
|
+
|
14
|
+
module Test
|
15
|
+
module Unit
|
16
|
+
class TestCase
|
17
|
+
include ThoughtBot::Shoulda::General
|
18
|
+
extend ThoughtBot::Shoulda::ActiveRecord
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
data/bin/gigantron
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rubigen'
|
3
|
+
|
4
|
+
if %w(-v --version).include? ARGV.first
|
5
|
+
require 'gigantron/version'
|
6
|
+
puts "#{File.basename($0)} #{Gigantron::VERSION::STRING}"
|
7
|
+
exit(0)
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'rubigen/scripts/generate'
|
11
|
+
source = RubiGen::PathSource.new(:application,
|
12
|
+
File.join(File.dirname(__FILE__), "../app_generators"))
|
13
|
+
RubiGen::Base.reset_sources
|
14
|
+
RubiGen::Base.append_sources source
|
15
|
+
RubiGen::Scripts::Generate.new.run(ARGV, :generator => 'gigantron')
|
data/config/hoe.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'gigantron/version'
|
2
|
+
|
3
|
+
AUTHOR = 'Ben Hughes' # can also be an array of Authors
|
4
|
+
EMAIL = "ben@pixelmachine.org"
|
5
|
+
DESCRIPTION = "description of gem"
|
6
|
+
GEM_NAME = 'gigantron' # what ppl will type to install your gem
|
7
|
+
RUBYFORGE_PROJECT = 'gigantron' # The unix name for your project
|
8
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
9
|
+
DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
|
10
|
+
EXTRA_DEPENDENCIES = [
|
11
|
+
['activesupport', '>= 2.0.2'],
|
12
|
+
['rubigen', '>= 1.3.2'],
|
13
|
+
['rake', '>= 0.8.1'],
|
14
|
+
['Shoulda', '>= 1.1.1'],
|
15
|
+
['activerecord', '>= 2.0.2'],
|
16
|
+
] # An array of rubygem dependencies [name, version]
|
17
|
+
|
18
|
+
@config_file = "~/.rubyforge/user-config.yml"
|
19
|
+
@config = nil
|
20
|
+
RUBYFORGE_USERNAME = "unknown"
|
21
|
+
def rubyforge_username
|
22
|
+
unless @config
|
23
|
+
begin
|
24
|
+
@config = YAML.load(File.read(File.expand_path(@config_file)))
|
25
|
+
rescue
|
26
|
+
puts <<-EOS
|
27
|
+
ERROR: No rubyforge config file found: #{@config_file}
|
28
|
+
Run 'rubyforge setup' to prepare your env for access to Rubyforge
|
29
|
+
- See http://newgem.rubyforge.org/rubyforge.html for more details
|
30
|
+
EOS
|
31
|
+
exit
|
32
|
+
end
|
33
|
+
end
|
34
|
+
RUBYFORGE_USERNAME.replace @config["username"]
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
REV = nil
|
39
|
+
# UNCOMMENT IF REQUIRED:
|
40
|
+
# REV = YAML.load(`svn info`)['Revision']
|
41
|
+
VERS = Gigantron::VERSION::STRING + (REV ? ".#{REV}" : "")
|
42
|
+
RDOC_OPTS = ['--quiet', '--title', 'gigantron documentation',
|
43
|
+
"--opname", "index.html",
|
44
|
+
"--line-numbers",
|
45
|
+
"--main", "README",
|
46
|
+
"--inline-source"]
|
47
|
+
|
48
|
+
|
49
|
+
class Hoe
|
50
|
+
silence_warnings do
|
51
|
+
RUBY_FLAGS = "-I#{%w(lib ext bin test).join(File::PATH_SEPARATOR)}" +
|
52
|
+
(ENV['RUBY_DEBUG'] ? " #{ENV['RUBY_DEBUG']}" : '')
|
53
|
+
end
|
54
|
+
def extra_deps
|
55
|
+
@extra_deps.reject! { |x| Array(x).first == 'hoe' }
|
56
|
+
@extra_deps
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Generate all the Rake tasks
|
61
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
62
|
+
$hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
63
|
+
p.developer(AUTHOR, EMAIL)
|
64
|
+
p.description = DESCRIPTION
|
65
|
+
p.summary = DESCRIPTION
|
66
|
+
p.url = HOMEPATH
|
67
|
+
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
68
|
+
p.test_globs = ["test/**/test_*.rb"]
|
69
|
+
p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
|
70
|
+
|
71
|
+
# == Optional
|
72
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
73
|
+
p.extra_deps = EXTRA_DEPENDENCIES
|
74
|
+
|
75
|
+
#p.spec_extras = {} # A hash of extra values to set in the gemspec.
|
76
|
+
end
|
77
|
+
|
78
|
+
CHANGES = $hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
|
79
|
+
PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
|
80
|
+
$hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
|
81
|
+
$hoe.rsync_args = '-av --delete --ignore-errors'
|
82
|
+
$hoe.spec.post_install_message = File.open(File.dirname(__FILE__) + "/../PostInstall.txt").read rescue ""
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
include FileUtils
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
%w[rake hoe newgem rubigen activerecord activesupport shoulda].each do |req_gem|
|
6
|
+
begin
|
7
|
+
require req_gem
|
8
|
+
rescue LoadError
|
9
|
+
puts "This Rakefile requires the '#{req_gem}' RubyGem."
|
10
|
+
puts "Installation: gem install #{req_gem} -y"
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
$:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class MapreduceTaskGenerator < RubiGen::Base
|
2
|
+
|
3
|
+
default_options :author => nil
|
4
|
+
|
5
|
+
attr_reader :name
|
6
|
+
|
7
|
+
def initialize(runtime_args, runtime_options = {})
|
8
|
+
super
|
9
|
+
usage if args.empty?
|
10
|
+
@name = args.shift
|
11
|
+
extract_options
|
12
|
+
end
|
13
|
+
|
14
|
+
def manifest
|
15
|
+
record do |m|
|
16
|
+
# Ensure appropriate folder(s) exists
|
17
|
+
m.directory 'test/'
|
18
|
+
m.directory 'test/tasks/'
|
19
|
+
m.template "test/tasks/test_task.rb", "test/tasks/test_#{@name}.rb"
|
20
|
+
m.directory 'tasks/'
|
21
|
+
m.template "tasks/task.rake", "tasks/#{@name}.rake"
|
22
|
+
m.directory 'mapreduce/'
|
23
|
+
m.template "mapreduce/mr_task.rb", "mapreduce/mr_#{@name}.rb"
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
def banner
|
30
|
+
<<-EOS
|
31
|
+
Creates a ...
|
32
|
+
|
33
|
+
USAGE: #{$0} #{spec.name} name
|
34
|
+
EOS
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_options!(opts)
|
38
|
+
# opts.separator ''
|
39
|
+
# opts.separator 'Options:'
|
40
|
+
# For each option below, place the default
|
41
|
+
# at the top of the file next to "default_options"
|
42
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
43
|
+
# "Some comment about this option",
|
44
|
+
# "Default: none") { |options[:author]| }
|
45
|
+
# opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
46
|
+
end
|
47
|
+
|
48
|
+
def extract_options
|
49
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
50
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
51
|
+
# raw instance variable value.
|
52
|
+
# @author = options[:author]
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class MapReduce<%= name.camelcase %>
|
2
|
+
include SkynetDebugger
|
3
|
+
|
4
|
+
def self.run
|
5
|
+
job = Skynet::Job.new(
|
6
|
+
:mappers => 2, #change to whatever is a good number
|
7
|
+
:reducers => 1, #same
|
8
|
+
:map_reduce_class => self,
|
9
|
+
:map_data => [] #acquire your data!
|
10
|
+
)
|
11
|
+
job.run
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.map(profiles)
|
15
|
+
#map code
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.reduce(pairs)
|
19
|
+
#reduce code
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper.rb'
|
2
|
+
|
3
|
+
class Test<%= name.camelcase %> < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
get_db_conn(GTRON_ENV)
|
6
|
+
@rake = Rake::Application.new
|
7
|
+
Rake.application = @rake
|
8
|
+
load File.dirname(__FILE__) + '/../../tasks/<%= name %>.rake'
|
9
|
+
end
|
10
|
+
|
11
|
+
should "be true" do
|
12
|
+
# Testing rake is a bit different
|
13
|
+
# http://blog.nicksieger.com/articles/2007/06/11/test-your-rake-tasks
|
14
|
+
# Example:
|
15
|
+
# @rake["task_name"].invoke
|
16
|
+
assert true
|
17
|
+
end
|
18
|
+
|
19
|
+
def teardown
|
20
|
+
Rake.application = nil
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class MigrationGenerator < RubiGen::Base
|
2
|
+
|
3
|
+
default_options :author => nil
|
4
|
+
|
5
|
+
attr_reader :name
|
6
|
+
|
7
|
+
def initialize(runtime_args, runtime_options = {})
|
8
|
+
super
|
9
|
+
usage if args.empty?
|
10
|
+
@name = args.shift
|
11
|
+
extract_options
|
12
|
+
end
|
13
|
+
|
14
|
+
def manifest
|
15
|
+
record do |m|
|
16
|
+
# Ensure appropriate folder(s) exists
|
17
|
+
m.directory "db/"
|
18
|
+
m.directory "db/migrate/"
|
19
|
+
m.template "db/migrate/migration.rb",
|
20
|
+
"db/migrate/#{next_migration_num}_#{name.underscore}.rb"
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
def banner
|
27
|
+
<<-EOS
|
28
|
+
Creates a ...
|
29
|
+
|
30
|
+
USAGE: #{$0} #{spec.name} name
|
31
|
+
EOS
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_options!(opts)
|
35
|
+
# opts.separator ''
|
36
|
+
# opts.separator 'Options:'
|
37
|
+
# For each option below, place the default
|
38
|
+
# at the top of the file next to "default_options"
|
39
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
40
|
+
# "Some comment about this option",
|
41
|
+
# "Default: none") { |options[:author]| }
|
42
|
+
# opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
43
|
+
end
|
44
|
+
|
45
|
+
def extract_options
|
46
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
47
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
48
|
+
# raw instance variable value.
|
49
|
+
# @author = options[:author]
|
50
|
+
end
|
51
|
+
|
52
|
+
def next_migration_num
|
53
|
+
#blegh, catalog existing migrations, find next
|
54
|
+
current = Dir.glob(
|
55
|
+
"#{@destination_root}/db/migrate/[0-9][0-9][0-9]_*.rb").map{|x|
|
56
|
+
/(\d{3})_.*\.rb/.match(x)[1].to_i
|
57
|
+
}.max
|
58
|
+
current ||= 0
|
59
|
+
"%03d" % current.succ
|
60
|
+
end
|
61
|
+
end
|