[Fusionforge-commits] FusionForge branch feature/subversion-multiple-repositories-per-project created. v6.0.3-465-gf22c47b

Franck Villaume nerville at libremir.placard.fr.eu.org
Thu Mar 31 15:19:14 CEST 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "FusionForge".

The branch, feature/subversion-multiple-repositories-per-project has been created
        at  f22c47b1d960136ec6d118fee0a9413b0d850a95 (commit)

- Log -----------------------------------------------------------------
https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=f22c47b1d960136ec6d118fee0a9413b0d850a95

commit f22c47b1d960136ec6d118fee0a9413b0d850a95
Author: Franck Villaume <franck.villaume at trivialdev.com>
Date:   Wed Mar 30 23:47:01 2016 +0200

    revert multi-browsing

diff --git a/src/plugins/scmsvn/common/SVNPlugin.class.php b/src/plugins/scmsvn/common/SVNPlugin.class.php
index 8c976ff..e19ad4a 100644
--- a/src/plugins/scmsvn/common/SVNPlugin.class.php
+++ b/src/plugins/scmsvn/common/SVNPlugin.class.php
@@ -233,19 +233,6 @@ some control over it to the project's administrator.");
 								sprintf(_('Browse %s Repository'), 'Subversion')
 			) ;
 		$b .= ']</p>';
-		# Extra repos
-		$result = db_query_params('SELECT repo_name FROM scm_secondary_repos WHERE group_id=$1 AND next_action = $2 AND plugin_id=$3 ORDER BY repo_name',
-								  array($project->getID(),
-										SCM_EXTRA_REPO_ACTION_UPDATE,
-										$this->getID()));
-		$rows = db_numrows($result);
-		$repo_list = array();
-		for ($i=0; $i<$rows; $i++) {
-			$repo_list[] = db_result($result,$i,'repo_name');
-		}
-		foreach ($repo_list as $repo_name) {
-			$b .= '['.util_make_link('/scm/browser.php?group_id='.$project->getID().'&extra='.$repo_name, _('Browse extra Subversion repository')._(': ').$repo_name).']'.html_e('br');
-		}
 		return $b;
 	}
 
@@ -295,12 +282,7 @@ some control over it to the project's administrator.");
 			return;
 		}
 		if ($project->usesPlugin($this->name)) {
-			if ($params['extra']) {
-				$repo_name = $params['extra'];
-			} else {
-				$repo_name = $project->getUnixName();
-			}
-			$iframe_src = '/scm/viewvc.php?root='.$repo_name;
+			$iframe_src = '/scm/viewvc.php?root='.$project->getUnixName();
 			if ($params['commit']) {
 				$iframe_src .= '&view=rev&revision='.$params['commit'];
 			}

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=af4645a834580400b921d82e6d7b372ad310dc7a

commit af4645a834580400b921d82e6d7b372ad310dc7a
Author: Franck Villaume <franck.villaume at trivialdev.com>
Date:   Wed Mar 30 09:09:11 2016 +0200

    setup the extra reponame in the browser page

diff --git a/src/plugins/scmsvn/common/SVNPlugin.class.php b/src/plugins/scmsvn/common/SVNPlugin.class.php
index d184313..8c976ff 100644
--- a/src/plugins/scmsvn/common/SVNPlugin.class.php
+++ b/src/plugins/scmsvn/common/SVNPlugin.class.php
@@ -294,9 +294,13 @@ some control over it to the project's administrator.");
 		if (!$project) {
 			return;
 		}
-
 		if ($project->usesPlugin($this->name)) {
-			$iframe_src = '/scm/viewvc.php?root='.$project->getUnixName();
+			if ($params['extra']) {
+				$repo_name = $params['extra'];
+			} else {
+				$repo_name = $project->getUnixName();
+			}
+			$iframe_src = '/scm/viewvc.php?root='.$repo_name;
 			if ($params['commit']) {
 				$iframe_src .= '&view=rev&revision='.$params['commit'];
 			}

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=61af4d31d064258de4960aac60cd64e68baa3c47

commit 61af4d31d064258de4960aac60cd64e68baa3c47
Author: Franck Villaume <franck.villaume at trivialdev.com>
Date:   Wed Mar 30 08:53:21 2016 +0200

    fix wrong var name + fix permission

diff --git a/src/plugins/scmsvn/common/SVNPlugin.class.php b/src/plugins/scmsvn/common/SVNPlugin.class.php
index 114b5b5..d184313 100644
--- a/src/plugins/scmsvn/common/SVNPlugin.class.php
+++ b/src/plugins/scmsvn/common/SVNPlugin.class.php
@@ -351,15 +351,15 @@ some control over it to the project's administrator.");
 		}
 
 		// Create project-wide secondary repositories
-		$result = db_query_params('SELECT repo_name FROM scm_secondary_repos WHERE group_id=$1 AND next_action = $2 AND plugin_id=$3',
+		$result = db_query_params('SELECT repo_name FROM scm_secondary_repos WHERE group_id = $1 AND next_action = $2 AND plugin_id = $3',
 					   array($project->getID(),
 						  SCM_EXTRA_REPO_ACTION_UPDATE,
 						  $this->getID()));
 		$rows = db_numrows($result);
 		for ($i = 0; $i < $rows; $i++) {
 			$repo_name = db_result($result, $i, 'repo_name');
-			$repodir = $repo_prefix.'/'.$repo_name;
-			if (!is_dir ($repo) || !is_file ("$repo/format")) {
+			$repo = $repo_prefix.'/'.$repo_name;
+			if (!is_dir($repo) || !is_file("$repo/format")) {
 				if (!mkdir($repo, 0700, true)) {
 					return false;
 				}
@@ -385,6 +385,11 @@ some control over it to the project's administrator.");
 				// see after to restrict the top-level directory
 				system ("chmod -R g+rwX,o+rX-w $repo") ;
 			}
+			if ($project->enableAnonSCM()) {
+				system("chmod g+rX-w,o+rX-w $repo") ;
+			} else {
+				system("chmod g+rX-w,o-rwx $repo") ;
+			}
 		}
 
 		// Delete project-wide secondary repositories

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=2ed691d86264c95c8e97da6deb4b57ba3cad2448

commit 2ed691d86264c95c8e97da6deb4b57ba3cad2448
Author: Franck Villaume <franck.villaume at trivialdev.com>
Date:   Tue Mar 29 23:36:20 2016 +0200

    Implement frontend to create/delete new SVN repository

diff --git a/src/plugins/scmsvn/common/SVNPlugin.class.php b/src/plugins/scmsvn/common/SVNPlugin.class.php
index 594fe21..114b5b5 100644
--- a/src/plugins/scmsvn/common/SVNPlugin.class.php
+++ b/src/plugins/scmsvn/common/SVNPlugin.class.php
@@ -55,6 +55,9 @@ some control over it to the project's administrator.");
 		$this->_addHook('scm_regen_apache_auth');
 		$this->_addHook('scm_generate_snapshots');
 		$this->_addHook('scm_gather_stats');
+		$this->_addHook('scm_admin_form');
+		$this->_addHook('scm_add_repo');
+		$this->_addHook('scm_delete_repo');
 		$this->_addHook('activity');
 
 		$this->provides['svn'] = true;
@@ -230,6 +233,19 @@ some control over it to the project's administrator.");
 								sprintf(_('Browse %s Repository'), 'Subversion')
 			) ;
 		$b .= ']</p>';
+		# Extra repos
+		$result = db_query_params('SELECT repo_name FROM scm_secondary_repos WHERE group_id=$1 AND next_action = $2 AND plugin_id=$3 ORDER BY repo_name',
+								  array($project->getID(),
+										SCM_EXTRA_REPO_ACTION_UPDATE,
+										$this->getID()));
+		$rows = db_numrows($result);
+		$repo_list = array();
+		for ($i=0; $i<$rows; $i++) {
+			$repo_list[] = db_result($result,$i,'repo_name');
+		}
+		foreach ($repo_list as $repo_name) {
+			$b .= '['.util_make_link('/scm/browser.php?group_id='.$project->getID().'&extra='.$repo_name, _('Browse extra Subversion repository')._(': ').$repo_name).']'.html_e('br');
+		}
 		return $b;
 	}
 
@@ -333,6 +349,62 @@ some control over it to the project's administrator.");
 		} else {
 			system("chmod g+rX-w,o-rwx $repo") ;
 		}
