@@ -0,0 +1,55 | |||||
|
1 | # Redmine - project management software | |||
|
2 | # Copyright (C) 2006-2009 Jean-Philippe Lang | |||
|
3 | # | |||
|
4 | # This program is free software; you can redistribute it and/or | |||
|
5 | # modify it under the terms of the GNU General Public License | |||
|
6 | # as published by the Free Software Foundation; either version 2 | |||
|
7 | # of the License, or (at your option) any later version. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
14 | # You should have received a copy of the GNU General Public License | |||
|
15 | # along with this program; if not, write to the Free Software | |||
|
16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
|
17 | ||||
|
18 | require File.dirname(__FILE__) + '/../test_helper' | |||
|
19 | require 'sys_controller' | |||
|
20 | ||||
|
21 | # Re-raise errors caught by the controller. | |||
|
22 | class SysController; def rescue_action(e) raise e end; end | |||
|
23 | ||||
|
24 | class SysControllerTest < Test::Unit::TestCase | |||
|
25 | fixtures :projects, :repositories | |||
|
26 | ||||
|
27 | def setup | |||
|
28 | @controller = SysController.new | |||
|
29 | @request = ActionController::TestRequest.new | |||
|
30 | @response = ActionController::TestResponse.new | |||
|
31 | Setting.sys_api_enabled = '1' | |||
|
32 | end | |||
|
33 | ||||
|
34 | def test_projects_with_repository_enabled | |||
|
35 | get :projects | |||
|
36 | assert_response :success | |||
|
37 | assert_equal 'application/xml', @response.content_type | |||
|
38 | with_options :tag => 'projects' do |test| | |||
|
39 | test.assert_tag :children => { :count => Project.active.has_module(:repository).count } | |||
|
40 | end | |||
|
41 | end | |||
|
42 | ||||
|
43 | def test_create_project_repository | |||
|
44 | assert_nil Project.find(4).repository | |||
|
45 | ||||
|
46 | post :create_project_repository, :id => 4, | |||
|
47 | :vendor => 'Subversion', | |||
|
48 | :repository => { :url => 'file:///create/project/repository/subproject2'} | |||
|
49 | assert_response :created | |||
|
50 | ||||
|
51 | r = Project.find(4).repository | |||
|
52 | assert r.is_a?(Repository::Subversion) | |||
|
53 | assert_equal 'file:///create/project/repository/subproject2', r.url | |||
|
54 | end | |||
|
55 | end |
@@ -1,5 +1,5 | |||||
1 |
# |
|
1 | # Redmine - project management software | |
2 |
# Copyright (C) 2006-200 |
|
2 | # Copyright (C) 2006-2009 Jean-Philippe Lang | |
3 | # |
|
3 | # | |
4 | # This program is free software; you can redistribute it and/or |
|
4 | # This program is free software; you can redistribute it and/or | |
5 | # modify it under the terms of the GNU General Public License |
|
5 | # modify it under the terms of the GNU General Public License | |
@@ -16,31 +16,35 | |||||
16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
17 |
|
17 | |||
18 | class SysController < ActionController::Base |
|
18 | class SysController < ActionController::Base | |
19 | wsdl_service_name 'Sys' |
|
19 | before_filter :check_enabled | |
20 | web_service_api SysApi |
|
|||
21 | web_service_scaffold :invoke |
|
|||
22 |
|
20 | |||
23 | before_invocation :check_enabled |
|
21 | def projects | |
24 |
|
22 | p = Project.active.has_module(:repository).find(:all, :include => :repository, :order => 'identifier') | ||
25 | # Returns the projects list, with their repositories |
|
23 | render :xml => p.to_xml(:include => :repository) | |
26 | def projects_with_repository_enabled |
|
|||
27 | Project.has_module(:repository).find(:all, :include => :repository, :order => 'identifier') |
|
|||
28 | end |
|
24 | end | |
29 |
|
25 | |||
30 | # Registers a repository for the given project identifier |
|
26 | def create_project_repository | |
31 | def repository_created(identifier, vendor, url) |
|
27 | project = Project.find(params[:id]) | |
32 | project = Project.find_by_identifier(identifier) |
|
28 | if project.repository | |
33 | # Do not create the repository if the project has already one |
|
29 | render :nothing => true, :status => 409 | |
34 | return 0 unless project && project.repository.nil? |
|
30 | else | |
35 |
logger. |
|
31 | logger.info "Repository for #{project.name} was reported to be created by #{request.remote_ip}." | |
36 |
repository = Repository.factory(vendor, |
|
32 | project.repository = Repository.factory(params[:vendor], params[:repository]) | |
37 | repository.save |
|
33 | if project.repository && project.repository.save | |
38 | repository.id || 0 |
|
34 | render :xml => project.repository, :status => 201 | |
|
35 | else | |||
|
36 | render :nothing => true, :status => 422 | |||
|
37 | end | |||
|
38 | end | |||
39 | end |
|
39 | end | |
40 |
|
40 | |||
41 | protected |
|
41 | protected | |
42 |
|
42 | |||
43 |
def check_enabled |
|
43 | def check_enabled | |
44 | Setting.sys_api_enabled? |
|
44 | User.current = nil | |
|
45 | unless Setting.sys_api_enabled? | |||
|
46 | render :nothing => 'Access denied. Repository management WS is disabled.', :status => 403 | |||
|
47 | return false | |||
|
48 | end | |||
45 | end |
|
49 | end | |
46 | end |
|
50 | end |
@@ -246,10 +246,11 ActionController::Routing::Routes.draw do |map| | |||||
246 | omap.repositories_entry 'repositories/annotate/:id/*path', :action => 'annotate' |
|
246 | omap.repositories_entry 'repositories/annotate/:id/*path', :action => 'annotate' | |
247 | omap.connect 'repositories/revision/:id/:rev', :action => 'revision' |
|
247 | omap.connect 'repositories/revision/:id/:rev', :action => 'revision' | |
248 | end |
|
248 | end | |
249 |
|
|
249 | ||
250 | # Allow downloading Web Service WSDL as a file with an extension |
|
250 | map.with_options :controller => 'sys' do |sys| | |
251 | # instead of a file named 'wsdl' |
|
251 | sys.connect 'sys/projects.:format', :action => 'projects', :conditions => {:method => :get} | |
252 | map.connect ':controller/service.wsdl', :action => 'wsdl' |
|
252 | sys.connect 'sys/projects/:id/repository.:format', :action => 'create_project_repository', :conditions => {:method => :post} | |
|
253 | end | |||
253 |
|
254 | |||
254 | # Install the default route as the lowest priority. |
|
255 | # Install the default route as the lowest priority. | |
255 | map.connect ':controller/:action/:id' |
|
256 | map.connect ':controller/:action/:id' |
@@ -57,11 +57,10 | |||||
57 |
|
57 | |||
58 | require 'getoptlong' |
|
58 | require 'getoptlong' | |
59 | require 'rdoc/usage' |
|
59 | require 'rdoc/usage' | |
60 | require 'soap/wsdlDriver' |
|
|||
61 | require 'find' |
|
60 | require 'find' | |
62 | require 'etc' |
|
61 | require 'etc' | |
63 |
|
62 | |||
64 |
Version = "1. |
|
63 | Version = "1.2" | |
65 | SUPPORTED_SCM = %w( Subversion Darcs Mercurial Bazaar Git Filesystem ) |
|
64 | SUPPORTED_SCM = %w( Subversion Darcs Mercurial Bazaar Git Filesystem ) | |
66 |
|
65 | |||
67 | opts = GetoptLong.new( |
|
66 | opts = GetoptLong.new( | |
@@ -164,21 +163,28 unless File.directory?($repos_base) | |||||
164 | log("directory '#{$repos_base}' doesn't exists", :exit => true) |
|
163 | log("directory '#{$repos_base}' doesn't exists", :exit => true) | |
165 | end |
|
164 | end | |
166 |
|
165 | |||
|
166 | begin | |||
|
167 | require 'activeresource' | |||
|
168 | rescue LoadError | |||
|
169 | log("This script requires activeresource.\nRun 'gem install activeresource' to install it.", :exit => true) | |||
|
170 | end | |||
|
171 | ||||
|
172 | class Project < ActiveResource::Base; end | |||
|
173 | ||||
167 | log("querying Redmine for projects...", :level => 1); |
|
174 | log("querying Redmine for projects...", :level => 1); | |
168 |
|
175 | |||
169 | $redmine_host.gsub!(/^/, "http://") unless $redmine_host.match("^https?://") |
|
176 | $redmine_host.gsub!(/^/, "http://") unless $redmine_host.match("^https?://") | |
170 | $redmine_host.gsub!(/\/$/, '') |
|
177 | $redmine_host.gsub!(/\/$/, '') | |
171 |
|
178 | |||
172 |
|
|
179 | Project.site = "#{$redmine_host}/sys"; | |
173 |
|
180 | |||
174 | begin |
|
181 | begin | |
175 | soap = SOAP::WSDLDriverFactory.new(wsdl_url).create_rpc_driver |
|
182 | # Get all active projects that have the Repository module enabled | |
|
183 | projects = Project.find(:all) | |||
176 | rescue => e |
|
184 | rescue => e | |
177 |
log("Unable to connect to #{ |
|
185 | log("Unable to connect to #{Project.site}: #{e}", :exit => true) | |
178 | end |
|
186 | end | |
179 |
|
187 | |||
180 | projects = soap.ProjectsWithRepositoryEnabled |
|
|||
181 |
|
||||
182 | if projects.nil? |
|
188 | if projects.nil? | |
183 | log('no project found, perhaps you forgot to "Enable WS for repository management"', :exit => true) |
|
189 | log('no project found, perhaps you forgot to "Enable WS for repository management"', :exit => true) | |
184 | end |
|
190 | end | |
@@ -247,7 +253,7 projects.each do |project| | |||||
247 | else |
|
253 | else | |
248 | # if repository is already declared in redmine, we don't create |
|
254 | # if repository is already declared in redmine, we don't create | |
249 | # unless user use -f with reposman |
|
255 | # unless user use -f with reposman | |
250 |
if $force == false and |
|
256 | if $force == false and project.respond_to?(:repository) | |
251 | log("\trepository for project #{project.identifier} already exists in Redmine", :level => 1) |
|
257 | log("\trepository for project #{project.identifier} already exists in Redmine", :level => 1) | |
252 | next |
|
258 | next | |
253 | end |
|
259 | end | |
@@ -274,11 +280,11 projects.each do |project| | |||||
274 | end |
|
280 | end | |
275 |
|
281 | |||
276 | if $svn_url |
|
282 | if $svn_url | |
277 | ret = soap.RepositoryCreated project.identifier, $scm, "#{$svn_url}#{project.identifier}" |
|
283 | begin | |
278 | if ret > 0 |
|
284 | project.post(:repository, :vendor => $scm, :repository => {:url => "#{$svn_url}#{project.identifier}"}) | |
279 | log("\trepository #{repos_path} registered in Redmine with url #{$svn_url}#{project.identifier}"); |
|
285 | log("\trepository #{repos_path} registered in Redmine with url #{$svn_url}#{project.identifier}"); | |
280 |
e |
|
286 | rescue => e | |
281 |
log("\trepository #{repos_path} not registered in Redmine |
|
287 | log("\trepository #{repos_path} not registered in Redmine: #{e.message}"); | |
282 | end |
|
288 | end | |
283 | end |
|
289 | end | |
284 |
|
290 |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now