Ruby on Rails
HowtoUseRailsWithSubversion

This assumes that you have already created a subversion repository, and you are just wondering how to setup your rails project.

If you have WEBrick or lighttpd running after running “script/server” in your rails directory, shutdown the server.

  1. Import your rails application.
    • navigate to the root of your rails app.
    • svn import . repository_url -m "Import" --username user
  2. Change to the directory containing your rails application, and rename it for safe keeping.
    • mv your_rails_app your_rails_app-backup
  3. Check out your rails application
    • svn checkout svn_url_to_your_repository your_rails_app
    • navigate to the root of this freshly checked out working copy.
  4. Remove the log files.
    • svn remove log/*
    • svn commit -m "removing all log files from subversion"
  5. Ignore the log files when they are re-created (Note for Capistrano/Switchtower users: the log directory is “shared” so it needs to be ignored itself, not just its contents)
    • svn propset svn:ignore "*.log" log/
    • svn update log/
    • svn commit -m "Ignoring all files in /log/ ending in .log"
  6. Ignore the tmp directory with all its content (cache, sessions, sockets) (Rails >= 1.1, ignore all tmp/ content.)
  7. Rails < 1.1
    • svn propset svn:ignore "*" tmp/sessions tmp/cache tmp/sockets
  8. Rails >= 1.1
    • svn remove tmp/*
    • svn propset svn:ignore "*" tmp/
    • svn update tmp/
  9. svn commit -m "Ignoring all files in /tmp/"
  1. Don’t version control database.yml
    • svn move config/database.yml config/database.example
    • svn commit -m "Moving database.yml to database.example to provide a template for anyone who checks out the code"
  2. Ignore database.yml when it’s re-created
    • svn propset svn:ignore "database.yml" config/
    • svn update config/
    • svn commit -m "Ignoring database.yml"

You’re done. Now your log files will not be checked into subversion on a commit, and you don’t need to worry about the database settings on your development machine and your production machine and things breaking as database.yml moves between them.

Feel free to skip the steps where you remove database.yml, but if you are working with several other programmers who may have different database.yml files you may want to keep it ignored.

NOTE TO FERRET/AAF Users
If working with multiple instances of the same database (including a live site version) you may want to ignore your indexes if stored in files with the index dir of your Rails app…

Another solution to accomodate multiple developer’s database setup would be to grab those parameters from the “environment”, each programmer’s own development environment that is. You could write database.yml like so:

development:
  adapter: mysql
  database: <%= ENV['DEV_DB'] %>
  host: <%= ENV['DEV_HOST'] %>
  username: <%= ENV['DEV_USER'] %>
  password: "<%= ENV['DEV_PASS'] %>"

Even production params could be specified like this too, which would help keep sensitive info out of the code repository.

WARNING
Settings environment variables on a shared host could be insecure. If you can run everything setuid and make your .[shell]rc and .htaccess files mode 0700 this would be a little more acceptable on a shared host.

Adding all new files to Subversion after running a generate script:

If you’re running Rails 0.14.3 or newer, the generator scripts can take the —svn (or -c) option to automatically add the created files via Subversion.

./script/generate scaffold  controller_name --svn

Run

./script/generate
without command line options for details.

Subversion has an option for “svn add” to make things much easier, by using “svn add * --force”.

svn --force add .

I found that svn add * --force is not a perfect solution, as it will force to add ignored resources into repository. In my machine, It automatically adds my ignored *.log files into respository. Those log files are ignored by using “svn propset svn:ignore *.log log/”.
Is this a bug of SVN?

The --force option does seem to override ignored resources, which can really throw a monkey wrench in your system. The following shell commands provide a nice way around that. They take the output from svn status and use it as input for svn add:


svn status | grep "^\?" | awk "{print $2}" | xargs svn add

Also, if you have filenames that include spaces, you can try:


svn status | grep "^\?" | sed -e 's/? *//' | sed -e 's/ /\ /g' | xargs svn add

You can put these in a shell script or just run them from the command line on -nix. There was also a similar windows script on this page at one point, but it seems to have vanished.


This will work from the commandline – $ drives interpolation in bash.


svn status | awk '/^\?/ {print $2}'|xargs -r svn add  

I added this alias to my TILDEHERE/.bash_profile


alias svnaddall='svn status | grep "^\?" | awk "{print \$2}" | xargs svn add'

Remember to execute “source TILDEHERE/.bash_profile” after adding that line for it to work.
—-

You might want to add that alias line to TILDE/.bashrc instead of TILDE/.bash_profile, so that it gets loaded automatically, and you don’t have to “source” it for every new shell.

—-

I’ve created a script named railscommit in my app’s script directory which I use to do commits to our svn repository. Here’s the contents, I’m not an experienced bash script writer so any improvements are welcome:

#!/bin/bash
echo ""
echo "Here's what we're going to do:"
echo " "
echo "Add the following files"
echo "-----------------------"
svn status | awk '/^\?/ {print $2}'
echo " "
echo "Remove the following files"
echo "--------------------------"
svn status | awk '/^!/ {print $2}'
echo " "
echo "Check in the following modified files"
echo "-------------------------------------"
svn status | awk '/^M/ {print $2}'
echo " "
echo "Proceed with commit? [yn]"
read answer
if [ "$answer" = "y" ]
then
	echo " "
	echo "Adding the following files"
	svn status | awk '/^\?/ {print $2}' | xargs svn add
	echo " "
	echo "Removing the following files"
	svn status | awk '/^!/ {print $2}' | xargs svn remove
	echo " "
	echo "Committing changes to repository"
	svn commit
else 
	echo " "
	echo "Commit cancelled"
fi

echo " "
echo "Want to check for updates? [yn]"
read answer
if [ "$answer" = "y" ]
then
	svn update
else 
	echo " "
	echo "Update cancelled"
fi

———

Okay my take on this script (in ruby of course):


#!/usr/bin/env ruby

# my take on a easy commit script for rails...
# it is far from prefect, so:
# please feed back the modifications you made to it!
#
# Fixed bugs on empty to_ arrays and spelling mistakes
# by Vesa-Pekka Palmu
# orginal by Cies Breijs -- cies.breijsATgmailDOTcom
# based on a bash script by Anonymous Gentleman
# found here: <a href="http://wiki.rubyonrails.org/rails/pages/HowtoUseRailsWithSubversion">http://wiki.rubyonrails.org/rails/pages/HowtoUseRailsWithSubversion</a>

to_add = []
to_remove = []
to_checkin = []

`svn status`.each_line do |l|
  action_char, path = l.split(' ', 2)
  path.strip!
  case action_char
    when '?'
      to_add << path
    when '!'
      to_remove << path
    when 'M'
      to_checkin << path
  end
end

puts "\nyou are about to..." 

def print_list(array, str)
  puts "\n#{str}:" 
  array.each { |i| puts "\t"+i }
  puts "\t<nothing>" if array.length == 0
end

print_list(to_add, 'add')
print_list(to_remove, 'remove')
print_list(to_checkin, 'checkin')

puts "\nplease write something for the commit log and hit enter..." 
puts "(hitting enter on an empty line will cancel this commit)\n\n" 

log = gets.strip

if log.empty?
  puts "commit cancelled!\n" 
  exit
end

puts "\ncontacting repository...\n" 

`svn add #{to_add.join(' ')}` unless to_add.empty?
`svn remove #{to_remove.join(' ')}` unless to_remove.empty?
puts "\n" + `svn commit -m "#{log.gsub('"', '\"')}"` + "\n" 

puts "running 'svn update' to be sure we are up-to-date..." 
puts `svn update`

puts "\nfinished.\n" 

Please fead back on it, or modify it…
I’ll update changes I to it here.

- Cies Breijs.

———

Windows Script came back. Drop it into script/ folder with name like:svn_addall.rb, then in RAILS_APP_ROOT, run:ruby script/svn_addall.rb. Good luck!


#######################################

  1. Author:Yufan Shi
  2. Email:yufanshi AT gmail.com
  3. Website:www.feed-tank.com
    #######################################
    require ‘win32ole’

shell = WIN32OLE.new(‘Wscript.Shell’)
objExec = shell.exec(“svn status”)
while !objExec.stdout.atendofstream
l = objExec.stdout.readline

if l =~ /^\?/ l = l.sub(/^\?( )*/,’svn add ’) objResult = shell.exec(l) while !objResult.stdout.atendofstream print objResult.stdout.readline,“\n” end end

end

######################################

As my development work shifts between Unix and Windows machines – each environment has Ruby installed in a different location, so each require a different shebang (#!) line at the start of all ‘dispatch.(star)’ files. To deal with this I perform a similar manoeuvre to that described above for database.yml.

Windows doesn’t even use the shebang line so this is pretty much pointless. Just change the shebang line in all the dispatch.(star) files to #!/usr/bin/env ruby and it will work fine in Windows and Unix/Linux.

This will launch subversion’s default text editor, and if you type and save the following info:

dispatch.rb
dispatch.cgi
dispatch.fcgi

…it should add these properties to subversion.

That should be that, so that now when I initially check out the project on whatever machine, I just need to create the dispatch.(star) files from the samples, make sure the shebang line is correct, and away I go.

I’m managing a website in my repository. How can I make the live site automatically update after every commit?

This is spelled out here:
http://subversion.tigris.org/faq.html#website-auto-update

The solution requires three steps:

  1. Compile a brief C script to run “svn update”
  2. Edit Apache configuration to not serve .svn directories
  3. Add a post-commit hook that executes the C script after each commit.

How to add a plugin to the project’s repository

somebody, please review and respond to olegf, if it’s working (not working) for you

Sometimes you want to use plugins for your Rails app. This is how you add them into your project as svn externals

ruby script/plugin install -x svn_url_to_plugin_repository
svn commit -m "added plugin xxx"

Now this plugin will be checked out into app/vendor/plugins/ and added to your repository as external dependency.

Next time you run

svn update
plugin code will be updated from its repository too.

You may want to disable this behaviour and specify the revision for the plugin you want. This is done by

svn propedit svn:externals vendor/plugins

And add revision number after the name of the plugin, like

globalize -r179 svn_url_to_plugin_repository

——

Adding a plugin as a vendor branch

If you want to use plugins but also want to modify them, you’ll need to check the code into your repository. However, at some point, you might want to pull down the latest version of the plugin and use additional features or bug-fixes that were added. At this point, you will need to somehow merge your changes with the changes made by the plugin’s author. Using vendor branches can really simplify this process.

Use vendor branches for plugins, not script/plugin install

——

Handling plugins from vendors that you edit gracefully Piston

This is a great way to manage your plugins and keep them up to date. Piston is a utility that eases vendor branch management. This is similar to svn:externals, except you have a local copy of the files, which you can modify at will. As long as the changes are mergeable, you should have no problems.
——

I documented how I create a Rails app and set up SVN revisioning on it over at my website. It’s a fairly straight-forward walkthrough that works well for me so far. YMMV.—GarrettMurray

Creating a New Rails App with SVN

——

I’ve created a ruby script (with the great help of seb and technoweenie) that can be used instead of the rails command to create your application AND import it into the repository “the subversion way”, ignoring various files as per steps 1-10 above (with the exception of #9). For the sake of keeping things DRY, you can find the latest version here: Create a Rails project skeleton and import and checkout from svn all at one

Scroll down to the bottom for the latest version. Use it and change it as much as you like, but post your changes so that I can benefit ;)

My ruby kung-fu is weak, so this code could probably use a good refactoring. Also, as the code is right now, you can’t use the same arguments you do for the regular rails command. Use the rails weenie site (where the code is) to comment and or suggest improvements and or update the code.

——
Yet Another Rails + Subversion page.

Subversion + Rails In Five Minutes

——

I wrote a script that could help:
Smart Subversion Script for Rails projects

——

If you go into /doc and run rake appdoc to regenerate the online docs, you’ll badly damage your checked out subversion files because the app directory will be deleted, including its .svn directory, so (almost) no subversion commands can be executed without error.

The “big hammer” way to fix this is to delete everything and start over with a fresh svn checkout.

My more elegant solution is to completely delete the /doc/app directory. Then it changes from a directory containing data files but no .svn dir, which svn cannot handle, to a completely missing dir, which svn knows how to handle. Then run a svn update to re-download the old /doc/app directory.

Either way, once svn is working again, quickly do a svn propedit svn:ignore doc to stop trying to version control your docs, and of course svn commit the change.

This does not work for me — I can delete/restore the file tree, and issue the propedit and commit commands, but the next time I update the doc tree (rake doc:reapp) svn starts complaining about the missing .svn directory again. Is there a solution that permanently swats this problem? (And shouldn’t the rake method NOT delete the whole tree?)

—-

I’m using Instant Rails, which everyone seems to say is a Good Thing™, but it’s use of the directory structure is incompatible with subversion (or cvs) standard practice.

To wit: Instant rails wants each application to sit directly under the $INSTANT_RAILS\rails_apps directory, while subversion likes \trunk, \tags, \branches. Now I could play games by making an AP_TRUNK directory, and let AP be my current branch, but that kinda isn’t the way things are supposed to go. Is there some back door to instant rails to get around this?

I used this solution for instant rails:
svn checkout file:///code/trunk/ .
the trailing slash and the dot copies your code to the current directory. So if you run this command in the instantrails\rails_apps\my_app\ folder, it will recreate the directory structure just like it is supposed to be. No hack…

—-

Another “product” you may want to also remove and ignore is db/schema.rb—especially if you share the code between multiple developers and/or servers. Keep schema.rb and your database in sync!

—-

Another SVN RAILS SCRIPT