my_enginery 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data/.gitignore +18 -0
  2. data/.travis.yml +9 -0
  3. data/CHANGELOG.md +14 -0
  4. data/Gemfile +12 -0
  5. data/LICENSE +19 -0
  6. data/README.md +957 -0
  7. data/Rakefile +48 -0
  8. data/app/base/.pryrc +1 -0
  9. data/app/base/Gemfile +25 -0
  10. data/app/base/Rakefile +4 -0
  11. data/app/base/app.rb +8 -0
  12. data/app/base/base/boot.rb +45 -0
  13. data/app/base/base/config.rb +127 -0
  14. data/app/base/base/controllers/rear-controllers/.gitkeep +0 -0
  15. data/app/base/base/database.rb +3 -0
  16. data/app/base/base/helpers/application_helpers.rb +3 -0
  17. data/app/base/base/migrations/.gitkeep +0 -0
  18. data/app/base/base/models/.gitkeep +0 -0
  19. data/app/base/base/specs/.gitkeep +0 -0
  20. data/app/base/base/views/.gitkeep +0 -0
  21. data/app/base/config.ru +4 -0
  22. data/app/base/config/config.yml +17 -0
  23. data/app/base/public/assets/Enginery.png +0 -0
  24. data/app/base/public/assets/Espresso.png +0 -0
  25. data/app/base/public/assets/application.css +13 -0
  26. data/app/base/public/assets/application.js +2 -0
  27. data/app/base/public/assets/bootstrap/css/bootstrap-responsive.min.css +9 -0
  28. data/app/base/public/assets/bootstrap/css/bootstrap.min.css +9 -0
  29. data/app/base/public/assets/bootstrap/img/glyphicons-halflings-white.png +0 -0
  30. data/app/base/public/assets/bootstrap/img/glyphicons-halflings.png +0 -0
  31. data/app/base/public/assets/bootstrap/js/bootstrap.min.js +6 -0
  32. data/app/base/public/assets/jquery.js +6 -0
  33. data/app/base/var/db/.gitkeep +0 -0
  34. data/app/base/var/log/.gitkeep +0 -0
  35. data/app/base/var/pid/.gitkeep +0 -0
  36. data/app/database/ActiveRecord.rb +11 -0
  37. data/app/database/DataMapper.rb +11 -0
  38. data/app/database/Sequel.rb +11 -0
  39. data/app/database/mysql.yml +24 -0
  40. data/app/database/postgres.yml +24 -0
  41. data/app/database/sqlite.yml +24 -0
  42. data/app/gemfiles/ActiveRecord.rb +1 -0
  43. data/app/gemfiles/BlueCloth.rb +1 -0
  44. data/app/gemfiles/DataMapper.rb +1 -0
  45. data/app/gemfiles/FastCGI.rb +1 -0
  46. data/app/gemfiles/Puma.rb +1 -0
  47. data/app/gemfiles/RDiscount.rb +1 -0
  48. data/app/gemfiles/RDoc.rb +1 -0
  49. data/app/gemfiles/RedCloth.rb +1 -0
  50. data/app/gemfiles/WEBrick.rb +1 -0
  51. data/app/gemfiles/WikiCloth.rb +1 -0
  52. data/app/gemfiles/mysql/ActiveRecord.rb +1 -0
  53. data/app/gemfiles/mysql/DataMapper.rb +1 -0
  54. data/app/gemfiles/mysql/Sequel.rb +1 -0
  55. data/app/gemfiles/postgres/ActiveRecord.rb +1 -0
  56. data/app/gemfiles/postgres/DataMapper.rb +1 -0
  57. data/app/gemfiles/postgres/Sequel.rb +1 -0
  58. data/app/gemfiles/sqlite/ActiveRecord.rb +1 -0
  59. data/app/gemfiles/sqlite/DataMapper.rb +1 -0
  60. data/app/gemfiles/sqlite/Sequel.rb +1 -0
  61. data/app/layouts/ERB/layout.erb +56 -0
  62. data/app/layouts/Erubis/layout.erb +56 -0
  63. data/app/layouts/Haml/layout.haml +38 -0
  64. data/app/layouts/Slim/layout.slim +38 -0
  65. data/app/migrations/ActiveRecord.erb +51 -0
  66. data/app/migrations/DataMapper.erb +61 -0
  67. data/app/migrations/Sequel.erb +54 -0
  68. data/app/migrations/tracking_table/ActiveRecord.rb +19 -0
  69. data/app/migrations/tracking_table/DataMapper.rb +26 -0
  70. data/app/migrations/tracking_table/Sequel.rb +18 -0
  71. data/app/rakefiles/ActiveRecord.rb +0 -0
  72. data/app/rakefiles/DataMapper.rb +1 -0
  73. data/app/rakefiles/Sequel.rb +0 -0
  74. data/app/rakefiles/Specular.rb +1 -0
  75. data/app/specfiles/Specular.erb +7 -0
  76. data/bin/my_enginery +235 -0
  77. data/lib/enginery.rb +23 -0
  78. data/lib/enginery/cli.rb +44 -0
  79. data/lib/enginery/configurator.rb +139 -0
  80. data/lib/enginery/delete.rb +116 -0
  81. data/lib/enginery/enginery.rb +41 -0
  82. data/lib/enginery/generator.rb +325 -0
  83. data/lib/enginery/helpers/app.rb +83 -0
  84. data/lib/enginery/helpers/generic.rb +145 -0
  85. data/lib/enginery/helpers/input.rb +123 -0
  86. data/lib/enginery/helpers/orm.rb +86 -0
  87. data/lib/enginery/helpers/validations.rb +101 -0
  88. data/lib/enginery/migrator.rb +371 -0
  89. data/lib/enginery/rake-tasks/data_mapper.rb +49 -0
  90. data/lib/enginery/rake-tasks/specular.rb +41 -0
  91. data/lib/enginery/registry.rb +101 -0
  92. data/lib/enginery/usage.rb +66 -0
  93. data/lib/enginery/version.rb +7 -0
  94. data/logo.png +0 -0
  95. data/my_enginery.gemspec +37 -0
  96. data/test/delete/test__admin.rb +49 -0
  97. data/test/delete/test__controller.rb +37 -0
  98. data/test/delete/test__helper.rb +49 -0
  99. data/test/delete/test__migration.rb +27 -0
  100. data/test/delete/test__model.rb +35 -0
  101. data/test/delete/test__route.rb +35 -0
  102. data/test/delete/test__spec.rb +59 -0
  103. data/test/delete/test__view.rb +51 -0
  104. data/test/generator/test__admin.rb +39 -0
  105. data/test/generator/test__controller.rb +123 -0
  106. data/test/generator/test__helper.rb +56 -0
  107. data/test/generator/test__model.rb +206 -0
  108. data/test/generator/test__project.rb +81 -0
  109. data/test/generator/test__route.rb +110 -0
  110. data/test/generator/test__spec.rb +56 -0
  111. data/test/generator/test__view.rb +85 -0
  112. data/test/migrator/test__auto_generation.rb +41 -0
  113. data/test/migrator/test__manual_generation.rb +59 -0
  114. data/test/migrator/test__migrations.rb +139 -0
  115. data/test/sandbox/.gitkeep +0 -0
  116. data/test/setup.rb +29 -0
  117. data/test/support/spec_helpers.rb +151 -0
  118. metadata +392 -0
@@ -0,0 +1,19 @@
1
+ ActiveRecord::Migration.verbose = false
2
+
3
+ module Enginery
4
+ class Migrator
5
+ class TracksMigrator < ActiveRecord::Migration
6
+ def up
7
+ return if table_exists?(TRACKING_TABLE)
8
+ create_table TRACKING_TABLE do |t|
9
+ TRACKING_TABLE__COLUMNS.each {|c| t.string(c, limit: 255)}
10
+ end
11
+ TRACKING_TABLE__INDEXES.each {|c| add_index(TRACKING_TABLE, c)}
12
+ end
13
+ end
14
+
15
+ class TracksModel < ActiveRecord::Base
16
+ self.table_name = TRACKING_TABLE
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ require 'dm-migrations'
2
+
3
+ module Enginery
4
+ class Migrator
5
+ TracksMigrator = DataMapper::Migration.new 0, TRACKING_TABLE do
6
+ @verbose = false
7
+ up do
8
+ unless DataMapper.repository(repository).adapter.storage_exists?(TRACKING_TABLE.to_s)
9
+ create_table TRACKING_TABLE do
10
+ column :id, Integer, serial: true
11
+ TRACKING_TABLE__COLUMNS.each {|c| column c, String, length: 255}
12
+ end
13
+ TRACKING_TABLE__INDEXES.each {|c| create_index(TRACKING_TABLE, c)}
14
+ end
15
+ end
16
+ end
17
+
18
+ class TracksModel
19
+ include DataMapper::Resource
20
+ repositories.each {|r| storage_names[r.name] = TRACKING_TABLE}
21
+ property :id, Serial
22
+ TRACKING_TABLE__COLUMNS.each {|c| property c, String, length: 255}
23
+ end
24
+ DataMapper.finalize
25
+ end
26
+ end
@@ -0,0 +1,18 @@
1
+ Sequel.extension :migration
2
+
3
+ module Enginery
4
+ class Migrator
5
+ TracksMigrator = Sequel.migration do
6
+ up do
7
+ create_table? TRACKING_TABLE do
8
+ primary_key :id
9
+ TRACKING_TABLE__COLUMNS.each {|c| column c, String, size: 255}
10
+ TRACKING_TABLE__INDEXES.each {|c| index c}
11
+ end
12
+ end
13
+ end
14
+
15
+ class TracksModel < Sequel::Model(TRACKING_TABLE)
16
+ end
17
+ end
18
+ end
File without changes
@@ -0,0 +1 @@
1
+ require 'enginery/rake-tasks/data_mapper'
File without changes
@@ -0,0 +1 @@
1
+ require 'enginery/rake-tasks/specular'
@@ -0,0 +1,7 @@
1
+
2
+ Spec.new "#{ @spec }" do
3
+ map #{ @controller }[:#{ @action }]
4
+
5
+ get
6
+ is(last_response).ok?
7
+ end
data/bin/my_enginery ADDED
@@ -0,0 +1,235 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optparse'
3
+
4
+ $:.unshift File.expand_path('../../lib', __FILE__)
5
+ require 'enginery'
6
+ require 'enginery/usage'
7
+
8
+ root, operation = Dir.pwd, $*[0].to_s
9
+
10
+ OptionParser.new do |o|
11
+ o.on '-h' do
12
+ puts Enginery.usage
13
+ exit 0
14
+ end
15
+ o.on '-v' do
16
+ puts EngineryVersion::FULL
17
+ exit 0
18
+ end
19
+ o.on '-c', "Display controllers in YAML format" do
20
+ puts Enginery::Registry.new(root).controllers
21
+ exit 0
22
+ end
23
+ o.on '-m', "Display models in YAML format" do
24
+ puts Enginery::Registry.new(root).models
25
+ exit 0
26
+ end
27
+ end.parse!
28
+
29
+ cli = Enginery::CLI.new
30
+ result = catch :enginery_failures do
31
+
32
+ case
33
+ when operation[0] == 'g'
34
+
35
+ unit = operation.sub(/\Ag(enerate)?\W?/, '')
36
+ args, setups, string_setups = Enginery::Helpers.parse_input(*$*[1..-1])
37
+ generator = Enginery::Generator.new(root, setups)
38
+
39
+ if args
40
+ if unit.empty? # generating application
41
+ if generator.generate_project(args[0])
42
+ Dir.chdir generator.dst_root do
43
+ cli.bundle :install
44
+ cli.new_controller 'Index', 'r:/' # generating Index controller
45
+ end
46
+ end
47
+ else
48
+
49
+ generator.fail_unless_in_app_folder!
50
+ generator.load_boot_rb # loading application
51
+
52
+ case
53
+ when unit =~ /\Ac(ontroller)?/
54
+ if args.size > 1 # generate multiple controllers
55
+ args.each {|c| cli.new_controller(c, string_setups)}
56
+ else
57
+ # generating controller
58
+ if generator.generate_controller(args[0])
59
+ # generating helper file
60
+ cli.new_helper args[0]
61
+
62
+ # generating index route
63
+ cli.new_route args[0], :index
64
+ end
65
+ end
66
+
67
+ when unit =~ /\Ar(oute)?/
68
+ if args.size > 2 # generate multiple routes
69
+ args[1..-1].each {|r| cli.new_route(args[0], r, string_setups)}
70
+ else
71
+ if generator.generate_route(*args)
72
+ # generating view file
73
+ cli.new_view *args[0..1]
74
+
75
+ # generating spec file
76
+ cli.new_spec *args[0..1]
77
+ end
78
+ end
79
+
80
+ when unit =~ /\As(pec)?/
81
+ if args.size > 2 # generate multiple specs
82
+ args[1..-1].each {|s| cli.new_spec(args[0], s, string_setups)}
83
+ else
84
+ generator.generate_spec(*args)
85
+ end
86
+
87
+ when unit =~ /\Ah(elper)?/
88
+ generator.generate_helper(*args)
89
+
90
+ when unit =~ /\Av(iew)?/
91
+ generator.generate_view(args[0], args[1])
92
+
93
+ when unit =~ /\Aa(dmin)?(_c(ontroller)?)?/
94
+ generator.generate_rear_controller(args[0])
95
+
96
+ when unit =~ /\Am(odel)?/
97
+ if args.size > 1 # generate multiple models
98
+ args.each {|m| cli.new_model(m, string_setups)}
99
+ else
100
+ if generator.generate_model(args[0])
101
+ cli.new_migration "initializing-#{args[0]}-model", "create_table_for:#{args[0]}", string_setups
102
+ cli.new_admin args[0]
103
+ end
104
+ end
105
+ end
106
+
107
+ end
108
+ end
109
+
110
+ when operation[0] == 'm'
111
+
112
+ operation = operation.sub(/\Am(igrat(e)?(ion)?)?(\W+)?/, '')
113
+ args, setups, string_setups = Enginery::Helpers.parse_input(*$*[1..-1])
114
+ migrator = Enginery::Migrator.new(root, setups)
115
+
116
+ migrator.fail_unless_in_app_folder!
117
+ migrator.load_boot_rb # loading application
118
+
119
+ if operation.empty? || operation =~ /\An(ew)?/ # new migration
120
+ migrator.new args[0]
121
+ elsif operation =~ /\Al(ist)?/
122
+ migrator.list
123
+ else
124
+ vector, extra = operation.scan(/(\w+)\:?(\w+)?/).flatten
125
+ force_run, force_yes = extra ? [extra.match(/\Af/i), extra.match(/\Ay/i)] : []
126
+
127
+ if file = setups[:file]
128
+ migrator.run(vector, file, force_run)
129
+ else
130
+ files = migrator.serials_to_files(vector, *args)
131
+
132
+ if files.empty?
133
+ outstanding_files = migrator.outstanding_migrations(vector)
134
+
135
+ if force_yes
136
+ files = outstanding_files
137
+ else
138
+ puts 'This will run all outstanding migrations in the following order:'
139
+ puts
140
+ puts outstanding_files.map {|f| f[/\A\d+/]}*' '
141
+ puts
142
+ puts ' Type Y and press enter to continue'
143
+ puts ' Press enter to cancel'
144
+ puts ' Use :yes options to get rid of this prompt - enginery m:%s:yes ...' % vector
145
+ answer = STDIN.gets.strip
146
+ files = outstanding_files if answer.match(/\Ay/i)
147
+ end
148
+ end
149
+
150
+ if files.empty?
151
+ puts
152
+ puts 'Nothing to run, exiting'
153
+ puts
154
+ exit 0
155
+ end
156
+
157
+ failed = false
158
+ files.each do |file|
159
+ (puts('', ' %s skipped due to previous errors' % file, ''); next) if failed
160
+ passed = cli.run_migration(vector, force_run, file, string_setups)
161
+ failed = true unless passed
162
+ end
163
+ puts
164
+ exit(1) if failed
165
+
166
+ end
167
+ end
168
+
169
+ when operation[0..5] == 'delete'
170
+
171
+ operation = operation.sub(/\Ad(elete)?(\W+)?/, '')
172
+ unit, extra = operation.scan(/(\w+)\:?(\w+)?/).flatten
173
+ force_run, force_yes = extra ? [extra.match(/\Af/i), extra.match(/\Ay/i)] : []
174
+ args, setups, string_setups = Enginery::Helpers.parse_input(*$*[1..-1])
175
+
176
+ case
177
+ when unit =~ /\Ac(ontroller)?/
178
+ delete_meth, delete_args, required_args = :controller, args[0..0], 1
179
+ when unit =~ /\Ar(oute)?/
180
+ delete_meth, delete_args, required_args = :route, args[0..1], 2
181
+ when unit =~ /\Av(iew)?/
182
+ delete_meth, delete_args, required_args = :view, args[0..1], 2
183
+ when unit =~ /\As(pec)?/
184
+ delete_meth, delete_args, required_args = :spec, args[0..1], 2
185
+ when unit =~ /\Ah(elper)?/
186
+ delete_meth, delete_args, required_args = :helper, args[0..0], 1
187
+ when unit =~ /\Aa(dmin)?(_c(ontroller)?)?/
188
+ delete_meth, delete_args, required_args = :rear_controller, args[0..0], 1
189
+ when unit =~ /\Amo(del)?/
190
+ delete_meth, delete_args, required_args = :model, args[0..0], 1
191
+ when unit =~ /\Ami(gration)?/
192
+ delete_meth, delete_args, required_args = :migration, args[0..0], 1
193
+ else
194
+ delete_meth = nil
195
+ end
196
+
197
+ if delete_meth
198
+ delete_args.size == required_args ||
199
+ Enginery::Helpers.fail('Please provide %s name' % delete_meth)
200
+
201
+ unless run = force_run || force_yes
202
+ puts
203
+ puts ' You are about to delete "%s" %s!' % [delete_args*"#", delete_meth]
204
+ puts
205
+ puts ' This action can not be undone!'
206
+ puts
207
+ puts ' Type Y and press enter to Continue'
208
+ puts ' Press enter to Abort'
209
+ puts ' Use :yes options to get rid of this prompt - enginery d:%s:yes ...' % unit
210
+ answer = STDIN.gets.strip
211
+ run = true if answer.match(/\Ay/i)
212
+ end
213
+ if run
214
+ delete = Enginery::Delete.new(root)
215
+ delete.load_boot_rb
216
+ delete.send delete_meth, *delete_args
217
+ end
218
+ else
219
+ Enginery::Helpers.fail '--- Unknown unit "%s" ---' % unit
220
+ end
221
+
222
+ else
223
+ puts "\n--- Unknown modifier %s ---\n" % operation.split(':').first
224
+ puts "use one of g[enerate], m[igration], delete\n"
225
+ puts Enginery.usage
226
+ exit 1
227
+ end
228
+ end
229
+
230
+ if result.is_a?(Enginery::Failure)
231
+ puts '', ' *** Operation FAILED ***'
232
+ result.failures.each {|f| puts ' %s' % f}
233
+ puts
234
+ exit 1
235
+ end
data/lib/enginery.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'fileutils'
2
+ require 'logger'
3
+ require 'yaml'
4
+ require 'date'
5
+ require 'pty'
6
+
7
+ require 'e'
8
+ require 'tenjin'
9
+
10
+ require 'enginery/enginery'
11
+
12
+ require 'enginery/helpers/app'
13
+ require 'enginery/helpers/generic'
14
+ require 'enginery/helpers/input'
15
+ require 'enginery/helpers/orm'
16
+ require 'enginery/helpers/validations'
17
+
18
+ require 'enginery/configurator'
19
+ require 'enginery/generator'
20
+ require 'enginery/migrator'
21
+ require 'enginery/delete'
22
+ require 'enginery/registry'
23
+ require 'enginery/cli'
@@ -0,0 +1,44 @@
1
+ module Enginery
2
+ class CLI
3
+ include Enginery::Helpers
4
+
5
+ %w[controller route helper view spec model admin].each do |unit|
6
+ define_method 'new_' + unit do |*args|
7
+ run '"%s" g:%s %s' % [executable, unit, args.flatten*' ']
8
+ end
9
+ end
10
+
11
+ def new_migration *args
12
+ run '"%s" m %s' % [executable, args.flatten*' ']
13
+ end
14
+
15
+ def run_migration vector, force_run, file, setups
16
+ run '"%s" m:%s:%s f:%s %s' % [executable, vector, force_run, file, setups]
17
+ end
18
+
19
+ def bundle task
20
+ run 'bundle %s' % task, output_cmd: true
21
+ end
22
+
23
+ def executable
24
+ $0
25
+ end
26
+
27
+ def run cmd, opts = {}
28
+ opts[:output_cmd] && (o; o(cmd))
29
+ PTY.spawn cmd do |r, w, pid|
30
+ begin
31
+ r.sync
32
+ r.each_line do |line|
33
+ o line.rstrip!
34
+ end
35
+ rescue Errno::EIO # simply ignoring this
36
+ ensure
37
+ ::Process.wait pid
38
+ end
39
+ end
40
+ $? && $?.exitstatus == 0
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,139 @@
1
+ module Enginery
2
+ class Configurator
3
+ include Helpers
4
+
5
+ def initialize dst_root, setups = {}, &proc
6
+ @dst_root, @setups = dst_root, setups||{}
7
+ @setups.is_a?(Hash) || fail('setups should be a Hash. A %s given instead' % @setups.class)
8
+ self.instance_exec(&proc) if block_given?
9
+ end
10
+
11
+ def update_config_yml
12
+ setups = normalize_setups(@setups)
13
+
14
+ setups.delete 'db'
15
+
16
+ engine = setups['engine'] || EConstants::VIEW__DEFAULT_ENGINE_NAME
17
+ path = src_path(:layouts, engine)
18
+ if File.directory?(path)
19
+ Dir[path + '/*'].each {|f| FileUtils.cp(f, dst_path.views)}
20
+ setups['layout'] = 'layout'
21
+ end
22
+
23
+ return if setups.empty?
24
+
25
+ yml = YAML.load File.read(dst_path.config_yml)
26
+ ENVIRONMENTS.each do |env|
27
+ (cfg = yml[env] || yml[env.to_s]) && cfg.update(setups)
28
+ end
29
+ o
30
+ write_file dst_path.config_yml, YAML.dump(yml)
31
+ output_source_code YAML.dump(setups).split("\n")
32
+ end
33
+
34
+ def update_gemfile
35
+ return if @setups.empty?
36
+
37
+ gems, gemfiles = [], []
38
+ target_gems = File.file?(dst_path.Gemfile) ?
39
+ extract_gems(File.read dst_path.Gemfile) : []
40
+
41
+ @setups.values_at(:orm, :engine, :server).compact.each do |klass|
42
+ gemfiles << [src_path(:gemfiles, '%s.rb' % klass), klass]
43
+ end
44
+ if orm = @setups[:orm]
45
+ db_type = (@setups[:db]||{})[:type] || DEFAULT_DB_TYPE
46
+ gemfiles << [src_path(:gemfiles, db_type, '%s.rb' % orm)]
47
+ end
48
+ gemfiles.each do |(gemfile,gem)|
49
+ if File.file?(gemfile)
50
+ File.readlines(gemfile).each do |l|
51
+ extract_gems(l).each do |g|
52
+ gems << l.chomp unless target_gems.include?(g)
53
+ end
54
+ end
55
+ else
56
+ next unless gem
57
+ gem = class_to_gem(gem)
58
+ gems << ("gem '%s'" % gem) unless target_gems.include?(gem)
59
+ end
60
+ end
61
+ return if gems.empty?
62
+ o
63
+ source_code = ['', *gems, '']
64
+ update_file dst_path.Gemfile, source_code.join("\n")
65
+ output_source_code source_code
66
+ end
67
+
68
+ def update_rakefile
69
+ test_framework = @setups[:test_framework] || DEFAULT_TEST_FRAMEWORK
70
+ source_file = src_path(:rakefiles, "#{test_framework}.rb")
71
+ unless File.file?(source_file)
72
+ o("%s not in the list of supported test frameworks: %s" % [
73
+ test_framework,
74
+ Dir[src_path(:rakefiles, '*.rb')].map {|f| f.sub(/\.rb\Z/, '')}*', '
75
+ ])
76
+ end
77
+ source_code = File.readlines(source_file)
78
+
79
+ if orm = @setups[:orm]
80
+ source_file = src_path(:rakefiles, '%s.rb' % orm)
81
+ source_code.concat File.readlines(source_file)
82
+ end
83
+ o
84
+ update_file dst_path.Rakefile, source_code
85
+ output_source_code(source_code)
86
+ end
87
+
88
+ def update_boot_rb
89
+ end
90
+
91
+ def update_database_rb
92
+ if orm = @setups[:orm]
93
+ source_file = src_path(:database, '%s.rb' % orm)
94
+ source_code = File.readlines(source_file)
95
+ o
96
+ update_file dst_path.database_rb, source_code
97
+ output_source_code(source_code)
98
+ end
99
+ end
100
+
101
+ def update_database_yml
102
+ setups = normalize_setups(@setups[:db])
103
+ type = setups['type'] || DEFAULT_DB_TYPE
104
+ yml = YAML.load File.read(src_path(:database, '%s.yml' % type))
105
+ ENVIRONMENTS.each do |env|
106
+ (cfg = yml[env] || yml[env.to_s]) && cfg.update(setups)
107
+ end
108
+ o
109
+ write_file dst_path.database_yml, YAML.dump(yml)
110
+ setups['pass'] = '___________' if setups['pass']
111
+ output_source_code(YAML.dump(setups).split("\n")) if setups.any?
112
+ end
113
+
114
+ private
115
+ def class_to_gem klass
116
+ underscore klass.to_s
117
+ end
118
+
119
+ def extract_gems string
120
+ string.split("\n").inject([]) do |gems,l|
121
+ l.strip!
122
+ (l =~ /\Agem/) &&
123
+ (gem = l.scan(/\Agem\s+([^,]*)/).flatten.first) &&
124
+ (gems << gem.gsub(/\A\W+|\W+\Z/, ''))
125
+ gems
126
+ end
127
+ end
128
+
129
+ def normalize_setups setups = {}
130
+ (setups||{}).inject({}) do |s,(k,v)|
131
+ key, val = k.to_s, v
132
+ val = val.to_i if v.respond_to?(:match) && v.match(/\A\d+\Z/)
133
+ val = val.to_s if val.is_a?(Symbol)
134
+ s.merge key => val
135
+ end
136
+ end
137
+
138
+ end
139
+ end