beet 0.3.1

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 (45) hide show
  1. data/.gitignore +2 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +13 -0
  4. data/Rakefile +59 -0
  5. data/TODO +17 -0
  6. data/VERSION +1 -0
  7. data/beet.gemspec +89 -0
  8. data/bin/beet +112 -0
  9. data/features/generating.feature +24 -0
  10. data/features/step_definitions/beet_steps.rb +7 -0
  11. data/features/step_definitions/common_steps.rb +172 -0
  12. data/features/support/common.rb +33 -0
  13. data/features/support/env.rb +25 -0
  14. data/lib/beet.rb +10 -0
  15. data/lib/beet/capistrano.rb +14 -0
  16. data/lib/beet/execution.rb +50 -0
  17. data/lib/beet/executor.rb +195 -0
  18. data/lib/beet/file_system.rb +143 -0
  19. data/lib/beet/gem_location_map.rb +64 -0
  20. data/lib/beet/interaction.rb +37 -0
  21. data/lib/beet/logger.rb +44 -0
  22. data/lib/beet/rails.rb +146 -0
  23. data/lib/beet/recipes/passenger/vhost.rb +17 -0
  24. data/lib/beet/recipes/rack/middleware.rb +17 -0
  25. data/lib/beet/recipes/rails/authlogic.rb +297 -0
  26. data/lib/beet/recipes/rails/clean_files.rb +4 -0
  27. data/lib/beet/recipes/rails/clearance.rb +22 -0
  28. data/lib/beet/recipes/rails/cms/bcms_blog.rb +21 -0
  29. data/lib/beet/recipes/rails/cms/bcms_event.rb +24 -0
  30. data/lib/beet/recipes/rails/css/blueprint.rb +5 -0
  31. data/lib/beet/recipes/rails/css/reset.rb +10 -0
  32. data/lib/beet/recipes/rails/db/mysql.rb +42 -0
  33. data/lib/beet/recipes/rails/db/postgres.rb +52 -0
  34. data/lib/beet/recipes/rails/git.rb +23 -0
  35. data/lib/beet/recipes/rails/jquery.rb +11 -0
  36. data/lib/beet/recipes/rails/rspec.rb +3 -0
  37. data/lib/beet/recipes/rails/shoulda.rb +1 -0
  38. data/lib/beet/scm.rb +36 -0
  39. data/lib/beet/scm/git.rb +15 -0
  40. data/lib/beet/scm/svn.rb +5 -0
  41. data/lib/beet/template_location_map.rb +13 -0
  42. data/test/executor_test.rb +24 -0
  43. data/test/file_system_test.rb +59 -0
  44. data/test/test_helper.rb +12 -0
  45. metadata +110 -0
