germinator 2.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.
- checksums.yaml +7 -0
- data/LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +32 -0
- data/lib/generators/germination_generator.rb +5 -0
- data/lib/generators/germinator_generator.rb +28 -0
- data/lib/generators/install_germinator_generator.rb +21 -0
- data/lib/germinator/base.rb +58 -0
- data/lib/germinator/errors.rb +19 -0
- data/lib/germinator/railtie.rb +11 -0
- data/lib/germinator/seed.rb +168 -0
- data/lib/germinator/seed_config.rb +22 -0
- data/lib/germinator/seed_file.rb +75 -0
- data/lib/germinator/seeder.rb +307 -0
- data/lib/germinator/version.rb +7 -0
- data/lib/germinator.rb +23 -0
- data/lib/tasks/germinator_tasks.rake +67 -0
- data/lib/templates/seed.rb +55 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +23 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +78 -0
- data/test/dummy/config/environments/test.rb +39 -0
- data/test/dummy/config/initializers/assets.rb +8 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +56 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/germinator_test.rb +7 -0
- data/test/test_helper.rb +18 -0
- metadata +170 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5c77e37d8984e4bd117b9aeee7ce37ff6489a893a6555fd9bdb693651f3d9f52
|
4
|
+
data.tar.gz: 1315177e453cb595934962910f474d2afe1e0e7f00f1f0735b8e8394578a58fc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d6fd1783842c26f8fa48dafd6e630ac56e37184187f4cc1ec80604443911a20b761c0f28ebb52e5c957121bb527a9e195c89064262e519a73ac16223b956b7d3
|
7
|
+
data.tar.gz: 216ba005a4b57b2a9ec1898316e66e512a6d4ee68c83a07c08a4c6d12f3e17689f1949ad035cd10f39afa393e471aff9787ee3b4398db9a3d7f178d0897e82dd
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2015 Wowza Media Systems, Inc.
|
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/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Germinator'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
Bundler::GemHelper.install_tasks
|
21
|
+
|
22
|
+
require 'rake/testtask'
|
23
|
+
|
24
|
+
Rake::TestTask.new(:test) do |t|
|
25
|
+
t.libs << 'lib'
|
26
|
+
t.libs << 'test'
|
27
|
+
t.pattern = 'test/**/*_test.rb'
|
28
|
+
t.verbose = false
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
task default: :test
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class GerminatorGenerator < Rails::Generators::Base
|
2
|
+
source_root File.expand_path('../../templates', __FILE__)
|
3
|
+
argument :seed_name, :type => :string, :default => nil
|
4
|
+
|
5
|
+
def build_seed_file
|
6
|
+
if seed_name.nil?
|
7
|
+
puts "You must provide a germinator seed name."
|
8
|
+
return
|
9
|
+
end
|
10
|
+
|
11
|
+
puts "Seed name: #{seed_name.underscore}"
|
12
|
+
name = seed_name.underscore
|
13
|
+
|
14
|
+
if Dir["#{Rails.root}/#{Germinator::SEED_PATH}/*_#{name}.rb"].length > 0
|
15
|
+
puts "The germinator seed name provided already exists. Please select another name."
|
16
|
+
return
|
17
|
+
end
|
18
|
+
|
19
|
+
timestamp = Time.now.strftime("%Y%m%d%H%M%S")
|
20
|
+
source_seed_file = "seed.rb"
|
21
|
+
destination_seed_file = "#{Rails.root}/#{Germinator::SEED_PATH}/#{timestamp}_#{name}.rb"
|
22
|
+
|
23
|
+
copy_file source_seed_file, destination_seed_file do |content|
|
24
|
+
content.gsub('%{class_name}', seed_name)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'germinator/base'
|
2
|
+
|
3
|
+
class InstallGerminatorGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path('../../..', __FILE__)
|
5
|
+
|
6
|
+
def add_germinator_version_table
|
7
|
+
Germinator::Base.confirm_database_table
|
8
|
+
end
|
9
|
+
|
10
|
+
def add_germinator_file_directory
|
11
|
+
file_directory = "#{Rails.root}/#{Germinator::SEED_PATH}"
|
12
|
+
puts "Building directory structure..."
|
13
|
+
unless File.directory?(file_directory)
|
14
|
+
empty_directory(file_directory)
|
15
|
+
puts " Added: #{file_directory}"
|
16
|
+
else
|
17
|
+
puts " Directory already exists: #{file_directory}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'germinator/version'
|
2
|
+
|
3
|
+
module Germinator
|
4
|
+
class Base
|
5
|
+
protected
|
6
|
+
##
|
7
|
+
# Override the puts method to add the ability to indent content in the output. This is a way of making it prettier for the
|
8
|
+
# console.
|
9
|
+
#
|
10
|
+
def puts content, indent=3
|
11
|
+
STDOUT.puts "#{(" "*indent)}#{content}"
|
12
|
+
end
|
13
|
+
|
14
|
+
##
|
15
|
+
# Helper to standardize the output for an error.
|
16
|
+
#
|
17
|
+
def puts_error e
|
18
|
+
puts "-"*80
|
19
|
+
puts e.message
|
20
|
+
e.backtrace.each do |trace|
|
21
|
+
puts trace
|
22
|
+
end
|
23
|
+
puts "-"*80
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Displays the configuration object values in the terminal.
|
28
|
+
#
|
29
|
+
def output_config seed
|
30
|
+
puts "Configuration: #{seed.config.to_hash}"
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
#
|
35
|
+
def self.confirm_database_table
|
36
|
+
ActiveRecord::Base.establish_connection
|
37
|
+
unless ActiveRecord::Base.connection.data_source_exists? Germinator::VERSION_2_TABLE_NAME
|
38
|
+
|
39
|
+
# Create the germinator_seeds table because it doesn't exist.
|
40
|
+
ActiveRecord::Base.connection.execute("CREATE TABLE `#{Germinator::VERSION_2_TABLE_NAME}` (`version` VARCHAR(20) NOT NULL, `name` VARCHAR(300) NOT NULL, `response` VARCHAR(40) NOT NULL, `message` VARCHAR(300))")
|
41
|
+
|
42
|
+
# Migrate the Version 1 Table to Version 2.
|
43
|
+
if ActiveRecord::Base.connection.data_source_exists? Germinator::VERSION_1_TABLE_NAME
|
44
|
+
# If the Version 1 germinator_migrations table still exists, copy its contents to the germinator_seeds table to keep the seeds in sync.
|
45
|
+
ActiveRecord::Base.connection.execute("INSERT INTO `#{Germinator::VERSION_2_TABLE_NAME}` (`version`, `name`, `response`, `message`) (SELECT version, '', 'Success', 'This entry was upgraded from Version 1' FROM `#{Germinator::VERSION_1_TABLE_NAME}` ORDER BY `version`)")
|
46
|
+
|
47
|
+
# Drop the old Version 1 table since it will no longer be used.
|
48
|
+
ActiveRecord::Base.connection.execute("DROP TABLE `#{Germinator::VERSION_1_TABLE_NAME}`")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
unless ActiveRecord::Base.connection.column_exists?(Germinator::VERSION_2_TABLE_NAME.to_sym, :configuration)
|
53
|
+
ActiveRecord::Base.connection.execute("ALTER TABLE `#{Germinator::VERSION_2_TABLE_NAME}` ADD `configuration` TEXT")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
module Germinator
|
3
|
+
module Errors
|
4
|
+
|
5
|
+
class Standard < StandardError; end
|
6
|
+
|
7
|
+
class InvalidSeedEnvironment < Standard
|
8
|
+
def message
|
9
|
+
"The current environment (#{Rails.env}) is not permitted to execute this seed."
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class InvalidSeedModel < Standard
|
14
|
+
def message
|
15
|
+
"The models designated in the seed configuration are not valid."
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'germinator/base'
|
2
|
+
require 'germinator/seed_config'
|
3
|
+
require 'germinator/errors'
|
4
|
+
|
5
|
+
module Germinator
|
6
|
+
##
|
7
|
+
# A base class for the seed files
|
8
|
+
#
|
9
|
+
class Seed < Germinator::Base
|
10
|
+
|
11
|
+
|
12
|
+
attr_reader :config, :response, :message
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@response = "Success"
|
16
|
+
@config = SeedConfig.new
|
17
|
+
configure @config
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# An overridable method that allows you to modify this seed's configuration
|
22
|
+
#
|
23
|
+
def configure c
|
24
|
+
# Set the environments configuration to the response from the
|
25
|
+
# environments method so that the file will be backward compatible.
|
26
|
+
c.environments = self.environments
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Specifies the commands to execute during a germinate process.
|
31
|
+
#
|
32
|
+
def germinate
|
33
|
+
# Do nothing for now.
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
##
|
38
|
+
# Specifies the commands to execute during a shrivel process.
|
39
|
+
#
|
40
|
+
def shrivel
|
41
|
+
# Do nothing for now.
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Either germinates or shrivles the database based on the direction specified.
|
46
|
+
#
|
47
|
+
# ==== Parameters:
|
48
|
+
#
|
49
|
+
# *direction* => The direction to execute. :up = germinate. :down = shrivel.
|
50
|
+
#
|
51
|
+
def migrate direction=:up
|
52
|
+
if is_valid_environment?
|
53
|
+
if models_are_valid?
|
54
|
+
begin
|
55
|
+
germinate if direction === :up
|
56
|
+
shrivel if direction === :down
|
57
|
+
rescue Exception => e
|
58
|
+
if config.stop_on_error
|
59
|
+
raise e
|
60
|
+
else
|
61
|
+
puts_error e
|
62
|
+
class_name = e.class.name
|
63
|
+
@response = class_name
|
64
|
+
@message = e.message
|
65
|
+
puts "Moving on..."
|
66
|
+
end
|
67
|
+
end
|
68
|
+
else
|
69
|
+
error = Germinator::Errors::InvalidSeedModel.new
|
70
|
+
@response = error.class.name.to_s.gsub(/Germinator\:\:Errors\:\:/,"")
|
71
|
+
@message = error.message
|
72
|
+
raise error
|
73
|
+
end
|
74
|
+
else
|
75
|
+
error = Germinator::Errors::InvalidSeedEnvironment.new
|
76
|
+
@response = error.class.name.to_s.gsub(/Germinator\:\:Errors\:\:/,"")
|
77
|
+
@message = error.message
|
78
|
+
raise error
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
##
|
84
|
+
# Specifies which environments the Seed instance is allowed to execute in.
|
85
|
+
#
|
86
|
+
# *DEPRECATED:* Please use the Seed#configure method to set the environments configuration.
|
87
|
+
#
|
88
|
+
def environments
|
89
|
+
return true
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
##
|
94
|
+
# Specifies the commands to execute during a plant process.
|
95
|
+
#
|
96
|
+
# *DEPRECATED:* Create a rake task to handle repeatable data manipulations.
|
97
|
+
#
|
98
|
+
def plant
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
private
|
103
|
+
##
|
104
|
+
# Determines if the current environment is an acceptable environment to execute this
|
105
|
+
# seed in.
|
106
|
+
#
|
107
|
+
def is_valid_environment?
|
108
|
+
envs = config.environments
|
109
|
+
return envs if !!envs == envs
|
110
|
+
return false unless envs.kind_of?(String) || envs.kind_of?(Array)
|
111
|
+
|
112
|
+
envs = [ envs ] if envs.kind_of?(String)
|
113
|
+
envs = envs.map{ |e| e.downcase }
|
114
|
+
|
115
|
+
envs.include?(Rails.env.downcase)
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
def models_are_valid?
|
120
|
+
valid_models = config.valid_models
|
121
|
+
return valid_models if !!valid_models == valid_models
|
122
|
+
return false unless valid_models.kind_of?(Hash)
|
123
|
+
|
124
|
+
puts "Validating models..."
|
125
|
+
|
126
|
+
valid_models.default = true
|
127
|
+
|
128
|
+
valid_models.each do |name, methods|
|
129
|
+
begin
|
130
|
+
model = Module.const_get(name.to_s.camelize)
|
131
|
+
return false unless model.is_a?(Class)
|
132
|
+
|
133
|
+
model.connection.schema_cache.clear!
|
134
|
+
model.reset_column_information
|
135
|
+
|
136
|
+
next if !!methods == methods
|
137
|
+
return false unless methods.kind_of?(Array)
|
138
|
+
|
139
|
+
methods.each do |method|
|
140
|
+
unless (model.column_names.include?(method.to_s) || model.instance_methods.include?(method.to_sym) || model.metaclass.instance_methods.include?(method.to_sym))
|
141
|
+
puts "Method #{method} does not exist for model #{name.to_s.camelize}", 6
|
142
|
+
return false
|
143
|
+
end
|
144
|
+
end
|
145
|
+
rescue NameError => e
|
146
|
+
puts "Model #{name.to_s.camelize} does not exist!", 6
|
147
|
+
puts_error(e)
|
148
|
+
return false
|
149
|
+
rescue Exception => e
|
150
|
+
puts ""
|
151
|
+
puts_error e
|
152
|
+
puts ""
|
153
|
+
return false
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
return true
|
158
|
+
end
|
159
|
+
|
160
|
+
private def ellipsisize(str, minimum_length=4,edge_length=3)
|
161
|
+
return self if str.length < minimum_length or str.length <= edge_length*2
|
162
|
+
edge = '.'*edge_length
|
163
|
+
mid_length = str.length - edge_length*2
|
164
|
+
str.gsub(/(#{edge}).{#{mid_length},}(#{edge})/, '\1...\2')
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Germinator
|
2
|
+
class SeedConfig
|
3
|
+
|
4
|
+
attr_accessor :stop_on_error, :stop_on_invalid_model, :environments, :valid_models
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@stop_on_error = false
|
8
|
+
@stop_on_invalid_model = false
|
9
|
+
@environments = true
|
10
|
+
@valid_models = true
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_hash
|
14
|
+
{
|
15
|
+
stop_on_error: @stop_on_error,
|
16
|
+
stop_on_invalid_model: @stop_on_invalid_model,
|
17
|
+
environments: @environments,
|
18
|
+
valid_models: @valid_models
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Germinator
|
2
|
+
|
3
|
+
|
4
|
+
##
|
5
|
+
# A helper class to parse a seed file name and return the appropriate
|
6
|
+
# values
|
7
|
+
#
|
8
|
+
class SeedFile
|
9
|
+
require 'pathname'
|
10
|
+
|
11
|
+
attr_reader :path
|
12
|
+
|
13
|
+
##
|
14
|
+
# Inititalize the class instance.
|
15
|
+
#
|
16
|
+
# ==== Parameters:
|
17
|
+
#
|
18
|
+
# *path* => The full path of the seed file being parsed.
|
19
|
+
#
|
20
|
+
def initialize path
|
21
|
+
@path = path
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
##
|
26
|
+
# Returns the base file name of the seed file.
|
27
|
+
#
|
28
|
+
def basename
|
29
|
+
Pathname.new(@path).basename.to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
##
|
34
|
+
# Returns the version portion of the seed file.
|
35
|
+
#
|
36
|
+
def version
|
37
|
+
parts = basename.split('_', 2)
|
38
|
+
return "" if parts.length === 0
|
39
|
+
return parts[0]
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
##
|
44
|
+
# Returns the name portion of the seed file.
|
45
|
+
#
|
46
|
+
def name
|
47
|
+
parts = basename.split('_', 2)
|
48
|
+
return "" if parts.length <= 1
|
49
|
+
return parts[1].gsub(/\.rb/, "").to_s
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
##
|
54
|
+
# Returns the full seed name of the seed file (no path or extension).
|
55
|
+
def seed_name
|
56
|
+
"#{version}_#{name}"
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
##
|
61
|
+
# Returns the name of the class for the seed file.
|
62
|
+
#
|
63
|
+
def class_name
|
64
|
+
name.camelize
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
##
|
69
|
+
# Override the to_s method to make it more readable.
|
70
|
+
#
|
71
|
+
def to_s
|
72
|
+
"[#{version}] #{class_name}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|