# HG changeset patch # User Chris Cannam # Date 1301329976 -3600 # Node ID 6c56a595dc1c2af031acde6fef07d642c96789e3 # Parent 93b4cfd3aaaae757181b642184bd50131f73365e# Parent defe55be97b9d9fb210123aa781221dd144a6e7e Merge from branch "feature_73" diff -r 93b4cfd3aaaa -r 6c56a595dc1c app/controllers/sys_controller.rb --- a/app/controllers/sys_controller.rb Mon Mar 28 17:30:04 2011 +0100 +++ b/app/controllers/sys_controller.rb Mon Mar 28 17:32:56 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 diff -r 93b4cfd3aaaa -r 6c56a595dc1c app/helpers/repositories_helper.rb --- a/app/helpers/repositories_helper.rb Mon Mar 28 17:30:04 2011 +0100 +++ b/app/helpers/repositories_helper.rb Mon Mar 28 17:32:56 2011 +0100 @@ -145,12 +145,6 @@ send(method, form, repository) if repository.is_a?(Repository) && respond_to?(method) && method != 'repository_field_tags' end - - def ssamr_scm_update(repository) - check_box_tag('repository_scm', value = "1", checked = false, onchange => remote_function(:url => { :controller => 'repositories', :action => 'ssamr_edit', :id => @project }, :method => :get, :with => "Form.serialize(this.form)")) - - end - def scm_select_tag(repository) scm_options = [["--- #{l(:actionview_instancetag_blank_option)} ---", '']] Redmine::Scm::Base.all.each do |scm| diff -r 93b4cfd3aaaa -r 6c56a595dc1c app/views/projects/settings/_repository.rhtml --- a/app/views/projects/settings/_repository.rhtml Mon Mar 28 17:30:04 2011 +0100 +++ b/app/views/projects/settings/_repository.rhtml Mon Mar 28 17:32:56 2011 +0100 @@ -10,17 +10,16 @@
+<% if @repository %> + <%= l(:text_settings_repo_explanation) %> br> + <% if @repository.is_external %> +
<%= l(:text_settings_repo_is_external) %> br> + <% else %> +
<%= l(:text_settings_repo_is_internal) %> br> + <% end %> +
-<% if @repository %> - <% if @repository.is_external %> - <%= l(:text_settings_repo_is_external) %> br> - <% else %> - <%= l(:text_settings_repo_is_internal) %> br> -<% end %> - <% else %> - <%= l(:text_settings_repo_creation) %> br> -<% end %> - @@ -28,16 +27,17 @@
<%= label_tag('repository_is_external', l(:label_is_external_repository)) %>
<%= check_box :repository, :is_external, :onclick => "toggle_ext_url()" %>
- <%= l(:setting_external_repository) %>
+
<%= l(:setting_external_repository) %>
<%= label_tag('repository_external_url', l(:label_repository_external_url)) %>
- <%= text_field :repository, :external_url, :disabled => true %>
- <%= l(:setting_external_repository_url) %>
+ <%= text_field :repository, :external_url, :disabled => !(@repository and @repository.is_external) %>
+
<%= l(:setting_external_repository_url) %>
<%= l(:text_settings_repo_need_help) %>
The source code repository for a project will be set up automatically within a few minutes of the project being created.
Please check again in five minutes, and contact us if there is any problem.
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.
If you don't want a repository at all, go to the Modules tab and switch it off there. + text_settings_repo_explanation: External repositories
Normally your project's primary repository will be the Mercurial repository hosted at this site.
However, if you already have your project hosted somewhere else, you can specify your existing external repository's URL here – then this site will track that repository in a read-only “mirror” 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 contact us if you need help deciding how best to set this up.
We can also import complete revision history from other systems into a new primary repository for you if you wish.
diff -r 93b4cfd3aaaa -r 6c56a595dc1c config/routes.rb
--- a/config/routes.rb Mon Mar 28 17:30:04 2011 +0100
+++ b/config/routes.rb Mon Mar 28 17:32:56 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
diff -r 93b4cfd3aaaa -r 6c56a595dc1c extra/soundsoftware/convert-external-repos.rb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extra/soundsoftware/convert-external-repos.rb Mon Mar 28 17:32:56 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
+
diff -r 93b4cfd3aaaa -r 6c56a595dc1c extra/soundsoftware/reposman-soundsoftware.rb
--- a/extra/soundsoftware/reposman-soundsoftware.rb Mon Mar 28 17:30:04 2011 +0100
+++ b/extra/soundsoftware/reposman-soundsoftware.rb Mon Mar 28 17:32:56 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
diff -r 93b4cfd3aaaa -r 6c56a595dc1c extra/soundsoftware/update-external-repo.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extra/soundsoftware/update-external-repo.sh Mon Mar 28 17:32:56 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