@@ -0,0 +1,64 @@
1
+ GEM_LOCATIONS = {
2
+ 'restful-authentcation' => 'git://github.com/technoweenie/restful-authentication.git',
3
+ 'authlogic' => 'git://github.com/binarylogic/authlogic.git',
4
+ 'clearance' => 'git://github.com/thoughtbot/clearance.git',
5
+ 'will_paginate' => 'git://github.com/mislav/will_paginate.git',
6
+ 'paperclip' => 'git://github.com/thoughtbot/paperclip.git',
7
+ 'attachment_fu' => 'git://github.com/technoweenie/attachment_fu.git',
8
+ 'rspec' => 'git://github.com/dchelimsky/rspec.git',
9
+ 'rspec-rails' => 'git://github.com/dchelimsky/rspec-rails.git',
10
+ 'cucumber' => 'git://github.com/aslakhellesoy/cucumber.git',
11
+ 'shoulda' => 'git://github.com/thoughtbot/shoulda.git',
12
+ 'matchy' => 'git://github.com/jeremymcanally/matchy.git',
13
+ 'context' => 'git://github.com/jeremymcanally/context.git',
14
+ 'exception-notifier' => 'git://github.com/Lipsiasoft/exception-notifier.git',
15
+ 'asset_packager' => 'git://github.com/sbecker/asset_packager.git',
16
+ 'acts_as_list' => 'git://github.com/rails/acts_as_list.git',
17
+ 'acts_as_tree' => 'git://github.com/rails/acts_as_tree.git',
18
+ 'webrat' => 'git://github.com/brynary/webrat.git',
19
+ 'rcov' => 'git://github.com/relevance/rcov.git',
20
+ 'rcov_plugin' => 'git://github.com/commondream/rcov_plugin.git',
21
+ 'flog' => 'git://github.com/seattlerb/flog.git',
22
+ 'flay' => 'git://github.com/seattlerb/flay.git',
23
+ 'hoe' => 'git://github.com/seattlerb/hoe.git',
24
+ 'integrity' => 'git://github.com/integrity/integrity.git',
25
+ 'active_merchant' => 'git://github.com/Shopify/active_merchant.git',
26
+ 'spree' => 'git://github.com/railsdog/spree.git',
27
+ 'exception_notification' => 'git://github.com/rails/exception_notification.git',
28
+ 'hoptoad_notifier' => 'git://github.com/thoughtbot/hoptoad_notifier.git',
29
+ 'exception_logger' => 'git://github.com/defunkt/exception_logger.git',
30
+ 'jeweler' => 'git://github.com/technicalpickles/jeweler.git',
31
+ 'newgem' => 'git://github.com/drnic/newgem.git',
32
+ 'bones' => 'git://github.com/TwP/bones.git',
33
+ 'echoe' => 'git://github.com/fauna/echoe.git',
34
+ 'nokogiri' => 'git://github.com/tenderlove/nokogiri.git',
35
+ 'hpricot' => 'git://github.com/why/hpricot.git',
36
+ 'httparty' => 'git://github.com/jnunemaker/httparty.git',
37
+ 'rest-client' => 'git://github.com/adamwiggins/rest-client.git',
38
+ 'typoeus' => 'git://github.com/pauldix/typhoeus.git',
39
+ 'redcloth' => 'git://github.com/jgarber/redcloth.git',
40
+ 'rdiscount' => 'git://github.com/rtomayko/rdiscount.git',
41
+ 'bluecloth' => 'git://github.com/mislav/bluecloth.git',
42
+ 'rr' => 'git://github.com/btakita/rr.git',
43
+ 'mocha' => 'git://github.com/floehopper/mocha.git',
44
+ 'stump' => 'git://github.com/jeremymcanally/stump.git',
45
+ 'active_scaffold' => 'git://github.com/activescaffold/active_scaffold.git',
46
+ 'delayed_job' => 'git://github.com/tobi/delayed_job.git',
47
+ 'starling' => 'git://github.com/starling/starling.git',
48
+ 'amqp' => 'git://github.com/tmm1/amqp.git',
49
+ 'negative-captcha' => 'git://github.com/subwindow/negative-captcha.git',
50
+ 'factory_girl' => 'git://github.com/thoughtbot/factory_girl.git',
51
+ 'machinist' => 'git://github.com/notahat/machinist.git',
52
+ 'thinking-sphinx' => 'git://github.com/freelancing-god/thinking-sphinx.git',
53
+ 'acts-as-taggable-on' => 'git://github.com/mbleigh/acts-as-taggable-on.git',
54
+ 'is_taggable' => 'git://github.com/giraffesoft/is_taggable.git',
55
+ 'forgery' => 'git://github.com/sevenwire/forgery.git',
56
+ 'faker' => 'git://github.com/yyyc514/faker.git',
57
+ 'whenever' => 'git://github.com/javan/whenever.git',
58
+ 'aasm' => 'git://github.com/rubyist/aasm.git',
59
+ 'workflow' => 'git://github.com/ryan-allen/workflow.git',
60
+ 'chef' => 'git://github.com/opscode/chef.git',
61
+ 'passenger' => 'git://github.com/FooBarWidget/passenger.git',
62
+ 'thin' => 'git://github.com/macournoyer/thin.git',
63
+ 'happymapper' => 'git://github.com/jnunemaker/happymapper.git',
64
+ }
@@ -0,0 +1,37 @@
1
+ module Beet
2
+ module Interaction
3
+ # Get a user's input
4
+ #
5
+ # ==== Example
6
+ #
7
+ # answer = ask("Should I freeze the latest Rails?")
8
+ # freeze! if ask("Should I freeze the latest Rails?") == "yes"
9
+ #
10
+ def ask(string)
11
+ log '', string
12
+ print '> '
13
+ STDIN.gets.strip
14
+ end
15
+
16
+ # Helper to test if the user says yes(y)?
17
+ #
18
+ # ==== Example
19
+ #
20
+ # freeze! if yes?("Should I freeze the latest Rails?")
21
+ #
22
+ def yes?(question)
23
+ answer = ask(question).downcase
24
+ answer == "y" || answer == "yes"
25
+ end
26
+
27
+ # Helper to test if the user does NOT say yes(y)?
28
+ #
29
+ # ==== Example
30
+ #
31
+ # capify! if no?("Will you be using vlad to deploy your application?")
32
+ #
33
+ def no?(question)
34
+ !yes?(question)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,44 @@
1
+ module Beet
2
+ class Logger # :nodoc:
3
+ attr_reader :out
4
+ attr_accessor :quiet
5
+
6
+ def initialize(out = $stdout)
7
+ @out = out
8
+ @quiet = false
9
+ @level = 0
10
+ end
11
+
12
+ def log(status, message, &block)
13
+ @out.print("%12s %s%s\n" % [status, ' ' * @level, message]) unless quiet
14
+ indent(&block) if block_given?
15
+ end
16
+
17
+ def indent(&block)
18
+ @level += 1
19
+ if block_given?
20
+ begin
21
+ block.call
22
+ ensure
23
+ outdent
24
+ end
25
+ end
26
+ end
27
+
28
+ def outdent
29
+ @level -= 1
30
+ if block_given?
31
+ begin
32
+ block.call
33
+ ensure
34
+ indent
35
+ end
36
+ end
37
+ end
38
+
39
+ private
40
+ def method_missing(method, *args, &block)
41
+ log(method.to_s, args.first, &block)
42
+ end
43
+ end
44
+ end
data/lib/beet/rails.rb ADDED
@@ -0,0 +1,146 @@
1
+ module Beet
2
+ module Rails
3
+ # Make an entry in Rails routing file conifg/routes.rb
4
+ #
5
+ # === Example
6
+ #
7
+ # route "map.root :controller => :welcome"
8
+ #
9
+ def route(routing_code)
10
+ log 'route', routing_code
11
+ sentinel = 'ActionController::Routing::Routes.draw do |map|'
12
+
13
+ in_root do
14
+ gsub_file 'config/routes.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
15
+ "#{match}\n #{routing_code}\n"
16
+ end
17
+ end
18
+ end
19
+
20
+ # Add Rails to /vendor/rails
21
+ #
22
+ # ==== Example
23
+ #
24
+ # freeze!
25
+ #
26
+ def freeze!(args = {})
27
+ log 'vendor', 'rails edge'
28
+ in_root { run('rake rails:freeze:edge', false) }
29
+ end
30
+
31
+ # Install a plugin. You must provide either a Subversion url or Git url.
32
+ # For a Git-hosted plugin, you can specify if it should be added as a submodule instead of cloned.
33
+ #
34
+ # ==== Examples
35
+ #
36
+ # plugin 'restful-authentication', :git => 'git://github.com/technoweenie/restful-authentication.git'
37
+ # plugin 'restful-authentication', :git => 'git://github.com/technoweenie/restful-authentication.git', :submodule => true
38
+ # plugin 'restful-authentication', :svn => 'svn://svnhub.com/technoweenie/restful-authentication/trunk'
39
+ #
40
+ def plugin(name, options)
41
+ log 'plugin', name
42
+
43
+ if options[:git] && options[:submodule]
44
+ in_root do
45
+ Git.run("submodule add #{options[:git]} vendor/plugins/#{name}")
46
+ end
47
+ elsif options[:git] || options[:svn]
48
+ in_root do
49
+ run_ruby_script("script/plugin install #{options[:svn] || options[:git]}", false)
50
+ end
51
+ else
52
+ log "! no git or svn provided for #{name}. skipping..."
53
+ end
54
+ end
55
+
56
+ # Adds an entry into config/environment.rb for the supplied gem :
57
+ def gem(name, options = {})
58
+ log 'gem', name
59
+ env = options.delete(:env)
60
+
61
+ gems_code = "config.gem '#{name}'"
62
+
63
+ if options.any?
64
+ opts = options.inject([]) {|result, h| result << [":#{h[0]} => #{h[1].inspect.gsub('"',"'")}"] }.sort.join(", ")
65
+ gems_code << ", #{opts}"
66
+ end
67
+
68
+ environment gems_code, :env => env
69
+ end
70
+
71
+ # Adds a line inside the Initializer block for config/environment.rb. Used by #gem
72
+ # If options :env is specified, the line is appended to the corresponding
73
+ # file in config/environments/#{env}.rb
74
+ def environment(data = nil, options = {}, &block)
75
+ sentinel = 'Rails::Initializer.run do |config|'
76
+
77
+ data = block.call if !data && block_given?
78
+
79
+ in_root do
80
+ if options[:env].nil?
81
+ gsub_file 'config/environment.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
82
+ "#{match}\n " << data
83
+ end
84
+ else
85
+ Array.wrap(options[:env]).each do|env|
86
+ append_file "config/environments/#{env}.rb", "\n#{data}"
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ # Create a new file in the vendor/ directory. Code can be specified
93
+ # in a block or a data string can be given.
94
+ #
95
+ # ==== Examples
96
+ #
97
+ # vendor("sekrit.rb") do
98
+ # sekrit_salt = "#{Time.now}--#{3.years.ago}--#{rand}--"
99
+ # "salt = '#{sekrit_salt}'"
100
+ # end
101
+ #
102
+ # vendor("foreign.rb", "# Foreign code is fun")
103
+ #
104
+ def vendor(filename, data = nil, &block)
105
+ log 'vendoring', filename
106
+ file("vendor/#{filename}", data, false, &block)
107
+ end
108
+
109
+
110
+ # Create a new initializer with the provided code (either in a block or a string).
111
+ #
112
+ # ==== Examples
113
+ #
114
+ # initializer("globals.rb") do
115
+ # data = ""
116
+ #
117
+ # ['MY_WORK', 'ADMINS', 'BEST_COMPANY_EVAR'].each do
118
+ # data << "#{const} = :entp"
119
+ # end
120
+ #
121
+ # data
122
+ # end
123
+ #
124
+ # initializer("api.rb", "API_KEY = '123456'")
125
+ #
126
+ def initializer(filename, data = nil, &block)
127
+ log 'initializer', filename
128
+ file("config/initializers/#{filename}", data, false, &block)
129
+ end
130
+
131
+ # Generate something using a generator from Rails or a plugin.
132
+ # The second parameter is the argument string that is passed to
133
+ # the generator or an Array that is joined.
134
+ #
135
+ # ==== Example
136
+ #
137
+ # generate(:authenticated, "user session")
138
+ #
139
+ def generate(what, *args)
140
+ log 'generating', what
141
+ argument = args.map {|arg| arg.to_s }.flatten.join(" ")
142
+
143
+ in_root { run_ruby_script("script/generate #{what} #{argument}", false) }
144
+ end
145
+ end # Rails
146
+ end # Beet
@@ -0,0 +1,17 @@
1
+ file "#{project_name}.local.vhost.conf" do
2
+ %{
3
+ <VirtualHost *:80>
4
+ ServerName #{project_name}.local
5
+ DocumentRoot "#{root}/public"
6
+ RackEnv development
7
+ <directory "#{root}/public">
8
+ Order allow,deny
9
+ Allow from all
10
+ </directory>
11
+ </VirtualHost>
12
+ }.strip
13
+ end
14
+ default_to = "/etc/apache2/passenger_pane_vhosts"
15
+ answer = ask "Write file to: [#{default_to} default]"
16
+ filename = answer.empty? ? default_to : answer
17
+ sudo "mv ./#{project_name}.local.vhost.conf #{filename}"
@@ -0,0 +1,17 @@
1
+ file project_name + ".rb" do
2
+ %{
3
+ module Rack
4
+ class #{project_name}
5
+
6
+ def initialize(app)
7
+ @app = app
8
+ end
9
+
10
+ def call(env)
11
+ [200, {'Content-Type' => 'text/html', 'Content-Length' => 100}, ['Hello World']]
12
+ end
13
+ end
14
+ end
15
+ }.strip
16
+ end
17
+
@@ -0,0 +1,297 @@
1
+ file "app/models/user_session.rb" do
2
+ %{
3
+ class UserSession < Authlogic::Session::Base
4
+ logout_on_timeout true # default is false
5
+ end
6
+ }.strip
7
+ end
8
+
9
+ file "app/models/user.rb" do
10
+ %{
11
+ class User < ActiveRecord::Base
12
+ acts_as_authentic do |c|
13
+ c.logged_in_timeout = 10.minutes # default is 10.minutes
14
+ end
15
+ end
16
+ }.strip
17
+ end
18
+
19
+ file "app/controllers/user_sessions_controller.rb" do
20
+ %{
21
+ class UserSessionsController < ApplicationController
22
+ before_filter :require_no_user, :only => [:new, :create]
23
+ before_filter :require_user, :only => :destroy
24
+
25
+ def new
26
+ @user_session = UserSession.new
27
+ end
28
+
29
+ def create
30
+ @user_session = UserSession.new(params[:user_session])
31
+ if @user_session.save
32
+ flash[:notice] = "Login successful!"
33
+ redirect_back_or_default account_url
34
+ else
35
+ render :action => :new
36
+ end
37
+ end
38
+
39
+ def destroy
40
+ current_user_session.destroy
41
+ flash[:notice] = "Logout successful!"
42
+ redirect_back_or_default new_user_session_url
43
+ end
44
+ end
45
+ }.strip
46
+ end
47
+
48
+
49
+ file "app/views/user_sessions/new.html.erb" do
50
+ %{
51
+ <h1>Login</h1>
52
+
53
+ <% form_for @user_session, :url => user_session_path do |f| %>
54
+ <%= f.error_messages %>
55
+ <%= f.label :email %><br />
56
+ <%= f.text_field :email %><br />
57
+ <br />
58
+ <%= f.label :password %><br />
59
+ <%= f.password_field :password %><br />
60
+ <br />
61
+ <%= f.check_box :remember_me %><%= f.label :remember_me %><br />
62
+ <br />
63
+ <%= f.submit "Login" %>
64
+ <% end %>
65
+ }.strip
66
+ end
67
+
68
+ # Setup some routes
69
+ route 'map.resource :user_session'
70
+ route 'map.resource :account, :controller => "users"'
71
+ route 'map.resources :users'
72
+ route 'map.register "/register", :controller => "users", :action => "new"'
73
+ route 'map.login "/login", :controller => "user_sessions", :action => "new"'
74
+ route 'map.logout "/logout", :controller => "user_sessions", :action => "destroy"'
75
+
76
+ file "app/controllers/application_controller.rb" do
77
+ %{
78
+ # Filters added to this controller apply to all controllers in the application.
79
+ # Likewise, all the methods added will be available for all controllers.
80
+
81
+ class ApplicationController < ActionController::Base
82
+ helper :all
83
+ helper_method :current_user_session, :current_user
84
+ filter_parameter_logging :password, :password_confirmation
85
+
86
+ private
87
+ def current_user_session
88
+ return @current_user_session if defined?(@current_user_session)
89
+ @current_user_session = UserSession.find
90
+ end
91
+
92
+ def current_user
93
+ return @current_user if defined?(@current_user)
94
+ @current_user = current_user_session && current_user_session.record
95
+ end
96
+
97
+ def require_user
98
+ unless current_user
99
+ store_location
100
+ flash[:notice] = "You must be logged in to access this page"
101
+ redirect_to new_user_session_url
102
+ return false
103
+ end
104
+ end
105
+
106
+ def require_no_user
107
+ if current_user
108
+ store_location
109
+ flash[:notice] = "You must be logged out to access this page"
110
+ redirect_to account_url
111
+ return false
112
+ end
113
+ end
114
+
115
+ def store_location
116
+ session[:return_to] = request.request_uri
117
+ end
118
+
119
+ def redirect_back_or_default(default)
120
+ redirect_to(session[:return_to] || default)
121
+ session[:return_to] = nil
122
+ end
123
+ end
124
+ }.strip
125
+ end
126
+
127
+ file "app/controllers/users_controller.rb" do
128
+ %{
129
+ class UsersController < ApplicationController
130
+ before_filter :require_no_user, :only => [:new, :create]
131
+ before_filter :require_user, :only => [:show, :edit, :update]
132
+
133
+ def new
134
+ @user = User.new
135
+ end
136
+
137
+ def create
138
+ @user = User.new(params[:user])
139
+ if @user.save
140
+ flash[:notice] = "Account registered!"
141
+ redirect_back_or_default account_url
142
+ else
143
+ render :action => :new
144
+ end
145
+ end
146
+
147
+ def show
148
+ @user = @current_user
149
+ end
150
+
151
+ def edit
152
+ @user = @current_user
153
+ end
154
+
155
+ def update
156
+ @user = @current_user # makes our views "cleaner" and more consistent
157
+ if @user.update_attributes(params[:user])
158
+ flash[:notice] = "Account updated!"
159
+ redirect_to account_url
160
+ else
161
+ render :action => :edit
162
+ end
163
+ end
164
+ end
165
+ }.strip
166
+ end
167
+
168
+ file "app/views/users/_form.html.erb" do
169
+ %{
170
+ <%= form.label :email %><br />
171
+ <%= form.text_field :email %><br />
172
+ <br />
173
+ <%= form.label :password, form.object.new_record? ? nil : "Change password" %><br />
174
+ <%= form.password_field :password %><br />
175
+ <br />
176
+ <%= form.label :password_confirmation %><br />
177
+ <%= form.password_field :password_confirmation %><br />
178
+ }.strip
179
+ end
180
+
181
+ file "app/views/users/edit.html.erb" do
182
+ %{
183
+ <h1>Edit My Account</h1>
184
+
185
+ <% form_for @user, :url => account_path do |f| %>
186
+ <%= f.error_messages %>
187
+ <%= render :partial => "form", :object => f %>
188
+ <%= f.submit "Update" %>
189
+ <% end %>
190
+
191
+ <br /><%= link_to "My Profile", account_path %>
192
+ }.strip
193
+ end
194
+
195
+ file "app/views/users/new.html.erb" do
196
+ %{
197
+ <h1>Register</h1>
198
+
199
+ <% form_for @user, :url => account_path do |f| %>
200
+ <%= f.error_messages %>
201
+ <%= render :partial => "form", :object => f %>
202
+ <%= f.submit "Register" %>
203
+ <% end %>
204
+ }.strip
205
+ end
206
+
207
+ file "app/views/users/show.html.erb" do
208
+ %{
209
+ <p>
210
+ <b>Email:</b>
211
+ <%=h @user.email %>
212
+ </p>
213
+
214
+ <p>
215
+ <b>Login count:</b>
216
+ <%=h @user.login_count %>
217
+ </p>
218
+
219
+ <p>
220
+ <b>Last request at:</b>
221
+ <%=h @user.last_request_at %>
222
+ </p>
223
+
224
+ <p>
225
+ <b>Last login at:</b>
226
+ <%=h @user.last_login_at %>
227
+ </p>
228
+
229
+ <p>
230
+ <b>Current login at:</b>
231
+ <%=h @user.current_login_at %>
232
+ </p>
233
+
234
+ <p>
235
+ <b>Last login ip:</b>
236
+ <%=h @user.last_login_ip %>
237
+ </p>
238
+
239
+ <p>
240
+ <b>Current login ip:</b>
241
+ <%=h @user.current_login_ip %>
242
+ </p>
243
+
244
+
245
+ <%= link_to 'Edit', edit_account_path %>
246
+ }.strip
247
+ end
248
+
249
+ # can't rely on internal rails migration generation, so we do it this way
250
+
251
+ #Dir.chdir("script") #for ruby 1.9.2 08/07/2009 . no need for ruby1.9.1p129
252
+ #run "./generate migration beet_authlogic_create_user" # for ruby 1.9.2 08/07/2009. no need for ruby1.9.1p129
253
+
254
+ run "script/generate migration beet_authlogic_create_user"
255
+
256
+ #now open it
257
+ #Dir.chdir("..") # for ruby 1.9.2 08/07/2009. no need for ruby1.9.1p129
258
+
259
+ file(Dir.glob('db/migrate/*beet_authlogic_create_user*').first) do
260
+ %{
261
+ class BeetAuthlogicCreateUser < ActiveRecord::Migration
262
+ def self.up
263
+ unless table_exists?(:users)
264
+ create_table :users do |t|
265
+ t.string :email, :null => false # optional, you can use login instead, or both
266
+ t.string :crypted_password, :null => false # optional, see below
267
+ t.string :password_salt, :null => false # optional, but highly recommended
268
+ t.string :persistence_token, :null => false # required
269
+ t.string :single_access_token, :null => false # optional, see Authlogic::Session::Params
270
+ t.string :perishable_token, :null => false # optional, see Authlogic::Session::Perishability
271
+
272
+ # Magic columns, just like ActiveRecord's created_at and updated_at. These are automatically maintained by Authlogic if they are present.
273
+ t.integer :login_count, :null => false, :default => 0 # optional, see Authlogic::Session::MagicColumns
274
+ t.integer :failed_login_count, :null => false, :default => 0 # optional, see Authlogic::Session::MagicColumns
275
+ t.datetime :last_request_at # optional, see Authlogic::Session::MagicColumns
276
+ t.datetime :current_login_at # optional, see Authlogic::Session::MagicColumns
277
+ t.datetime :last_login_at # optional, see Authlogic::Session::MagicColumns
278
+ t.string :current_login_ip # optional, see Authlogic::Session::MagicColumns
279
+ t.string :last_login_ip # optional, see Authlogic::Session::MagicColumns
280
+ end
281
+ end
282
+ end
283
+
284
+ def self.down
285
+ drop_table :users
286
+ end
287
+ end
288
+ }.strip
289
+ end
290
+
291
+
292
+ gem 'authlogic', :version => '~> 2.0.0'
293
+
294
+ rake "gems:install", :sudo => true
295
+ rake "db:create:all"
296
+ rake "db:migrate"
297
+