Hoopla!

now with extra whiz-bang!

Hoopla!

Advanced Rails Creation Script

February 10, 2007 · 0 comments

Akhil Bansal recently wrote two excellent scripts for creating new Rails projects. The first was in bash (a sensible choice) and the second was a Ruby port of the same code. I've taken his code one step further and developed it into a Ruby program that's easier to modify to your own needs.

Take the following code, throw it on your system somewhere and run it. It'll set up a Rails app and take care of all the nutty details like ignoring log files and removing those pesky tmp and components directories from your repository.

#!/usr/bin/env ruby
require 'fileutils'

class LayRails

  attr_accessor :path, :name, :svn_username, :svn_url, :svn_password

  def initialize
    setup && lay
  end

  def setup

    unless system('rails -v') || system('rails.cmd -v')
      puts "Cannot find rails. Terminating..."
      exit 0
    end    

    self.path = enter "Enter Rails Application Path:(eg: /home/akhil/ror): "
    self.name = ARGV.first || path.split('/').last
    self.svn_username = enter  "Enter svn username: "
    self.svn_password = enter "Enter the svn password: "
    self.svn_url = enter "Enter the svn url: "

    puts "
      ---------------------------------------
      Please verify the following variables: 
      Svn Username: #{svn_username}
      Svn URL: #{svn_url}
      Svn Password: #{svn_password.gsub(/./, '*')}
      Application Path: #{path}
      Application name: #{name}"

    while yes_no = enter("Proceed (y/n)").strip.upcase
      return true if 'Y' == yes_no
      if 'N' == yes_no
        puts 'Terminating...'
        exit 0
      else
        puts 'Please enter either a "y" or a "n"'
        puts 'yes_no: '+yes_no.inspect
      end
    end
  end

  def lay

    puts  "Generating rails project: (#{path})"
    @windows ?
      psystem("rails.cmd #{f path}") :
      psystem("rails #{f path}")

    puts  "SVNinitial import: "
    puts "svn import #{path} #{svn_url}/trunk -m \"Initial Import\" --username #{svn_username} --password #{svn_password.gsub(/./, '*')}"
    system "svn import #{path} #{svn_url}/trunk -m \"Initial Import\" --username #{svn_username} --password #{svn_password}"

    FileUtils.remove_dir(path, true)

    puts  "Checking out from svn: "

    psystem "svn checkout #{svn_url}/trunk #{path}"
    FileUtils.cd(path, :verbose => true)

    remove f('log/*'), 'Removing all log files from SVN'
    ignore '*', 'log', 'Ignoring all log files under log dir'
    remove 'tmp', 'Removing tmp directory from SVN'
    remove 'components', 'Removing components directory from SVN'
    ignore 'tmp', '.', 'Ignoring tmp dir'

    puts  "Generating optimized database file"
    File.open(f('config/database.yml'), 'w') {|f| f.write(database_yml_file) }
    puts  "Moving database.yml to database.example"
    psystem f('svn move config/database.yml config/database.example')
    psystem 'svn commit -m "Moving database.yml to database.example to provide a template for anyone who checks out the code " '
    ignore 'database.yml', 'config', 'Ignoring database.yml'
    puts  "Finished."
  end

  def remove(what, log)
    psystem "svn remove #{what}"
    commit log
  end

  def ignore(what, where, log)
    psystem "svn propset svn:ignore '#{what}' #{where}"
    psystem "svn update"
    commit log
  end

  def commit(log)
    psystem "svn commit -m '#{log}'"
  end

  def f(string)
    @windows ||= RUBY_PLATFORM =~ /mswin/i
    @windows ? 
      string.gsub('/', '\\') : 
      string
  end

  def psystem(string)
    puts string
    system string
  end

  def enter(string)
    puts string
    gets.strip
  end

  def database_yml_file
    <

production:
  <<: *credentials
development:
  <<: *credentials
  database: #{name}_development
test:
  <<: *credentials
  database: #{name}_test
DBYML
  end

  def credits
    puts < - based on the work of Akhil Bansal"
CREDITS
  end

end

# and away we go
LayRails.new

→ 0 comments Tags:

Installing Mephisto on DreamHost

August 19, 2006 · 2 comments

I’ve tried out Typo for a while and it’s pretty nice but I’m hearing raves about Mephisto. I’m sheep-like enough to always follow coding trends so I can’t see any way out of trying Mephisto on for size.

The first thing that I saw on the installation instructions was that it doesn’t ship with all the required parts. You’ve got to check out Rails to the vendor directory (easy enough) and add at least one gem.

Adding the TZinfo (‘time-zone info’) gem proved a pain so I just downloaded it from it’s rubyforge project and throw it into my vendor directory
cd rails_app/vendor
wget http://rubyforge.org/frs/download.php/11738/tzinfo-0.3.0.tar.gz
tar xvzf tzinfo-0.3.0.tar.gz
rm tzinfo-0.3.0.tar.gz

A little migration, replacing the default .htaccess and dispatch.fcgi files with my customized ones, some short prayers that this process goes quickly and I don’t screw away my whole day on something I didn’t even plan to do, and it’s all done. Except that it’s not.

I’m not sure if this is the new cool thing to do or if it’s just a bad choice supported for legacy reasons, but you can’t use migrations on a fresh mephisto database. You’ve got to type `rake db:bootstrap` and it creates the tables and throws some default values in there. I’d prefer migrations, but whatever. At least it got done.