+
+		// Create project-wide secondary repositories
+		$result = db_query_params('SELECT repo_name FROM scm_secondary_repos WHERE group_id=$1 AND next_action = $2 AND plugin_id=$3',
+					   array($project->getID(),
+						  SCM_EXTRA_REPO_ACTION_UPDATE,
+						  $this->getID()));
+		$rows = db_numrows($result);
+		for ($i = 0; $i < $rows; $i++) {
+			$repo_name = db_result($result, $i, 'repo_name');
+			$repodir = $repo_prefix.'/'.$repo_name;
+			if (!is_dir ($repo) || !is_file ("$repo/format")) {
+				if (!mkdir($repo, 0700, true)) {
+					return false;
+				}
+				$ret = 0;
+				system ("svnadmin create $repo", $ret);
+				if ($ret != 0) {
+					return false;
+				}
+				system ("sed -i '/enable-rep-sharing = false/s/^. //' $repo/db/fsfs.conf") ;
+				// dav/ directory is required by old svn clients (eg. svn 1.6.17 on ubuntu 12.04)
+				if (!is_dir ("$repo/dav")) {
+					mkdir("$repo/dav");
+				}
+				system ("svn mkdir -m'Init' file:///$repo/trunk file:///$repo/tags file:///$repo/branches >/dev/null") ;
+				system ("find $repo -type d -print0 | xargs -r -0 chmod g+s") ;
+				// Allow read/write users to modify the SVN repository
+				$rw_unix_group = $project->getUnixName() . '_scmrw';
+				system("chgrp -R $rw_unix_group $repo");
+				// Allow read-only users to enter the (top-level) directory
+				$ro_unix_group = $project->getUnixName() . '_scmro';
+				system("chgrp $ro_unix_group $repo");
+				// open permissions to allow switching private/public easily
+				// see after to restrict the top-level directory
+				system ("chmod -R g+rwX,o+rX-w $repo") ;
+			}
+		}
+
+		// Delete project-wide secondary repositories
+		$result = db_query_params('SELECT repo_name FROM scm_secondary_repos WHERE group_id=$1 AND next_action = $2 AND plugin_id=$3',
+					   array($project->getID(),
+						  SCM_EXTRA_REPO_ACTION_DELETE,
+						  $this->getID()));
+		$rows = db_numrows ($result);
+		for ($i=0; $i<$rows; $i++) {
+			$repo_name = db_result($result, $i, 'repo_name');
+			$repodir = $repo_prefix.'/'.$repo_name;
+			if (util_is_valid_repository_name($repo_name)) {
+				system("rm -rf $repodir");
+			}
+			db_query_params ('DELETE FROM scm_secondary_repos WHERE group_id=$1 AND repo_name=$2 AND next_action = $3 AND plugin_id=$4',
+					 array($project->getID(),
+						$repo_name,
+						SCM_EXTRA_REPO_ACTION_DELETE,
+						$this->getID()));
+		}
 		$this->regenApacheAuth($params);
 	}
 
@@ -765,6 +837,129 @@ some control over it to the project's administrator.");
 		}
 		return $revisionsArr;
 	}
