changeset 310:b9c2ba9e49b4 live

Merge from branch "feature_73"
author Chris Cannam
date Mon, 28 Mar 2011 17:50:25 +0100
parents 2de308601155 (current diff) defe55be97b9 (diff)
children 0a829eae7cf3
files config/locales/en-GB.yml config/locales/en.yml config/routes.rb
diffstat 15 files changed, 403 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/app/controllers/repositories_controller.rb	Wed Mar 23 11:33:36 2011 +0000
+++ b/app/controllers/repositories_controller.rb	Mon Mar 28 17:50:25 2011 +0100
@@ -36,7 +36,11 @@
   
   def edit
     @repository = @project.repository
+
     if !@repository
+
+      params[:repository_scm]='Mercurial'
+
       @repository = Repository.factory(params[:repository_scm])
       @repository.project = @project if @repository
     end
@@ -44,6 +48,7 @@
       @repository.attributes = params[:repository]
       @repository.save
     end
+
     render(:update) do |page|
       page.replace_html "tab-content-repository", :partial => 'projects/settings/repository'
       if @repository && !@project.repository
--- a/app/controllers/sys_controller.rb	Wed Mar 23 11:33:36 2011 +0000
+++ b/app/controllers/sys_controller.rb	Mon Mar 28 17:50:25 2011 +0100
@@ -55,6 +55,20 @@
     render :nothing => true, :status => 404
   end
 
+  def get_external_repo_url
+    project = Project.find(params[:id])
+    if project.repository
+      repo = project.repository
+      if repo.is_external?
+        render :text => repo.external_url, :status => 200
+      else
+        render :nothing => true, :status => 200
+      end
+    end
+  rescue ActiveRecord::RecordNotFound
+    render :nothing => true, :status => 404
+  end
+
   def set_embedded_active
     project = Project.find(params[:id])
     mods = project.enabled_modules
--- a/app/helpers/repositories_helper.rb	Wed Mar 23 11:33:36 2011 +0000
+++ b/app/helpers/repositories_helper.rb	Mon Mar 28 17:50:25 2011 +0100
@@ -151,7 +151,7 @@
       scm_options << ["Repository::#{scm}".constantize.scm_name, scm] if Setting.enabled_scm.include?(scm) || (repository && repository.class.name.demodulize == scm)
     end
     
