*
* Copyright 2009, Roland Mas
* Copyright 2009, Mehdi Dogguy <mehdi@debian.org>
- * Copyright 2012, Franck Villaume - TrivialDev
+ * Copyright 2012-2013, Franck Villaume - TrivialDev
+ * Copyright © 2013
+ * Thorsten Glaser <t.glaser@tarent.de>
* http://fusionforge.org
*
* This file is part of FusionForge.
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-forge_define_config_item('default_server', 'scmgit', forge_get_config ('web_host')) ;
-forge_define_config_item('repos_path', 'scmgit', forge_get_config('chroot').'/scmrepos/git') ;
+forge_define_config_item('default_server', 'scmgit', forge_get_config ('web_host'));
+forge_define_config_item('repos_path', 'scmgit', forge_get_config('chroot').'/scmrepos/git');
+forge_define_config_item('use_ssh', 'scmgit', false);
+forge_set_config_item_bool('use_ssh', 'scmgit');
+forge_define_config_item('use_dav', 'scmgit', true);
+forge_set_config_item_bool('use_dav', 'scmgit');
+forge_define_config_item('use_ssl', 'scmgit', true);
+forge_set_config_item_bool('use_ssl', 'scmgit');
class GitPlugin extends SCMPlugin {
function GitPlugin() {
$this->_addHook('scm_update_repolist');
$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('widget_instance', 'myPageBox', false);
$this->_addHook('widgets', 'widgets', false);
+ $this->_addHook('activity');
+ $this->_addHook('weekly');
$this->register();
}
function printShortStats ($params) {
$project = $this->checkParams($params);
if (!$project) {
- return false;
+ return;
}
- if ($project->usesPlugin($this->name)) {
+ if ($project->usesPlugin($this->name) && forge_check_perm('scm', $project->getID(), 'read')) {
$result = db_query_params('SELECT sum(commits) AS commits, sum(adds) AS adds FROM stats_cvs_group WHERE group_id=$1',
array ($project->getID())) ;
$commit_num = db_result($result,0,'commits');
}
function getBlurb() {
- return '<p>' . _('Documentation for Git is available at <a href="http://git-scm.com/">http://git-scm.com/</a>.') . '</p>';
+ return '<p>'
+ . sprintf(_('Documentation for %1$s is available at <a href="%2$s">%2$s</a>.'),
+ 'Git',
+ 'http://git-scm.com/')
+ . '</p>';
}
function getInstructionsForAnon($project) {
- $b = '<h2>' . _('Anonymous Git Access') . '</h2>';
+ $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 = '<h2>' . ngettext('Anonymous Access to the Git repository',
+ 'Anonymous Access to the Git repositories',
+ count($repo_list)) . '</h2>';
+
$b .= '<p>';
- $b .= _('This project\'s Git repository can be checked out through anonymous access with the following command.');
- $b .= '</p>';
+ $b .= ngettext('This project\'s Git repository can be checked out through anonymous access with the following command.',
+ 'This project\'s Git repositories can be checked out through anonymous access with the following commands.',
+ count($repo_list));
- $b .= '<p>' ;
- $b .= '<tt>git clone '.util_make_url ('/anonscm/git/'.$project->getUnixName().'/'.$project->getUnixName().'.git').'</tt><br />';
$b .= '</p>';
- $result = db_query_params('SELECT u.user_id, u.user_name, u.realname FROM plugin_scmgit_personal_repos p, users u WHERE p.group_id=$1 AND u.user_id=p.user_id AND u.unix_status=$2',
+ foreach ($repo_list as $repo_name) {
+ $b .= '<p>' ;
+ $b .= '<tt>git clone '.util_make_url ('/anonscm/git/'.$project->getUnixName().'/'.$repo_name.'.git').'</tt><br />';
+ $b .= '</p>';
+ }
+
+ $result = db_query_params('SELECT u.user_id, u.user_name, u.realname FROM scm_personal_repos p, users u WHERE p.group_id=$1 AND u.user_id=p.user_id AND u.unix_status=$2 AND plugin_id=$3',
array ($project->getID(),
- 'A'));
+ 'A',
+ $this->getID()));
$rows = db_numrows($result);
if ($rows > 0) {
$b .= '<h2>';
- $b .= _('Developer\'s repository');
+ $b .= ngettext('Developer\'s repository',
+ 'Developer\'s repositories',
+ $rows);
$b .= '</h2>'."\n";
$b .= '<p>';
$b .= ngettext('One of this project\'s members also has a personal Git repository that can be checked out anonymously.',
$user_id = db_result($result,$i,'user_id');
$user_name = db_result($result,$i,'user_name');
$real_name = db_result($result,$i,'realname');
- $b .= '<tt>git clone '.util_make_url('/anonscm/git/'.$project->getUnixName().'/users/'.$user_name.'.git').'</tt> ('.util_make_link_u ($user_name, $user_id, $real_name).')<br />';
+ $b .= '<tt>git clone '.util_make_url('/anonscm/git/'.$project->getUnixName().'/users/'.$user_name.'.git').'</tt> ('.util_make_link_u ($user_name, $user_id, $real_name).') ['.util_make_link('/scm/browser.php?group_id='.$project->getID().'&user_id='.$user_id, _('Browse Git Repository')).']<br />';
}
$b .= '</p>';
}
}
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');
+ }
if (session_loggedin()) {
$u = user_get_object(user_getid());
$d = $u->getUnixName();
+ $validSetup = 0;
+ $b = '';
if (forge_get_config('use_ssh', 'scmgit')) {
- $b = '<h2>';
- $b .= _('Developer Git Access via SSH');
+ $b .= '<h2>';
+ $b = '<h2>' . ngettext('Developer Access to the Git repository via SSH',
+ 'Developer Access to the Git repositories via SSH',
+ count($repo_list)) . '</h2>';
$b .= '</h2>';
$b .= '<p>';
- $b .= _('Only project developers can access the Git tree via this method. SSH must be installed on your client machine. Enter your site password when prompted.');
+ $b .= ngettext('Only project developers can access the GIT repository via this method. SSH must be installed on your client machine. Enter your site password when prompted.',
+ 'Only project developers can access the GIT repositories via this method. SSH must be installed on your client machine. Enter your site password when prompted.',
+ count($repo_list));
+
$b .= '</p>';
- $b .= '<p><tt>git clone git+ssh://'.$d.'@' . $this->getBoxForProject($project) . '/'. forge_get_config('repos_path', 'scmgit') .'/'. $project->getUnixName() .'/'. $project->getUnixName() .'.git</tt></p>' ;
- } elseif (forge_get_config('use_dav', 'scmgit')) {
+ foreach ($repo_list as $repo_name) {
+ $b .= '<p><tt>git clone git+ssh://'.$d.'@' . $project->getSCMBox() . '/'. forge_get_config('repos_path', 'scmgit') .'/'. $project->getUnixName() .'/'. $repo_name .'.git</tt></p>' ;
+ }
+
+ $validSetup = 1;
+ }
+ if (forge_get_config('use_dav', 'scmgit')) {
$protocol = forge_get_config('use_ssl', 'scmgit')? 'https' : 'http';
- $b = '<h2>';
- $b .= _('Developer Git Access via HTTP');
+ $b .= '<h2>';
+ $b = '<h2>' . ngettext('Developer Access to the Git repository via HTTP',
+ 'Developer Access to the Git repositories via HTTP',
+ count($repo_list)) . '</h2>';
+
$b .= '</h2>';
$b .= '<p>';
- $b .= _('Only project developers can access the Git tree via this method. Enter your site password when prompted.');
+ $b .= ngettext('Only project developers can access the GIT repository via this method. Enter your site password when prompted.',
+ 'Only project developers can access the GIT repositories via this method. Enter your site password when prompted.',
+ count($repo_list));
+
$b .= '</p>';
- $b .= '<p><tt>git clone '.$protocol.'://'.$d.'@' . $this->getBoxForProject($project) . '/'. forge_get_config('scm_root', 'scmgit') .'/'. $project->getUnixName() .'/'. $project->getUnixName() .'.git</tt></p>' ;
- } else {
+ foreach ($repo_list as $repo_name) {
+ $b .= '<p><tt>git clone '.$protocol.'://'.$d.'@' . $project->getSCMBox() . '/'. forge_get_config('scm_root', 'scmgit') .'/'. $project->getUnixName() .'/'. $repo_name .'.git</tt></p>' ;
+ }
+
+ $validSetup = 1;
+ }
+ if ($validSetup == 0) {
$b = '<p class="warning">'._('Missing configuration for access in scmgit.ini : use_ssh and use_dav disabled').'</p>';
}
} else {
if (forge_get_config('use_ssh', 'scmgit')) {
$b = '<h2>';
- $b .= _('Developer Git Access via SSH');
+ $b = '<h2>' . ngettext('Developer Access to the Git repository via SSH',
+ 'Developer Access to the Git repositories via SSH',
+ count($repo_list)) . '</h2>';
+
$b .= '</h2>';
$b .= '<p>';
- $b .= _('Only project developers can access the Git tree via this method. SSH must be installed on your client machine. Substitute <i>developername</i> with the proper value. Enter your site password when prompted.');
+ $b .= ngettext('Only project developers can access the GIT repository via this method. SSH must be installed on your client machine. Substitute <em>developername</em> with the proper value. Enter your site password when prompted.',
+ 'Only project developers can access the GIT repositories via this method. SSH must be installed on your client machine. Substitute <em>developername</em> with the proper value. Enter your site password when prompted.',
+ count($repo_list));
+
$b .= '</p>';
- $b .= '<p><tt>git clone git+ssh://<i>'._('developername').'</i>@' . $this->getBoxForProject($project) . '/'. forge_get_config('repos_path', 'scmgit') .'/'. $project->getUnixName() .'/'. $project->getUnixName() .'.git</tt></p>' ;
- } elseif (forge_get_config('use_dav', 'scmgit')) {
+ foreach ($repo_list as $repo_name) {
+ $b .= '<p><tt>git clone git+ssh://<i>'._('developername').'</i>@' . $project->getSCMBox() . '/'. forge_get_config('repos_path', 'scmgit') .'/'. $project->getUnixName() .'/'. $repo_name .'.git</tt></p>' ;
+ }
+
+ }
+ if (forge_get_config('use_dav', 'scmgit')) {
$protocol = forge_get_config('use_ssl', 'scmgit')? 'https' : 'http';
$b = '<h2>';
- $b .= _('Developer Git Access via HTTP');
+ $b = '<h2>' . ngettext('Developer Access to the Git repository via HTTP',
+ 'Developer Access to the Git repositories via HTTP',
+ count($repo_list)) . '</h2>';
$b .= '</h2>';
$b .= '<p>';
- $b .= _('Only project developers can access the Git tree via this method. Enter your site password when prompted.');
+ $b .= ngettext('Only project developers can access the GIT repository via this method. Enter your site password when prompted.',
+ 'Only project developers can access the GIT repositories via this method. Enter your site password when prompted.',
+ count($repo_list));
+
$b .= '</p>';
- $b .= '<p><tt>git clone '.$protocol.'://<i>'._('developername').'</i>@' . $this->getBoxForProject($project) . '/'. forge_get_config('scm_root', 'scmgit') .'/'. $project->getUnixName() .'/'. $project->getUnixName() .'.git</tt></p>' ;
+ foreach ($repo_list as $repo_name) {
+ $b .= '<p><tt>git clone '.$protocol.'://<i>'._('developername').'</i>@' . $project->getSCMBox() . '/'. forge_get_config('scm_root', 'scmgit') .'/'. $project->getUnixName() .'/'. $repo_name .'.git</tt></p>' ;
+ }
+
}
}
if (session_loggedin()) {
$u =& user_get_object(user_getid()) ;
if ($u->getUnixStatus() == 'A') {
- $result = db_query_params('SELECT * FROM plugin_scmgit_personal_repos p WHERE p.group_id=$1 AND p.user_id=$2',
- array ($project->getID(),
- $u->getID()));
+ $result = db_query_params('SELECT * FROM scm_personal_repos p WHERE p.group_id=$1 AND p.user_id=$2 AND plugin_id=$3',
+ array ($project->getID(),
+ $u->getID(),
+ $this->getID()));
if ($result && db_numrows ($result) > 0) {
$b .= '<h2>';
$b .= _('Access to your personal repository');
function printBrowserPage($params) {
$project = $this->checkParams($params);
if (!$project) {
- return false;
+ return;
}
if ($project->usesPlugin($this->name)) {
- if ($this->browserDisplayable($project)) {
+ if ($params['user_id']) {
+ $user = user_get_object($params['user_id']);
+ echo $project->getUnixName().'/users/'.$user->getUnixName();
+ print '<iframe src="'.util_make_url("/plugins/scmgit/cgi-bin/gitweb.cgi?p=".$project->getUnixName().'/users/'.$user->getUnixName().'.git').'" frameborder="0" width=100% height=700></iframe>' ;
+ } elseif ($this->browserDisplayable($project)) {
print '<iframe src="'.util_make_url("/plugins/scmgit/cgi-bin/gitweb.cgi?p=".$project->getUnixName().'/'.$project->getUnixName().'.git').'" frameborder="0" width=100% height=700></iframe>' ;
}
}
return false ;
}
- if (! $project->usesPlugin ($this->name)) {
+ if (! $project->usesPlugin($this->name)) {
return false;
}
$project_name = $project->getUnixName();
- $root = forge_get_config('repos_path', 'scmgit') . '/' . $project_name ;
- system ("mkdir -p $root");
+ $root = forge_get_config('repos_path', 'scmgit') . '/' . $project_name;
+ if (!is_dir($root)) {
+ system("mkdir -p $root");
+ }
$output = '';
if (forge_get_config('use_ssh','scmgit')) {
} else {
$unix_group = forge_get_config('apache_group');
}
+ system ("chgrp $unix_group $root") ;
+ // Create main repository
$main_repo = $root . '/' . $project_name . '.git' ;
if (!is_dir($main_repo) || (!is_file("$main_repo/HEAD") &&
!is_dir("$main_repo/objects") && !is_dir("$main_repo/refs"))) {
if ($tmp_repo == false) {
return false;
}
- $result = system ("GIT_DIR=\"$tmp_repo\" git init --bare --shared=group") ;
- $output .= join("<br />", array($result));
- $result = system ("GIT_DIR=\"$tmp_repo\" git update-server-info") ;
- $output .= join("<br />", array($result));
+ $result = '';
+ exec ("GIT_DIR=\"$tmp_repo\" git init --bare --shared=group", $result) ;
+ $output .= join("<br />", $result);
+ $result = '';
+ exec ("GIT_DIR=\"$tmp_repo\" git update-server-info", $result) ;
+ $output .= join("<br />", $result);
if (is_file ("$tmp_repo/hooks/post-update.sample")) {
rename ("$tmp_repo/hooks/post-update.sample",
"$tmp_repo/hooks/post-update") ;
}
if (!is_file ("$tmp_repo/hooks/post-update")) {
- $f = fopen ("$tmp_repo/hooks/post-update") ;
+ $f = fopen ("$tmp_repo/hooks/post-update", 'w') ;
fwrite ($f, "exec git-update-server-info\n") ;
fclose ($f) ;
}
system ("echo \"Git repository for $project_name\" > $tmp_repo/description") ;
system ("find $tmp_repo -type d | xargs chmod g+s") ;
system ("chgrp -R $unix_group $tmp_repo") ;
+ system ("chmod -R g+wX,o+rX-w $tmp_repo") ;
if ($project->enableAnonSCM()) {
system ("chmod g+wX,o+rX-w $root") ;
- system ("chmod -R g+wX,o+rX-w $tmp_repo") ;
} else {
system ("chmod g+wX,o-rwx $root") ;
- system ("chmod -R g+wX,o-rwx $tmp_repo") ;
+ system ("chmod g+wX,o-rwx $tmp_repo") ;
}
$ret = true;
/*
if ($ret != 0) {
return false;
}
+ system ("echo \"Git repository for $project_name\" > $main_repo/description") ;
+ system ("find $main_repo -type d | xargs chmod g+s");
+ if (forge_get_config('use_dav','scmgit')) {
+ $f = fopen(forge_get_config('config_path').'/httpd.conf.d/plugin-scmgit-dav.inc','a');
+ fputs($f,'Use Project '.$project_name."\n");
+ fclose($f);
+ system(forge_get_config('httpd_reload_cmd','scmgit'));
+ }
}
if (forge_get_config('use_ssh','scmgit')) {
if ($project->enableAnonSCM()) {
system ("chmod g-rwx,o-rwx $main_repo") ;
}
- $result = db_query_params ('SELECT u.user_name FROM plugin_scmgit_personal_repos p, users u WHERE p.group_id=$1 AND u.user_id=p.user_id AND u.unix_status=$2',
+ // Create project-wide secondary repositories
+ $result = db_query_params ('SELECT repo_name, description, clone_url 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');
+ $description = db_result($result,$i,'description');
+ $clone_url = db_result($result,$i,'clone_url');
+ $repodir = $root . '/' . $repo_name . '.git' ;
+ if (!is_file ("$repodir/HEAD") && !is_dir("$repodir/objects") && !is_dir("$repodir/refs")) {
+ if ($clone_url != '') {
+ system ("cd $root;git clone --bare $clone_url $repodir") ;
+ } else {
+ system ("GIT_DIR=\"$repodir\" git init --bare --shared=group") ;
+ }
+ system ("GIT_DIR=\"$repodir\" git update-server-info") ;
+ if (is_file ("$repodir/hooks/post-update.sample")) {
+ rename ("$repodir/hooks/post-update.sample",
+ "$repodir/hooks/post-update") ;
+ }
+ if (!is_file ("$repodir/hooks/post-update")) {
+ $f = fopen ("$repodir/hooks/post-update") ;
+ fwrite ($f, "exec git-update-server-info\n") ;
+ fclose ($f) ;
+ }
+ if (is_file ("$repodir/hooks/post-update")) {
+ system ("chmod +x $repodir/hooks/post-update") ;
+ }
+ $f = fopen("$repodir/description", "w");
+ fwrite($f, $description."\n");
+ fclose($f);
+ system ("chgrp -R $unix_group $repodir") ;
+ system ("chmod g+s $root") ;
+ if ($project->enableAnonSCM()) {
+ system ("chmod -R g+wX,o+rX-w $main_repo") ;
+ } else {
+ system ("chmod -R g+wX,o-rwx $main_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 = $root . '/' . $repo_name . '.git' ;
+ 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()));
+ }
+
+ // Create users' personal repositories
+ $result = db_query_params ('SELECT u.user_name FROM scm_personal_repos p, users u WHERE p.group_id=$1 AND u.user_id=p.user_id AND u.unix_status=$2 AND plugin_id=$3',
array ($project->getID(),
- 'A')) ;
+ 'A',
+ $this->getID()));
$rows = db_numrows ($result) ;
for ($i=0; $i<$rows; $i++) {
system ("mkdir -p $root/users") ;
$user_name = db_result($result,$i,'user_name');
$repodir = $root . '/users/' . $user_name . '.git' ;
-
+
if (!is_dir($repodir) && mkdir ($repodir, 0700)) {
chown ($repodir, $user_name) ;
fwrite($config_f, "\$stylesheet = '". util_make_url('/plugins/scmgit/gitweb.css')."';\n");
fwrite($config_f, "\$javascript = '". util_make_url('/plugins/scmgit/gitweb.js')."';\n");
fwrite($config_f, "\$prevent_xss = 'true';\n");
+ fwrite($config_f, "\$feature{'actions'}{'default'} = [('project home', '" .
+ util_make_url('/plugins/scmgit/?func=grouppage/%n') .
+ "', 'summary')];\n");
fclose($config_f);
- chmod ($fname.'.new', 0644) ;
- rename ($fname.'.new', $fname) ;
+ chmod($fname.'.new', 0644);
+ rename($fname.'.new', $fname);
- $fname = $config_dir . '/gitweb.list' ;
+ $fname = $config_dir . '/gitweb.list';
+ $f = fopen($fname.'.new', 'w');
- $f = fopen ($fname.'.new', 'w');
+ $engine = RBACEngine::getInstance();
foreach ($list as $project) {
- $repos = $this->getRepositories($rootdir . "/" . $project->getUnixName());
- foreach ($repos as $repo) {
- $reldir = substr($repo, strlen($rootdir) + 1);
- fwrite($f, $reldir . "\n");
- }
+ $repos = $this->getRepositories($rootdir . "/" . $project->getUnixName());
+ foreach ($repos as $repo) {
+ $reldir = substr($repo, strlen($rootdir) + 1);
+ fwrite($f, $reldir . "\n");
+ }
+ $users = $engine->getUsersByAllowedAction('scm',$project->getID(),'write');
+ $password_data = '';
+ foreach ($users as $user) {
+ $password_data .= $user->getUnixName().':'.$user->getUnixPasswd()."\n";
+ }
+ $faname = forge_get_config('data_path').'/gituser-authfile.'.$project->getUnixName();
+ $fa = fopen($faname.'.new', 'w');
+ fwrite($fa, $password_data);
+ fclose($fa);
+ chmod($faname.'.new', 0644);
+ rename($faname.'.new', $faname);
}
fclose($f);
chmod($fname.'.new', 0644);
continue;
$result = $this->getRepositories($fullname);
$list = array_merge($list, $result);
- } else if ($entry == "HEAD") {
+ } elseif ($entry == "HEAD") {
$list[] = $path;
}
}
$repo = forge_get_config('repos_path', 'scmgit') . '/' . $project->getUnixName() . '/' . $project->getUnixName() . '.git';
if (!is_dir ($repo) || !is_dir ("$repo/refs")) {
- // echo "No repository\n" ;
+ // echo "No repository $repo\n" ;
return false ;
}
// Author line
$last_user = $matches['name'];
$user2email[$last_user] = strtolower($matches['mail']);
+ if (!isset($usr_adds[$last_user])) {
+ $usr_adds[$last_user] = 0;
+ $usr_updates[$last_user] = 0;
+ $usr_deletes[$last_user] = 0;
+ }
} else {
// Short-commit stats line
- preg_match("/^(?P<mode>[AM])\s+(?P<file>.+)$/", $line, $matches);
+ $result = preg_match("/^(?P<mode>[AMD])\s+(?P<file>.+)$/", $line, $matches);
+ if (!$result) continue;
if ($last_user == "") continue;
+ if (!isset ($usr_adds[$last_user])) $usr_adds[$last_user] = 0;
+ if (!isset ($usr_updates[$last_user])) $usr_updates[$last_user] = 0;
+ if (!isset ($usr_deletes[$last_user])) $usr_deletes[$last_user] = 0;
if ($matches['mode'] == 'A') {
$usr_adds[$last_user]++;
$adds++;
}
}
- $uu = $usr_updates[$user] ? $usr_updates[$user] : 0 ;
- $ua = $usr_adds[$user] ? $usr_adds[$user] : 0 ;
+ $uu = isset ($usr_updates[$user]) ? $usr_updates[$user] : 0 ;
+ $ua = isset ($usr_adds[$user]) ? $usr_adds[$user] : 0 ;
if ($uu > 0 || $ua > 0) {
if (!db_query_params ('INSERT INTO stats_cvs_user (month,day,group_id,user_id,commits,adds) VALUES ($1,$2,$3,$4,$5,$6)',
array ($month_string,
* @return boolean
*/
function widgets($params) {
- require_once('common/widget/WidgetLayoutManager.class.php');
+ require_once 'common/widget/WidgetLayoutManager.class.php';
if ($params['owner_type'] == WidgetLayoutManager::OWNER_TYPE_GROUP) {
$params['fusionforge_widgets'][] = 'plugin_scmgit_project_latestcommits';
}
function myPageBox($params) {
global $gfplugins;
$user = UserManager::instance()->getCurrentUser();
- require_once('common/widget/WidgetLayoutManager.class.php');
+ require_once 'common/widget/WidgetLayoutManager.class.php';
if ($params['widget'] == 'plugin_scmgit_user_myrepositories') {
require_once $gfplugins.$this->name.'/common/scmgit_Widget_MyRepositories.class.php';
$params['instance'] = new scmgit_Widget_MyRepositories(WidgetLayoutManager::OWNER_TYPE_USER, $user->getId());
}
}
+
+ function weekly(&$params) {
+ $res = db_query_params('SELECT group_id FROM groups WHERE status=$1 AND use_scm=1 ORDER BY group_id DESC',
+ array ('A'));
+ if (!$res) {
+ $params['output'] .= 'ScmGit Plugin: Unable to get list of projects using SCM: '.db_error();
+ return false;
+ }
+
+ $params['output'] .= 'ScmGit Plugin: Running "git gc --quiet" on '.db_numrows($res).' repositories.'."\n";
+ while ($row = db_fetch_array($res)) {
+ $project = group_get_object($row['group_id']);
+ if (!$project || !is_object($project)) {
+ continue;
+ } elseif ($project->isError()) {
+ continue;
+ }
+ if (!$project->usesPlugin($this->name)) {
+ continue;
+ }
+
+ $project_name = $project->getUnixName();
+ $repo = forge_get_config('repos_path', 'scmgit') . '/' . $project_name . '/' . $project_name .'.git';
+ if (is_dir($repo)) {
+ chdir($repo);
+ $params['output'] .= $project_name.': '.`git gc --quiet 2>&1`;
+ }
+ }
+ }
+
+ function activity($params) {
+ $group_id = $params['group'];
+ $project = group_get_object($group_id);
+ if (! $project->usesPlugin($this->name)) {
+ return false;
+ }
+ if (in_array('scmgit', $params['show']) || (count($params['show']) < 1)) {
+ $start_time = $params['begin'];
+ $end_time = $params['end'];
+ $repo = forge_get_config('repos_path', 'scmgit') . '/' . $project->getUnixName() . '/' . $project->getUnixName() . '.git';
+ $pipe = popen("GIT_DIR=\"$repo\" git log --date=raw --since=@$start_time --until=@$end_time --all --pretty='format:%ad||%ae||%s||%h' --name-status", 'r' );
+ while (!feof($pipe) && $data = fgets($pipe)) {
+ $line = trim($data);
+ $splitedLine = explode('||', $line);
+ if (sizeof($splitedLine) == 4) {
+ $result = array();
+ $result['section'] = 'scm';
+ $result['group_id'] = $group_id;
+ $result['ref_id'] = 'browser.php?group_id='.$group_id;
+ $result['description'] = $splitedLine[2].' (commit '.$splitedLine[3].')';
+ $userObject = user_get_object_by_email($splitedLine[1]);
+ if (is_a($userObject, 'GFUser')) {
+ $result['realname'] = make_user_link($userObject->getUnixName(), $userObject->getRealName());
+ } else {
+ $result['realname'] = '';
+ }
+ $splitedDate = explode(' ', $splitedLine[0]);
+ $result['activity_date'] = $splitedDate[0];
+ $result['subref_id'] = '';
+ $params['results'][] = $result;
+ }
+ }
+ }
+ $params['ids'][] = $this->name;
+ $params['texts'][] = _('Git Commits');
+ return true;
+ }
+
+ 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['clone'])) {
+ $url = $params['clone'];
+ if ($url == '') {
+ // Start from empty
+ $clone = $url;
+ } elseif (preg_match('|^git://|', $url) || preg_match('|^https?://|', $url)) {
+ // External URLs: OK
+ $clone = $url;
+ } elseif ($url == $project->getUnixName()) {
+ $clone = $url;
+ } elseif (($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 ($project->getID(),
+ $url,
+ $this->getID())))
+ && db_result($result, 0, 'count')) {
+ // Local repo: try to clone from an existing repo in same project
+ // Repository found
+ $clone = $url;
+ } else {
+ $params['error_msg'] = _('Invalid URL from which to clone');
+ $clone = '';
+ return false;
+ }
+ }
+ if (isset($params['description'])) {
+ $description = $params['description'];
+ }
+ if ($clone && !$description) {
+ $description = sprintf(_('Clone of %s'), $params['clone']);
+ }
+ if (!$description) {
+ $description = "Git 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) {
+ $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();
+
+ $select_repo = '<select name="frontpage">' . "\n";
+ $result = db_query_params('SELECT repo_name, description, clone_url 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'],
+ 'clone_url' => $data['clone_url']);
+ }
+ if (count($existing_repos) == 0) {
+ printf('<h2>'._('No extra Git repository for project %1$s').'</h2>', $project_name);
+ } else {
+ $t = sprintf(ngettext('Extra Git repository for project %1$s',
+ 'Extra Git repositories for project %1$s',
+ count($existing_repos)), $project_name);
+ print '<h2>'.$t.'</h2>';
+ print '<table><thead><tr><th>'._('Repository name').'</th><th>'._('Initial repository description').'</th><th>'._('Initial clone URL (if any)').'</th><th>'._('Delete').'</th></tr></thead><tbody>';
+ foreach ($existing_repos as $repo) {
+ print "<tr><td><tt>$repo[repo_name]</tt></td><td>$repo[description]</td><td>$repo[clone_url]</td><td>";
+?>
+<form name="form_delete_repo_<?php echo $repo['repo_name']?>"
+ action="<?php echo getStringFromServer('PHP_SELF'); ?>" method="post">
+<input type="hidden" name="group_id" value="<?php echo $params['group_id'] ?>" />
+<input type="hidden" name="delete_repository" value="1" />
+<input type="hidden" name="repo_name" value="<?php echo $repo['repo_name']?>" />
+<input type="submit" name="submit" value="<?php echo _('Delete') ?>" />
+</form>
+<?php
+ print "</td></tr>\n";
+ }
+ print '</tbody></table>';
+ }
+
+ printf('<h2>'._('Create new Git repository for project %1$s').'</h2>', $project_name);
+
+ ?>
+<form name="form_create_repo"
+ action="<?php echo getStringFromServer('PHP_SELF'); ?>" method="post">
+<input type="hidden" name="group_id" value="<?php echo $params['group_id'] ?>" />
+<input type="hidden" name="create_repository" value="1" />
+<p><strong><?php echo _('Repository name:') ?></strong><?php echo utils_requiredField(); ?><br />
+<input type="text" required="required" size="20" name="repo_name" value="" /></p>
+<p><strong><?php echo _('Description:'); ?></strong><br />
+<input type="text" size="60" name="description" value="" /></p>
+<p><strong><?php echo _('Initial clone URL (or name of an existing repository in this project; leave empty to start with an empty repository):') ?></strong><br />
+<input type="text" size="60" name="clone" value="<?php echo $project_name; ?>" /></p>
+<input type="submit" name="cancel" value="<?php echo _('Cancel') ?>" />
+<input type="submit" name="submit" value="<?php echo _('Submit') ?>" />
+</form>
+
+ <?php
+ }
+
}
// Local Variables:
// mode: php
// c-file-style: "bsd"
// End:
-
-?>