+
+	function scm_add_repo(&$params) {
+		$project = $this->checkParams($params);
+		if (!$project) {
+			return false;
+		}
+		if (!$project->usesPlugin($this->name)) {
+			return false;
+		}
+
+		if (!isset($params['repo_name'])) {
+			return false;
+		}
+
+		if ($params['repo_name'] == $project->getUnixName()) {
+			$params['error_msg'] = _('Cannot create a secondary repository with the same name as the primary');
+			return false;
+		}
+
+		if (!util_is_valid_repository_name($params['repo_name'])) {
+			$params['error_msg'] = _('This repository name is not valid');
+			return false;
+		}
+
+		$result = db_query_params('SELECT count(*) AS count FROM scm_secondary_repos WHERE group_id=$1 AND repo_name = $2 AND plugin_id=$3',
+					  array($params['group_id'],
+						 $params['repo_name'],
+						 $this->getID()));
+		if (!$result) {
+			$params['error_msg'] = db_error();
+			return false;
+		}
+		if (db_result($result, 0, 'count')) {
+			$params['error_msg'] = sprintf(_('A repository %s already exists'), $params['repo_name']);
+			return false;
+		}
+		$description = '';
+		$clone = '';
+		if (isset($params['description'])) {
+			$description = $params['description'];
+		}
+		if (!$description) {
+			$description = "Subversion repository $params[repo_name] for project ".$project->getUnixName();
+		}
+		$result = db_query_params('INSERT INTO scm_secondary_repos (group_id, repo_name, description, clone_url, plugin_id) VALUES ($1, $2, $3, $4, $5)',
+					   array($params['group_id'],
+						  $params['repo_name'],
+						  $description,
+						  $clone,
+						  $this->getID()));
+		if (!$result) {
+			$params['error_msg'] = db_error();
+			return false;
+		}
+
+		plugin_hook ("scm_admin_update", $params);
+		return true;
+	}
+	function scm_admin_form(&$params) {
+		global $HTML;
+		$project = $this->checkParams($params);
+		if (!$project) {
+			return false;
+		}
+		if (!$project->usesPlugin($this->name)) {
+			return false;
+		}
+
+		session_require_perm('project_admin', $params['group_id']);
+
+		$project_name = $project->getUnixName();
+
+		$result = db_query_params('SELECT repo_name, description FROM scm_secondary_repos WHERE group_id=$1 AND next_action = $2 AND plugin_id=$3 ORDER BY repo_name',
+					  array($params['group_id'],
+						 SCM_EXTRA_REPO_ACTION_UPDATE,
+						 $this->getID()));
+		if (!$result) {
+			$params['error_msg'] = db_error();
+			return false;
+		}
+		$existing_repos = array();
+		while($data = db_fetch_array($result)) {
+			$existing_repos[] = array('repo_name' => $data['repo_name'],
+						  'description' => $data['description']);
+		}
+		if (count($existing_repos) == 0) {
+			echo $HTML->information(_('No extra Subversion repository for project').' '.$project_name);
+		} else {
+			echo html_e('h2', array(), sprintf(ngettext('Extra Subversion repository for project %1$s',
+									'Extra Subversion repositories for project %1$s',
+									count($existing_repos)), $project_name));
+			$titleArr = array(_('Repository name'), ('Initial repository description'), _('Delete'));
+			echo $HTML->listTableTop($titleArr);
+			foreach ($existing_repos as $key => $repo) {
+				$cells = array();
+				$cells[][] = html_e('tt', array(), $repo['repo_name']);
+				$cells[][] = $repo['description'];
+				$deleteForm = $HTML->openForm(array('name' => 'form_delete_repo_'.$repo['repo_name'], 'action' => getStringFromServer('PHP_SELF'), 'method' => 'post'));
+				$deleteForm .= html_e('input', array('type' => 'hidden', 'name' => 'group_id', 'value' => $params['group_id']));
+				$deleteForm .= html_e('input', array('type' => 'hidden', 'name' => 'delete_repository', 'value' => 1));
+				$deleteForm .= html_e('input', array('type' => 'hidden', 'name' => 'repo_name', 'value' => $repo['repo_name']));
+				$deleteForm .= html_e('input', array('type' => 'hidden', 'name' => 'scm_enable_anonymous', 'value' => ($project->enableAnonSCM()? 1 : 0)));
+				$deleteForm .= html_e('input', array('type' => 'submit', 'name' => 'submit', 'value' => _('Delete')));
+				$deleteForm .= $HTML->closeForm();
+				$cells[][] = $deleteForm;
+				echo $HTML->multiTableRow(array('class' => $HTML->boxGetAltRowStyle($key, true)), $cells);
+			}
+			echo $HTML->listTableBottom();
+		}
+
+		echo html_e('h2', array(), _('Create new Subversion repository for project').' '.$project_name);
+		echo $HTML->openForm(array('name' => 'form_create_repo', 'action' => getStringFromServer('PHP_SELF'), 'method' => 'post'));
+		echo html_e('input', array('type' => 'hidden', 'name' => 'group_id', 'value' => $params['group_id']));
+		echo html_e('input', array('type' => 'hidden', 'name' => 'create_repository', 'value' => 1));
+		echo html_e('p', array(), html_e('strong', array(), _('Repository name')._(':')).utils_requiredField().html_e('br').
+				html_e('input', array('type' => 'text', 'required' => 'required', 'size' => 20, 'name' => 'repo_name', 'value' => '')));
+		echo html_e('p', array(), html_e('strong', array(), _('Description')._(':')).html_e('br').
+				html_e('input', array('type' => 'text', 'size' => 60, 'name' => 'description', 'value' => '')));
+		echo html_e('input', array('type' => 'hidden', 'name' => 'scm_enable_anonymous', 'value' => ($project->enableAnonSCM()? 1 : 0)));
+		echo html_e('input', array('type' => 'submit', 'name' => 'cancel', 'value' => _('Cancel')));
+		echo html_e('input', array('type' => 'submit', 'name' => 'submit', 'value' => _('Submit')));
+		echo $HTML->closeForm();
+	}
 }
 
 // End of class, helper functions now

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=880df7fcb2a22b736cfdaefd4e2669c576d1d59a

commit 880df7fcb2a22b736cfdaefd4e2669c576d1d59a
Author: Franck Villaume <franck.villaume at trivialdev.com>
Date:   Tue Mar 29 16:06:04 2016 +0200

    fix weird behavior on macro ScmUser

diff --git a/src/etc/httpd.conf.d/vhost-scm-macros.inc b/src/etc/httpd.conf.d/vhost-scm-macros.inc
index 78070ae..b92e392 100644
--- a/src/etc/httpd.conf.d/vhost-scm-macros.inc
+++ b/src/etc/httpd.conf.d/vhost-scm-macros.inc
@@ -5,7 +5,7 @@
 # - specify explicit user (Require $user)
 
 <Macro ScmUser $user>
-  SetEnvIf Request_URI ^/authscm/$user/ ITKUID=$user ITKGID=users
+  SetEnvIf Request_URI ^/authscm/$user/.* ITKUID=$user ITKGID=users
   # Note: when setting ITKUID, the user's groups (project memberships) are added
   # Note: it's important to set ITKGID, otherwise privilege separation breaks as gid stays 'www-data'
 

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=6a7da28b83f0aebb1a8e0c91700102d7c64efa0c

commit 6a7da28b83f0aebb1a8e0c91700102d7c64efa0c
Author: Franck Villaume <franck.villaume at trivialdev.com>
Date:   Tue Mar 29 15:46:24 2016 +0200

    fix PHP warning in error log. Cannot access to repo dir

diff --git a/src/plugins/scmsvn/common/SVNPlugin.class.php b/src/plugins/scmsvn/common/SVNPlugin.class.php
index a4683b8..594fe21 100644
--- a/src/plugins/scmsvn/common/SVNPlugin.class.php
+++ b/src/plugins/scmsvn/common/SVNPlugin.class.php
@@ -100,10 +100,14 @@ some control over it to the project's administrator.");
 		$repo = 'file://' . forge_get_config('repos_path', $this->name).'/'.$project->getUnixName().'.svn/'.$repo_name.'/';
 		$res = array ();
 		$module = 'trunk';
-		if (!(exec("svn ls '$repo'", $res) && in_array($module.'/', $res))) {
+		if (!is_file($repo.'/format')) {
 			$module = '';
+		} else {
+			exec("svn ls '$repo'", $res);
+			if (!in_array($module.'/', $res)) {
+				$module = '';
+			}
 		}
-
 		return '/'.$module;
 	}
 

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=418cdf8a43187c3b8996cf749427d7e0110c38e3

commit 418cdf8a43187c3b8996cf749427d7e0110c38e3
Author: Franck Villaume <franck.villaume at trivialdev.com>
Date:   Tue Mar 29 15:07:40 2016 +0200

    avoid httpd variable overwrite

diff --git a/src/plugins/scmsvn/etc/httpd.conf.d/vhost-scm-macros-scmsvn-auth.inc b/src/plugins/scmsvn/etc/httpd.conf.d/vhost-scm-macros-scmsvn-auth.inc
index 284d864..020a36e 100644
--- a/src/plugins/scmsvn/etc/httpd.conf.d/vhost-scm-macros-scmsvn-auth.inc
+++ b/src/plugins/scmsvn/etc/httpd.conf.d/vhost-scm-macros-scmsvn-auth.inc
@@ -1,5 +1,5 @@
-<Macro ScmsvnUser $user $project_auth $repo_auth>
-<Location /authscm/$user/svn/$project_auth/$repo_auth>
+<Macro ScmsvnUser $user_auth $project_auth $repo_auth>
+<Location /authscm/$user_auth/svn/$project_auth/$repo_auth>
   DAV svn
   SVNPath ${FF__scmsvn__repos_path}/$project_auth.svn/$repo_auth
   # Note: ^ this need to be in the macro, doesn't work in a LocationMatch

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=26d27230305ee365cc8f0aa958506fb2b92e9994