-    select_tag('repository_scm', 
+    select_tag('repository_scm',
                options_for_select(scm_options, repository.class.name.demodulize),
                :disabled => (repository && !repository.new_record?),
                :onchange => remote_function(:url => { :controller => 'repositories', :action => 'edit', :id => @project }, :method => :get, :with => "Form.serialize(this.form)")
--- a/app/models/repository/mercurial.rb	Wed Mar 23 11:33:36 2011 +0000
+++ b/app/models/repository/mercurial.rb	Mon Mar 28 17:50:25 2011 +0100
@@ -19,7 +19,7 @@
 
 class Repository::Mercurial < Repository
   attr_protected :root_url
-  validates_presence_of :url
+  # validates_presence_of :url
 
   FETCH_AT_ONCE = 100  # number of changesets to fetch at once
 
--- a/app/views/projects/settings/_repository.rhtml	Wed Mar 23 11:33:36 2011 +0000
+++ b/app/views/projects/settings/_repository.rhtml	Mon Mar 28 17:50:25 2011 +0100
@@ -1,3 +1,6 @@
+
+<%= javascript_include_tag 'repository' %>
+
 <% remote_form_for :repository, @repository, 
                    :url => { :controller => 'repositories', :action => 'edit', :id => @project },
                    :builder => TabularFormBuilder,
@@ -6,22 +9,48 @@
 <%= error_messages_for 'repository' %>
 
 <div class="box tabular">
-<% if !@repository || !@repository.url %>
-<ul><li><%= l(:text_settings_repo_creation) %></li></ul>
-<% end %>
-<p><%= label_tag('repository_scm', l(:label_scm)) %><%= scm_select_tag(@repository) %></p>
-<%= repository_field_tags(f, @repository) if @repository %>
+
+<p>
+<% if @repository %>
+   <%= l(:text_settings_repo_explanation) %></ br>
+   <% if @repository.is_external %>
+     <p><%= l(:text_settings_repo_is_external) %></ br>
+   <% else %>
+     <p><%= l(:text_settings_repo_is_internal) %></ br>
+   <% end %>
+</p>
+
+
+
+
+
+<p>
+	<%= label_tag('repository_is_external', l(:label_is_external_repository)) %>
+	<%= check_box :repository, :is_external, :onclick => "toggle_ext_url()" %> 
+	<br/><em><%= l(:setting_external_repository) %></em>
+</p>
+
+
+<p>
+	<%= label_tag('repository_external_url', l(:label_repository_external_url)) %>
+	<%= text_field :repository, :external_url, :disabled => !(@repository and @repository.is_external) %> 
+	<br/><em><%= l(:setting_external_repository_url) %></em>
+</p>
+
+<p><%= l(:text_settings_repo_need_help) %></p>
+
 </div>
 
 <div class="contextual">
 <% if @repository && !@repository.new_record? %>
 <%= link_to(l(:label_user_plural), {:controller => 'repositories', :action => 'committers', :id => @project}, :class => 'icon icon-user') %>
-<%= link_to(l(:button_delete), {:controller => 'repositories', :action => 'destroy', :id => @project},
-            :confirm => l(:text_are_you_sure),
-            :method => :post,
-            :class => 'icon icon-del') %>
 <% end %>
 </div>
 
-<%= submit_tag((@repository.nil? || @repository.new_record?) ? l(:button_create) : l(:button_save), :disabled => @repository.nil?) %>
+<%= submit_tag(l(:button_save), :onclick => remote_function(:url => { :controller => 'repositories', :action => 'edit', :id => @project }, :method => :get, :with => "Form.serialize(this.form)")) %>
+
+<% else %>
+   <%= l(:text_settings_repo_creation) %></ br>
 <% end %>
+
+<% end %>
--- a/app/views/users/edit.rhtml	Wed Mar 23 11:33:36 2011 +0000
+++ b/app/views/users/edit.rhtml	Mon Mar 28 17:50:25 2011 +0100
@@ -8,3 +8,4 @@
 <%= render_tabs user_settings_tabs %>
 
 <% html_title(l(:label_user), @user.login, l(:label_administration)) -%>
+
--- a/config/locales/en-GB.yml	Wed Mar 23 11:33:36 2011 +0000
+++ b/config/locales/en-GB.yml	Mon Mar 28 17:50:25 2011 +0100
@@ -296,6 +296,9 @@
   field_group_by: Group results by
   field_sharing: Sharing
   
+  setting_external_repository: "In the case you wish to follow an external repository"
+  setting_external_repository_url: "The external repository URL"
+  label_repository_external_url: "External rep URL"
   setting_app_title: Application title
   setting_app_subtitle: Application subtitle
   setting_welcome_text: Welcome text
@@ -479,6 +482,7 @@
   label_information_plural: Information
   label_please_login: Please log in
   label_register: Register
+  label_terms_and_conditions: Terms & Conditions for use of code.soundsoftware.ac.uk
   label_login_with_open_id_option: or login with OpenID
   label_password_lost: Lost password
   label_home: Home
@@ -619,6 +623,7 @@
   label_not_contains: doesn't contain
   label_day_plural: days
   label_repository: Repository
+  label_is_external_repository: External?
   label_repository_plural: Repositories
   label_browse: Browse
   label_modification: "{{count}} change"
@@ -901,6 +906,9 @@
   text_settings_repo_creation: The repository for a project should be set up automatically within a few minutes of the project being created.<br>You should not have to adjust any settings here; please check again in ten minutes.
   text_files_active_change: <br>Click the star to switch active status for a download on or off.<br>Active files will be shown more prominently in the download page.
   
+  text_settings_repo_is_internal: The repository for this project is an internal Mercurial Repository, hosted by SoundSoftware.ac.uk. 
+  text_settings_repo_is_external: You are tracking an external repository, with a mirror Mercurial repository hosted by SoundSoftware.ac.uk.
+
   default_role_manager: Manager
   default_role_developer: Developer
   default_role_reporter: Reporter
--- a/config/locales/en.yml	Wed Mar 23 11:33:36 2011 +0000
+++ b/config/locales/en.yml	Mon Mar 28 17:50:25 2011 +0100
@@ -305,7 +305,10 @@
   field_assigned_to_role: "Assignee's role"
   field_text: Text field
   field_visible: Visible
-  
+ 
+  setting_external_repository: "Select this if the project's main repository is hosted somewhere else"
+  setting_external_repository_url: "The URL of the existing external repository. Must be publicly accessible without a password"
+  label_repository_external_url: "External repository URL"
   setting_tipoftheday_text: Tip of the Day
   setting_notifications_text: Notifications
   field_terms_and_conditions: 'Terms and Conditions:'
@@ -490,6 +493,8 @@
   label_information_plural: Information
   label_please_login: Please log in
   label_register: Register
+  label_terms_and_conditions: Terms & Conditions for use of code.soundsoftware.ac.uk
+  label_accept_terms_and_conditions: I have read the terms and conditions and fully accept them
   label_login_with_open_id_option: or login with OpenID
   label_password_lost: Lost password
   label_home: Home
@@ -631,6 +636,7 @@
   label_not_contains: doesn't contain
   label_day_plural: days
   label_repository: Repository
+  label_is_external_repository: Track an external repository
   label_repository_plural: Repositories
   label_browse: Browse
   label_modification: "{{count}} change"
@@ -914,7 +920,7 @@
   text_enumeration_destroy_question: "{{count}} objects are assigned to this value."
   text_enumeration_category_reassign_to: 'Reassign them to this value:'
   text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
-  text_repository_usernames_mapping: "Select or update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
+  text_repository_usernames_mapping: "Select the project member associated with each username found in the repository log.\nUsers whose name or email matches that in the repository are mapped automatically."
   text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
   text_custom_field_possible_values_info: 'One line for each value'
   text_wiki_page_destroy_question: "This page has {{descendants}} child page(s) and descendant(s). What do you want to do?"
@@ -924,8 +930,14 @@
   text_own_membership_delete_confirmation: "You are about to remove some or all of your permissions and may no longer be able to edit this project after that.\nAre you sure you want to continue?"
   text_zoom_in: Zoom in
   text_zoom_out: Zoom out
-  text_settings_repo_creation: The repository for a project should be set up automatically within a few minutes of the project being created.<br>You should not have to adjust any settings here.<br>Please check again in ten minutes, and <a href="/projects/soundsoftware-site/wiki/Help">contact us</a> if there is any problem.
+  text_settings_repo_creation: <b>Creating repository...</b></p><p>The source code repository for a project will be set up automatically within a few minutes of the project being created.</p><p>Please check again in five minutes, and <a href="/projects/soundsoftware-site/wiki/Help">contact us</a> if there is any problem.</p><p>If you wish to use this project to track a repository that is already hosted somewhere else, please wait until the repository has been created here and then return to this settings page to configure it.</p><p>If you don't want a repository at all, go to the Modules tab and switch it off there.
   text_files_active_change: <br>Click the star to switch active status for a download on or off.<br>Active files will be shown more prominently in the download page.
+  text_settings_repo_explanation: <b>External repositories</b><p>Normally your project's primary repository will be the Mercurial repository hosted at this site.<p>However, if you already have your project hosted somewhere else, you can specify your existing external repository's URL here &ndash; then this site will track that repository in a read-only &ldquo;mirror&rdquo; copy.  External Mercurial, git and Subversion repositories can be tracked. Note that you cannot switch to an external repository if you have already made any commits to the repository hosted here.
+  text_settings_repo_is_internal: Currently the repository hosted at this site is the primary repository for this project.
+  text_settings_repo_is_external: Currently the repository hosted at this site is a read-only copy of an external repository.
+  text_settings_repo_need_help: Please <a href="/projects/soundsoftware-site/wiki/Help">contact us</a> if you need help deciding how best to set this up.<br>We can also import complete revision history from other systems into a new primary repository for you if you wish.
+
+
  
   default_role_manager: Manager
   default_role_developer: Developer
--- a/config/routes.rb	Wed Mar 23 11:33:36 2011 +0000
+++ b/config/routes.rb	Mon Mar 28 17:50:25 2011 +0100
@@ -236,6 +236,7 @@
   map.with_options :controller => 'sys' do |sys|
     sys.connect 'sys/projects.:format', :action => 'projects', :conditions => {:method => :get}
     sys.connect 'sys/projects/:id/repository.:format', :action => 'create_project_repository', :conditions => {:method => :post}
+    sys.connect 'sys/projects/:id/external-repository.:format', :action => 'get_external_repo_url', :conditions => {:method => :get}
     sys.connect 'sys/projects/:id/embedded.:format', :action => 'set_embedded_active', :conditions => { :method => :post }
   end
  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/db/migrate/20110207142856_add_ext_rep_to_repositories.rb	Mon Mar 28 17:50:25 2011 +0100
@@ -0,0 +1,11 @@
+class AddExtRepToRepositories < ActiveRecord::Migration
+  def self.up
+    add_column :repositories, :is_external, :bool
+    add_column :repositories, :external_url, :string
+  end
+
+  def self.down
+    remove_column :repositories, :is_external
+    remove_column :repositories, :external_url
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extra/soundsoftware/convert-external-repos.rb	Mon Mar 28 17:50:25 2011 +0100
@@ -0,0 +1,173 @@
+#!/usr/bin/env ruby
+
+# == Synopsis
+#
+# convert-external-repos: Update local Mercurial mirrors of external repos,
+# by running an external command for each project requiring an update.
+#
+# == Usage
+#
+#    convert-external-repos [OPTIONS...] -s [DIR] -r [HOST]
+#     
+# == Arguments (mandatory)
+#
+#   -s, --scm-dir=DIR         use DIR as base directory for repositories
+#   -r, --redmine-host=HOST   assume Redmine is hosted on HOST. Examples:
+#                             -r redmine.example.net
+#                             -r http://redmine.example.net
+#                             -r https://example.net/redmine
+#   -k, --key=KEY             use KEY as the Redmine API key
+#   -c, --command=COMMAND     use this command to update each external
+#                             repository: command is called with the name
+#                             of the project, the path to its repo, and
+#                             its external repo url as its three args
+#
+# == Options
+#
+#   --http-user=USER          User for HTTP Basic authentication with Redmine WS
+#   --http-pass=PASSWORD      Password for Basic authentication with Redmine WS
+#   -t, --test                only show what should be done
+#   -h, --help                show help and exit
+#   -v, --verbose             verbose
+#   -V, --version             print version and exit
+#   -q, --quiet               no log
+
+
+require 'getoptlong'
+require 'rdoc/usage'
+require 'find'
+require 'etc'
+
+Version = "1.0"
+
+opts = GetoptLong.new(
+                      ['--scm-dir',      '-s', GetoptLong::REQUIRED_ARGUMENT],
+                      ['--redmine-host', '-r', GetoptLong::REQUIRED_ARGUMENT],
+                      ['--key',          '-k', GetoptLong::REQUIRED_ARGUMENT],
+                      ['--http-user',          GetoptLong::REQUIRED_ARGUMENT],
+                      ['--http-pass',          GetoptLong::REQUIRED_ARGUMENT],
+                      ['--command' ,     '-c', GetoptLong::REQUIRED_ARGUMENT],
+                      ['--test',         '-t', GetoptLong::NO_ARGUMENT],
+                      ['--verbose',      '-v', GetoptLong::NO_ARGUMENT],
+                      ['--version',      '-V', GetoptLong::NO_ARGUMENT],
+                      ['--help'   ,      '-h', GetoptLong::NO_ARGUMENT],
+                      ['--quiet'  ,      '-q', GetoptLong::NO_ARGUMENT]
+                      )
+
+$verbose      = 0
+$quiet        = false
+$redmine_host = ''
+$repos_base   = ''
+$http_user    = ''
+$http_pass    = ''
+$test         = false
+
+def log(text, options={})
+  level = options[:level] || 0
+  puts text unless $quiet or level > $verbose
+  exit 1 if options[:exit]
+end
+
+def system_or_raise(command)
+  raise "\"#{command}\" failed" unless system command
+end
+
+begin
+  opts.each do |opt, arg|
+    case opt
+    when '--scm-dir';        $repos_base   = arg.dup
+    when '--redmine-host';   $redmine_host = arg.dup
+    when '--key';            $api_key      = arg.dup
+    when '--http-user';      $http_user    = arg.dup
+    when '--http-pass';      $http_pass    = arg.dup
+    when '--command';        $command      = arg.dup
+    when '--verbose';        $verbose += 1
+    when '--test';           $test = true
+    when '--version';        puts Version; exit
+    when '--help';           RDoc::usage
+    when '--quiet';          $quiet = true
+    end
+  end
+rescue
+  exit 1
+end
+
+if $test
+  log("running in test mode")
+end
+
+if ($redmine_host.empty? or $repos_base.empty? or $command.empty?)
+  RDoc::usage
+end
+
+unless File.directory?($repos_base)
+  log("directory '#{$repos_base}' doesn't exist", :exit => true)
+end
+
+begin
+  require 'active_resource'
+rescue LoadError
+  log("This script requires activeresource.\nRun 'gem install activeresource' to install it.", :exit => true)
+end
+
+class Project < ActiveResource::Base
+  self.headers["User-agent"] = "SoundSoftware external repository converter/#{Version}"
+end
+
+log("querying Redmine for projects...", :level => 1);
+
+$redmine_host.gsub!(/^/, "http://") unless $redmine_host.match("^https?://")
+$redmine_host.gsub!(/\/$/, '')
+
+Project.site = "#{$redmine_host}/sys";
+Project.user = $http_user;
+Project.password = $http_pass;
+
+begin
+  # Get all active projects that have the Repository module enabled
+  projects = Project.find(:all, :params => {:key => $api_key})
+rescue => e
+  log("Unable to connect to #{Project.site}: #{e}", :exit => true)
+end
+
+if projects.nil?
+  log('no project found, perhaps you forgot to "Enable WS for repository management"', :exit => true)
+end
+
+log("retrieved #{projects.size} projects", :level => 1)
+
+projects.each do |project|
+  log("treating project #{project.name}", :level => 1)
+
+  if project.identifier.empty?
+    log("\tno identifier for project #{project.name}")
+    next
+  elsif not project.identifier.match(/^[a-z0-9\-]+$/)
+    log("\tinvalid identifier for project #{project.name} : #{project.identifier}");
+    next
+  end
+
+  if !project.respond_to?(:repository) or !project.repository.is_external?
+    log("\tproject #{project.identifier} does not use an external repository");
+    next
+  end
+
+  external_url = project.repository.external_url;
+  log("\tproject #{project.identifier} has external repository url #{external_url}");
+
+  if !external_url.match(/^[a-z][a-z+]{0,8}[a-z]:\/\//)
+    log("\tthis doesn't look like a plausible url to me, skipping")
+    next
+  end
+
+  repos_path = File.join($repos_base, project.identifier).gsub(File::SEPARATOR, File::ALT_SEPARATOR || File::SEPARATOR)
+
+  unless File.directory?(repos_path)
+    log("\tproject repo directory '#{repos_path}' doesn't exist")
+    next
+  end
+
+  system($command, project.identifier, repos_path, external_url)
+
+end
+  
--- a/extra/soundsoftware/reposman-soundsoftware.rb	Wed Mar 23 11:33:36 2011 +0000
+++ b/extra/soundsoftware/reposman-soundsoftware.rb	Mon Mar 28 17:50:25 2011 +0100
@@ -9,12 +9,12 @@
 #    reposman [OPTIONS...] -s [DIR] -r [HOST]
 #     
 #  Examples:
-#    reposman --svn-dir=/var/svn --redmine-host=redmine.example.net --scm subversion
+#    reposman --scm-dir=/var/svn --redmine-host=redmine.example.net --scm subversion
 #    reposman -s /var/git -r redmine.example.net -u http://svn.example.net --scm git
 #
 # == Arguments (mandatory)
 #
-#   -s, --svn-dir=DIR         use DIR as base directory for svn repositories
+#   -s, --scm-dir=DIR         use DIR as base directory for repositories
 #   -r, --redmine-host=HOST   assume Redmine is hosted on HOST. Examples:
 #                             -r redmine.example.net
 #                             -r http://redmine.example.net
@@ -70,7 +70,7 @@
 SUPPORTED_SCM = %w( Subversion Darcs Mercurial Bazaar Git Filesystem )
 
 opts = GetoptLong.new(
-                      ['--svn-dir',      '-s', GetoptLong::REQUIRED_ARGUMENT],
+                      ['--scm-dir',      '-s', GetoptLong::REQUIRED_ARGUMENT],
                       ['--redmine-host', '-r', GetoptLong::REQUIRED_ARGUMENT],
                       ['--key',          '-k', GetoptLong::REQUIRED_ARGUMENT],
                       ['--owner',        '-o', GetoptLong::REQUIRED_ARGUMENT],
@@ -133,7 +133,7 @@
 begin
   opts.each do |opt, arg|
     case opt
-    when '--svn-dir';        $repos_base   = arg.dup
+    when '--scm-dir';        $repos_base   = arg.dup
     when '--redmine-host';   $redmine_host = arg.dup
     when '--key';            $api_key      = arg.dup
     when '--owner';          $svn_owner    = arg.dup; $use_groupid = false;
@@ -174,7 +174,7 @@
 end
 
 unless File.directory?($repos_base)
-  log("directory '#{$repos_base}' doesn't exists", :exit => true)
+  log("directory '#{$repos_base}' doesn't exist", :exit => true)
 end
 
 begin
@@ -184,7 +184,7 @@
 end
 
 class Project < ActiveResource::Base
-  self.headers["User-agent"] = "Redmine repository manager/#{Version}"
+  self.headers["User-agent"] = "SoundSoftware repository manager/#{Version}"
 end
 
 log("querying Redmine for projects...", :level => 1);
@@ -346,5 +346,14 @@
     log("\trepository #{repos_path} created");
   end
 
+  if project.respond_to?(:repository) and project.repository.is_external?
+    external_url = project.repository.external_url;
+    log("\tproject #{project.identifier} has external repository url #{external_url}");
+    if !external_url.match(/^https?:/)
+      # wot about git, svn/svn+ssh, etc? should we just check for a scheme at all?
+      log("\tthis is not an http(s) url: ignoring");
+    end
+  end
+
 end
   
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extra/soundsoftware/update-external-repo.sh	Mon Mar 28 17:50:25 2011 +0100
@@ -0,0 +1,107 @@
+#!/bin/sh
+
+mirrordir="/var/mirror"
+logfile="/var/www/test-cannam/log/update-external-repo.log"
+
+project="$1"
+local_repo="$2"
+remote_repo="$3"
+
+if [ -z "$project" ] || [ -z "$local_repo" ] || [ -z "$remote_repo" ]; then
+    echo "Usage: $0 <project> <local-repo-path> <remote-repo-url>"
+    exit 2
+fi
+
+  # We need to handle different source repository types separately.
+  # 
+  # The convert extension cannot convert directly from a remote git
+  # repo; we'd have to mirror to a local repo first.  Incremental
+  # conversions do work though.  The hg-git plugin will convert
+  # directly from remote repositories, but not via all schemes
+  # (e.g. https is not currently supported).  It's probably easier to
+  # use git itself to clone locally and then convert or hg-git from
+  # there.
+  # 
+  # We can of course convert directly from remote Subversion repos,
+  # but we need to keep track of that -- you can ask to convert into a
+  # repo that has already been used (for Mercurial) and it'll do so
+  # happily; we don't want that.
+  #
+  # Converting from a remote Hg repo should be fine!
+  #
+  # One other thing -- we can't actually tell the difference between
+  # the various SCM types based on URL alone.  We have to try them
+  # (ideally in an order determined by a guess based on the URL) and
+  # see what happens.
+
+project_mirror="$mirrordir/$project"
+mkdir -p "$project_mirror"
+project_repo_mirror="$project_mirror/repo"
+
+  # Some test URLs:
+  # 
+  # http://aimc.googlecode.com/svn/trunk/
+  # http://aimc.googlecode.com/svn/
+  # http://vagar.org/git/flam
+  # https://github.com/wslihgt/IMMF0salience.git
+  # http://hg.breakfastquay.com/dssi-vst/
+  # git://github.com/schacon/hg-git.git
+  # http://svn.drobilla.net/lad (externals!)
+
+# If we are importing from another distributed system, then our aim is
+# to create either a Hg repo or a git repo at $project_mirror, which
+# we can then pull from directly to the Hg repo at $local_repo (using
+# hg-git, in the case of a git repo).
+
+# Importing from SVN, we should use hg convert directly to the target
+# hg repo (or should we?) but keep a record of the last changeset ID
+# we brought in, and test each time whether it matches the last
+# changeset ID actually in the repo
+
+success=""
+
+if [ -d "$project_repo_mirror" ]; then
+
+    # Repo mirror exists: update it
+    echo "$$: Mirror for project $project exists at $project_repo_mirror, updating" 1>&2
+
+    if [ -d "$project_repo_mirror/.hg" ]; then
+	hg --config extensions.convert= convert --datesort "$remote_repo" "$project_repo_mirror" && success=true
+    elif [ -d "$project_repo_mirror/.git" ]; then
+	( cd "$project_repo_mirror" && git fetch "$remote_repo" ) && success=true
+    else 
+	echo "$$: ERROR: Repo mirror dir $project_repo_mirror exists but is not an Hg or git repo" 1>&2
+    fi
+
+else
+
+    # Repo mirror does not exist yet
+    echo "$$: Mirror for project $project does not yet exist at $project_repo_mirror, trying to convert or clone" 1>&2
+
+    case "$remote_repo" in
+	*git*) 
+	    git clone "$remote_repo" "$project_repo_mirror" ||
+	    hg --config extensions.convert= convert --datesort "$remote_repo" "$project_repo_mirror"
+	    ;;
+	*)
+	    hg --config extensions.convert= convert --datesort "$remote_repo" "$project_repo_mirror" ||
+	    git clone "$remote_repo" "$project_repo_mirror" ||
+	    hg clone "$remote_repo" "$project_repo_mirror"
+	    ;;
+    esac && success=true
+
+fi
+	
+echo "Success=$success"
+
+if [ -n "$success" ]; then
+    echo "$$: Update successful, pulling into local repo at $local_repo"
+    if [ -d "$project_repo_mirror/.git" ]; then
+	if [ ! -d "$local_repo" ]; then
+	    hg init "$local_repo"
+	fi
+	( cd "$local_repo" && hg --config extensions.hgext.git= pull "$project_repo_mirror" )
+    else 
+	( cd "$local_repo" && hg pull "$project_repo_mirror" )
+    fi
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/public/javascripts/repository.js	Mon Mar 28 17:50:25 2011 +0100
@@ -0,0 +1,7 @@
+function toggle_ext_url(){
+	if($('repository_is_external').checked)
+	    $('repository_external_url').enable();
+	else
+	    $('repository_external_url').disable();
+}
+
--- a/public/javascripts/ssamr_registration.js	Wed Mar 23 11:33:36 2011 +0000
+++ b/public/javascripts/ssamr_registration.js	Mon Mar 28 17:50:25 2011 +0100
@@ -4,13 +4,12 @@
 
 /* institution related functions */
 Event.observe(window, 'load',
-  function() {
-		
+  function() {		
 		if(!$('ssamr_user_details_institution_type_true').checked && $('ssamr_user_details_institution_type_true').checked){
-  			$('ssamr_user_details_other_institution').disable();
-  			$('ssamr_user_details_institution_id').enable();
-  			$('ssamr_user_details_institution_type_true').checked = true;
-  			$('ssamr_user_details_institution_type_false').checked = false;
+		    $('ssamr_user_details_other_institution').disable();
+		    $('ssamr_user_details_institution_id').enable();
+		    $('ssamr_user_details_institution_type_true').checked = true;
+		    $('ssamr_user_details_institution_type_false').checked = false;
 		}
 	}
 );