my_enginery 0.2.8

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.
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