commit 26d27230305ee365cc8f0aa958506fb2b92e9994
Author: Franck Villaume <franck.villaume at trivialdev.com>
Date:   Tue Mar 29 14:34:37 2016 +0200

    fix php syntax

diff --git a/src/plugins/scmsvn/common/SVNPlugin.class.php b/src/plugins/scmsvn/common/SVNPlugin.class.php
index 491013c..a4683b8 100644
--- a/src/plugins/scmsvn/common/SVNPlugin.class.php
+++ b/src/plugins/scmsvn/common/SVNPlugin.class.php
@@ -290,7 +290,7 @@ some control over it to the project's administrator.");
 		if (!$project->isActive()) return false;
 		if (!$project->usesPlugin($this->name)) return false;
 
-		$repo_prefix = forge_get_config('repos_path', 'scmsvn').$project->getUnixName().'.svn/';
+		$repo_prefix = forge_get_config('repos_path', 'scmsvn').'/'.$project->getUnixName().'.svn/';
 		if (!is_dir($repo_prefix) && !mkdir($repo_prefix, 0755, true)) {
 			return false;
 		}

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=8676221cb11b817c69a7c6b3f2653412b1f80a67

commit 8676221cb11b817c69a7c6b3f2653412b1f80a67
Author: Franck Villaume <franck.villaume at trivialdev.com>
Date:   Tue Mar 29 13:45:37 2016 +0200

    remove useless code

diff --git a/src/plugins/scmsvn/common/SVNPlugin.class.php b/src/plugins/scmsvn/common/SVNPlugin.class.php
index 6541a68..491013c 100644
--- a/src/plugins/scmsvn/common/SVNPlugin.class.php
+++ b/src/plugins/scmsvn/common/SVNPlugin.class.php
@@ -152,8 +152,6 @@ some control over it to the project's administrator.");
 		$b = '';
 		$b .= html_e('h2', array(), _('Developer Access'));
 