My first impressions are good, we’ll see how it goes finding a good theme.

→ 2 comments Tags:

Converting a Rails App to Capistrano deployment

August 03, 2006 · 0 comments

I’ve got one client for whom I’m building a Rails app and I started it long before I knew anything about Capistrano. Mostly things are pretty straightforward and all is working as it should – but there are a couple of hangups.

Shared Resources

My site allows users to upload portraits of themselves. These are kept right in the open in the public directory under a folder named “portraits”. They can also upload films, documents, etc. using the model Documents which stores its stuff in ./public/documents.

The first real hassle of converting to capistrano was dealing with these because up until now I’ve kept them in the SVN repository for fear of losing any data and pisisng off a user. With the number of deployments I do I no longer want to put these files in the repository but that would remove them from the site. Capistrano does a fresh checkout each time it deploys and if something’s not in SVN then it just plain doesn’t make it back into the app.

Capistrano does allow the use of a shared folder located above the live app directory. The trick is getting stuff into there and making sure that capistrano can recognize it every time I deploy.

My Solution

It turns out the Capistrano allows highly configurable deployment options. All I needed to do was to move the folders out of ./public and into shared
mv ./public/documents ../shared/
mv ./public/portraits ../shared/
then edit my deploy script so it links those folders up into each new public directory
task :after_update_code do
  %w{documents portraits}.each do |share|
    run "ln -s #{shared_path}/#{share} #{release_path}/public/#{share}" 
  end
end
It didn’t take long for me to realize that I needed to do the same with any other file that wouldn’t be in SVN. For me, this is my database.yml file and cofig/environment.rb file
task :after_update_code do
  %w{documents portraits}.each do |share|
    run "ln -s #{shared_path}/#{share} #{release_path}/public/#{share}" 
  end
  %w{database.yml environment.rb}.each do |config|
    run "ln -nfs #{shared_path}/#{config} #{release_path}/config/#{config}" 
  end
end

There’s actually a number of tasks that you could add this code to. You could put it right into the deploy task by using `task :deploy` or you could make it run immediately after deploy is run by `task :after_deploy`

So far so good with Capistrano.

→ 0 comments Tags:

Rails .bash_profile (.bashrc)

April 17, 2006 · 0 comments

If you use Subversion and develop Rails on either Linux, Mac OS X, or through a shell into a shared server you could use this.

A while ago I realized that many of the commands I was using on a regular basis were cumbersome. With Subversion especially I found the commands lengthy. With Rails I kept wanting a ‘remigrate’ command so I could test my migrations to see if they were valid all the way down to 0 and back up. To edit your .bashrc or .bash_profile entries simply type:
nano ~/.bash_profile
(you can replace ‘nano’ with whatever editor you like). You can add as many other aliases as you want to help with whatever commands you use most – just make sure there are no spaces on either side of the equals sign!

The following is the text from my .bash_profile file in my home directory:

alias migrate='rake migrate'
alias clone='rake clone_structure_to_test'
alias remigrate='rake migrate VERSION=0 && rake migrate'
alias remigrate_prod='rake migrate VERSION=0 RAILS_ENV=production && rake migrate RAILS_ENV=production'
alias remigrate_dev='rake migrate VERSION=0 RAILS_ENV=development && rake migrate RAILS_ENV=development'
alias l='ls -l'
alias st='svn st'
alias update='svn update'
alias delete='svn delete'
alias add='svn add'
alias copy='svn copy'
alias move='svn move'
alias commit='svn commit'
alias commitm='svn commit -m ""'
alias upcom='svn update && svn commit -m ""'
alias upco='svn update && svn commit'
The following allows me to type just ‘update’ to do an svn update or ‘commitm’ if I want to commit without bothering to enter a log message (useful for one-person projects). ‘upcom’ and ‘remigrate’ are my two favorites because they allow for quick access to multiple commands.

Let me know if you have any others I should add to speed up my work!

→ 0 comments Tags:

uninitialized constant Admin::GeneralController

April 10, 2006 · 0 comments

I just updated my typo to revision 1004 and, while almost all of my site is accessible, going to /admin barfs out a 500 error.

From my log:
1
2
3
4
5
6
7
8
9
10
11
12
13
NameError (uninitialized constant Admin::GeneralController):
    /vendor/rails/activerecord/lib///activesupport/lib/active_support/dependencies.rb:100:in `const_missing'
    generated/routing/recognition.rb:9:in `recognize_path'
    /vendor/rails/actionpack/lib/action_controller/routing.rb:477:in `recognize!'
    /vendor/rails/railties/lib/dispatcher.rb:38:in `dispatch'
    /vendor/rails/railties/lib/fcgi_handler.rb:150:in `process_request'
    /vendor/rails/railties/lib/fcgi_handler.rb:54:in `process!'
    /vendor/rails/railties/lib/fcgi_handler.rb:53:in `each_cgi'
    /usr/lib/ruby/1.8/fcgi.rb:597:in `each'
    /usr/lib/ruby/1.8/fcgi.rb:597:in `each_cgi'
    /vendor/rails/railties/lib/fcgi_handler.rb:53:in `process!'
    /vendor/rails/railties/lib/fcgi_handler.rb:23:in `process!'
    dispatch.fcgi:34

Going straight to /admin/content/new can get me to where I can post – so this might just be a typo somewhere.

→ 0 comments Tags: