require 'fileutils' require 'uri' Capistrano.configuration(:must_exist).load do # By default, all repositories are group writable by the group 'scm' # Originally I have envisaged this value being initialized here as: # # set :scm_group, lambda {'scm_' + application} # # however the SVN docs convinced me it's probably overkill. # http://svnbook.red-bean.com/nightly/en/svn-book.html#svn.serverconfig.pathbasedauthz # set :scm_group, 'scm' # The following values define the svn repository to work with. # If any are undefined but :repository is set, we'll extract the # necessary values from it, otherwise we'll prompt the user. # # An example of :repository entries are: # # set :repository, 'svn+ssh://scm.deprecated.org/var/svn/deprec/trunk' # set :repository, 'file:///tmp/svn/deprec/trunk' # # I've only used svn+ssh but it shouldn't be hard to get the file scheme working. # set (:svn_scheme) do repository ? URI.parse(repository).scheme : 'svn+ssh' end set (:scm_host) do if repository URI.parse(repository).host || 'localhost' elsif ENV['HOSTS'] svn_host = ENV['HOSTS'] else Capistrano::CLI.password_prompt('svn host: ') end end # This is the actual path in the svn repos where we'll check our project into set (:repos_path) do repository ? URI.parse(repository).path : Capistrano::CLI.password_prompt('svn repos path: ') end # We'll calculate this based on the repos_path. It's used when initializing the repository set (:repos_root) do (repository ? URI.parse(repository).path : repos_path).sub(/\/(trunk|tags|branches)$/, '') end # account name to perform actions on # this is a hack to allow us to optionally pass a variable to tasks set (:svn_account) do Capistrano::CLI.prompt('account name: ') end # XXX sudo apt-get install swig python-dev # XXX requires apache already installed... desc "install Subversion version control system" task :svn_install, :roles => :scm do # svn 1.4 server improves on 1.3 and is backwards compatible with 1.3 clients # http://subversion.tigris.org/svn_1.4_releasenotes.html # # We're using FSFS instead of BerkeleyDB. Read why below: # http://svnbook.red-bean.com/nightly/en/svn-book.html#svn.reposadmin.basics.backends # # NOTE: we're bulding the python bindings for trac # ./subversion/bindings/swig/INSTALL # version = 'subversion-1.4.4' set :src_package, { :file => version + '.tar.gz', :md5sum => '702655defa418bab8f683f6268b4fd30 subversion-1.4.4.tar.gz', :dir => version, :url => "http://subversion.tigris.org/downloads/#{version}.tar.gz", :unpack => "tar zxf #{version}.tar.gz;", :configure => %w( ./configure --prefix=/usr/local --with-apxs=/usr/local/apache2/bin/apxs --with-apr=/usr/local/apache2 --with-apr-util=/usr/local/apache2 PYTHON=/usr/bin/python ; ).reject{|arg| arg.match '#'}.join(' ') , # DRY this up :make => 'make;', :install => 'make install;', :post_install => ' make swig-py; make install-swig-py; echo /usr/local/lib/svn-python > /usr/lib/python2.4/site-packages/subversion.pth; ' } enable_universe apt.install( {:base => %w(libneon25 libneon25-dev swig python-dev)}, :stable ) deprec.download_src(src_package, src_dir) deprec.install_from_src(src_package, src_dir) end desc "grant a user access to svn repos" task :svn_grant_user_access, :roles => :scm do deprec.useradd(svn_account) deprec.groupadd(scm_group) deprec.add_user_to_group(svn_account, scm_group) end task :scm_setup do # deprecated svn_setup end task :svn_setup do svn_import_project end desc "Create subversion repository and import project into it" task :svn_import_project, :roles => :scm do svn_create_repos svn_import end desc "Create a subversion repository" task :svn_create_repos, :roles => :scm do set :svn_account, user svn_grant_user_access # deprec.useradd(user) # deprec.groupadd(scm_group) # deprec.add_user_to_group(user, scm_group) deprec.mkdir(repos_root, :mode => '2775', :group => scm_group) sudo "svnadmin verify #{repos_root} > /dev/null 2>&1 || sudo svnadmin create #{repos_root}" sudo "chmod -R g+w #{repos_root}" end # Adapted from code in Bradley Taylors RailsMachine gem desc "Import project into subversion repository." task :svn_import, :roles => :scm do repository ||= "#{svn_scheme}://#{scm_host == 'localhost' ? '/' : scm_host}/#{repos_path}" new_path = "../#{application}" tags = repository.sub("trunk", "tags") branches = repository.sub("trunk", "branches") puts "Adding branches and tags" system "svn mkdir -m 'Adding tags and branches directories' #{tags} #{branches}" puts "Importing application." system "svn import #{repository} -m 'Import'" cwd = Dir.getwd puts "Moving application to new directory" Dir.chdir '../' system "mv #{cwd} #{cwd}.imported" puts "Checking out application." system "svn co #{repository} #{application}" Dir.chdir application svn_remove_log_and_tmp puts "Your repository is: #{repository}" end # Lifted from Bradley Taylors RailsMachine gem desc "remove and ignore log files and tmp from subversion" task :svn_remove_log_and_tmp, :roles => :scm do puts "removing log directory contents from svn" system "svn remove log/*" puts "ignoring log directory" system "svn propset svn:ignore '*.log' log/" system "svn update log/" puts "removing contents of tmp sub-directorys from svn" system "svn remove tmp/cache/*" system "svn remove tmp/pids/*" system "svn remove tmp/sessions/*" system "svn remove tmp/sockets/*" puts "ignoring tmp directory" system "svn propset svn:ignore '*' tmp/cache" system "svn propset svn:ignore '*' tmp/pids" system "svn propset svn:ignore '*' tmp/sessions" system "svn propset svn:ignore '*' tmp/sockets" system "svn update tmp/" puts "committing changes" system "svn commit -m 'Removed and ignored log files and tmp'" end # desc "Cache svn name and password on the server. Useful for http-based repositories." task :svn_cache_credentials do run_with_input "svn list #{repository}" end # XXX TODO # desc "backup repository" # task :svn_backup_respository, :roles => :scm do # puts "read http://svnbook.red-bean.com/nightly/en/svn-book.html#svn.reposadmin.maint.backup" # end end