Forums | Users |
Search | Signup | Login

External SVN hook

Subscribe to External SVN hook 1 post, 1 voice

 
Avatar matta 4 post(s)

Hey All;

Due to reasons beyond my control, we can’t host our SVN repo with UF. That said, I have been working with Josh and the API and have knocked out a post-commit SVN hook. You can put it in repo/hooks/post-commit.

You need to put in your user ID from UF and map your project ID to your repo, these are found in the XML from the API. The user is the user account on your machine that you use to check in commits.

Here is the code:

#!/usr/bin/ruby
require 'yaml'
require 'cgi'

# configure multiple project settings below
SVNLOOK    = '/usr/bin/svnlook'
CURL       = '/usr/bin/curl'
LOG_FILE   = '/tmp/svn-hooks.log'

def gather_and_post(repo_path, revision, options)

 user_id = nil
 project_id = nil
 commit_dirs_changed = `#{SVNLOOK} dirs-changed #{repo_path} -r #{revision}`

 options[:prefixes].each_pair do |prefix,id|
  project_id = id if commit_dirs_changed.split(/\n/)[0].match(prefix)
 end
 return if project_id.nil?

 commit_author  = `#{SVNLOOK} author #{repo_path} -r #{revision}`.chop
 commit_log     = `#{SVNLOOK} log #{repo_path} -r #{revision}`
 commit_date    = `#{SVNLOOK} date #{repo_path} -r #{revision}`
 commit_changed = `#{SVNLOOK} changed #{repo_path} -r #{revision}`

 options[:users].each_pair do |user,id|
  user_id = id if commit_author == user
 end
 return if user_id.nil?  

  changeset_xml = <<-END_XML
<changeset>
 <author-id type="integer">#{CGI.escapeHTML(user_id.to_s)}</author-id>
  <message>#{CGI.escapeHTML(commit_log)}</message>
   <revision type="integer">#{CGI.escapeHTML(revision.to_s)}</revision>
</changeset>
END_XML

 url = '%s/api/v1/projects/%s/changesets?process_message_actions=true' % [options[:account], project_id]
 cmd = "#{CURL} -u #{options[:user_pass]} -X POST -H 'Accept: application/xml' -H 'Content-Type: application/xml' -d '#{changeset_xml.gsub(/'/, "\\'").strip}' #{url}" 
 %x{#{cmd}}
end

begin
  options = {
    :account => 'http://yourdomain.unfuddle.com', 
    :user_pass => "your_regular_username:your_regular_password",
    :users => {"matt" => nnn}, 
    :prefixes => {"project/trunk" => nnn}
    }
  puts ARGV[0] + " " + ARGV[1]

  gather_and_post ARGV[0], ARGV[1], options
rescue
  %x{echo "repo:#{ARGV[0]} rev: #{ARGV[1]}" > #{LOG_FILE}}
  %x{echo "Error: #{$!} trace:#{caller}" >> #{LOG_FILE}}
end