padrino-gen 0.9.14 → 0.9.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/LICENSE +1 -1
  2. data/README.rdoc +17 -2
  3. data/Rakefile +1 -2
  4. data/bin/padrino-gen +2 -3
  5. data/lib/padrino-gen.rb +2 -2
  6. data/lib/padrino-gen/generators/actions.rb +62 -8
  7. data/lib/padrino-gen/generators/app.rb +2 -1
  8. data/lib/padrino-gen/generators/cli.rb +3 -3
  9. data/lib/padrino-gen/generators/components/orms/activerecord.rb +10 -9
  10. data/lib/padrino-gen/generators/components/orms/couchrest.rb +1 -1
  11. data/lib/padrino-gen/generators/components/orms/datamapper.rb +11 -9
  12. data/lib/padrino-gen/generators/components/orms/mongoid.rb +1 -1
  13. data/lib/padrino-gen/generators/components/orms/mongomapper.rb +1 -1
  14. data/lib/padrino-gen/generators/components/orms/mongomatic.rb +85 -0
  15. data/lib/padrino-gen/generators/components/orms/ohm.rb +72 -0
  16. data/lib/padrino-gen/generators/components/orms/sequel.rb +12 -11
  17. data/lib/padrino-gen/generators/components/renderers/erubis.rb +3 -0
  18. data/lib/padrino-gen/generators/components/renderers/liquid.rb +4 -0
  19. data/lib/padrino-gen/generators/components/stylesheets/compass.rb +3 -3
  20. data/lib/padrino-gen/generators/components/stylesheets/compass/application.scss +1 -1
  21. data/lib/padrino-gen/generators/components/stylesheets/less.rb +12 -23
  22. data/lib/padrino-gen/generators/components/stylesheets/sass.rb +6 -16
  23. data/lib/padrino-gen/generators/components/stylesheets/scss.rb +16 -0
  24. data/lib/padrino-gen/generators/components/tests/riot.rb +5 -23
  25. data/lib/padrino-gen/generators/controller.rb +1 -1
  26. data/lib/padrino-gen/generators/mailer.rb +3 -1
  27. data/lib/padrino-gen/generators/migration.rb +1 -1
  28. data/lib/padrino-gen/generators/model.rb +1 -1
  29. data/lib/padrino-gen/generators/plugin.rb +47 -0
  30. data/lib/padrino-gen/generators/project.rb +39 -22
  31. data/lib/padrino-gen/generators/project/config/boot.rb +12 -0
  32. data/lib/padrino-gen/generators/runner.rb +90 -0
  33. data/lib/padrino-gen/generators/templates/initializer.rb.tt +5 -0
  34. data/lib/padrino-gen/generators/templates/mailer.rb.tt +10 -0
  35. data/lib/padrino-gen/padrino-tasks/datamapper.rb +8 -7
  36. data/padrino-gen.gemspec +11 -12
  37. data/test/fixtures/admin_template.rb +7 -0
  38. data/test/fixtures/example_template.rb +14 -0
  39. data/test/fixtures/git_template.rb +4 -0
  40. data/test/fixtures/plugin_template.rb +13 -0
  41. data/test/fixtures/rake_template.rb +9 -0
  42. data/test/helper.rb +64 -2
  43. data/test/test_app_generator.rb +16 -1
  44. data/test/test_controller_generator.rb +1 -1
  45. data/test/test_generator.rb +1 -1
  46. data/test/test_mailer_generator.rb +11 -1
  47. data/test/test_model_generator.rb +64 -20
  48. data/test/test_plugin_generator.rb +123 -0
  49. data/test/test_project_generator.rb +134 -77
  50. metadata +37 -103
