changeset 240:6c282df74a30 feature_73

Merge from branch "cannam-pre-20110113-merge"
author Chris Cannam
date Tue, 22 Feb 2011 16:50:58 +0000
parents ed8222a04634 (diff) 7cec015f07ce (current diff)
children 7658d21a1493
files app/controllers/sys_controller.rb config/locales/en-GB.yml config/locales/en.yml config/routes.rb
diffstat 9 files changed, 249 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/app/controllers/sys_controller.rb	Tue Feb 22 16:48:15 2011 +0000
+++ b/app/controllers/sys_controller.rb	Tue Feb 22 16:50:58 2011 +0000
@@ -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/views/projects/settings/_repository.rhtml	Tue Feb 22 16:48:15 2011 +0000
+++ b/app/views/projects/settings/_repository.rhtml	Tue Feb 22 16:50:58 2011 +0000
@@ -11,6 +11,22 @@
 <% end %>
 <p><%= label_tag('repository_scm', l(:label_scm)) %><%= scm_select_tag(@repository) %></p>
 <%= repository_field_tags(f, @repository) if @repository %>
+
+
+<p>
+	<%= label_tag('repository_is_external', l(:label_is_external_repository)) %>
+	<%= check_box :repository, :is_external %> 
+	<%= l(:setting_external_repository) %>
+</p>
+
+
+<p>
+	<%= label_tag('repository_external_url', l(:label_repository_external_url)) %>
+	<%= text_field :repository, :external_url %> 
+	<%= l(:setting_external_repository_url) %>
+</p>
+
+
 </div>
 
 <div class="contextual">
--- a/app/views/users/edit.rhtml	Tue Feb 22 16:48:15 2011 +0000
+++ b/app/views/users/edit.rhtml	Tue Feb 22 16:50:58 2011 +0000
@@ -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	Tue Feb 22 16:48:15 2011 +0000
+++ b/config/locales/en-GB.yml	Tue Feb 22 16:50:58 2011 +0000
@@ -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"
--- a/config/locales/en.yml	Tue Feb 22 16:48:15 2011 +0000
+++ b/config/locales/en.yml	Tue Feb 22 16:50:58 2011 +0000
@@ -305,7 +305,10 @@
   field_assigned_to_role: "Assignee's role"
   field_text: Text field
   field_visible: Visible
-  
+ 
+  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_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: External?
   label_repository_plural: Repositories
   label_browse: Browse
   label_modification: "{{count}} change"
--- a/config/routes.rb	Tue Feb 22 16:48:15 2011 +0000
+++ b/config/routes.rb	Tue Feb 22 16:50:58 2011 +0000
@@ -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	Tue Feb 22 16:50:58 2011 +0000
@@ -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	Tue Feb 22 16:50:58 2011 +0000
@@ -0,0 +1,183 @@
+#!/usr/bin/env ruby
+
+# == Synopsis
+#
+# convert-external-repos: Update local Mercurial mirrors of external repos
+#
+# This command is specific to the SoundSoftware Redmine instance and
+# its use of Mercurial repositories.  It makes use of the hg convert extension.
+#
+# == Usage
+#
+#    convert-external-repos [OPTIONS...] -s [DIR] -r [HOST]
+#     
+# == Arguments (mandatory)
+#
+#   -h, --hg-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
+#
+# == 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(
+                      ['--hg-dir',       '-h', GetoptLong::REQUIRED_ARGUMENT],
+                      ['--redmine-host', '-r', GetoptLong::REQUIRED_ARGUMENT],
+                      ['--key',          '-k', GetoptLong::REQUIRED_ARGUMENT],
+                      ['--http-user',          GetoptLong::REQUIRED_ARGUMENT],
+                      ['--http-pass',          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 '--hg-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 '--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?)
+  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("project repo directory '#{$repos_path}' doesn't exist")
+    next
+  end
+
+  # We need to handle different source repository types separately.
+  # 
+  # The convert extension cannot convert directly from a remote git
+  # repo; we have to mirror to a local repo first.  Incremental
+  # conversions do work though.
+  # 
+  # 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!
+  #
+
+  
+
+end
+  
--- a/extra/soundsoftware/reposman-soundsoftware.rb	Tue Feb 22 16:48:15 2011 +0000
+++ b/extra/soundsoftware/reposman-soundsoftware.rb	Tue Feb 22 16:50:58 2011 +0000
@@ -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