-		$module = $this->topModule($project);
-
 		if (session_loggedin()) {
 			$u = user_get_object(user_getid());
 			$d = $u->getUnixName() ;

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=600458e7e0ee9b6f775dfe7607cf076c9c413c9b

commit 600458e7e0ee9b6f775dfe7607cf076c9c413c9b
Merge: 34388b8 c63be52
Author: Franck Villaume <franck.villaume at trivialdev.com>
Date:   Tue Mar 29 09:44:27 2016 +0200

    Merge branch 'master' into master-multi-svn-repos


https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=34388b8dcefec6ff6c3a386d5cea3068dc24d496

commit 34388b8dcefec6ff6c3a386d5cea3068dc24d496
Author: Franck Villaume <franck.villaume at trivialdev.com>
Date:   Tue Mar 29 00:16:56 2016 +0200

    fix SVN create repo & user perm regeneration

diff --git a/src/plugins/scmsvn/common/SVNPlugin.class.php b/src/plugins/scmsvn/common/SVNPlugin.class.php
index 9d4a7dd..6541a68 100644
--- a/src/plugins/scmsvn/common/SVNPlugin.class.php
+++ b/src/plugins/scmsvn/common/SVNPlugin.class.php
@@ -292,12 +292,12 @@ some control over it to the project's administrator.");
 		if (!$project->isActive()) return false;
 		if (!$project->usesPlugin($this->name)) return false;
 
-		$repo_prefix = forge_get_config('repos_path', 'scmsvn');
+		$repo_prefix = forge_get_config('repos_path', 'scmsvn').$project->getUnixName().'.svn/';
 		if (!is_dir($repo_prefix) && !mkdir($repo_prefix, 0755, true)) {
 			return false;
 		}
 
-		$repo = $repo_prefix.'/'.$project->getUnixName().'.svn/'.$project->getUnixName();
+		$repo = $repo_prefix.'/'.$project->getUnixName();
 
 		if (!is_dir ($repo) || !is_file ("$repo/format")) {
 			if (!mkdir($repo, 0700, true)) {
@@ -331,6 +331,7 @@ some control over it to the project's administrator.");
 		} else {
 			system("chmod g+rX-w,o-rwx $repo") ;
 		}
+		$this->regenApacheAuth($params);
 	}
 
 	function updateRepositoryList(&$params) {

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=87176dc70122c87542e04e44156c955957045b20

commit 87176dc70122c87542e04e44156c955957045b20
Author: Franck Villaume <franck.villaume at trivialdev.com>
Date:   Mon Mar 28 19:16:07 2016 +0200

    fix wrong test

diff --git a/src/db/20160324-svn-prepare-multirepo.php b/src/db/20160324-svn-prepare-multirepo.php
index adf32f6..85a46c0 100644
--- a/src/db/20160324-svn-prepare-multirepo.php
+++ b/src/db/20160324-svn-prepare-multirepo.php
@@ -31,7 +31,7 @@ if (is_dir($svn_root)) {
 			$keep = true;
 			//check if this is a real repo with a project. reponame = unix_group_name
 			$group = group_get_object_by_name($svn_repodir);
-			if (!$group || !is_object($group) || !$group->isError()) {
+			if (!$group || !is_object($group) || $group->isError()) {
 				$keep = false;
 			}
 			if ($keep) {

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=ba8f4264506a1dc7aa8f63726fb840c746e93fbc

commit ba8f4264506a1dc7aa8f63726fb840c746e93fbc
Author: Franck Villaume <franck.villaume at trivialdev.com>
Date:   Mon Mar 28 19:05:11 2016 +0200

    Initial support for multi SVN repositories 2/2

diff --git a/src/plugins/scmsvn/common/SVNPlugin.class.php b/src/plugins/scmsvn/common/SVNPlugin.class.php
index d3c98f6..9d4a7dd 100644
--- a/src/plugins/scmsvn/common/SVNPlugin.class.php
+++ b/src/plugins/scmsvn/common/SVNPlugin.class.php
@@ -48,8 +48,7 @@ class SVNPlugin extends SCMPlugin {
 _("This plugin contains the Subversion subsystem of FusionForge. It allows
 each FusionForge project to have its own Subversion repository, and gives
 some control over it to the project's administrator.");
-		$this->svn_root_fs = forge_get_config('repos_path',
-											  $this->name);
+		$this->svn_root_fs = forge_get_config('repos_path', $this->name);
 		$this->svn_root_dav = '/svn';
 		$this->_addHook('scm_browser_page');
 		$this->_addHook('scm_update_repolist');
@@ -96,9 +95,9 @@ some control over it to the project's administrator.");
 				. '</p>';
 	}
 
-	function topModule($project) {
+	function topModule($project, $repo_name) {
 		// Check toplevel module presence
-		$repo = 'file://' . forge_get_config('repos_path', $this->name).'/'.$project->getUnixName().'/';
+		$repo = 'file://' . forge_get_config('repos_path', $this->name).'/'.$project->getUnixName().'.svn/'.$repo_name.'/';
 		$res = array ();
 		$module = 'trunk';
 		if (!(exec("svn ls '$repo'", $res) && in_array($module.'/', $res))) {
@@ -109,25 +108,49 @@ some control over it to the project's administrator.");
 	}
 
 	function getInstructionsForAnon($project) {
-		$b = '<h2>' . _('Anonymous Subversion Access') . '</h2>';
-		$b .= '<p>';
-		$b .= _("This project's SVN repository can be checked out through anonymous access with the following command(s).");
-		$b .= '</p>';
+		$repo_list = array($project->getUnixName());
+		$result = db_query_params('SELECT repo_name FROM scm_secondary_repos WHERE group_id=$1 AND next_action = $2 AND plugin_id=$3 ORDER BY repo_name',
+				array($project->getID(), SCM_EXTRA_REPO_ACTION_UPDATE, $this->getID()));
+		$rows = db_numrows($result);
+
+		for ($i = 0; $i < $rows; $i++) {
+			$repo_list[] = db_result($result, $i, 'repo_name');
+		}
+
+		$b = html_e('h2', array(), _('Anonymous Access'));
+		$b .= html_e('p', array(),
+			ngettext("This project's SVN repository can be checked out through anonymous access with the following command(s).",
+				"This project's SVN repositories can be checked out through anonymous access with the following command(s).",
+				count($repo_list)));
 
-		$b .= '<p>' ;
-		$module = $this->topModule($project);
 		if (forge_get_config('use_ssh', 'scmsvn')) {
-			$b .= '<tt>svn checkout svn://'.forge_get_config('scm_host').$this->svn_root_fs.'/'.$project->getUnixName().$module.'</tt><br />';
+			$b .= html_e('h3', array(), _('via SVN'));
+			foreach ($repo_list as $repo_name) {
+				$module = $this->topModule($project, $repo_name);
+				$b .= html_e('tt', array(), 'svn checkout svn://'.forge_get_config('scm_host').$this->svn_root_fs.'/'.$project->getUnixName().'.svn/'.$repo_name.$module).html_e('br');
+			}
 		}
 		if (forge_get_config('use_dav', 'scmsvn')) {
-				$b .= '<p><tt>svn checkout http'.((forge_get_config('use_ssl', 'scmsvn')) ? 's' : '').'://'. forge_get_config('scm_host'). '/anonscm/svn/'.$project->getUnixName().$module.'</tt></p>' ;
+			$b .= html_e('h3', array(), _('via DAV'));
+			foreach ($repo_list as $repo_name) {
+				$module = $this->topModule($project, $repo_name);
+				$b .= html_e('tt', array(), 'svn checkout http'.((forge_get_config('use_ssl', 'scmsvn')) ? 's' : '').'://'. forge_get_config('scm_host'). '/anonscm/svn/'.$project->getUnixName().'/'.$repo_name.$module).html_e('br');
+			}
 		}
-		$b .= '</p>';
 		return $b;
 	}
 
 	function getInstructionsForRW($project) {
+		$repo_list = array($project->getUnixName());
+		$result = db_query_params('SELECT repo_name FROM scm_secondary_repos WHERE group_id=$1 AND next_action = $2 AND plugin_id=$3 ORDER BY repo_name',
+				array($project->getID(), SCM_EXTRA_REPO_ACTION_UPDATE, $this->getID()));
+		$rows = db_numrows($result);
+		for ($i=0; $i<$rows; $i++) {
+			$repo_list[] = db_result($result, $i, 'repo_name');
+		}
+
 		$b = '';
+		$b .= html_e('h2', array(), _('Developer Access'));
 
 		$module = $this->topModule($project);
 
@@ -135,57 +158,55 @@ some control over it to the project's administrator.");
 			$u = user_get_object(user_getid());
 			$d = $u->getUnixName() ;
 			if (forge_get_config('use_ssh', 'scmsvn')) {
-				$b .= '<h2>';
-				$b .= sprintf(_('Developer %s Access via SSH'), 'Subversion');
-				$b .= '</h2>';
-				$b .= '<p>';
-				$b .= sprintf(_('Only project developers can access the %s tree via this method.'), 'Subversion');
-				$b .= ' ';
-				$b .= _('SSH must be installed on your client machine.');
-				$b .= ' ';
-				$b .= _('Enter your site password when prompted.');
-				$b .= '</p>';
-				$b .= '<p><tt>svn checkout svn+ssh://'.$d.'@' . forge_get_config('scm_host') . $this->svn_root_fs .'/'. $project->getUnixName().$module.'</tt></p>' ;
+				$b .= html_e('h3', array(), _('via SSH'));
+				$b .= html_e('p', array(),
+					ngettext('Only project developers can access the Subversion repository via this method.',
+						'Only project developers can access the Subversion repositories via this method.',
+						count($repo_list)).
+					' '. _('SSH must be installed on your client machine.'));
+				foreach ($repo_list as $repo_name) {
+					$module = $this->topModule($project, $repo_name);
+					$b .= html_e('tt', array(), 'svn checkout svn+ssh://'.$d.'@'.forge_get_config('scm_host').$this->svn_root_fs.'/'.$project->getUnixName().'.svn/'.$repo_name.$module).html_e('br');
+				}
 			}
 			if (forge_get_config('use_dav', 'scmsvn')) {
-				$b .= '<h2>';
-				$b .= _('Developer Subversion Access via DAV');
-				$b .= '</h2>';
+				$b .= html_e('h3', array(), _('via DAV'));
 				$b .= '<p>';
-				$b .= sprintf(_('Only project developers can access the %s tree via this method.'), 'Subversion');
-				$b .= ' ';
-				$b .= _('Enter your site password when prompted.');
-				$b .= '</p>';
-				$b .= '<p><tt>svn checkout --username '.$d.' http'.((forge_get_config('use_ssl', 'scmsvn')) ? 's' : '').'://'. forge_get_config('scm_host'). '/authscm/'.$d.'/svn/'.$project->getUnixName().$module.'</tt></p>' ;
+				$b .= html_e('p', array(),
+					ngettext('Only project developers can access the Subversion repository via this method.',
+						'Only project developers can access the Subversion repositories via this method.',
+						count($repo_list)).
+					' '. _('Enter your site password when prompted.'));
+				foreach ($repo_list as $repo_name) {
+					$module = $this->topModule($project, $repo_name);
+					$b .= html_e('tt', array(), 'svn checkout --username '.$d.' http'.((forge_get_config('use_ssl', 'scmsvn')) ? 's' : '').'://'.forge_get_config('scm_host').'/authscm/'.$d.'/svn/'.$project->getUnixName().'/'.$repo_name.$module).html_e('br');
+				}
 			}
 		} else {
 			if (forge_get_config('use_ssh', 'scmsvn')) {
-				$b .= '<h2>';
-				$b .= sprintf(_('Developer %s Access via SSH'), 'Subversion');
-				$b .= '</h2>';
-				$b .= '<p>';
-				$b .= sprintf(_('Only project developers can access the %s tree via this method.'), 'Subversion');
-				$b .= ' ';
-				$b .= _('SSH must be installed on your client machine.');
-				$b .= ' ';
-				$b .= _('Substitute <em>developername</em> with the proper value.');
-				$b .= ' ';
-				$b .= _('Enter your site password when prompted.');
-				$b .= '</p>';
-				$b .= '<p><tt>svn checkout svn+ssh://<i>'._('developername').'</i>@' . forge_get_config('scm_host') . $this->svn_root_fs .'/'. $project->getUnixName().$module.'</tt></p>' ;
+				$b .= html_e('h3', array(), _('via SSH'));
+				$b .= html_e('p', array(),
+					ngettext('Only project developers can access the Subversion repository via this method.',
+						'Only project developers can access the Subversion repositories via this method.',
+						count($repo_list)).
+					' '. _('SSH must be installed on your client machine.'));
+				foreach ($repo_list as $repo_name) {
+					$module = $this->topModule($project, $repo_name);
+					$b .= html_e('tt', array(), 'svn checkout svn+ssh://<i>'._('developername').'</i>@'.forge_get_config('scm_host').$this->svn_root_fs.'/'.$project->getUnixName().'.svn/'.$repo_name.$module).html_e('br');
+				}
 			}
 			if (forge_get_config('use_dav', 'scmsvn')) {
-				$b .= '<h2>';
-				$b .= _('Developer Subversion Access via DAV');
-				$b .= '</h2>';
+				$b .= html_e('h3', array(), _('via DAV'));
 				$b .= '<p>';
-				$b .= sprintf(_('Only project developers can access the %s tree via this method.'), 'Subversion');
-				$b .= ' ';
-				$b .= _('Substitute <em>developername</em> with the proper value.');
-				$b .= ' ';
-				$b .= _('Enter your site password when prompted.');
-				$b .= '</p>';
-				$b .= '<p><tt>svn checkout --username <i>'._('developername').'</i> http'.((forge_get_config('use_ssl', 'scmsvn')) ? 's' : '').'://'. forge_get_config('scm_host'). '/authscm/<i>'._('developername').'</i>/svn/'.$project->getUnixName().$module.'</tt></p>' ;
+				$b .= html_e('p', array(),
+					ngettext('Only project developers can access the Subversion repository via this method.',
+						'Only project developers can access the Subversion repositories via this method.',
+						count($repo_list)).
+					' '. _('Enter your site password when prompted.'));
+				foreach ($repo_list as $repo_name) {
+					$module = $this->topModule($project, $repo_name);
+					$b .= html_e('tt', array(), 'svn checkout --username <i>'._('developername').'</i> http'.((forge_get_config('use_ssl', 'scmsvn')) ? 's' : '').'://'.forge_get_config('scm_host').'/authscm/<i>'._('developername').'</i>/svn/'.$project->getUnixName().'/'.$repo_name.$module).html_e('br');
+				}
 			}
 		}
 		return $b;
@@ -196,8 +217,7 @@ some control over it to the project's administrator.");
 	}
 
 	function getBrowserLinkBlock($project) {
-		global $HTML ;
-		$b = $HTML->boxMiddle(sprintf(_('%s Repository Browser'), 'Subversion'));
+		$b = html_e('h2', array(), _('Subversion Repository Browser'));
 		$b .= '<p>';
 		$b .= sprintf(_("Browsing the %s tree gives you a view into the current status of this project's code."), 'Subversion');
 		$b .= ' ';
@@ -207,13 +227,13 @@ some control over it to the project's administrator.");
 		$b .= util_make_link ("/scm/browser.php?group_id=".$project->getID(),
 								sprintf(_('Browse %s Repository'), 'Subversion')
 			) ;
-		$b .= ']</p>' ;
-		return $b ;
+		$b .= ']</p>';
+		return $b;
 	}
 
 	function getStatsBlock($project) {
-		global $HTML ;
-		$b = '' ;
+		global $HTML;
+		$b = '';
 
 		$result = db_query_params('SELECT u.realname, u.user_name, u.user_id, sum(updates) as updates, sum(adds) as adds, sum(adds+updates) as combined FROM stats_cvs_user s, users u WHERE group_id=$1 AND s.user_id=u.user_id AND (updates>0 OR adds >0) GROUP BY u.user_id, realname, user_name, u.user_id ORDER BY combined DESC, realname',
 					  array ($project->getID()));
@@ -251,7 +271,6 @@ some control over it to the project's administrator.");
 	}
 
 	function printBrowserPage($params) {
-		global $HTML;
 		$useautoheight = 0;
 		$project = $this->checkParams($params);
 		if (!$project) {
@@ -278,7 +297,7 @@ some control over it to the project's administrator.");
 			return false;
 		}
 
-		$repo = $repo_prefix . '/' . $project->getUnixName();
+		$repo = $repo_prefix.'/'.$project->getUnixName().'.svn/'.$project->getUnixName();
 
 		if (!is_dir ($repo) || !is_file ("$repo/format")) {
 			if (!mkdir($repo, 0700, true)) {
@@ -319,17 +338,50 @@ some control over it to the project's administrator.");
 
 	function regenApacheAuth(&$params) {
 		# Enable /authscm/$user/svn URLs
-		$config_fname = forge_get_config('data_path').'/scmsvn-auth.inc';
-		$config_f = fopen($config_fname.'.new', 'w');
-
-		$res = db_query_params("SELECT login, passwd FROM nss_passwd WHERE status=$1", array('A'));
+		# format of Macro is 3 params
+		# Use ScmsvnUser user project reponame
+
+		# Enable /anonscm/svn URLs
+		# format of Macro is 2 params
+		# Use ScmsvnRepoAnon project reponame
+		$config_fname_auth = forge_get_config('data_path').'/scmsvn-auth.inc';
+		$config_f_auth = fopen($config_fname_auth.'.new', 'w');
+		$config_fname_anon = forge_get_config('data_path').'/scmsvn-auth-anon.inc';
+		$config_f_anon = fopen($config_fname_anon.'.new', 'w');
+
+		$res = db_query_params('SELECT unix_group_name, group_id FROM groups WHERE status = $1 and type_id = $2 and is_template =$3 and register_time > 0',
+					array('A', 1, 0));
 		while ($arr = db_fetch_array($res)) {
-			fwrite($config_f, 'Use ScmsvnUser '.$arr['login']."\n");
+			$groupObject = group_get_object($arr['group_id']);
+			if ($groupObject->usesPlugin($this->name)) {
+				$users = $groupObject->getUsers();
+				$repo_list = array();
+				$repo_list[] = $arr['unix_group_name'];
+				$result = db_query_params('SELECT repo_name FROM scm_secondary_repos WHERE group_id=$1 AND next_action = $2 AND plugin_id=$3 ORDER BY repo_name',
+					array($arr['group_id'], SCM_EXTRA_REPO_ACTION_UPDATE, $this->getID()));
+				$rows = db_numrows($result);
+				for ($i = 0; $i < $rows; $i++) {
+					$repo_list[] = db_result($result, $i, 'repo_name');
+				}
+				foreach ($repo_list as $repo_name) {
+					foreach ($users as $user) {
+						if (forge_check_perm_for_user($user, 'scm', $arr['group_id'], 'write')) {
+							fwrite($config_f_auth, 'Use ScmsvnUser '.$user->getUnixName().' '.$arr['unix_group_name'].' '.$repo_name."\n");
+						}
+					}
+					if ($groupObject->enableAnonSCM()) {
+						fwrite($config_f_anon, 'Use ScmsvnRepoAnon '.$arr['unix_group_name'].' '.$repo_name."\n");
+					}
+				}
+			}
 		}
 
-		fclose($config_f);
-		chmod($config_fname.'.new', 0644);
-		rename($config_fname.'.new', $config_fname);
+		fclose($config_f_auth);
+		chmod($config_fname_auth.'.new', 0644);
+		rename($config_fname_auth.'.new', $config_fname_auth);
+		fclose($config_f_anon);
+		chmod($config_fname_anon.'.new', 0644);
+		rename($config_fname_anon.'.new', $config_fname_anon);
 	}
 
 	function gatherStats($params) {
@@ -368,7 +420,7 @@ some control over it to the project's administrator.");
 			$usr_deletes = array();
 			$usr_commits = array();
 
-			$repo = forge_get_config('repos_path', 'scmsvn') . '/' . $project->getUnixName();
+			$repo = forge_get_config('repos_path', 'scmsvn').'/'.$project->getUnixName().'.svn/'.$project->getUnixName();
 			if (!is_dir ($repo) || !is_file ("$repo/format")) {
 				db_rollback();
 				return false;
@@ -505,7 +557,7 @@ some control over it to the project's administrator.");
 		}
 
 		$toprepo = forge_get_config('repos_path', 'scmsvn');
-		$repo = $toprepo . '/' . $project->getUnixName();
+		$repo = $toprepo.'/'.$group_name.'.svn/'.$group_name;
 
 		if (!is_dir ($repo) || !is_file ("$repo/format")) {
 			if (is_file($snapshot)) {
@@ -522,7 +574,7 @@ some control over it to the project's administrator.");
 			return false ;
 		}
 		$today = date ('Y-m-d') ;
-		$dir = $project->getUnixName ()."-$today" ;
+		$dir = $group_name."-$today" ;
 		system ("mkdir -p $tmp") ;
 		$code = 0 ;
 		system ("svn ls file://$repo/trunk > /dev/null 2> /dev/null", $code) ;
@@ -542,7 +594,7 @@ some control over it to the project's administrator.");
 		}
 
 		if ($ut) {
-			system ("tar cCf $toprepo - ".$project->getUnixName() ."|".forge_get_config('compression_method')."> $tmp/tarball") ;
+			system ("tar cCf $toprepo - ".$group_name."|".forge_get_config('compression_method')."> $tmp/tarball") ;
 			chmod ("$tmp/tarball", 0644) ;
 			copy ("$tmp/tarball", $tarball) ;
 			unlink ("$tmp/tarball") ;
diff --git a/src/plugins/scmsvn/etc/httpd.conf.d/vhost-scm-macros-scmsvn.inc b/src/plugins/scmsvn/etc/httpd.conf.d/vhost-scm-macros-scmsvn.inc
deleted file mode 100644
index 2517c85..0000000
--- a/src/plugins/scmsvn/etc/httpd.conf.d/vhost-scm-macros-scmsvn.inc
+++ /dev/null
@@ -1,13 +0,0 @@
-<Macro ScmsvnUser $user>
-<Location /authscm/$user/svn>
-  DAV svn
-  SVNParentPath ${FF__scmsvn__repos_path}
-  # Note: ^ this need to be in the macro, doesn't work in a LocationMatch
-  # This is pretty annoying, because this requires a plugin-specific macro :/
-  # <LocationMatch /authscm/[^/]+/svn>
-  # -> Can't open file '/srv/svn/authscm/format'
-</Location>
-</Macro>
-
-# Note: macros defined in a separate file because they can't be
-# defined twice (e.g. included twice from http and https virtualhosts)
diff --git a/src/plugins/scmsvn/etc/httpd.conf.d/vhost-scm-plugin-scmsvn.inc b/src/plugins/scmsvn/etc/httpd.conf.d/vhost-scm-plugin-scmsvn.inc
index 1eb8c9e..ea58ab9 100644
--- a/src/plugins/scmsvn/etc/httpd.conf.d/vhost-scm-plugin-scmsvn.inc
+++ b/src/plugins/scmsvn/etc/httpd.conf.d/vhost-scm-plugin-scmsvn.inc
@@ -2,16 +2,6 @@
   Include ${FF__core__config_path}/httpd.conf.d/disable-scripts.inc
 </Directory>
 
-# Read-only access for public repos
-<Location /anonscm/svn/>
-  DAV svn
-  SVNParentPath ${FF__scmsvn__repos_path}
-  # allow read-only browsing
-  <LimitExcept GET PROPFIND OPTIONS REPORT>
-  </LimitExcept>
-</Location>
-
-
 # SVN tools
 <Directory ${FF__core__plugins_path}/scmsvn/libexec>
   Require all granted
diff --git a/src/plugins/scmsvn/libexec/svnlog.php b/src/plugins/scmsvn/libexec/svnlog.php
index 440bfc0..1fad5cb 100644
--- a/src/plugins/scmsvn/libexec/svnlog.php
+++ b/src/plugins/scmsvn/libexec/svnlog.php
@@ -3,6 +3,7 @@
  * Returns commit log for inclusion in web frontend
  *
  * Copyright 2015  Inria (Sylvain Beucler)
+ * Copyright 2016, Franck Villaume - TrivialDev
  *
  * This file is part of FusionForge.
  *
@@ -71,7 +72,7 @@ if ($mode == 'date_range') {
 	if (!ctype_digit($limit))
 		die('Invalid limit');
 	$options = "--limit $limit";
-	
+
 	if ($mode == 'latest_user') {
 		$user_name = $_GET['user_name'];
 		if (!preg_match('/^[a-z0-9][-a-z0-9_\.]+\z/', $user_name))
@@ -80,7 +81,7 @@ if ($mode == 'date_range') {
 	}
 }
 
-$repo = forge_get_config('repos_path', 'scmsvn') . '/' . $unix_group_name;
+$repo = forge_get_config('repos_path', 'scmsvn').'/'.$unix_group_name.'.svn/'.$unix_group_name;
 if (is_dir($repo)) {
 	passthru("svn log file://$repo --xml -v $options 2> /dev/null");
 }
diff --git a/src/plugins/scmsvn/libexec/viewvc.cgi b/src/plugins/scmsvn/libexec/viewvc.cgi
index 86b0b27..e48b0d9 100755
--- a/src/plugins/scmsvn/libexec/viewvc.cgi
+++ b/src/plugins/scmsvn/libexec/viewvc.cgi
@@ -1,9 +1,29 @@
 #!/usr/bin/env python
 # Locate ViewVC and run it
+#
+# Previous Copyright, FusionForge Team
+# Copyright 2016, Franck Villaume - TrivialDev
+#
+# This file is part of FusionForge.
+#
+# FusionForge is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published
+# by the Free Software Foundation; either version 2 of the License,
+# or (at your option) any later version.
+#
+# FusionForge is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 import sys
 import os
 import glob
+import re
 
 LIBRARY_GLOBS = (
   r'/usr/lib/viewvc/lib',  # Debian
@@ -48,7 +68,18 @@ import subprocess
 encoding = os.environ.get('HTTP_ACCEPT_ENCODING', None)
 if 'HTTP_ACCEPT_ENCODING' in os.environ: del os.environ['HTTP_ACCEPT_ENCODING']
 repos_path = subprocess.check_output(['forge_get_config', 'repos_path', 'scmsvn']).rstrip()
-cfg.general.root_parents = [repos_path+': svn']
+uri = os.environ['REQUEST_URI']
+if uri.find('root=') != -1:
+  # uri is: /some/thing/?root=svnrepo&something&else
+  subrepos_path1 = re.sub('^.*?root=', '', uri)
+  subrepos_path = re.sub('&.*$', '', subrepos_path1)
+else:
+  # uri is: /some/thing/svnrepo/?
+  #  or is: /some/thing/svnrepo?
+  subrepos_path1 = uri.split('/')[3]
+  subrepos_path = re.sub('\?.*$', '', subrepos_path1)
+
+cfg.general.root_parents = [repos_path+'/'+subrepos_path+'.svn: svn']
 
 # Authentify request
 try:
diff --git a/src/www/scm/include/viewvc_utils.php b/src/www/scm/include/viewvc_utils.php
index 40ed848..50a81d1 100644
--- a/src/www/scm/include/viewvc_utils.php
+++ b/src/www/scm/include/viewvc_utils.php
@@ -69,7 +69,7 @@ function viewcvs_execute($repos_name, $repos_type) {
 	if ($repos_type == "cvs") {
 		$repos_root = forge_get_config('repos_path', 'scmcvs').'/'.$repos_name;
 	} elseif ($repos_type == "svn") {
-		$repos_root = forge_get_config('repos_path', 'scmsvn').'/'.$repos_name;
+		$repos_root = forge_get_config('repos_path', 'scmsvn').'/'.$repos_name.'.svn/'.$repos_name;
 	} else {
 		die("Invalid repository type");
 	}

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=f14ce7ed6b4533e73ec67cfbebeeb9d6dc424992

commit f14ce7ed6b4533e73ec67cfbebeeb9d6dc424992
Author: Franck Villaume <franck.villaume at trivialdev.com>
Date:   Mon Mar 28 18:04:45 2016 +0200

    Initial support for multi SVN repositories

diff --git a/src/db/20160324-svn-prepare-multirepo.php b/src/db/20160324-svn-prepare-multirepo.php
new file mode 100644
index 0000000..adf32f6
--- /dev/null
+++ b/src/db/20160324-svn-prepare-multirepo.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Move SVN repos to the new structure to support multi SVN repositories
+ * Copyright, 2016, Franck Villaume - TrivialDev
+ * http://fusionforge.org/
+ *
+ * This file is part of FusionForge.
+ *
+ * FusionForge is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * FusionForge is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+require_once dirname(__FILE__).'/../common/include/env.inc.php';
+require_once $gfcommon.'include/pre.php';
+
+$svn_root = forge_get_config('repos_path', 'scmsvn');
+if (is_dir($svn_root)) {
+	if ($svn_opendir = opendir($svn_root)) {
+		while (($svn_repodir = readdir($svn_opendir)) !== false) {
+			$keep = true;
+			//check if this is a real repo with a project. reponame = unix_group_name
+			$group = group_get_object_by_name($svn_repodir);
+			if (!$group || !is_object($group) || !$group->isError()) {
+				$keep = false;
+			}
+			if ($keep) {
+				if (mkdir($svn_root.'/'.$svn_repodir.'.svn')) {
+					if (!rename($svn_root.'/'.$svn_repodir, $svn_root.'/'.$svn_repodir.'.svn/'.$svn_repodir)) {
+						echo "UNABLE TO MOVE TO FINAL DESTINATION REPO: ".$svn_repodir."\n";
+					}
+				} else {
+					echo "UNABLE TO CREATE TARGET DIR FOR REPO: ".$svn_repodir."\n";
+				}
+			}
+		}
+	}
+}
+echo "SUCCESS\n";
diff --git a/src/plugins/scmsvn/etc/httpd.conf.d/vhost-scm-macros-scmsvn-anon.inc b/src/plugins/scmsvn/etc/httpd.conf.d/vhost-scm-macros-scmsvn-anon.inc
new file mode 100644
index 0000000..49ea03c
--- /dev/null
+++ b/src/plugins/scmsvn/etc/httpd.conf.d/vhost-scm-macros-scmsvn-anon.inc
@@ -0,0 +1,13 @@
+<Macro ScmsvnRepoAnon $project_anon $repo_anon>
+<Location /anonscm/svn/$project_anon/$repo_anon>
+  DAV svn
+  SVNPath ${FF__scmsvn__repos_path}/$project_anon.svn/$repo_anon
+  # Note: ^ this need to be in the macro, doesn't work in a LocationMatch
+  # This is pretty annoying, because this requires a plugin-specific macro :/
+  # <LocationMatch /authscm/[^/]+/svn>
+  # -> Can't open file '/srv/svn/authscm/format'
+</Location>
+</Macro>
+
+# Note: macros defined in a separate file because they can't be
+# defined twice (e.g. included twice from http and https virtualhosts)
diff --git a/src/plugins/scmsvn/etc/httpd.conf.d/vhost-scm-macros-scmsvn-auth.inc b/src/plugins/scmsvn/etc/httpd.conf.d/vhost-scm-macros-scmsvn-auth.inc
new file mode 100644
index 0000000..284d864
--- /dev/null
+++ b/src/plugins/scmsvn/etc/httpd.conf.d/vhost-scm-macros-scmsvn-auth.inc
@@ -0,0 +1,13 @@
+<Macro ScmsvnUser $user $project_auth $repo_auth>
+<Location /authscm/$user/svn/$project_auth/$repo_auth>
+  DAV svn
+  SVNPath ${FF__scmsvn__repos_path}/$project_auth.svn/$repo_auth
+  # Note: ^ this need to be in the macro, doesn't work in a LocationMatch
+  # This is pretty annoying, because this requires a plugin-specific macro :/
+  # <LocationMatch /authscm/[^/]+/svn>
+  # -> Can't open file '/srv/svn/authscm/format'
+</Location>
+</Macro>
+
+# Note: macros defined in a separate file because they can't be
+# defined twice (e.g. included twice from http and https virtualhosts)

-----------------------------------------------------------------------


hooks/post-receive
-- 
FusionForge



More information about the Fusionforge-commits mailing list