data/LICENSE CHANGED
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
17
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
18
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
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.
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc CHANGED
@@ -10,7 +10,7 @@ as possible, supporting a myriad of test frameworks, js libraries, mocking libra
10
10
  See the guide for {Padrino Generators}[http://www.padrinorb.com/guides/generators] for a
11
11
  more in-depth look at the system.
12
12
 
13
- === Application Generator
13
+ === Project Generator
14
14
 
15
15
  Padrino provides generator support for quickly creating new Padrino applications. This provides many benefits
16
16
  such as constructing the recommended Padrino application structure, auto-generating a Gemfile listing
@@ -39,15 +39,30 @@ You can also instruct the generator to skip a certain component to avoid using o
39
39
  The available components and their default options are listed below:
40
40
 
41
41
  test:: rspec (default), bacon, shoulda, cucumber, testspec, riot
42
- renderer:: haml (default), erb
42
+ renderer:: haml (default), erb, erubis, liquid
43
43
  stylesheet:: sass (default), less, compass
44
44
  mock:: none (default), mocha, rr
45
45
  script:: none (default), jquery, prototype, mootools, rightjs, extcore, dojo
46
46
  orm:: none (default), datamapper, mongomapper, mongoid, activerecord, sequel, couchrest
47
47
 
48
+ In addition, you can generate projects based on existing templates:
49
+
50
+ $ padrino-gen project demo_project --template sampleblog
51
+
48
52
  To learn more about the project generator, check out the guide to
49
53
  {Padrino Generators}[http://www.padrinorb.com/guides/generators].
50
54
 
55
+ === Plugin System
56
+
57
+ Padrino provides support for plugins to be executed within your application. For example:
58
+
59
+ $ padrino-gen plugin hoptoad
60
+
61
+ would install the hoptoad middleware into your application automatically.
62
+
63
+ To learn more about the plugin system, check out the guide to
64
+ {Padrino Generators}[http://www.padrinorb.com/guides/generators].
65
+
51
66
  === Sub App Generator
52
67
 
53
68
  Unlike other ruby frameworks Padrino is principally designed for mounting multiple apps at the same time.
data/Rakefile CHANGED
@@ -1,5 +1,4 @@
1
1
  # coding:utf-8
2
2
  RAKE_ROOT = __FILE__
3
-
4
3
  require 'rubygems'
5
- require File.expand_path(File.dirname(__FILE__) + '/../gem_rake_helper')
4
+ require File.expand_path(File.dirname(__FILE__) + '/../gem_rake_helper')
data/bin/padrino-gen CHANGED
@@ -1,11 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
- require 'rubygems' unless defined?(Gem)
2
+ require 'rubygems' unless defined?(Gem) # Useful only on --dev mode
3
3
 
4
- # We load padrino-gen
5
4
  padrino_gen_path = File.expand_path('../../lib', __FILE__)
6
5
  $:.unshift(padrino_gen_path) if File.directory?(padrino_gen_path) && !$:.include?(padrino_gen_path)
7
6
 
8
- # We try to load the vendored padrino-core if exist
7
+ # We try to load the vendored padrino-core if exist (useful also for --dev mode)
9
8
  padrino_core_path = File.expand_path('../../../padrino-core/lib', __FILE__)
10
9
  $:.unshift(padrino_core_path) if File.directory?(padrino_core_path) && !$:.include?(padrino_core_path)
11
10
 
data/lib/padrino-gen.rb CHANGED
@@ -30,7 +30,6 @@ module Padrino
30
30
  DEV_PATH = File.expand_path("../../", File.dirname(__FILE__))
31
31
 
32
32
  class << self
33
-
34
33
  ##
35
34
  # Here we store our generators paths
36
35
  #
@@ -58,6 +57,7 @@ module Padrino
58
57
  def load_components!
59
58
  require 'padrino-gen/generators/actions'
60
59
  require 'padrino-gen/generators/components/actions'
60
+ require 'padrino-gen/generators/runner'
61
61
  load_paths.flatten.each { |file| require file }
62
62
  end
63
63
  end
@@ -67,7 +67,7 @@ end # Padrino
67
67
  ##
68
68
  # We add our generators to Padrino::Genererator
69
69
  #
70
- Padrino::Generators.load_paths << Dir[File.dirname(__FILE__) + '/padrino-gen/generators/{project,app,mailer,controller,model,migration}.rb']
70
+ Padrino::Generators.load_paths << Dir[File.dirname(__FILE__) + '/padrino-gen/generators/{project,app,mailer,controller,model,migration,plugin}.rb']
71
71
 
72
72
  ##
73
73
  # We add our tasks to padrino-core
@@ -65,22 +65,23 @@ module Padrino
65
65
  # Returns true if the option passed is a valid choice for component
66
66
  # valid_option?(:mock, 'rr')
67
67
  def valid_choice?(component, choice)
68
- self.class.available_choices_for(component).include? choice.to_sym
68
+ choice.present? && self.class.available_choices_for(component).include?(choice.to_sym)
69
69
  end
70
70
 
71
71
  # Creates a component_config file at the destination containing all component options
72
72
  # Content is a yamlized version of a hash containing component name mapping to chosen value
73
73
  def store_component_config(destination)
74
+ components = @_components || options
74
75
  create_file(destination) do
75
- self.class.component_types.inject({}) { |result, component|
76
- result[component] = options[component].to_s; result
76
+ self.class.component_types.inject({}) { |result, comp|
77
+ result[comp] = components[comp].to_s; result
77
78
  }.to_yaml
78
79
  end
79
80
  end
80
81
 
81
82
  # Returns the root for this thor class (also aliased as destination root).
82
83
  def destination_root(*paths)
83
- File.join(@destination_stack.last, paths)
84
+ File.expand_path(File.join(@destination_stack.last, paths))
84
85
  end
85
86
 
86
87
  # Returns true if inside a Padrino application
@@ -103,27 +104,80 @@ module Padrino
103
104
  # Adds all the specified gems into the Gemfile for bundler
104
105
  # require_dependencies 'active_record'
105
106
  # require_dependencies 'mocha', 'bacon', :group => 'test'
107
+ # require_dependencies 'json', :version => ">=1.2.3"
106
108
  def require_dependencies(*gem_names)
107
109
  options = gem_names.extract_options!
108
110
  gem_names.reverse.each { |lib| insert_into_gemfile(lib, options) }
109
111
  end
112
+ alias :require_dependency :require_dependencies
110
113
 
111
114
  # Inserts a required gem into the Gemfile to add the bundler dependency
112
115
  # insert_into_gemfile(name)
113
116
  # insert_into_gemfile(name, :group => 'test', :require => 'foo')
117
+ # insert_into_gemfile(name, :group => 'test', :version => ">1.2.3")
114
118
  def insert_into_gemfile(name, options={})
115
119
  after_pattern = options[:group] ? "#{options[:group].to_s.capitalize} requirements\n" : "Component requirements\n"
120
+ version = options.delete(:version)
116
121
  gem_options = options.map { |k, v| "#{k.inspect} => #{v.inspect}" }.join(", ")
117
- include_text = "gem '#{name}'" << (gem_options.present? ? ", #{gem_options}" : "") << "\n"
122
+ write_option = gem_options.present? ? ", #{gem_options}" : ""
123
+ write_version = version.present? ? ", #{version.inspect}" : ""
124
+ include_text = "gem '#{name}'"<< write_version << write_option << "\n"
118
125
  inject_into_file('Gemfile', include_text, :after => after_pattern)
119
126
  end
120
127
 
121
- ## Return true if our project has test component
128
+ # Inserts an hook before or after load in our boot.rb
129
+ # insert_hook("DataMapper.finalize", :after_load)
130
+ def insert_hook(include_text, where)
131
+ inject_into_file('config/boot.rb', " #{include_text}\n", :after => "Padrino.#{where} do\n")
132
+ end
133
+
134
+ # Registers and Creates Initializer.
135
+ # initializer :test, "some stuff here"
136
+ def initializer(name, data=nil)
137
+ @_init_name, @_init_data = name, data
138
+ register = data.present? ? " register #{name.to_s.camelize}Initializer\n" : " register #{name}\n"
139
+ inject_into_file destination_root("/app/app.rb"), register, :after => "Padrino::Application\n"
140
+ template "templates/initializer.rb.tt", destination_root("/lib/#{name}_init.rb") if data.present?
141
+ end
142
+
143
+ # Insert the regired gem and add in boot.rb custom contribs.
144
+ def require_contrib(contrib)
145
+ insert_into_gemfile 'padrino-contrib'
146
+ contrib = "require '" + File.join("padrino-contrib", contrib) + "'\n"
147
+ inject_into_file destination_root("/config/boot.rb"), contrib, :before => "\nPadrino.load!"
148
+ end
149
+
150
+ # Return true if our project has test component
122
151
  def test?
123
152
  fetch_component_choice(:test).to_s != 'none'
124
153
  end
125
154
 
126
- ## Raise SystemExit if the app is inexistent
155
+ # Return true if we have a tiny skeleton
156
+ def tiny?
157
+ File.exist?(destination_root("app/controllers.rb"))
158
+ end
159
+
160
+ # Run the bundler
161
+ def run_bundler
162
+ say "Bundling application dependencies using bundler...", :yellow
163
+ in_root { run 'bundle install' }
164
+ end
165
+
166
+ # Ask something to the user and receives a response.
167
+ #
168
+ # ==== Example
169
+ #
170
+ # ask("What is your name?")
171
+ # ask("Path for ruby", "/usr/local/bin/ruby") => "Path for ruby (leave blank for /usr/local/bin/ruby):"
172
+ #
173
+ def ask(statement, default=nil, color=nil)
174
+ default_text = default ? " (leave blank for #{default}):" : nil
175
+ say("#{statement}#{default_text} ", color)
176
+ result = $stdin.gets.strip
177
+ result.blank? ? default : result
178
+ end
179
+
180
+ # Raise SystemExit if the app is inexistent
127
181
  def check_app_existence(app)
128
182
  unless File.exist?(destination_root(app))
129
183
  say
@@ -187,4 +241,4 @@ module Padrino
187
241
  end
188
242
  end # Actions
189
243
  end # Generators
190
- end # Padrino
244
+ end # Padrino
@@ -30,6 +30,7 @@ module Padrino
30
30
  self.destination_root = options[:root]
31
31
  @app_name = name.gsub(/\W/, "_").underscore.camelize
32
32
  if in_app_root?
33
+ self.behavior = :revoke if options[:destroy]
33
34
  app_skeleton(name, options[:tiny])
34
35
  empty_directory destination_root("public/#{name}")
35
36
  append_file destination_root("config/apps.rb"), "\nPadrino.mount(\"#{@app_name}\").to(\"/#{name.underscore}\")"
@@ -45,7 +46,7 @@ module Padrino
45
46
 
46
47
  TEXT
47
48
  else
48
- say "You are not at the root of a Padrino application! (config/boot.rb not found)" and exit unless in_app_root?
49
+ say "You are not at the root of a Padrino application! (config/boot.rb not found)"
49
50
  end
50
51
  end
51
52
  end # App
@@ -1,4 +1,3 @@
1
- require 'rubygems'
2
1
  require 'thor/group'
3
2
 
4
3
  module Padrino
@@ -12,13 +11,14 @@ module Padrino
12
11
  # Include related modules
13
12
  include Thor::Actions
14
13
 
15
- class_option :root, :desc => "The root destination", :aliases => '-r', :default => nil, :type => :string
14
+ class_option :root, :desc => "The root destination", :aliases => '-r', :default => ".", :type => :string
16
15
 
17
16
  # We need to TRY to load boot because some of our app dependencies maybe have
18
17
  # custom generators, so is necessary know who are.
19
18
  def load_boot
20
19
  begin
21
20
  ENV['PADRINO_LOG_LEVEL'] ||= "test"
21
+ ENV['BUNDLE_GEMFILE'] = File.join(options[:root], "Gemfile") if options[:root]
22
22
  boot = options[:root] ? File.join(options[:root], 'config/boot.rb') : 'config/boot.rb'
23
23
  if File.exist?(boot)
24
24
  require File.expand_path(boot)
@@ -27,7 +27,7 @@ module Padrino
27
27
  require 'padrino-core/support_lite' unless defined?(SupportLite)
28
28
  end
29
29
  rescue Exception => e
30
- puts "=> Problem loading config/boot.rb"
30
+ puts "=> Problem loading #{boot}"
31
31
  puts ["=> #{e.message}", *e.backtrace].join("\n ")
32
32
  end
33
33
  end
@@ -75,21 +75,22 @@ SQLITE
75
75
 
76
76
  def setup_orm
77
77
  ar = AR
78
+ db = @app_name.underscore
78
79
  case options[:adapter]
79
80
  when 'mysql'
80
- ar.gsub! /!DB_DEVELOPMENT!/, MYSQL.gsub(/!DB_NAME!/,"\"#{name}_development\"")
81
- ar.gsub! /!DB_PRODUCTION!/, MYSQL.gsub(/!DB_NAME!/,"\"#{name}_production\"")
82
- ar.gsub! /!DB_TEST/, MYSQL.gsub(/!DB_NAME!/,"\"#{name}_test\"")
81
+ ar.gsub! /!DB_DEVELOPMENT!/, MYSQL.gsub(/!DB_NAME!/,"\"#{db}_development\"")
82
+ ar.gsub! /!DB_PRODUCTION!/, MYSQL.gsub(/!DB_NAME!/,"\"#{db}_production\"")
83
+ ar.gsub! /!DB_TEST/, MYSQL.gsub(/!DB_NAME!/,"\"#{db}_test\"")
83
84
  require_dependencies 'mysql'
84
85
  when 'postgres'
85
- ar.gsub! /!DB_DEVELOPMENT!/, POSTGRES.gsub(/!DB_NAME!/,"\"#{name}_development\"")
86
- ar.gsub! /!DB_PRODUCTION!/, POSTGRES.gsub(/!DB_NAME!/,"\"#{name}_production\"")
87
- ar.gsub! /!DB_TEST!/, POSTGRES.gsub(/!DB_NAME!/,"\"#{name}_test\"")
86
+ ar.gsub! /!DB_DEVELOPMENT!/, POSTGRES.gsub(/!DB_NAME!/,"\"#{db}_development\"")
87
+ ar.gsub! /!DB_PRODUCTION!/, POSTGRES.gsub(/!DB_NAME!/,"\"#{db}_production\"")
88
+ ar.gsub! /!DB_TEST!/, POSTGRES.gsub(/!DB_NAME!/,"\"#{db}_test\"")
88
89
  require_dependencies 'pg', :require => 'postgres'
89
90
  else
90
- ar.gsub! /!DB_DEVELOPMENT!/, SQLITE.gsub(/!DB_NAME!/,"Padrino.root('db', \"#{name}_development.db\")")
91
- ar.gsub! /!DB_PRODUCTION!/, SQLITE.gsub(/!DB_NAME!/,"Padrino.root('db', \"#{name}_production.db\")")
92
- ar.gsub! /!DB_TEST!/, SQLITE.gsub(/!DB_NAME!/,"Padrino.root('db', \"#{name}_test.db\")")
91
+ ar.gsub! /!DB_DEVELOPMENT!/, SQLITE.gsub(/!DB_NAME!/,"Padrino.root('db', \"#{db}_development.db\")")
92
+ ar.gsub! /!DB_PRODUCTION!/, SQLITE.gsub(/!DB_NAME!/,"Padrino.root('db', \"#{db}_production.db\")")
93
+ ar.gsub! /!DB_TEST!/, SQLITE.gsub(/!DB_NAME!/,"Padrino.root('db', \"#{db}_test.db\")")
93
94
  require_dependencies 'sqlite3-ruby', :require => 'sqlite3'
94
95
  end
95
96
  require_dependencies 'activerecord', :require => 'active_record'
@@ -10,7 +10,7 @@ COUCHREST
10
10
  def setup_orm
11
11
  require_dependencies 'couchrest'
12
12
  require_dependencies 'json_pure'
13
- create_file("config/database.rb", COUCHREST.gsub(/!NAME!/, name.underscore))
13
+ create_file("config/database.rb", COUCHREST.gsub(/!NAME!/, @app_name.underscore))
14
14
  empty_directory('app/models')
15
15
  end
16
16
 
@@ -22,27 +22,29 @@ DM
22
22
 
23
23
  def setup_orm
24
24
  dm = DM
25
+ db = @app_name.underscore
25
26
  require_dependencies 'data_mapper'
26
27
  require_dependencies case options[:adapter]
27
28
  when 'mysql'
28
- dm.gsub!(/!DB_DEVELOPMENT!/,"\"mysql://root@localhost/#{name}_development\"")
29
- dm.gsub!(/!DB_PRODUCTION!/,"\"mysql://root@localhost/#{name}_production\"")
30
- dm.gsub!(/!DB_TEST!/,"\"mysql://root@localhost/#{name}_test\"")
29
+ dm.gsub!(/!DB_DEVELOPMENT!/,"\"mysql://root@localhost/#{db}_development\"")
30
+ dm.gsub!(/!DB_PRODUCTION!/,"\"mysql://root@localhost/#{db}_production\"")
31
+ dm.gsub!(/!DB_TEST!/,"\"mysql://root@localhost/#{db}_test\"")
31
32
  'dm-mysql-adapter'
32
33
  when 'postgres'
33
- dm.gsub!(/!DB_DEVELOPMENT!/,"\"postgres://root@localhost/#{name}_development\"")
34
- dm.gsub!(/!DB_PRODUCTION!/,"\"postgres://root@localhost/#{name}_production\"")
35
- dm.gsub!(/!DB_TEST!/,"\"postgres://root@localhost/#{name}_test\"")
34
+ dm.gsub!(/!DB_DEVELOPMENT!/,"\"postgres://root@localhost/#{db}_development\"")
35
+ dm.gsub!(/!DB_PRODUCTION!/,"\"postgres://root@localhost/#{db}_production\"")
36
+ dm.gsub!(/!DB_TEST!/,"\"postgres://root@localhost/#{db}_test\"")
36
37
  'dm-postgres-adapter'
37
38
  else
38
- dm.gsub!(/!DB_DEVELOPMENT!/,"\"sqlite3://\" + Padrino.root('db', \"#{name}_development.db\")")
39
- dm.gsub!(/!DB_PRODUCTION!/,"\"sqlite3://\" + Padrino.root('db', \"#{name}_production.db\")")
40
- dm.gsub!(/!DB_TEST!/,"\"sqlite3://\" + Padrino.root('db', \"#{name}_test.db\")")
39
+ dm.gsub!(/!DB_DEVELOPMENT!/,"\"sqlite3://\" + Padrino.root('db', \"#{db}_development.db\")")
40
+ dm.gsub!(/!DB_PRODUCTION!/,"\"sqlite3://\" + Padrino.root('db', \"#{db}_production.db\")")
41
+ dm.gsub!(/!DB_TEST!/,"\"sqlite3://\" + Padrino.root('db', \"#{db}_test.db\")")
41
42
  'dm-sqlite-adapter'
42
43
  end
43
44
 
44
45
  create_file("config/database.rb", dm)
45
46
  empty_directory('app/models')
47
+ insert_hook("DataMapper.finalize", :after_load)
46
48
  end
47
49
 
48
50
  DM_MODEL = (<<-MODEL) unless defined?(DM_MODEL)
@@ -29,7 +29,7 @@ MONGO
29
29
  def setup_orm
30
30
  require_dependencies 'bson_ext', :require => 'mongo'
31
31
  require_dependencies 'mongoid'
32
- create_file("config/database.rb", MONGOID.gsub(/!NAME!/, name.underscore.gsub('.','_')))
32
+ create_file("config/database.rb", MONGOID.gsub(/!NAME!/, @app_name.underscore))
33
33
  empty_directory('app/models')
34
34
  end
35
35
 
@@ -11,7 +11,7 @@ MONGO
11
11
  def setup_orm
12
12
  require_dependencies 'bson_ext', :require => 'mongo'
13
13
  require_dependencies 'mongo_mapper'
14
- create_file("config/database.rb", MONGO.gsub(/!NAME!/, name.underscore))
14
+ create_file("config/database.rb", MONGO.gsub(/!NAME!/, @app_name.underscore))
15
15
  empty_directory('app/models')
16
16
  end
17
17
 
@@ -0,0 +1,85 @@
1
+ MONGOMATIC = (<<-MONGO) unless defined?(MONGOMATIC)
2
+
3
+ case Padrino.env
4
+ when :development then Mongomatic.db = Mongo::Connection.new.db("!NAME!_development")
5
+ when :production then Mongomatic.db = Mongo::Connection.new.db("!NAME!_production")
6
+ when :test then Mongomatic.db = Mongo::Connection.new.db("!NAME!_test")
7
+ end
8
+ MONGO
9
+
10
+ def setup_orm
11
+ mongomatic = MONGOMATIC
12
+ require_dependencies 'bson_ext', :require => 'mongo'
13
+ require_dependencies 'mongomatic'
14
+ create_file("config/database.rb", MONGOMATIC.gsub(/!NAME!/, @app_name.underscore))
15
+ empty_directory('app/models')
16
+ end
17
+
18
+ MONGOMATIC_MODEL = (<<-MODEL) unless defined?(MONGOMATIC_MODEL)
19
+ class !NAME! < Mongomatic::Base
20
+ include Mongomatic::Expectations::Helper
21
+
22
+ # Mongomatic does not have the traditional
23
+ # model definition that AR/MM/DM et. al. have.
24
+ # Staying true to the "ad-hoc" nature of MongoDB,
25
+ # there are no explicit column definitions in the
26
+ # model file.
27
+
28
+ # However you can "fake it" by making a column
29
+ # required using expectations
30
+ # For the sake of padrino g model,
31
+ # we'll assume that any property defined
32
+ # on the command-line is required
33
+ # In the case of Integer types, we'll add
34
+ # the expectation: be_a_number
35
+ # Future enhancement may allow a regex for
36
+ # String datatypes
37
+
38
+
39
+ # Examples
40
+ # def validate
41
+ # expectations do
42
+ # be_present self['name'], "Name cannot be blank"
43
+ # be_present self['email'], "Email cannot be blank"
44
+ # be_present self['age'], "Age cannot be blank"
45
+ # be_present self['password'], "Password cannot be blank"
46
+ # be_a_number self['age'], "Age must be a number"
47
+ # be_of_length self['password'], "Password must be at least 8 characters", :minimum => 8
48
+ # end
49
+ # end
50
+
51
+ # def create_indexes
52
+ # self.collection.create_index('name', :unique => true)
53
+ # self.collection.create_index('email', :unique => true)
54
+ # self.collection.create_index('age')
55
+ # end
56
+ def validate
57
+ expectations do
58
+ !FIELDS!
59
+ !INTEGERS!
60
+ end
61
+ end
62
+
63
+ end
64
+ MODEL
65
+
66
+ # options => { :fields => ["title:string", "body:string"], :app => 'app' }
67
+ def create_model_file(name, options={})
68
+ model_path = destination_root(options[:app], 'models', "#{name.to_s.underscore}.rb")
69
+ field_tuples = options[:fields].collect { |value| value.split(":") }
70
+ column_declarations = field_tuples.collect { |field, kind| "be_present self['#{field}'], '#{field} cannot be blank'" }.join("\n ")
71
+ # Really ugly oneliner
72
+ integers = field_tuples.select { |col, type| type =~ /[Ii]nteger/ }.collect { |field, kind| "be_a_number self['#{field}'], '#{field} must be a number'" }.join("\n ")
73
+ model_contents = MONGOMATIC_MODEL.gsub(/!NAME!/, name.to_s.camelize)
74
+ model_contents.gsub!(/!FIELDS!/, column_declarations)
75
+ model_contents.gsub!(/!INTEGERS!/, integers)
76
+ create_file(model_path, model_contents)
77
+ end
78
+
79
+ def create_model_migration(filename, name, fields)
80
+ # NO MIGRATION NEEDED
81
+ end
82
+
83
+ def create_migration_file(migration_name, name, columns)
84
+ # NO MIGRATION NEEDED
85
+ end