Merged master back into the code review work.
This commit is contained in:
commit
dd56d681b3
12
AUTHORS
12
AUTHORS
@ -9,4 +9,14 @@ Much appreciated contributors:
|
||||
Baptiste Michaud <bactisme@gmail.com> - Subversion synchronization
|
||||
Julien Issler
|
||||
Manuel Eidenberger <eidenberger@gmail.com>
|
||||
Patrick Georgi
|
||||
Ciaran Gultnieks
|
||||
Mehdi Kabab
|
||||
Sindre R. Myren
|
||||
Patrick Georgi <patrick.georgi@coresystems.de>
|
||||
Adrien Bustany
|
||||
Charles Melbye
|
||||
Baptiste Durand-Bret
|
||||
|
||||
And all the nice users who spent time reporting issues and promoting
|
||||
the project. The project could not live without them.
|
||||
|
||||
|
@ -70,6 +70,13 @@ folder. Here is a configuration example:
|
||||
$cfg['idf_plugin_syncgit_path_gitserve'] = '/home/www/indefero/scripts/gitserve.py'; # yes .py
|
||||
$cfg['idf_plugin_syncgit_path_authorized_keys'] = '/home/git/.ssh/authorized_keys';
|
||||
$cfg['idf_plugin_syncgit_sync_file'] = '/tmp/SYNC-GIT';
|
||||
# Remove the git repositories which do not have a corresponding project
|
||||
# This is run at cron time
|
||||
$cfg['idf_plugin_syncgit_remove_orphans'] = false;
|
||||
# git account home dir
|
||||
$cfg['idf_plugin_syncgit_git_home_dir'] = '/home/git';
|
||||
# where are going to be the git repositories
|
||||
$cfg['idf_plugin_sncgit_base_repositories'] = '/home/git/repositories';
|
||||
|
||||
When someone will change his SSH key or add a new one, the
|
||||
`/tmp/SYNC-GIT` file will be created. The cron job
|
||||
|
@ -66,6 +66,8 @@ need to put the following in your configuration file:
|
||||
$cfg['idf_plugin_syncsvn_authz_file'] = '/home/svn/dav_svn.authz';
|
||||
$cfg['idf_plugin_syncsvn_passwd_file'] = '/home/svn/dav_svn.passwd';
|
||||
$cfg['idf_plugin_syncsvn_svn_path'] = '/home/svn/repositories';
|
||||
// Delete the corresponding repository when deleting the project
|
||||
$cfg['idf_plugin_syncsvn_remove_orphans'] = false;
|
||||
|
||||
You can have more control over the permissions given to the owners,
|
||||
members, extra authorized users and anonymous users if you want with
|
||||
|
@ -37,5 +37,5 @@ set_include_path(get_include_path()
|
||||
require 'Pluf.php';
|
||||
Pluf::start(dirname(__FILE__).'/../src/IDF/conf/idf.php');
|
||||
Pluf_Dispatcher::loadControllers(Pluf::f('idf_views'));
|
||||
IDF_Plugin_SyncGit_Serve::main($argv, $_ENV);
|
||||
IDF_Plugin_SyncGit_Serve::main($argv, array_merge($_SERVER, $_ENV));
|
||||
|
||||
|
@ -144,12 +144,14 @@ class IDF_Commit extends Pluf_Model
|
||||
if ($r->count() > 0) {
|
||||
return $r[0];
|
||||
}
|
||||
if (!isset($change->full_message)) {
|
||||
$change->full_message = '';
|
||||
}
|
||||
$scm = IDF_Scm::get($project);
|
||||
$commit = new IDF_Commit();
|
||||
$commit->project = $project;
|
||||
$commit->scm_id = $change->commit;
|
||||
$commit->summary = $change->title;
|
||||
$commit->fullmessage = $change->full_message;
|
||||
list($commit->summary, $commit->fullmessage) = self::toUTF8(array($change->title, $change->full_message));
|
||||
$commit->author = $scm->findAuthor($change->author);
|
||||
$commit->origauthor = $change->author;
|
||||
$commit->creation_dtime = $change->date;
|
||||
@ -176,6 +178,39 @@ class IDF_Commit extends Pluf_Model
|
||||
return $commit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert encoding to UTF8.
|
||||
*
|
||||
* If an array is given, the encoding is detected only on the
|
||||
* first value and then used to convert all the strings.
|
||||
*
|
||||
* @param mixed String or array of string to be converted
|
||||
* @return mixed String or array of string
|
||||
*/
|
||||
public static function toUTF8($text)
|
||||
{
|
||||
$enc = 'ASCII, UTF-8, ISO-8859-1, JIS, EUC-JP, SJIS';
|
||||
$ref = $text;
|
||||
if (is_array($text)) {
|
||||
$ref = $text[0];
|
||||
}
|
||||
if (Pluf_Text_UTF8::check($ref)) {
|
||||
return $text;
|
||||
}
|
||||
$encoding = mb_detect_encoding($ref, $enc, true);
|
||||
if ($encoding == false) {
|
||||
$encoding = Pluf_Text_UTF8::detect_cyr_charset($ref);
|
||||
}
|
||||
if (is_array($text)) {
|
||||
foreach ($text as $t) {
|
||||
$res[] = mb_convert_encoding($t, 'UTF-8', $encoding);
|
||||
}
|
||||
return $res;
|
||||
} else {
|
||||
return mb_convert_encoding($text, 'UTF-8', $encoding);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the timeline fragment for the commit.
|
||||
*
|
||||
@ -202,7 +237,7 @@ class IDF_Commit extends Pluf_Model
|
||||
</tr>
|
||||
<tr class="extra">
|
||||
<td colspan="2">
|
||||
<div class="helptext right">'.__('Commit').' <a href="'.$url.'" class="mono">'.$this->scm_id.'</a>, '.__('by').' '.$user.'</div></td></tr>';
|
||||
<div class="helptext right">'.sprintf(__('Commit %s, by %s'), '<a href="'.$url.'" class="mono">'.$this->scm_id.'</a>', $user).'</div></td></tr>';
|
||||
return Pluf_Template::markSafe($out);
|
||||
}
|
||||
|
||||
|
@ -172,6 +172,7 @@ class IDF_Diff
|
||||
|
||||
public static function padLine($line)
|
||||
{
|
||||
$line = str_replace("\t", ' ', $line);
|
||||
$n = strlen($line);
|
||||
for ($i=0;$i<$n;$i++) {
|
||||
if (substr($line, $i, 1) != ' ') {
|
||||
|
@ -60,7 +60,7 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form
|
||||
array('required' => true,
|
||||
'label' => __('Shortname'),
|
||||
'initial' => '',
|
||||
'help_text' => __('It must be unique for each project and composed only of letters and digits.'),
|
||||
'help_text' => __('It must be unique for each project and composed only of letters, digits and dash (-) like "my-project".'),
|
||||
));
|
||||
|
||||
$this->fields['scm'] = new Pluf_Form_Field_Varchar(
|
||||
@ -133,6 +133,16 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form
|
||||
'IDF_Form_Admin_ProjectCreate', $params);
|
||||
}
|
||||
|
||||
public function clean_owners()
|
||||
{
|
||||
return IDF_Form_MembersConf::checkBadLogins($this->cleaned_data['owners']);
|
||||
}
|
||||
|
||||
public function clean_members()
|
||||
{
|
||||
return IDF_Form_MembersConf::checkBadLogins($this->cleaned_data['members']);
|
||||
}
|
||||
|
||||
public function clean_svn_remote_url()
|
||||
{
|
||||
$this->cleaned_data['svn_remote_url'] = (!empty($this->cleaned_data['svn_remote_url'])) ? $this->cleaned_data['svn_remote_url'] : '';
|
||||
@ -150,7 +160,7 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form
|
||||
{
|
||||
$shortname = $this->cleaned_data['shortname'];
|
||||
if (preg_match('/[^\-A-Za-z0-9]/', $shortname)) {
|
||||
throw new Pluf_Form_Invalid(__('This shortname contains illegal characters, please use only letters and digits.'));
|
||||
throw new Pluf_Form_Invalid(__('This shortname contains illegal characters, please use only letters, digits and dash (-).'));
|
||||
}
|
||||
if (mb_substr($shortname, 0, 1) == '-') {
|
||||
throw new Pluf_Form_Invalid(__('The shortname cannot start with the dash (-) character.'));
|
||||
|
@ -61,6 +61,16 @@ class IDF_Form_Admin_ProjectUpdate extends Pluf_Form
|
||||
));
|
||||
}
|
||||
|
||||
public function clean_owners()
|
||||
{
|
||||
return IDF_Form_MembersConf::checkBadLogins($this->cleaned_data['owners']);
|
||||
}
|
||||
|
||||
public function clean_members()
|
||||
{
|
||||
return IDF_Form_MembersConf::checkBadLogins($this->cleaned_data['members']);
|
||||
}
|
||||
|
||||
public function save($commit=true)
|
||||
{
|
||||
if (!$this->isValid()) {
|
||||
|
@ -179,8 +179,11 @@ class IDF_Form_Admin_UserUpdate extends Pluf_Form
|
||||
function clean_first_name()
|
||||
{
|
||||
$first_name = trim($this->cleaned_data['first_name']);
|
||||
if ($first_name == '---') {
|
||||
throw new Pluf_Form_Invalid(__('--- is not a valid first name.'));
|
||||
}
|
||||
if ($first_name == mb_strtoupper($first_name)) {
|
||||
return mb_convert_case(mb_strtolower($first_name),
|
||||
$first_name = mb_convert_case(mb_strtolower($first_name),
|
||||
MB_CASE_TITLE, 'UTF-8');
|
||||
}
|
||||
return $first_name;
|
||||
|
@ -67,6 +67,45 @@ class IDF_Form_MembersConf extends Pluf_Form
|
||||
$this->project->membershipsUpdated();
|
||||
}
|
||||
|
||||
public function clean_owners()
|
||||
{
|
||||
return self::checkBadLogins($this->cleaned_data['owners']);
|
||||
}
|
||||
|
||||
public function clean_members()
|
||||
{
|
||||
return self::checkBadLogins($this->cleaned_data['members']);
|
||||
}
|
||||
|
||||
/**
|
||||
* From the input, find the bad logins.
|
||||
*
|
||||
* @throws Pluf_Form_Invalid exception when bad logins are found
|
||||
* @param string Comma, new line delimited list of logins
|
||||
* @return string Comma, new line delimited list of logins
|
||||
*/
|
||||
public static function checkBadLogins($logins)
|
||||
{
|
||||
$bad = array();
|
||||
foreach (preg_split("/\015\012|\015|\012|\,/", $logins, -1, PREG_SPLIT_NO_EMPTY) as $login) {
|
||||
$sql = new Pluf_SQL('login=%s', array(trim($login)));
|
||||
try {
|
||||
$user = Pluf::factory('Pluf_User')->getOne(array('filter'=>$sql->gen()));
|
||||
if (null == $user) {
|
||||
$bad[] = $login;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$bad[] = $login;
|
||||
}
|
||||
}
|
||||
$n = count($bad);
|
||||
if ($n) {
|
||||
$badlogins = Pluf_esc(implode(', ', $bad));
|
||||
throw new Pluf_Form_Invalid(sprintf(_n('The following login is invalid: %s.', 'The following login are invalids: %s.', $n), $badlogins));
|
||||
}
|
||||
return $logins;
|
||||
}
|
||||
|
||||
/**
|
||||
* The update of the memberships is done in different places. This
|
||||
* avoids duplicating code.
|
||||
|
@ -95,6 +95,10 @@ class IDF_Form_PasswordInputKey extends Pluf_Form
|
||||
return false;
|
||||
}
|
||||
$cr = new Pluf_Crypt(md5(Pluf::f('secret_key')));
|
||||
return split(':', $cr->decrypt($encrypted), 3);
|
||||
$f = split(':', $cr->decrypt($encrypted), 3);
|
||||
if (count($f) != 3) {
|
||||
return false;
|
||||
}
|
||||
return $f;
|
||||
}
|
||||
}
|
||||
|
@ -59,8 +59,10 @@ class IDF_Form_ReviewCreate extends Pluf_Form
|
||||
'rows' => 7,
|
||||
),
|
||||
));
|
||||
$sql = new Pluf_SQL('project=%s', array($this->project->id));
|
||||
$commits = Pluf::factory('IDF_Commit')->getList(array('order' => 'creation_dtime DESC',
|
||||
'nb' => 10));
|
||||
'nb' => 10,
|
||||
'filter' => $sql->gen()));
|
||||
$choices = array();
|
||||
foreach ($commits as $c) {
|
||||
$id = (strlen($c->scm_id) > 10) ? substr($c->scm_id, 0, 10) : $c->scm_id;
|
||||
|
@ -86,6 +86,11 @@ class IDF_Form_TabsConf extends Pluf_Form
|
||||
));
|
||||
}
|
||||
|
||||
public function clean_authorized_users()
|
||||
{
|
||||
return IDF_Form_MembersConf::checkBadLogins($this->cleaned_data['authorized_users']);
|
||||
}
|
||||
|
||||
public function save($commit=true)
|
||||
{
|
||||
if (!$this->isValid()) {
|
||||
|
@ -46,6 +46,16 @@ class IDF_Form_UpdateUpload extends Pluf_Form
|
||||
'size' => 67,
|
||||
),
|
||||
));
|
||||
$this->fields['changelog'] = new Pluf_Form_Field_Varchar(
|
||||
array('required' => false,
|
||||
'label' => __('Description'),
|
||||
'initial' => $this->upload->changelog,
|
||||
'widget' => 'Pluf_Form_Widget_TextareaInput',
|
||||
'widget_attrs' => array(
|
||||
'cols' => 58,
|
||||
'rows' => 13,
|
||||
),
|
||||
));
|
||||
$tags = $this->upload->get_tags_list();
|
||||
for ($i=1;$i<7;$i++) {
|
||||
$initial = '';
|
||||
@ -132,6 +142,7 @@ class IDF_Form_UpdateUpload extends Pluf_Form
|
||||
}
|
||||
// Create the upload
|
||||
$this->upload->summary = trim($this->cleaned_data['summary']);
|
||||
$this->upload->changelog = trim($this->cleaned_data['changelog']);
|
||||
$this->upload->modif_dtime = gmdate('Y-m-d H:i:s');
|
||||
$this->upload->update();
|
||||
$this->upload->batchAssoc('IDF_Tag', $tags);
|
||||
|
@ -44,6 +44,16 @@ class IDF_Form_Upload extends Pluf_Form
|
||||
'size' => 67,
|
||||
),
|
||||
));
|
||||
$this->fields['changelog'] = new Pluf_Form_Field_Varchar(
|
||||
array('required' => false,
|
||||
'label' => __('Description'),
|
||||
'initial' => '',
|
||||
'widget' => 'Pluf_Form_Widget_TextareaInput',
|
||||
'widget_attrs' => array(
|
||||
'cols' => 58,
|
||||
'rows' => 13,
|
||||
),
|
||||
));
|
||||
$this->fields['file'] = new Pluf_Form_Field_File(
|
||||
array('required' => true,
|
||||
'label' => __('File'),
|
||||
@ -155,6 +165,7 @@ class IDF_Form_Upload extends Pluf_Form
|
||||
$upload->project = $this->project;
|
||||
$upload->submitter = $this->user;
|
||||
$upload->summary = trim($this->cleaned_data['summary']);
|
||||
$upload->changelog = trim($this->cleaned_data['changelog']);
|
||||
$upload->file = $this->cleaned_data['file'];
|
||||
$upload->filesize = filesize(Pluf::f('upload_path').'/'.$this->project->shortname.'/files/'.$this->cleaned_data['file']);
|
||||
$upload->downloads = 0;
|
||||
|
@ -193,7 +193,7 @@ class IDF_Issue extends Pluf_Model
|
||||
$ic = (in_array($this->status, $request->project->getTagIdsByStatus('closed'))) ? 'issue-c' : 'issue-o';
|
||||
$out .= sprintf(__('<a href="%1$s" class="%2$s" title="View issue">Issue %3$d</a>, %4$s'), $url, $ic, $this->id, Pluf_esc($this->summary)).'</td>';
|
||||
$out .= "\n".'<tr class="extra"><td colspan="2">
|
||||
<div class="helptext right">'.sprintf(__('Creation of <a href="%s" class="%s">issue %d</a>'), $url, $ic, $this->id).', '.__('by').' '.$user.'</div></td></tr>';
|
||||
<div class="helptext right">'.sprintf(__('Creation of <a href="%s" class="%s">issue %d</a>, by %s'), $url, $ic, $this->id, $user).'</div></td></tr>';
|
||||
return Pluf_Template::markSafe($out);
|
||||
}
|
||||
|
||||
|
@ -170,7 +170,7 @@ class IDF_IssueComment extends Pluf_Model
|
||||
|
||||
|
||||
$out .= "\n".'<tr class="extra"><td colspan="2">
|
||||
<div class="helptext right">'.sprintf(__('Comment on <a href="%s" class="%s">issue %d</a>'), $url, $ic, $issue->id).', '.__('by').' '.$user.'</div></td></tr>';
|
||||
<div class="helptext right">'.sprintf(__('Comment on <a href="%s" class="%s">issue %d</a>, by %s'), $url, $ic, $issue->id, $user).'</div></td></tr>';
|
||||
|
||||
return Pluf_Template::markSafe($out);
|
||||
}
|
||||
|
@ -123,4 +123,9 @@ class IDF_IssueFile extends Pluf_Model
|
||||
}
|
||||
$this->modif_dtime = gmdate('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
function preDelete()
|
||||
{
|
||||
@unlink(Pluf::f('upload_issue_path').'/'.$this->attachment);
|
||||
}
|
||||
}
|
||||
|
52
src/IDF/Migrations/11GitCache.php
Normal file
52
src/IDF/Migrations/11GitCache.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# This file is part of InDefero, an open source project management application.
|
||||
# Copyright (C) 2008 Céondo Ltd and contributors.
|
||||
#
|
||||
# InDefero 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.
|
||||
#
|
||||
# InDefero 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
# ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* Add the DB based Git cache.
|
||||
*/
|
||||
|
||||
function IDF_Migrations_11GitCache_up($params=null)
|
||||
{
|
||||
$models = array(
|
||||
'IDF_Scm_Cache_Git',
|
||||
);
|
||||
$db = Pluf::db();
|
||||
$schema = new Pluf_DB_Schema($db);
|
||||
foreach ($models as $model) {
|
||||
$schema->model = new $model();
|
||||
$schema->createTables();
|
||||
}
|
||||
}
|
||||
|
||||
function IDF_Migrations_11GitCache_down($params=null)
|
||||
{
|
||||
$models = array(
|
||||
'IDF_Scm_Cache_Git',
|
||||
);
|
||||
$db = Pluf::db();
|
||||
$schema = new Pluf_DB_Schema($db);
|
||||
foreach ($models as $model) {
|
||||
$schema->model = new $model();
|
||||
$schema->dropTables();
|
||||
}
|
||||
}
|
55
src/IDF/Migrations/12DownloadDesc.php
Normal file
55
src/IDF/Migrations/12DownloadDesc.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# This file is part of InDefero, an open source project management application.
|
||||
# Copyright (C) 2008 Céondo Ltd and contributors.
|
||||
#
|
||||
# InDefero 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.
|
||||
#
|
||||
# InDefero 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
# ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* Add the private column for the project.
|
||||
*/
|
||||
|
||||
function IDF_Migrations_12DownloadDesc_up($params=null)
|
||||
{
|
||||
$table = Pluf::factory('IDF_Upload')->getSqlTable();
|
||||
$sql = array();
|
||||
$sql['PostgreSQL'] = 'ALTER TABLE '.$table.' ADD COLUMN "changelog" TEXT DEFAULT \'\'';
|
||||
$sql['MySQL'] = 'ALTER TABLE '.$table.' ADD COLUMN `changelog` LONGTEXT DEFAULT \'\'';
|
||||
$db = Pluf::db();
|
||||
$engine = Pluf::f('db_engine');
|
||||
if (!isset($sql[$engine])) {
|
||||
throw new Exception('SQLite complex migration not supported.');
|
||||
}
|
||||
$db->execute($sql[$engine]);
|
||||
}
|
||||
|
||||
function IDF_Migrations_12DownloadDesc_down($params=null)
|
||||
{
|
||||
$table = Pluf::factory('IDF_Upload')->getSqlTable();
|
||||
$sql = array();
|
||||
$sql['PostgreSQL'] = 'ALTER TABLE '.$table.' DROP COLUMN "changelog"';
|
||||
$sql['MySQL'] = 'ALTER TABLE '.$table.' DROP COLUMN `changelog`';
|
||||
$db = Pluf::db();
|
||||
$engine = Pluf::f('db_engine');
|
||||
if (!isset($sql[$engine])) {
|
||||
throw new Exception('SQLite complex migration not supported.');
|
||||
}
|
||||
$db->execute($sql[$engine]);
|
||||
|
||||
}
|
@ -46,6 +46,7 @@ function IDF_Migrations_Install_setup($params=null)
|
||||
'IDF_Review_Patch',
|
||||
'IDF_Review_FileComment',
|
||||
'IDF_Key',
|
||||
'IDF_Scm_Cache_Git',
|
||||
);
|
||||
$db = Pluf::db();
|
||||
$schema = new Pluf_DB_Schema($db);
|
||||
@ -83,6 +84,7 @@ function IDF_Migrations_Install_teardown($params=null)
|
||||
$perm = Pluf_Permission::getFromString('IDF.project-authorized-user');
|
||||
if ($perm) $perm->delete();
|
||||
$models = array(
|
||||
'IDF_Scm_Cache_Git',
|
||||
'IDF_Key',
|
||||
'IDF_Review_FileComment',
|
||||
'IDF_Review_Patch',
|
||||
|
@ -40,7 +40,7 @@ class IDF_Plugin_SyncGit_Cron
|
||||
$cmd = Pluf::f('idf_plugin_syncgit_path_gitserve', '/dev/null');
|
||||
$authorized_keys = Pluf::f('idf_plugin_syncgit_path_authorized_keys', false);
|
||||
if (false == $authorized_keys) {
|
||||
throw new Pluf_Exception_SettingError('Setting git_path_authorized_keys not set.');
|
||||
throw new Pluf_Exception_SettingError('Setting idf_plugin_syncgit_path_authorized_keys not set.');
|
||||
}
|
||||
if (!is_writable($authorized_keys)) {
|
||||
throw new Exception('Cannot create file: '.$authorized_keys);
|
||||
@ -69,6 +69,44 @@ class IDF_Plugin_SyncGit_Cron
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove orphan repositories.
|
||||
*/
|
||||
public static function removeOrphanRepositories()
|
||||
{
|
||||
$path = Pluf::f('idf_plugin_syncgit_base_repositories', '/home/git/repositories');
|
||||
if (!is_dir($path) || is_link($path)) {
|
||||
throw new Pluf_Exception_SettingError(sprintf(
|
||||
'Directory %s does not exist! Setting "idf_plugin_syncgit_base_repositories not set.',
|
||||
$path));
|
||||
}
|
||||
if (!is_writable($path)) {
|
||||
throw new Exception(sprintf('Repository %s is not writable.', $path));
|
||||
}
|
||||
$projects = array();
|
||||
foreach (Pluf::factory('IDF_Project')->getList() as $project) {
|
||||
$projects[] = $project->shortname;
|
||||
}
|
||||
unset($project);
|
||||
$it = new DirectoryIterator($path);
|
||||
$orphans = array();
|
||||
while ($it->valid()) {
|
||||
if (!$it->isDot() && $it->isDir() && !in_array(basename($it->getFileName(), '.git'), $projects)) {
|
||||
$orphans[] = $it->getPathName();
|
||||
}
|
||||
$it->next();
|
||||
}
|
||||
if (count($orphans)) {
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').'rm -rf '.implode(' ', $orphans);
|
||||
exec($cmd);
|
||||
while (list(, $project) = each($orphans)) {
|
||||
if (is_dir($project)) {
|
||||
throw new Exception(sprintf('Cannot remove %s directory.', $project));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a sync is needed.
|
||||
*
|
||||
@ -79,6 +117,9 @@ class IDF_Plugin_SyncGit_Cron
|
||||
@unlink(Pluf::f('idf_plugin_syncgit_sync_file'));
|
||||
self::sync();
|
||||
self::markExport();
|
||||
if (Pluf::f('idf_plugin_syncgit_remove_orphans', false)) {
|
||||
self::removeOrphanRepositories();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,9 @@ class IDF_Plugin_SyncSvn
|
||||
case 'Pluf_User::passwordUpdated':
|
||||
$plug->processSyncPasswd($params['user']);
|
||||
break;
|
||||
case 'IDF_Project::preDelete':
|
||||
$plug->processSvnDelete($params['project']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,6 +87,31 @@ class IDF_Plugin_SyncSvn
|
||||
return ($return == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the project from the drive and update the access rights.
|
||||
*
|
||||
* @param IDF_Project
|
||||
* @return bool Success
|
||||
*/
|
||||
function processSvnDelete($project)
|
||||
{
|
||||
if (!Pluf::f('idf_plugin_syncsvn_remove_orphans', false)) {
|
||||
return;
|
||||
}
|
||||
if ($project->getConf()->getVal('scm') != 'svn') {
|
||||
return false;
|
||||
}
|
||||
$this->SyncAccess($project); // exclude $project
|
||||
$shortname = $project->shortname;
|
||||
if (false===($svn_path=Pluf::f('idf_plugin_syncsvn_svn_path',false))) {
|
||||
throw new Pluf_Exception_SettingError("'idf_plugin_syncsvn_svn_path' must be defined in your configuration file.");
|
||||
}
|
||||
if (file_exists($svn_path.'/'.$shortname)) {
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').'rm -rf '.$svn_path.'/'.$shortname;
|
||||
exec($cmd);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronise an user's password.
|
||||
*
|
||||
@ -156,8 +184,10 @@ class IDF_Plugin_SyncSvn
|
||||
* We rebuild the complete file each time. This is just to be sure
|
||||
* not to bork the rights when trying to just edit part of the
|
||||
* file.
|
||||
*
|
||||
* @param IDF_Project Possibly exclude a project (null)
|
||||
*/
|
||||
function SyncAccess()
|
||||
function SyncAccess($exclude=null)
|
||||
{
|
||||
$authz_file = Pluf::f('idf_plugin_syncsvn_authz_file');
|
||||
$access_owners = Pluf::f('idf_plugin_syncsvn_access_owners', 'rw');
|
||||
@ -170,6 +200,9 @@ class IDF_Plugin_SyncSvn
|
||||
}
|
||||
$fcontent = '';
|
||||
foreach (Pluf::factory('IDF_Project')->getList() as $project) {
|
||||
if ($exclude and $exclude->id == $project->id) {
|
||||
continue;
|
||||
}
|
||||
$conf = new IDF_Conf();
|
||||
$conf->setProject($project);
|
||||
if ($conf->getVal('scm') != 'svn' or
|
||||
|
@ -349,16 +349,54 @@ class IDF_Project extends Pluf_Model
|
||||
return new Pluf_Template_ContextVars($tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the repository size.
|
||||
*
|
||||
* @param bool Force to skip the cache (false)
|
||||
* @return int Size in byte or -1 if not available
|
||||
*/
|
||||
public function getRepositorySize($force=false)
|
||||
{
|
||||
$last_eval = $this->getConf()->getVal('repository_size_check_date', 0);
|
||||
if (!$force and $last_eval > time()-86400) {
|
||||
return $this->getConf()->getVal('repository_size', -1);
|
||||
}
|
||||
$scm = IDF_Scm::get($this);
|
||||
$this->getConf()->setVal('repository_size', $scm->getRepositorySize());
|
||||
$this->getConf()->setVal('repository_size_check_date', time());
|
||||
return $this->getConf()->getVal('repository_size', -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the access url to the repository.
|
||||
*
|
||||
* This will return the right url based on the user.
|
||||
*
|
||||
* @param Pluf_User The user (null)
|
||||
*/
|
||||
public function getSourceAccessUrl($user=null)
|
||||
{
|
||||
$right = $this->getConf()->getVal('source_access_rights', 'all');
|
||||
if (($user == null or $user->isAnonymous())
|
||||
and $right == 'all' and !$this->private) {
|
||||
return $this->getRemoteAccessUrl();
|
||||
}
|
||||
return $this->getWriteRemoteAccessUrl($user);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the remote access url to the repository.
|
||||
*
|
||||
* This will always return the anonymous access url.
|
||||
*/
|
||||
public function getRemoteAccessUrl()
|
||||
{
|
||||
$conf = $this->getConf();
|
||||
$scm = $conf->getVal('scm', 'git');
|
||||
$scms = Pluf::f('allowed_scm');
|
||||
return call_user_func(array($scms[$scm], 'getRemoteAccessUrl'),
|
||||
Pluf::loadClass($scms[$scm]);
|
||||
return call_user_func(array($scms[$scm], 'getAnonymousAccessUrl'),
|
||||
$this);
|
||||
}
|
||||
|
||||
@ -369,13 +407,13 @@ class IDF_Project extends Pluf_Model
|
||||
* same as the one to read. For example, you do a checkout with
|
||||
* git-daemon and push with SSH.
|
||||
*/
|
||||
public function getWriteRemoteAccessUrl()
|
||||
public function getWriteRemoteAccessUrl($user)
|
||||
{
|
||||
$conf = $this->getConf();
|
||||
$scm = $conf->getVal('scm', 'git');
|
||||
$scms = Pluf::f('allowed_scm');
|
||||
return call_user_func(array($scms[$scm], 'getWriteRemoteAccessUrl'),
|
||||
$this);
|
||||
return call_user_func(array($scms[$scm], 'getAuthAccessUrl'),
|
||||
$this, $user);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -541,4 +579,42 @@ class IDF_Project extends Pluf_Model
|
||||
Pluf_Signal::send('IDF_Project::created',
|
||||
'IDF_Project', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* The delete() call do not like circular references and the
|
||||
* IDF_Tag is creating some. We predelete to solve these issues.
|
||||
*/
|
||||
public function preDelete()
|
||||
{
|
||||
/**
|
||||
* [signal]
|
||||
*
|
||||
* IDF_Project::preDelete
|
||||
*
|
||||
* [sender]
|
||||
*
|
||||
* IDF_Project
|
||||
*
|
||||
* [description]
|
||||
*
|
||||
* This signal allows an application to perform special
|
||||
* operations at the deletion of a project.
|
||||
*
|
||||
* [parameters]
|
||||
*
|
||||
* array('project' => $project)
|
||||
*
|
||||
*/
|
||||
$params = array('project' => $this);
|
||||
Pluf_Signal::send('IDF_Project::preDelete',
|
||||
'IDF_Project', $params);
|
||||
$what = array('IDF_Upload', 'IDF_Review', 'IDF_Issue',
|
||||
'IDF_WikiPage', 'IDF_Commit',
|
||||
);
|
||||
foreach ($what as $m) {
|
||||
foreach (Pluf::factory($m)->getList(array('filter' => 'project='.(int)$this->id)) as $item) {
|
||||
$item->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
320
src/IDF/Scm.php
320
src/IDF/Scm.php
@ -22,10 +22,55 @@
|
||||
# ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* Manage differents SCM systems
|
||||
* Manage differents SCM systems.
|
||||
*
|
||||
* This is the base class with the different required methods to be
|
||||
* implemented by the SCMs. Each SCM backend need to extend this
|
||||
* class. We are not using an interface because this is not really
|
||||
* needed.
|
||||
*
|
||||
* The philosophy behind the interface is not to provide a wrapper
|
||||
* around the different SCMs but to provide methods to retrieve in the
|
||||
* most efficient way the informations to be displayed/needed in the
|
||||
* web interface. This means that each SCM can use the best options,
|
||||
* including caching to retrieve the informations.
|
||||
*
|
||||
* Note on caching: You must not cache ephemeral information like the
|
||||
* changelog, but you can cache the commit info (except with
|
||||
* subversion where you can change commit info...). It is ok to do
|
||||
* some caching for the lifetime of the IDF_Scm object, for example
|
||||
* not to retrieve several times the list of branches, etc.
|
||||
*
|
||||
* All the output of the methods must be serializable. This means that
|
||||
* if you are parsing XML you need to correctly cast the results as
|
||||
* string when needed.
|
||||
*/
|
||||
class IDF_Scm
|
||||
{
|
||||
/**
|
||||
* String template for consistent error messages.
|
||||
*/
|
||||
public $error_tpl = 'Error command "%s" returns code %d and output: %s';
|
||||
|
||||
/**
|
||||
* Path to the repository.
|
||||
*/
|
||||
public $repo = '';
|
||||
|
||||
/**
|
||||
* Corresponding project object.
|
||||
*/
|
||||
public $project = null;
|
||||
|
||||
/**
|
||||
* Cache storage.
|
||||
*
|
||||
* It must only be used to store data for the lifetime of the
|
||||
* object. For example if you need to get the list of branches in
|
||||
* several functions, better to try to get from the cache first.
|
||||
*/
|
||||
protected $cache = array();
|
||||
|
||||
|
||||
/**
|
||||
* Returns an instance of the correct scm backend object.
|
||||
@ -33,7 +78,7 @@ class IDF_Scm
|
||||
* @param IDF_Project
|
||||
* @return Object
|
||||
*/
|
||||
public static function get($project=null)
|
||||
public static function get($project)
|
||||
{
|
||||
// Get scm type from project conf ; defaults to git
|
||||
// We will need to cache the factory
|
||||
@ -43,46 +88,251 @@ class IDF_Scm
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to exec but with caching.
|
||||
* Return the size of the repository in bytes.
|
||||
*
|
||||
* @param string Command
|
||||
* @param &array Output
|
||||
* @param &int Return value
|
||||
* @return string Last line of the output
|
||||
* @return int Size in byte, -1 if the size cannot be evaluated.
|
||||
*/
|
||||
public static function exec($command, &$output=array(), &$return=0)
|
||||
public function getRepositorySize()
|
||||
{
|
||||
$command = Pluf::f('idf_exec_cmd_prefix', '').$command;
|
||||
$key = md5($command);
|
||||
$cache = Pluf_Cache::factory();
|
||||
if (null === ($res=$cache->get($key))) {
|
||||
$ll = exec($command, $output, $return);
|
||||
if ($return != 0 and Pluf::f('debug_scm', false)) {
|
||||
throw new IDF_Scm_Exception(sprintf('Error when running command: "%s", return code: %d', $command, $return));
|
||||
}
|
||||
$cache->set($key, array($ll, $return, $output));
|
||||
} else {
|
||||
list($ll, $return, $output) = $res;
|
||||
}
|
||||
return $ll;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to shell_exec but with caching.
|
||||
* Returns the URL of the git daemon.
|
||||
*
|
||||
* @param string Command
|
||||
* @return string Output of the command
|
||||
* @param IDF_Project
|
||||
* @return string URL
|
||||
*/
|
||||
public static function shell_exec($command)
|
||||
public static function getAnonymousAccessUrl($project)
|
||||
{
|
||||
$command = Pluf::f('idf_exec_cmd_prefix', '').$command;
|
||||
$key = md5($command);
|
||||
$cache = Pluf_Cache::factory();
|
||||
if (null === ($res=$cache->get($key))) {
|
||||
$res = shell_exec($command);
|
||||
$cache->set($key, $res);
|
||||
throw new Pluf_Exception_NotImplemented();
|
||||
}
|
||||
return $res;
|
||||
|
||||
/**
|
||||
* Returns the URL for SSH access
|
||||
*
|
||||
* @param IDF_Project
|
||||
* @param Pluf_User
|
||||
* @return string URL
|
||||
*/
|
||||
public static function getAuthAccessUrl($project, $user)
|
||||
{
|
||||
throw new Pluf_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the backend is available for display.
|
||||
*
|
||||
* @return bool Available
|
||||
*/
|
||||
public function isAvailable()
|
||||
{
|
||||
throw new Pluf_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a revision or commit is valid.
|
||||
*
|
||||
* @param string Revision or commit
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidRevision($rev)
|
||||
{
|
||||
throw new Pluf_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns in which branches a commit/path is.
|
||||
*
|
||||
* A commit can be in several branches and some of the SCMs are
|
||||
* managing branches using subfolders (like Subversion).
|
||||
*
|
||||
* This means that to know in which branch we are at the moment,
|
||||
* one needs to have both the path and the commit.
|
||||
*
|
||||
* @param string Commit
|
||||
* @param string Path
|
||||
* @return array Branches
|
||||
*/
|
||||
public function inBranches($commit, $path)
|
||||
{
|
||||
throw new Pluf_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of branches.
|
||||
*
|
||||
* The return value must be a branch indexed array with the
|
||||
* optional path to access the branch as value. For example with
|
||||
* git you would get (note that some people are using / in the
|
||||
* name of their git branches):
|
||||
*
|
||||
* <pre>
|
||||
* array('master' => '',
|
||||
* 'foo-branch' => '',
|
||||
* 'design/feature1' => '')
|
||||
* </pre>
|
||||
*
|
||||
* But with Subversion, as the branches are managed as subfolder
|
||||
* with a special folder for trunk, you would get something like:
|
||||
*
|
||||
* <pre>
|
||||
* array('trunk' => 'trunk',
|
||||
* 'foo-branch' => 'branches/foo-branch',)
|
||||
* </pre>
|
||||
*
|
||||
* @return array Branches
|
||||
*/
|
||||
public function getBranches()
|
||||
{
|
||||
throw new Pluf_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of tags.
|
||||
*
|
||||
* The format is the same as for the branches.
|
||||
*
|
||||
* @see self::getBranches()
|
||||
*
|
||||
* @return array Tags
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
throw new Pluf_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the main branch.
|
||||
*
|
||||
* The main branch is the one displayed by default. For example
|
||||
* master, trunk or tip.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMainBranch()
|
||||
{
|
||||
throw new Pluf_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of files in a given folder.
|
||||
*
|
||||
* The list is an array of standard class objects with attributes
|
||||
* for each file/directory/external element.
|
||||
*
|
||||
* This is the most important method of the SCM backend as this is
|
||||
* the one conveying the speed feeling of the application. All the
|
||||
* dirty optimization tricks are allowed there.
|
||||
*
|
||||
* @param string Revision or commit
|
||||
* @param string Folder ('/')
|
||||
* @param string Branch (null)
|
||||
* @return array
|
||||
*/
|
||||
public function getTree($rev, $folder='/', $branch=null)
|
||||
{
|
||||
throw new Pluf_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get commit details.
|
||||
*
|
||||
* @param string Commit or revision number
|
||||
* @param bool Get commit diff (false)
|
||||
* @return stdClass
|
||||
*/
|
||||
public function getCommit($commit, $getdiff=false)
|
||||
{
|
||||
throw new Pluf_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get latest changes.
|
||||
*
|
||||
* It default to the main branch. If possible you should code in a
|
||||
* way to avoid repetitive calls to getCommit. Try to be
|
||||
* efficient.
|
||||
*
|
||||
* @param string Branch (null)
|
||||
* @param int Number of changes (25)
|
||||
* @return array List of commits
|
||||
*/
|
||||
public function getChangeLog($branch=null, $n=10)
|
||||
{
|
||||
throw new Pluf_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the string describing the author from the log find the
|
||||
* author in the database.
|
||||
*
|
||||
* If the input is an array, it will return an array of results.
|
||||
*
|
||||
* @param mixed string/array Author
|
||||
* @return mixed Pluf_User or null or array
|
||||
*/
|
||||
public function findAuthor($author)
|
||||
{
|
||||
throw new Pluf_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a revision and a file path, retrieve the file content.
|
||||
*
|
||||
* The $cmd_only parameter is to only request the command that is
|
||||
* used to get the file content. This is used when downloading a
|
||||
* file at a given revision as it can be passed to a
|
||||
* Pluf_HTTP_Response_CommandPassThru reponse. This allows to
|
||||
* stream a large response without buffering it in memory.
|
||||
*
|
||||
* The file definition is coming from getPathInfo().
|
||||
*
|
||||
* @see self::getPathInfo()
|
||||
*
|
||||
* @param stdClass File definition
|
||||
* @param bool Returns command only (false)
|
||||
* @return string File content
|
||||
*/
|
||||
public function getFile($def, $cmd_only=false)
|
||||
{
|
||||
throw new Pluf_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about a file or a path.
|
||||
*
|
||||
* @param string File or path
|
||||
* @param string Revision (null)
|
||||
* @return mixed False or stdClass with info
|
||||
*/
|
||||
public function getPathInfo($file, $rev=null)
|
||||
{
|
||||
throw new Pluf_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a revision and possible path returns additional properties.
|
||||
*
|
||||
* @param string Revision
|
||||
* @param string Path ('')
|
||||
* @return mixed null or array of properties
|
||||
*/
|
||||
public function getProperties($rev, $path='')
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the command to create a zip archive at a given commit.
|
||||
*
|
||||
* @param string Commit
|
||||
* @param string Prefix ('repository/')
|
||||
* @return string Command
|
||||
*/
|
||||
public function getArchiveCommand($commit, $prefix='repository/')
|
||||
{
|
||||
throw new Pluf_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,13 +345,13 @@ class IDF_Scm
|
||||
$key = 'IDF_Scm:'.$project->shortname.':lastsync';
|
||||
if (null === ($res=$cache->get($key))) {
|
||||
$scm = IDF_Scm::get($project);
|
||||
foreach ($scm->getBranches() as $branche) {
|
||||
foreach ($scm->getChangeLog($branche, 25) as $change) {
|
||||
if ($scm->isAvailable()) {
|
||||
foreach ($scm->getChangeLog($scm->getMainBranch(), 25) as $change) {
|
||||
IDF_Commit::getOrAdd($change, $project);
|
||||
}
|
||||
}
|
||||
$cache->set($key, true, (int)(Pluf::f('cache_timeout', 300)/2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
134
src/IDF/Scm/Cache/Git.php
Normal file
134
src/IDF/Scm/Cache/Git.php
Normal file
@ -0,0 +1,134 @@
|
||||
<?php
|
||||
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# This file is part of InDefero, an open source project management application.
|
||||
# Copyright (C) 2008 Céondo Ltd and contributors.
|
||||
#
|
||||
# InDefero 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.
|
||||
#
|
||||
# InDefero 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
# ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* This class implements the cache storage for the Git commits.
|
||||
*
|
||||
* The storage is simple. Each commit is linked to a project to drop
|
||||
* the cache when the project is dropped. The key is the commit hash
|
||||
* and the data is the date, author and one line title of information.
|
||||
*
|
||||
* A clean interface is available to bulk set/get a series of commit
|
||||
* info with the minimum of SQL queries. The goal is to be fast.
|
||||
*/
|
||||
class IDF_Scm_Cache_Git extends Pluf_Model
|
||||
{
|
||||
public $_model = __CLASS__;
|
||||
|
||||
/**
|
||||
* The current project to limit the search to.
|
||||
*/
|
||||
public $_project = null;
|
||||
|
||||
/**
|
||||
* Store in the cache blob infos.
|
||||
*
|
||||
* The info is an array of stdClasses, with hash, date, title and
|
||||
* author properties.
|
||||
*
|
||||
* @param array Blob infos
|
||||
*/
|
||||
public function store($infos)
|
||||
{
|
||||
foreach ($infos as $blob) {
|
||||
$cache = new IDF_Scm_Cache_Git();
|
||||
$cache->project = $this->_project;
|
||||
$cache->githash = $blob->hash;
|
||||
$blob->title = IDF_Commit::toUTF8($blob->title);
|
||||
$cache->content = $blob->date.chr(31).$blob->author.chr(31).$blob->title;
|
||||
$sql = new Pluf_SQL('project=%s AND githash=%s',
|
||||
array($this->_project->id, $blob->hash));
|
||||
if (0 == Pluf::factory(__CLASS__)->getCount(array('filter' => $sql->gen()))) {
|
||||
$cache->create();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get for the given hashes the corresponding date, title and
|
||||
* author.
|
||||
*
|
||||
* It returns an hash indexed array with the info. If an hash is
|
||||
* not in the db, the key is not set.
|
||||
*
|
||||
* Note that the hashes must always come from internal tools.
|
||||
*
|
||||
* @param array Hashes to get info
|
||||
* @return array Blob infos
|
||||
*/
|
||||
public function retrieve($hashes)
|
||||
{
|
||||
$res = array();
|
||||
$db = $this->getDbConnection();
|
||||
$hashes = array_map(array($db, 'esc'), $hashes);
|
||||
$sql = new Pluf_SQL('project=%s AND githash IN ('.implode(', ', $hashes).')',
|
||||
array($this->_project->id));
|
||||
foreach (Pluf::factory(__CLASS__)->getList(array('filter' => $sql->gen())) as $blob) {
|
||||
$tmp = split(chr(31), $blob->content, 3);
|
||||
|
||||
$res[$blob->githash] = (object) array(
|
||||
'hash' => $blob->githash,
|
||||
'date' => $tmp[0],
|
||||
'title' => $tmp[2],
|
||||
'author' => $tmp[1],
|
||||
);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* The storage is composed of 4 columns, id, project, hash and the
|
||||
* raw data.
|
||||
*/
|
||||
function init()
|
||||
{
|
||||
$this->_a['table'] = 'idf_scm_cache_git';
|
||||
$this->_a['model'] = __CLASS__;
|
||||
$this->_a['cols'] = array(
|
||||
// It is mandatory to have an "id" column.
|
||||
'id' =>
|
||||
array(
|
||||
'type' => 'Pluf_DB_Field_Sequence',
|
||||
'blank' => true,
|
||||
),
|
||||
'project' =>
|
||||
array(
|
||||
'type' => 'Pluf_DB_Field_Foreignkey',
|
||||
'model' => 'IDF_Project',
|
||||
'blank' => false,
|
||||
),
|
||||
'githash' =>
|
||||
array(
|
||||
'type' => 'Pluf_DB_Field_Varchar',
|
||||
'blank' => false,
|
||||
'size' => 40,
|
||||
'index' => true,
|
||||
),
|
||||
'content' =>
|
||||
array(
|
||||
'type' => 'Pluf_DB_Field_Text',
|
||||
'blank' => false,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -25,14 +25,153 @@
|
||||
* Git utils.
|
||||
*
|
||||
*/
|
||||
class IDF_Scm_Git
|
||||
class IDF_Scm_Git extends IDF_Scm
|
||||
{
|
||||
public $repo = '';
|
||||
public $mediumtree_fmt = 'commit %H%nAuthor: %an <%ae>%nTree: %T%nDate: %ai%n%n%s%n%n%b';
|
||||
|
||||
public function __construct($repo)
|
||||
/* ============================================== *
|
||||
* *
|
||||
* Common Methods Implemented By All The SCMs *
|
||||
* *
|
||||
* ============================================== */
|
||||
|
||||
public function __construct($repo, $project=null)
|
||||
{
|
||||
$this->repo = $repo;
|
||||
$this->project = $project;
|
||||
}
|
||||
|
||||
public function getRepositorySize()
|
||||
{
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').'du -sk '
|
||||
.escapeshellarg($this->repo);
|
||||
$out = split(' ', shell_exec($cmd), 2);
|
||||
return (int) $out[0]*1024;
|
||||
}
|
||||
|
||||
public function isAvailable()
|
||||
{
|
||||
try {
|
||||
$branches = $this->getBranches();
|
||||
} catch (IDF_Scm_Exception $e) {
|
||||
return false;
|
||||
}
|
||||
return (count($branches) > 0);
|
||||
}
|
||||
|
||||
public function getBranches()
|
||||
{
|
||||
if (isset($this->cache['branches'])) {
|
||||
return $this->cache['branches'];
|
||||
}
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '')
|
||||
.sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' branch',
|
||||
escapeshellarg($this->repo));
|
||||
exec($cmd, $out, $return);
|
||||
if ($return != 0) {
|
||||
throw new IDF_Scm_Exception(sprintf($this->error_tpl,
|
||||
$cmd, $return,
|
||||
implode("\n", $out)));
|
||||
}
|
||||
$res = array();
|
||||
foreach ($out as $b) {
|
||||
$b = substr($b, 2);
|
||||
if (false !== strpos($b, '/')) {
|
||||
$res[$this->getCommit($b)->commit] = $b;
|
||||
} else {
|
||||
$res[$b] = '';
|
||||
}
|
||||
}
|
||||
$this->cache['branches'] = $res;
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function getMainBranch()
|
||||
{
|
||||
$possible = array('master', 'main', 'trunk', 'local');
|
||||
$branches = array_keys($this->getBranches());
|
||||
foreach ($possible as $p) {
|
||||
if (in_array($p, $branches)) {
|
||||
return $p;
|
||||
}
|
||||
}
|
||||
return (isset($branches[0])) ? $branches[0] : 'master';
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: Running the `git branch --contains $commit` is
|
||||
* theoritically the best way to do it, until you figure out that
|
||||
* you cannot cache the result and that it takes several seconds
|
||||
* to execute on a big tree.
|
||||
*/
|
||||
public function inBranches($commit, $path)
|
||||
{
|
||||
return (in_array($commit, array_keys($this->getBranches())))
|
||||
? array($commit) : array();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Git "tree" is not the same as the tree we get here.
|
||||
*
|
||||
* With git each commit object stores a related tree object. This
|
||||
* tree is basically providing what is in the given folder at the
|
||||
* given commit. It looks something like that:
|
||||
*
|
||||
* <pre>
|
||||
* 100644 blob bcd155e609c51b4651aab9838b270cce964670af AUTHORS
|
||||
* 100644 blob 87b44c5c7df3cc90c031317c1ac8efcfd8a13631 COPYING
|
||||
* 100644 blob 2a0f899cbfe33ea755c343b06a13d7de6c22799f INSTALL.mdtext
|
||||
* 040000 tree 2f469c4c5318aa4ad48756874373370f6112f77b doc
|
||||
* 040000 tree 911e0bd2706f0069b04744d6ef41353faf06a0a7 logo
|
||||
* </pre>
|
||||
*
|
||||
* You can then follow what is in the given folder (let say doc)
|
||||
* by using the hash.
|
||||
*
|
||||
* This means that you will have not to confuse the git tree and
|
||||
* the output tree in the following method.
|
||||
*
|
||||
* @see http://www.kernel.org/pub/software/scm/git/docs/git-ls-tree.html
|
||||
*
|
||||
*/
|
||||
public function getTree($commit, $folder='/', $branch=null)
|
||||
{
|
||||
$folder = ($folder == '/') ? '' : $folder;
|
||||
// now we grab the info about this commit including its tree.
|
||||
if (false == ($co = $this->getCommit($commit))) {
|
||||
return false;
|
||||
}
|
||||
if ($folder) {
|
||||
// As we are limiting to a given folder, we need to find
|
||||
// the tree corresponding to this folder.
|
||||
$tinfo = $this->getTreeInfo($commit, $folder);
|
||||
if (isset($tinfo[0]) and $tinfo[0]->type == 'tree') {
|
||||
$tree = $tinfo[0]->hash;
|
||||
} else {
|
||||
throw new Exception(sprintf(__('Folder %1$s not found in commit %2$s.'), $folder, $commit));
|
||||
}
|
||||
} else {
|
||||
$tree = $co->tree;
|
||||
}
|
||||
$res = array();
|
||||
foreach ($this->getTreeInfo($tree) as $file) {
|
||||
// Now we grab the files in the current tree with as much
|
||||
// information as possible.
|
||||
if ($file->type == 'blob') {
|
||||
$file->date = $co->date;
|
||||
$file->log = '----';
|
||||
$file->author = 'Unknown';
|
||||
}
|
||||
$file->fullpath = ($folder) ? $folder.'/'.$file->file : $file->file;
|
||||
if ($file->type == 'commit') {
|
||||
// We have a submodule
|
||||
$file = $this->getSubmodule($file, $commit);
|
||||
}
|
||||
$res[] = $file;
|
||||
}
|
||||
// Grab the details for each blob and return the list.
|
||||
return $this->getTreeDetails($res);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -54,25 +193,12 @@ class IDF_Scm_Git
|
||||
return ($users->count() > 0) ? $users[0] : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the URL of the git daemon.
|
||||
*
|
||||
* @param IDF_Project
|
||||
* @return string URL
|
||||
*/
|
||||
public static function getRemoteAccessUrl($project)
|
||||
public static function getAnonymousAccessUrl($project)
|
||||
{
|
||||
return sprintf(Pluf::f('git_remote_url'), $project->shortname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL for SSH access
|
||||
*
|
||||
* @param IDF_Project
|
||||
* @return string URL
|
||||
*/
|
||||
public static function getWriteRemoteAccessUrl($project)
|
||||
public static function getAuthAccessUrl($project, $user)
|
||||
{
|
||||
return sprintf(Pluf::f('git_write_remote_url'), $project->shortname);
|
||||
}
|
||||
@ -86,114 +212,53 @@ class IDF_Scm_Git
|
||||
public static function factory($project)
|
||||
{
|
||||
$rep = sprintf(Pluf::f('git_repositories'), $project->shortname);
|
||||
return new IDF_Scm_Git($rep);
|
||||
return new IDF_Scm_Git($rep, $project);
|
||||
}
|
||||
|
||||
|
||||
public function isValidRevision($commit)
|
||||
{
|
||||
return ('commit' == $this->testHash($commit));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a given object hash.
|
||||
*
|
||||
* @param string Object hash.
|
||||
* @param null to be svn client compatible
|
||||
* @return mixed false if not valid or 'blob', 'tree', 'commit'
|
||||
*/
|
||||
public function testHash($hash, $dummy=null)
|
||||
public function testHash($hash)
|
||||
{
|
||||
$cmd = sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' cat-file -t %s',
|
||||
escapeshellarg($this->repo),
|
||||
escapeshellarg($hash));
|
||||
$ret = 0; $out = array();
|
||||
IDF_Scm::exec($cmd, $out, $ret);
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
exec($cmd, $out, $ret);
|
||||
if ($ret != 0) return false;
|
||||
return trim($out[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a commit hash returns an array of files in it.
|
||||
*
|
||||
* A file is a class with the following properties:
|
||||
*
|
||||
* 'perm', 'type', 'size', 'hash', 'file'
|
||||
*
|
||||
* @param string Commit ('HEAD')
|
||||
* @param string Base folder ('')
|
||||
* @return array
|
||||
*/
|
||||
public function filesAtCommit($commit='HEAD', $folder='')
|
||||
{
|
||||
// now we grab the info about this commit including its tree.
|
||||
$co = $this->getCommit($commit);
|
||||
if ($folder) {
|
||||
// As we are limiting to a given folder, we need to find
|
||||
// the tree corresponding to this folder.
|
||||
$found = false;
|
||||
foreach ($this->getTreeInfo($co->tree, true, $folder) as $file) {
|
||||
if ($file->type == 'tree' and $file->file == $folder) {
|
||||
$found = true;
|
||||
$tree = $file->hash;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$found) {
|
||||
throw new Exception(sprintf(__('Folder %1$s not found in commit %2$s.'), $folder, $commit));
|
||||
}
|
||||
} else {
|
||||
$tree = $co->tree;
|
||||
}
|
||||
$res = array();
|
||||
// get the raw log corresponding to this commit to find the
|
||||
// origin of each file.
|
||||
$rawlog = array();
|
||||
$cmd = sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' log --raw --abbrev=40 --pretty=oneline -5000 %s',
|
||||
escapeshellarg($this->repo), escapeshellarg($commit));
|
||||
IDF_Scm::exec($cmd, $rawlog);
|
||||
// We reverse the log to be able to use a fixed efficient
|
||||
// regex without back tracking.
|
||||
$rawlog = implode("\n", array_reverse($rawlog));
|
||||
foreach ($this->getTreeInfo($tree, false) as $file) {
|
||||
// Now we grab the files in the current tree with as much
|
||||
// information as possible.
|
||||
$matches = array();
|
||||
if ($file->type == 'blob' and preg_match('/^\:\d{6} \d{6} [0-9a-f]{40} '.$file->hash.' .*^([0-9a-f]{40})/msU',
|
||||
$rawlog, $matches)) {
|
||||
$fc = $this->getCommit($matches[1]);
|
||||
$file->date = $fc->date;
|
||||
$file->log = $fc->title;
|
||||
$file->author = $fc->author;
|
||||
} else if ($file->type == 'blob') {
|
||||
$file->date = $co->date;
|
||||
$file->log = '----';
|
||||
$file->author = 'Unknown';
|
||||
}
|
||||
$file->fullpath = ($folder) ? $folder.'/'.$file->file : $file->file;
|
||||
if ($file->type == 'commit') {
|
||||
// We have a submodule
|
||||
$file = $this->getSubmodule($file, $commit);
|
||||
}
|
||||
$res[] = $file;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tree info.
|
||||
*
|
||||
* @param string Tree hash
|
||||
* @param bool Do we recurse in subtrees (true)
|
||||
* @param string Folder in which we want to get the info ('')
|
||||
* @return array Array of file information.
|
||||
*/
|
||||
public function getTreeInfo($tree, $recurse=true, $folder='')
|
||||
public function getTreeInfo($tree, $folder='')
|
||||
{
|
||||
if ('tree' != $this->testHash($tree)) {
|
||||
if (!in_array($this->testHash($tree), array('tree', 'commit'))) {
|
||||
throw new Exception(sprintf(__('Not a valid tree: %s.'), $tree));
|
||||
}
|
||||
$cmd_tmpl = 'GIT_DIR=%s '.Pluf::f('git_path', 'git').' ls-tree%s -t -l %s %s';
|
||||
$cmd = sprintf($cmd_tmpl,
|
||||
escapeshellarg($this->repo),
|
||||
($recurse) ? ' -r' : '',
|
||||
$cmd_tmpl = 'GIT_DIR=%s '.Pluf::f('git_path', 'git').' ls-tree -l %s %s';
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '')
|
||||
.sprintf($cmd_tmpl, escapeshellarg($this->repo),
|
||||
escapeshellarg($tree), escapeshellarg($folder));
|
||||
$out = array();
|
||||
$res = array();
|
||||
IDF_Scm::exec($cmd, $out);
|
||||
exec($cmd, $out);
|
||||
foreach ($out as $line) {
|
||||
list($perm, $type, $hash, $size, $file) = preg_split('/ |\t/', $line, 5, PREG_SPLIT_NO_EMPTY);
|
||||
$res[] = (object) array('perm' => $perm, 'type' => $type,
|
||||
@ -211,65 +276,46 @@ class IDF_Scm_Git
|
||||
* @param string Commit ('HEAD')
|
||||
* @return false Information
|
||||
*/
|
||||
public function getFileInfo($totest, $commit='HEAD')
|
||||
public function getPathInfo($totest, $commit='HEAD')
|
||||
{
|
||||
$cmd_tmpl = 'GIT_DIR=%s '.Pluf::f('git_path', 'git').' ls-tree -r -t -l %s';
|
||||
$cmd = sprintf($cmd_tmpl,
|
||||
escapeshellarg($this->repo),
|
||||
escapeshellarg($commit));
|
||||
$out = array();
|
||||
IDF_Scm::exec($cmd, $out);
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
exec($cmd, $out);
|
||||
foreach ($out as $line) {
|
||||
list($perm, $type, $hash, $size, $file) = preg_split('/ |\t/', $line, 5, PREG_SPLIT_NO_EMPTY);
|
||||
if ($totest == $file) {
|
||||
$pathinfo = pathinfo($file);
|
||||
return (object) array('perm' => $perm, 'type' => $type,
|
||||
'size' => $size, 'hash' => $hash,
|
||||
'file' => $file);
|
||||
'fullpath' => $file,
|
||||
'file' => $pathinfo['basename']);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a blob.
|
||||
*
|
||||
* @param string request_file_info
|
||||
* @param null to be svn client compatible
|
||||
* @return string Raw blob
|
||||
*/
|
||||
public function getBlob($request_file_info, $dummy=null)
|
||||
public function getFile($def, $cmd_only=false)
|
||||
{
|
||||
return shell_exec(sprintf(Pluf::f('idf_exec_cmd_prefix', '').
|
||||
$cmd = sprintf(Pluf::f('idf_exec_cmd_prefix', '').
|
||||
'GIT_DIR=%s '.Pluf::f('git_path', 'git').' cat-file blob %s',
|
||||
escapeshellarg($this->repo),
|
||||
escapeshellarg($request_file_info->hash)));
|
||||
escapeshellarg($def->hash));
|
||||
return ($cmd_only) ? $cmd : shell_exec($cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the branches.
|
||||
*
|
||||
* @return array Branches.
|
||||
*/
|
||||
public function getBranches()
|
||||
{
|
||||
$out = array();
|
||||
IDF_Scm::exec(sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' branch',
|
||||
escapeshellarg($this->repo)), $out);
|
||||
$res = array();
|
||||
foreach ($out as $b) {
|
||||
$res[] = substr($b, 2);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get commit details.
|
||||
*
|
||||
* @param string Commit ('HEAD').
|
||||
* @param bool Get commit diff (false).
|
||||
* @return array Changes.
|
||||
* @param string Commit
|
||||
* @param bool Get commit diff (false)
|
||||
* @return array Changes
|
||||
*/
|
||||
public function getCommit($commit='HEAD', $getdiff=false)
|
||||
public function getCommit($commit, $getdiff=false)
|
||||
{
|
||||
if ($getdiff) {
|
||||
$cmd = sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' show --date=iso --pretty=format:%s %s',
|
||||
@ -283,7 +329,11 @@ class IDF_Scm_Git
|
||||
escapeshellarg($commit));
|
||||
}
|
||||
$out = array();
|
||||
IDF_Scm::exec($cmd, $out);
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
exec($cmd, $out, $ret);
|
||||
if ($ret != 0 or count($out) == 0) {
|
||||
return false;
|
||||
}
|
||||
$log = array();
|
||||
$change = array();
|
||||
$inchange = false;
|
||||
@ -315,7 +365,8 @@ class IDF_Scm_Git
|
||||
"'commit %H%n'",
|
||||
escapeshellarg($commit));
|
||||
$out = array();
|
||||
IDF_Scm::exec($cmd, $out);
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
exec($cmd, $out);
|
||||
$affected = count($out) - 2;
|
||||
$added = 0;
|
||||
$removed = 0;
|
||||
@ -347,7 +398,8 @@ class IDF_Scm_Git
|
||||
escapeshellarg($this->repo), $n, $this->mediumtree_fmt,
|
||||
escapeshellarg($commit));
|
||||
$out = array();
|
||||
IDF_Scm::exec($cmd, $out);
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
exec($cmd, $out);
|
||||
return self::parseLog($out, 4);
|
||||
}
|
||||
|
||||
@ -355,14 +407,12 @@ class IDF_Scm_Git
|
||||
* Parse the log lines of a --pretty=medium log output.
|
||||
*
|
||||
* @param array Lines.
|
||||
* @param int Number of lines in the headers (3)
|
||||
* @return array Change log.
|
||||
*/
|
||||
public static function parseLog($lines, $hdrs=3)
|
||||
public static function parseLog($lines)
|
||||
{
|
||||
$res = array();
|
||||
$c = array();
|
||||
$hdrs += 2;
|
||||
$inheads = true;
|
||||
$next_is_title = false;
|
||||
foreach ($lines as $line) {
|
||||
@ -401,19 +451,12 @@ class IDF_Scm_Git
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$c['full_message'] = trim($c['full_message']);
|
||||
$c['full_message'] = !empty($c['full_message']) ? trim($c['full_message']) : '';
|
||||
$res[] = (object) $c;
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the command to create a zip archive at a given commit.
|
||||
*
|
||||
* @param string Commit
|
||||
* @param string Prefix ('git-repo-dump')
|
||||
* @return string Command
|
||||
*/
|
||||
public function getArchiveCommand($commit, $prefix='git-repo-dump/')
|
||||
public function getArchiveCommand($commit, $prefix='repository/')
|
||||
{
|
||||
return sprintf(Pluf::f('idf_exec_cmd_prefix', '').
|
||||
'GIT_DIR=%s '.Pluf::f('git_path', 'git').' archive --format=zip --prefix=%s %s',
|
||||
@ -440,15 +483,232 @@ class IDF_Scm_Git
|
||||
public function getSubmodule($file, $commit)
|
||||
{
|
||||
$file->type = 'extern';
|
||||
$info = $this->getFileInfo('.gitmodules', $commit);
|
||||
$file->extern = '';
|
||||
$info = $this->getPathInfo('.gitmodules', $commit);
|
||||
if ($info == false) {
|
||||
return $file;
|
||||
}
|
||||
$gitmodules = $this->getBlob($info);
|
||||
$gitmodules = $this->getFile($info);
|
||||
if (preg_match('#\[submodule\s+\"'.$file->fullpath.'\"\]\s+path\s=\s(\S+)\s+url\s=\s(\S+)#mi', $gitmodules, $matches)) {
|
||||
$file->extern = $matches[2];
|
||||
}
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Foreach file in the tree, find the details.
|
||||
*
|
||||
* @param array Tree information
|
||||
* @return array Updated tree information
|
||||
*/
|
||||
public function getTreeDetails($tree)
|
||||
{
|
||||
$n = count($tree);
|
||||
$details = array();
|
||||
for ($i=0;$i<$n;$i++) {
|
||||
if ($tree[$i]->type == 'blob') {
|
||||
$details[$tree[$i]->hash] = $i;
|
||||
}
|
||||
}
|
||||
if (!count($details)) {
|
||||
return $tree;
|
||||
}
|
||||
$res = $this->getCachedBlobInfo($details);
|
||||
$toapp = array();
|
||||
foreach ($details as $blob => $idx) {
|
||||
if (isset($res[$blob])) {
|
||||
$tree[$idx]->date = $res[$blob]->date;
|
||||
$tree[$idx]->log = $res[$blob]->title;
|
||||
$tree[$idx]->author = $res[$blob]->author;
|
||||
} else {
|
||||
$toapp[$blob] = $idx;
|
||||
}
|
||||
}
|
||||
if (count($toapp)) {
|
||||
$res = $this->appendBlobInfoCache($toapp);
|
||||
foreach ($details as $blob => $idx) {
|
||||
if (isset($res[$blob])) {
|
||||
$tree[$idx]->date = $res[$blob]->date;
|
||||
$tree[$idx]->log = $res[$blob]->title;
|
||||
$tree[$idx]->author = $res[$blob]->author;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append build info cache.
|
||||
*
|
||||
* The append method tries to get only the necessary details, so
|
||||
* instead of going through all the commits one at a time, it will
|
||||
* try to find a smarter way with regex.
|
||||
*
|
||||
* @see self::buildBlobInfoCache
|
||||
*
|
||||
* @param array The blob for which we need the information
|
||||
* @return array The information
|
||||
*/
|
||||
public function appendBlobInfoCache($blobs)
|
||||
{
|
||||
$rawlog = array();
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '')
|
||||
.sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' log --raw --abbrev=40 --pretty=oneline -5000 --skip=%%s',
|
||||
escapeshellarg($this->repo));
|
||||
$skip = 0;
|
||||
$res = array();
|
||||
exec(sprintf($cmd, $skip), $rawlog);
|
||||
while (count($rawlog) and count($blobs)) {
|
||||
$rawlog = implode("\n", array_reverse($rawlog));
|
||||
foreach ($blobs as $blob => $idx) {
|
||||
if (preg_match('/^\:\d{6} \d{6} [0-9a-f]{40} '
|
||||
.$blob.' .*^([0-9a-f]{40})/msU',
|
||||
$rawlog, $matches)) {
|
||||
$fc = $this->getCommit($matches[1]);
|
||||
$res[$blob] = (object) array('hash' => $blob,
|
||||
'date' => $fc->date,
|
||||
'title' => $fc->title,
|
||||
'author' => $fc->author);
|
||||
unset($blobs[$blob]);
|
||||
}
|
||||
}
|
||||
$rawlog = array();
|
||||
$skip += 5000;
|
||||
if ($skip > 20000) {
|
||||
// We are in the case of the import of a big old
|
||||
// repository, we can store as unknown the commit info
|
||||
// not to try to retrieve them each time.
|
||||
foreach ($blobs as $blob => $idx) {
|
||||
$res[$blob] = (object) array('hash' => $blob,
|
||||
'date' => '0',
|
||||
'title' => '----',
|
||||
'author' => 'Unknown');
|
||||
}
|
||||
break;
|
||||
}
|
||||
exec(sprintf($cmd, $skip), $rawlog);
|
||||
}
|
||||
$this->cacheBlobInfo($res);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the blob info cache.
|
||||
*
|
||||
* We build the blob info cache 500 commits at a time.
|
||||
*/
|
||||
public function buildBlobInfoCache()
|
||||
{
|
||||
$rawlog = array();
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '')
|
||||
.sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' log --raw --abbrev=40 --pretty=oneline -500 --skip=%%s',
|
||||
escapeshellarg($this->repo));
|
||||
$skip = 0;
|
||||
exec(sprintf($cmd, $skip), $rawlog);
|
||||
while (count($rawlog)) {
|
||||
$commit = '';
|
||||
$data = array();
|
||||
foreach ($rawlog as $line) {
|
||||
if (substr($line, 0, 1) != ':') {
|
||||
$commit = $this->getCommit(substr($line, 0, 40));
|
||||
continue;
|
||||
}
|
||||
$blob = substr($line, 56, 40);
|
||||
$data[] = (object) array('hash' => $blob,
|
||||
'date' => $commit->date,
|
||||
'title' => $commit->title,
|
||||
'author' => $commit->author);
|
||||
}
|
||||
$this->cacheBlobInfo($data);
|
||||
$rawlog = array();
|
||||
$skip += 500;
|
||||
exec(sprintf($cmd, $skip), $rawlog);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get blob info.
|
||||
*
|
||||
* When we display the tree, we want to know when a given file was
|
||||
* created, who was the author and at which date. This is a very
|
||||
* slow operation for git as we need to go through the full
|
||||
* history, find when then blob was introduced, then grab the
|
||||
* corresponding commit. This is why we need a cache.
|
||||
*
|
||||
* @param array List as keys of blob hashs to get info for
|
||||
* @return array Hash indexed results, when not found not set
|
||||
*/
|
||||
public function getCachedBlobInfo($hashes)
|
||||
{
|
||||
$cache = new IDF_Scm_Cache_Git();
|
||||
$cache->_project = $this->project;
|
||||
return $cache->retrieve(array_keys($hashes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache blob info.
|
||||
*
|
||||
* Given a series of blob info, cache them.
|
||||
*
|
||||
* @param array Blob info
|
||||
* @return bool Success
|
||||
*/
|
||||
public function cacheBlobInfo($info)
|
||||
{
|
||||
$cache = new IDF_Scm_Cache_Git();
|
||||
$cache->_project = $this->project;
|
||||
return $cache->store($info);
|
||||
}
|
||||
|
||||
public function getFileCachedBlobInfo($hashes)
|
||||
{
|
||||
$res = array();
|
||||
$cache = Pluf::f('tmp_folder').'/IDF_Scm_Git-'.md5($this->repo).'.cache.db';
|
||||
if (!file_exists($cache)) {
|
||||
return $res;
|
||||
}
|
||||
$data = file_get_contents($cache);
|
||||
if (false === $data) {
|
||||
return $res;
|
||||
}
|
||||
$data = split(chr(30), $data);
|
||||
foreach ($data as $rec) {
|
||||
if (isset($hashes[substr($rec, 0, 40)])) {
|
||||
$tmp = split(chr(31), substr($rec, 40), 3);
|
||||
$res[substr($rec, 0, 40)] =
|
||||
(object) array('hash' => substr($rec, 0, 40),
|
||||
'date' => $tmp[0],
|
||||
'title' => $tmp[2],
|
||||
'author' => $tmp[1]);
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* File cache blob info.
|
||||
*
|
||||
* Given a series of blob info, cache them.
|
||||
*
|
||||
* @param array Blob info
|
||||
* @return bool Success
|
||||
*/
|
||||
public function fileCacheBlobInfo($info)
|
||||
{
|
||||
// Prepare the data
|
||||
$data = array();
|
||||
foreach ($info as $file) {
|
||||
$data[] = $file->hash.$file->date.chr(31).$file->author.chr(31).$file->title;
|
||||
}
|
||||
$data = implode(chr(30), $data).chr(30);
|
||||
$cache = Pluf::f('tmp_folder').'/IDF_Scm_Git-'.md5($this->repo).'.cache.db';
|
||||
$fp = fopen($cache, 'ab');
|
||||
if ($fp) {
|
||||
flock($fp, LOCK_EX);
|
||||
fwrite($fp, $data, strlen($data));
|
||||
fclose($fp); // releases the lock too
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -25,22 +25,33 @@
|
||||
* Mercurial utils.
|
||||
*
|
||||
*/
|
||||
class IDF_Scm_Mercurial
|
||||
class IDF_Scm_Mercurial extends IDF_Scm
|
||||
{
|
||||
public $repo = '';
|
||||
|
||||
public function __construct($repo)
|
||||
public function __construct($repo, $project=null)
|
||||
{
|
||||
$this->repo = $repo;
|
||||
$this->project = $project;
|
||||
}
|
||||
|
||||
public function getRepositorySize()
|
||||
{
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').'du -sk '
|
||||
.escapeshellarg($this->repo);
|
||||
$out = split(' ', shell_exec($cmd), 2);
|
||||
return (int) $out[0]*1024;
|
||||
}
|
||||
|
||||
public static function factory($project)
|
||||
{
|
||||
$rep = sprintf(Pluf::f('mercurial_repositories'), $project->shortname);
|
||||
return new IDF_Scm_Mercurial($rep, $project);
|
||||
}
|
||||
|
||||
public function isAvailable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the string describing the author from the log find the
|
||||
* author in the database.
|
||||
*
|
||||
* @param string Author
|
||||
* @return mixed Pluf_User or null
|
||||
*/
|
||||
public function findAuthor($author)
|
||||
{
|
||||
// We extract the email.
|
||||
@ -53,27 +64,29 @@ class IDF_Scm_Mercurial
|
||||
return ($users->count() > 0) ? $users[0] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL of the git daemon.
|
||||
*
|
||||
* @param IDF_Project
|
||||
* @return string URL
|
||||
*/
|
||||
public static function getRemoteAccessUrl($project)
|
||||
public function getMainBranch()
|
||||
{
|
||||
return 'tip';
|
||||
}
|
||||
|
||||
public static function getAnonymousAccessUrl($project)
|
||||
{
|
||||
return sprintf(Pluf::f('mercurial_remote_url'), $project->shortname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this object correctly initialized for the project.
|
||||
*
|
||||
* @param IDF_Project
|
||||
* @return IDF_Scm_Git
|
||||
*/
|
||||
public static function factory($project)
|
||||
public static function getAuthAccessUrl($project, $user)
|
||||
{
|
||||
$rep = sprintf(Pluf::f('mercurial_repositories'), $project->shortname);
|
||||
return new IDF_Scm_Mercurial($rep);
|
||||
return sprintf(Pluf::f('mercurial_remote_url'), $project->shortname);
|
||||
}
|
||||
|
||||
public function isValidRevision($rev)
|
||||
{
|
||||
$cmd = sprintf(Pluf::f('hg_path', 'hg').' log -R %s -r %s',
|
||||
escapeshellarg($this->repo),
|
||||
escapeshellarg($rev));
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
exec($cmd, $out, $ret);
|
||||
return ($ret == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,24 +103,15 @@ class IDF_Scm_Mercurial
|
||||
escapeshellarg($hash));
|
||||
$ret = 0;
|
||||
$out = array();
|
||||
IDF_Scm::exec($cmd, $out, $ret);
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
exec($cmd, $out, $ret);
|
||||
return ($ret != 0) ? false : 'commit';
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a commit hash returns an array of files in it.
|
||||
*
|
||||
* A file is a class with the following properties:
|
||||
*
|
||||
* 'perm', 'type', 'size', 'hash', 'file'
|
||||
*
|
||||
* @param string Commit ('HEAD')
|
||||
* @param string Base folder ('')
|
||||
* @return array
|
||||
*/
|
||||
public function filesAtCommit($commit='tip', $folder='')
|
||||
public function getTree($commit, $folder='/', $branch=null)
|
||||
{
|
||||
// now we grab the info about this commit including its tree.
|
||||
$folder = ($folder == '/') ? '' : $folder;
|
||||
$co = $this->getCommit($commit);
|
||||
if ($folder) {
|
||||
// As we are limiting to a given folder, we need to find
|
||||
@ -143,26 +147,24 @@ class IDF_Scm_Mercurial
|
||||
$cmd = sprintf($cmd_tmpl, escapeshellarg($this->repo), $tree, ($recurse) ? '' : '');
|
||||
$out = array();
|
||||
$res = array();
|
||||
IDF_Scm::exec($cmd, $out);
|
||||
$out_hack = array();
|
||||
foreach ($out as $line) {
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
exec($cmd, $out);
|
||||
$tmp_hack = array();
|
||||
while (null !== ($line = array_pop($out))) {
|
||||
list($hash, $perm, $exec, $file) = preg_split('/ |\t/', $line, 4);
|
||||
$file = trim($file);
|
||||
$dir = explode('/', $file, -1);
|
||||
$tmp = '';
|
||||
for ($i=0; $i < count($dir); $i++) {
|
||||
for ($i=0, $n=count($dir); $i<$n; $i++) {
|
||||
if ($i > 0) {
|
||||
$tmp .= '/';
|
||||
}
|
||||
$tmp .= $dir[$i];
|
||||
if (!in_array("empty\t000\t\t$tmp/", $out_hack))
|
||||
$out_hack[] = "empty\t000\t\t$tmp/";
|
||||
if (!isset($tmp_hack["empty\t000\t\t$tmp/"])) {
|
||||
$out[] = "empty\t000\t\t$tmp/";
|
||||
$tmp_hack["empty\t000\t\t$tmp/"] = 1;
|
||||
}
|
||||
$out_hack[] = "$hash\t$perm\t$exec\t$file";
|
||||
}
|
||||
foreach ($out_hack as $line) {
|
||||
list($hash, $perm, $exec, $file) = preg_split('/ |\t/', $line, 4);
|
||||
$file = trim($file);
|
||||
if (preg_match('/^(.*)\/$/', $file, $match)) {
|
||||
$type = 'tree';
|
||||
$file = $match[1];
|
||||
@ -187,40 +189,38 @@ class IDF_Scm_Mercurial
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file info.
|
||||
*
|
||||
* @param string Commit ('HEAD')
|
||||
* @return false Information
|
||||
*/
|
||||
public function getFileInfo($totest, $commit='tip')
|
||||
public function getPathInfo($totest, $commit='tip')
|
||||
{
|
||||
$cmd_tmpl = Pluf::f('hg_path', 'hg').' manifest -R %s --debug -r %s';
|
||||
$cmd = sprintf($cmd_tmpl, escapeshellarg($this->repo), $commit);
|
||||
$out = array();
|
||||
$res = array();
|
||||
IDF_Scm::exec($cmd, $out);
|
||||
$out_hack = array();
|
||||
foreach ($out as $line) {
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
exec($cmd, $out);
|
||||
$tmp_hack = array();
|
||||
while (null !== ($line = array_pop($out))) {
|
||||
list($hash, $perm, $exec, $file) = preg_split('/ |\t/', $line, 4);
|
||||
$file = trim($file);
|
||||
$dir = explode('/', $file, -1);
|
||||
$tmp = '';
|
||||
for ($i=0; $i < count($dir); $i++) {
|
||||
for ($i=0, $n=count($dir); $i<$n; $i++) {
|
||||
if ($i > 0) {
|
||||
$tmp .= '/';
|
||||
}
|
||||
$tmp .= $dir[$i];
|
||||
if (!in_array("empty\t000\t\t$tmp/", $out_hack)) {
|
||||
$out_hack[] = "emtpy\t000\t\t$tmp/";
|
||||
if ($tmp == $totest) {
|
||||
$pathinfo = pathinfo($totest);
|
||||
return (object) array('perm' => '000', 'type' => 'tree',
|
||||
'hash' => $hash,
|
||||
'fullpath' => $totest,
|
||||
'file' => $pathinfo['basename'],
|
||||
'commit' => $commit
|
||||
);
|
||||
}
|
||||
if (!isset($tmp_hack["empty\t000\t\t$tmp/"])) {
|
||||
$out[] = "empty\t000\t\t$tmp/";
|
||||
$tmp_hack["empty\t000\t\t$tmp/"] = 1;
|
||||
}
|
||||
}
|
||||
$out_hack[] = "$hash\t$perm\t$exec\t$file";
|
||||
}
|
||||
|
||||
foreach ($out_hack as $line) {
|
||||
list($hash, $perm, $exec, $file) = preg_split('/ |\t/', $line, 4);
|
||||
$file = trim ($file);
|
||||
if (preg_match('/^(.*)\/$/', $file, $match)) {
|
||||
$type = 'tree';
|
||||
$file = $match[1];
|
||||
@ -228,30 +228,26 @@ class IDF_Scm_Mercurial
|
||||
$type = 'blob';
|
||||
}
|
||||
if ($totest == $file) {
|
||||
$pathinfo = pathinfo($totest);
|
||||
return (object) array('perm' => $perm, 'type' => $type,
|
||||
'hash' => $hash,
|
||||
'file' => $file,
|
||||
'fullpath' => $totest,
|
||||
'file' => $pathinfo['basename'],
|
||||
'commit' => $commit
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a blob.
|
||||
*
|
||||
* @param string request_file_info
|
||||
* @param null to be svn client compatible
|
||||
* @return string Raw blob
|
||||
*/
|
||||
public function getBlob($request_file_info, $dummy=null)
|
||||
public function getFile($def, $cmd_only=false)
|
||||
{
|
||||
return IDF_Scm::shell_exec(sprintf(Pluf::f('hg_path', 'hg').' cat -R %s -r %s %s',
|
||||
$cmd = sprintf(Pluf::f('hg_path', 'hg').' cat -R %s -r %s %s',
|
||||
escapeshellarg($this->repo),
|
||||
$dummy,
|
||||
escapeshellarg($this->repo . '/' . $request_file_info->file)));
|
||||
escapeshellarg($def->commit),
|
||||
escapeshellarg($this->repo.'/'.$def->file));
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
return ($cmd_only) ? $cmd : shell_exec($cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -261,17 +257,28 @@ class IDF_Scm_Mercurial
|
||||
*/
|
||||
public function getBranches()
|
||||
{
|
||||
if (isset($this->cache['branches'])) {
|
||||
return $this->cache['branches'];
|
||||
}
|
||||
$out = array();
|
||||
IDF_Scm::exec(sprintf(Pluf::f('hg_path', 'hg').' branches -R %s',
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
exec(sprintf(Pluf::f('hg_path', 'hg').' branches -R %s',
|
||||
escapeshellarg($this->repo)), $out);
|
||||
$res = array();
|
||||
foreach ($out as $b) {
|
||||
preg_match('/(\S+).*\S+:(\S+)/', $b, $match);
|
||||
$res[] = $match[1];
|
||||
$res[$match[1]] = '';
|
||||
}
|
||||
$this->cache['branches'] = $res;
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function inBranches($commit, $path)
|
||||
{
|
||||
return (in_array($commit, array_keys($this->getBranches())))
|
||||
? array($commit) : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get commit details.
|
||||
*
|
||||
@ -286,7 +293,8 @@ class IDF_Scm_Mercurial
|
||||
$cmd = sprintf($tmpl,
|
||||
escapeshellarg($commit), escapeshellarg($this->repo));
|
||||
$out = array();
|
||||
IDF_Scm::exec($cmd, $out);
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
exec($cmd, $out);
|
||||
$log = array();
|
||||
$change = array();
|
||||
$inchange = false;
|
||||
@ -327,7 +335,8 @@ class IDF_Scm_Mercurial
|
||||
{
|
||||
$cmd = sprintf(Pluf::f('hg_path', 'hg').' log -R %s -l%s ', escapeshellarg($this->repo), $n, $commit);
|
||||
$out = array();
|
||||
IDF_Scm::exec($cmd, $out);
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
exec($cmd, $out);
|
||||
return self::parseLog($out, 6);
|
||||
}
|
||||
|
||||
|
@ -22,23 +22,44 @@
|
||||
# ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* SVN utils.
|
||||
* Subversion backend.
|
||||
* When a branch is not a branch.
|
||||
*
|
||||
* Contrary to most other SCMs, Subversion is using folders to manage
|
||||
* the branches and so what is either the commit or the branch in
|
||||
* other SCMs is the revision number with Subversion. So, do not be
|
||||
* surprised if you have the feeling that the methods are not really
|
||||
* returning what could be expected from their names.
|
||||
*/
|
||||
class IDF_Scm_Svn
|
||||
class IDF_Scm_Svn extends IDF_Scm
|
||||
{
|
||||
public $repo = '';
|
||||
|
||||
public $username = '';
|
||||
public $password = '';
|
||||
private $assoc = array('dir' => 'tree',
|
||||
'file' => 'blob');
|
||||
|
||||
|
||||
public function __construct($repo, $username='', $password='')
|
||||
public function __construct($repo, $project=null)
|
||||
{
|
||||
$this->repo = $repo;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->project = $project;
|
||||
$this->cache['commitmess'] = array();
|
||||
}
|
||||
|
||||
public function isAvailable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getRepositorySize()
|
||||
{
|
||||
if (strpos($this->repo, 'file://') !== 0) {
|
||||
return -1;
|
||||
}
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').'du -sk '
|
||||
.escapeshellarg(substr($this->repo, 7));
|
||||
$out = split(' ', shell_exec($cmd), 2);
|
||||
return (int) $out[0]*1024;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,7 +82,24 @@ class IDF_Scm_Svn
|
||||
* @param IDF_Project
|
||||
* @return string URL
|
||||
*/
|
||||
public static function getRemoteAccessUrl($project)
|
||||
public static function getAnonymousAccessUrl($project)
|
||||
{
|
||||
$conf = $project->getConf();
|
||||
if (false !== ($url=$conf->getVal('svn_remote_url', false))
|
||||
&& !empty($url)) {
|
||||
// Remote repository
|
||||
return $url;
|
||||
}
|
||||
return sprintf(Pluf::f('svn_remote_url'), $project->shortname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL of the subversion repository.
|
||||
*
|
||||
* @param IDF_Project
|
||||
* @return string URL
|
||||
*/
|
||||
public static function getAuthAccessUrl($project, $user)
|
||||
{
|
||||
$conf = $project->getConf();
|
||||
if (false !== ($url=$conf->getVal('svn_remote_url', false))
|
||||
@ -85,15 +123,35 @@ class IDF_Scm_Svn
|
||||
if (false !== ($rep=$conf->getVal('svn_remote_url', false))
|
||||
&& !empty($rep)) {
|
||||
// Remote repository
|
||||
return new IDF_Scm_Svn($rep,
|
||||
$conf->getVal('svn_username'),
|
||||
$conf->getVal('svn_password'));
|
||||
$scm = new IDF_Scm_Svn($rep, $project);
|
||||
$scm->username = $conf->getVal('svn_username');
|
||||
$scm->password = $conf->getVal('svn_password');
|
||||
return $scm;
|
||||
} else {
|
||||
$rep = sprintf(Pluf::f('svn_repositories'), $project->shortname);
|
||||
return new IDF_Scm_Svn($rep);
|
||||
return new IDF_Scm_Svn($rep, $project);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subversion revisions are either a number or 'HEAD'.
|
||||
*/
|
||||
public function isValidRevision($rev)
|
||||
{
|
||||
if ($rev == 'HEAD') {
|
||||
return true;
|
||||
}
|
||||
$cmd = sprintf(Pluf::f('svn_path', 'svn').' info --username=%s --password=%s %s@%s',
|
||||
escapeshellarg($this->username),
|
||||
escapeshellarg($this->password),
|
||||
escapeshellarg($this->repo),
|
||||
escapeshellarg($rev));
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
exec($cmd, $out, $ret);
|
||||
return (0 == $ret);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test a given object hash.
|
||||
*
|
||||
@ -113,7 +171,8 @@ class IDF_Scm_Svn
|
||||
escapeshellarg($this->password),
|
||||
escapeshellarg($this->repo.'/'.$path),
|
||||
escapeshellarg($rev));
|
||||
$xmlInfo = IDF_Scm::shell_exec($cmd);
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
$xmlInfo = shell_exec($cmd);
|
||||
|
||||
// If exception is thrown, return false
|
||||
try {
|
||||
@ -132,29 +191,17 @@ class IDF_Scm_Svn
|
||||
return 'commit';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given a commit hash returns an array of files in it.
|
||||
*
|
||||
* A file is a class with the following properties:
|
||||
*
|
||||
* 'perm', 'type', 'size', 'hash', 'file'
|
||||
*
|
||||
* @param string Commit ('HEAD')
|
||||
* @param string Base folder ('')
|
||||
* @return array
|
||||
*/
|
||||
public function filesAtCommit($rev='HEAD', $folder='')
|
||||
public function getTree($commit, $folder='/', $branch=null)
|
||||
{
|
||||
$cmd = sprintf(Pluf::f('svn_path', 'svn').' ls --xml --username=%s --password=%s %s@%s',
|
||||
escapeshellarg($this->username),
|
||||
escapeshellarg($this->password),
|
||||
escapeshellarg($this->repo.'/'.$folder),
|
||||
escapeshellarg($rev));
|
||||
$xmlLs = IDF_Scm::shell_exec($cmd);
|
||||
$xml = simplexml_load_string($xmlLs);
|
||||
escapeshellarg($commit));
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
$xml = simplexml_load_string(shell_exec($cmd));
|
||||
$res = array();
|
||||
$folder = (strlen($folder)) ? $folder.'/' : '';
|
||||
$folder = (strlen($folder) and ($folder != '/')) ? $folder.'/' : '';
|
||||
foreach ($xml->list->entry as $entry) {
|
||||
$file = array();
|
||||
$file['type'] = $this->assoc[(string) $entry['kind']];
|
||||
@ -163,10 +210,7 @@ class IDF_Scm_Svn
|
||||
$file['date'] = gmdate('Y-m-d H:i:s',
|
||||
strtotime((string) $entry->commit->date));
|
||||
$file['rev'] = (string) $entry->commit['revision'];
|
||||
// Get commit message
|
||||
$currentReposFile = $this->repo.'/'.$folder.$file['file'];
|
||||
$file['log'] = $this->getCommitMessage($currentReposFile, $rev);
|
||||
|
||||
$file['log'] = $this->getCommitMessage($file['rev']);
|
||||
// Get the size if the type is blob
|
||||
if ($file['type'] == 'blob') {
|
||||
$file['size'] = (string) $entry->size;
|
||||
@ -175,116 +219,154 @@ class IDF_Scm_Svn
|
||||
$file['perm'] = '';
|
||||
$res[] = (object) $file;
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a commit message for given file and revision.
|
||||
* Get the commit message of a revision revision.
|
||||
*
|
||||
* @param string File
|
||||
* @param string Commit ('HEAD')
|
||||
*
|
||||
* @return String commit message
|
||||
*/
|
||||
private function getCommitMessage($file, $rev='HEAD')
|
||||
private function getCommitMessage($rev='HEAD')
|
||||
{
|
||||
if (isset($this->cache['commitmess'][$rev])) {
|
||||
return $this->cache['commitmess'][$rev];
|
||||
}
|
||||
$cmd = sprintf(Pluf::f('svn_path', 'svn').' log --xml --limit 1 --username=%s --password=%s %s@%s',
|
||||
escapeshellarg($this->username),
|
||||
escapeshellarg($this->password),
|
||||
escapeshellarg($file),
|
||||
escapeshellarg($this->repo),
|
||||
escapeshellarg($rev));
|
||||
$xmlLog = IDF_Scm::shell_exec($cmd);
|
||||
$xml = simplexml_load_string($xmlLog);
|
||||
return (string) $xml->logentry->msg;
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
$xml = simplexml_load_string(shell_exec($cmd));
|
||||
$this->cache['commitmess'][$rev] = (string) $xml->logentry->msg;
|
||||
return $this->cache['commitmess'][$rev];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the file info.
|
||||
*
|
||||
* @param string File
|
||||
* @param string Commit ('HEAD')
|
||||
* @return false Information
|
||||
*/
|
||||
public function getFileInfo($totest, $rev='HEAD')
|
||||
public function getPathInfo($filename, $rev=null)
|
||||
{
|
||||
if ($rev == null) {
|
||||
$rev = 'HEAD';
|
||||
}
|
||||
$cmd = sprintf(Pluf::f('svn_path', 'svn').' info --xml --username=%s --password=%s %s@%s',
|
||||
escapeshellarg($this->username),
|
||||
escapeshellarg($this->password),
|
||||
escapeshellarg($this->repo.'/'.$totest),
|
||||
escapeshellarg($this->repo.'/'.$filename),
|
||||
escapeshellarg($rev));
|
||||
$xmlInfo = IDF_Scm::shell_exec($cmd);
|
||||
$xml = simplexml_load_string($xmlInfo);
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
$xml = simplexml_load_string(shell_exec($cmd));
|
||||
if (!isset($xml->entry)) {
|
||||
return false;
|
||||
}
|
||||
$entry = $xml->entry;
|
||||
|
||||
$file = array();
|
||||
$file['fullpath'] = $totest;
|
||||
$file['fullpath'] = $filename;
|
||||
$file['hash'] = (string) $entry->repository->uuid;
|
||||
$file['type'] = $this->assoc[(string) $entry['kind']];
|
||||
$file['file'] = $totest;
|
||||
$file['rev'] = (string) $entry->commit['revision'];
|
||||
$pathinfo = pathinfo($filename);
|
||||
$file['file'] = $pathinfo['basename'];
|
||||
$file['rev'] = $rev;
|
||||
$file['author'] = (string) $entry->author;
|
||||
$file['date'] = gmdate('Y-m-d H:i:s', strtotime((string) $entry->commit->date));
|
||||
$file['size'] = (string) $entry->size;
|
||||
$file['log'] = '';
|
||||
|
||||
return (object) $file;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a blob.
|
||||
*
|
||||
* @param string request_file_info
|
||||
* @return string Raw blob
|
||||
*/
|
||||
public function getBlob($request_file_info, $rev)
|
||||
public function getFile($def, $cmd_only=false)
|
||||
{
|
||||
$cmd = sprintf(Pluf::f('svn_path', 'svn').' cat --username=%s --password=%s %s@%s',
|
||||
escapeshellarg($this->username),
|
||||
escapeshellarg($this->password),
|
||||
escapeshellarg($this->repo.'/'.$request_file_info->fullpath),
|
||||
escapeshellarg($rev));
|
||||
return IDF_Scm::shell_exec($cmd);
|
||||
escapeshellarg($this->repo.'/'.$def->fullpath),
|
||||
escapeshellarg($def->rev));
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
return ($cmd_only) ? $cmd : shell_exec($cmd);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the branches.
|
||||
* Subversion branches are repository based.
|
||||
*
|
||||
* @return array Branches.
|
||||
* One need to list the folder to know them.
|
||||
*/
|
||||
public function getBranches()
|
||||
{
|
||||
$res = array('HEAD');
|
||||
if (isset($this->cache['branches'])) {
|
||||
return $this->cache['branches'];
|
||||
}
|
||||
$res = array();
|
||||
$cmd = sprintf(Pluf::f('svn_path', 'svn').' ls --username=%s --password=%s %s@HEAD',
|
||||
escapeshellarg($this->username),
|
||||
escapeshellarg($this->password),
|
||||
escapeshellarg($this->repo.'/branches'));
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
exec($cmd, $out, $ret);
|
||||
if ($ret == 0) {
|
||||
foreach ($out as $entry) {
|
||||
if (substr(trim($entry), -1) == '/') {
|
||||
$branch = substr(trim($entry), 0, -1);
|
||||
$res[$branch] = 'branches/'.$branch;
|
||||
}
|
||||
}
|
||||
}
|
||||
ksort($res);
|
||||
$cmd = sprintf(Pluf::f('svn_path', 'svn').' info --username=%s --password=%s %s@HEAD',
|
||||
escapeshellarg($this->username),
|
||||
escapeshellarg($this->password),
|
||||
escapeshellarg($this->repo.'/trunk'));
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
exec($cmd, $out, $ret);
|
||||
if ($ret == 0) {
|
||||
$res = array('trunk' => 'trunk') + $res;
|
||||
}
|
||||
$this->cache['branches'] = $res;
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function getMainBranch()
|
||||
{
|
||||
return 'HEAD';
|
||||
}
|
||||
|
||||
public function inBranches($commit, $path)
|
||||
{
|
||||
foreach ($this->getBranches() as $branch => $bpath) {
|
||||
if ($bpath and 0 === strpos($path, $bpath)) {
|
||||
return array($branch);
|
||||
}
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get commit details.
|
||||
*
|
||||
* @param string Commit ('HEAD')
|
||||
* @param string Commit
|
||||
* @param bool Get commit diff (false)
|
||||
* @return array Changes
|
||||
*/
|
||||
public function getCommit($rev='HEAD', $getdiff=false)
|
||||
public function getCommit($commit, $getdiff=false)
|
||||
{
|
||||
if (!$this->isValidRevision($commit)) {
|
||||
return false;
|
||||
}
|
||||
$res = array();
|
||||
$cmd = sprintf(Pluf::f('svn_path', 'svn').' log --xml -v --username=%s --password=%s %s@%s',
|
||||
$cmd = sprintf(Pluf::f('svn_path', 'svn').' log --xml --limit 1 -v --username=%s --password=%s %s@%s',
|
||||
escapeshellarg($this->username),
|
||||
escapeshellarg($this->password),
|
||||
escapeshellarg($this->repo),
|
||||
escapeshellarg($rev));
|
||||
$xmlRes = IDF_Scm::shell_exec($cmd);
|
||||
escapeshellarg($commit));
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
$xmlRes = shell_exec($cmd);
|
||||
$xml = simplexml_load_string($xmlRes);
|
||||
$res['author'] = (string) $xml->logentry->author;
|
||||
$res['date'] = gmdate('Y-m-d H:i:s', strtotime((string) $xml->logentry->date));
|
||||
$res['title'] = (string) $xml->logentry->msg;
|
||||
$res['commit'] = (string) $xml->logentry['revision'];
|
||||
$res['changes'] = ($getdiff) ? $this->getDiff($rev) : '';
|
||||
$res['changes'] = ($getdiff) ? $this->getDiff($commit) : '';
|
||||
$res['tree'] = '';
|
||||
return (object) $res;
|
||||
}
|
||||
@ -306,7 +388,8 @@ class IDF_Scm_Svn
|
||||
$cmd = sprintf(Pluf::f('svnlook_path', 'svnlook').' changed -r %s %s',
|
||||
escapeshellarg($commit),
|
||||
escapeshellarg($repo));
|
||||
$out = IDF_Scm::shell_exec($cmd);
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
$out = shell_exec($cmd);
|
||||
$lines = preg_split("/\015\012|\015|\012/", $out);
|
||||
return (count($lines) > 100);
|
||||
}
|
||||
@ -319,60 +402,49 @@ class IDF_Scm_Svn
|
||||
escapeshellarg($this->username),
|
||||
escapeshellarg($this->password),
|
||||
escapeshellarg($this->repo));
|
||||
return IDF_Scm::shell_exec($cmd);
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
return shell_exec($cmd);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get latest changes.
|
||||
*
|
||||
* @param string Commit ('HEAD').
|
||||
* @param string Revision or ('HEAD').
|
||||
* @param int Number of changes (10).
|
||||
*
|
||||
* @return array Changes.
|
||||
*/
|
||||
public function getChangeLog($rev='HEAD', $n=10)
|
||||
public function getChangeLog($branch=null, $n=10)
|
||||
{
|
||||
if ($branch != 'HEAD' and !preg_match('/^\d+$/', $branch)) {
|
||||
// we accept only revisions or HEAD
|
||||
$branch = 'HEAD';
|
||||
}
|
||||
$res = array();
|
||||
$cmd = sprintf(Pluf::f('svn_path', 'svn').' log --xml -v --limit %s --username=%s --password=%s %s@%s',
|
||||
escapeshellarg($n),
|
||||
escapeshellarg($this->username),
|
||||
escapeshellarg($this->password),
|
||||
escapeshellarg($this->repo),
|
||||
escapeshellarg($rev));
|
||||
$xmlRes = IDF_Scm::shell_exec($cmd);
|
||||
escapeshellarg($branch));
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
$xmlRes = shell_exec($cmd);
|
||||
$xml = simplexml_load_string($xmlRes);
|
||||
|
||||
$res = array();
|
||||
foreach ($xml->logentry as $entry) {
|
||||
$log = array();
|
||||
$log['author'] = (string) $entry->author;
|
||||
$log['date'] = gmdate('Y-m-d H:i:s', strtotime((string) $entry->date));
|
||||
$log['title'] = (string) $entry->msg;
|
||||
$split = split("[\n\r]", (string) $entry->msg, 2);
|
||||
$log['title'] = $split[0];
|
||||
$log['commit'] = (string) $entry['revision'];
|
||||
$log['full_message'] = '';
|
||||
|
||||
$log['full_message'] = (isset($split[1])) ? trim($split[1]) : '';
|
||||
$res[] = (object) $log;
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate the command to create a zip archive at a given commit.
|
||||
* Unsupported feature in subversion
|
||||
*
|
||||
* @param string dummy
|
||||
* @param string dummy
|
||||
* @return Exception
|
||||
*/
|
||||
public function getArchiveCommand($commit, $prefix='git-repo-dump/')
|
||||
{
|
||||
throw new Exception('Unsupported feature.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get additionnals properties on path and revision
|
||||
*
|
||||
@ -388,7 +460,8 @@ class IDF_Scm_Svn
|
||||
escapeshellarg($this->password),
|
||||
escapeshellarg($this->repo.'/'.$path),
|
||||
escapeshellarg($rev));
|
||||
$xmlProps = IDF_Scm::shell_exec($cmd);
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
$xmlProps = shell_exec($cmd);
|
||||
$props = simplexml_load_string($xmlProps);
|
||||
|
||||
// No properties, returns an empty array
|
||||
@ -423,7 +496,8 @@ class IDF_Scm_Svn
|
||||
escapeshellarg($this->password),
|
||||
escapeshellarg($this->repo.'/'.$path),
|
||||
escapeshellarg($rev));
|
||||
$xmlProp = IDF_Scm::shell_exec($cmd);
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
$xmlProp = shell_exec($cmd);
|
||||
$prop = simplexml_load_string($xmlProp);
|
||||
|
||||
return (string) $prop->target->property;
|
||||
@ -445,7 +519,8 @@ class IDF_Scm_Svn
|
||||
escapeshellarg($this->password),
|
||||
escapeshellarg($this->repo),
|
||||
escapeshellarg($rev));
|
||||
$xmlInfo = IDF_Scm::shell_exec($cmd);
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
|
||||
$xmlInfo = shell_exec($cmd);
|
||||
|
||||
$xml = simplexml_load_string($xmlInfo);
|
||||
return (string) $xml->entry->commit['revision'];
|
||||
|
@ -37,22 +37,22 @@ class IDF_Template_IssueComment extends Pluf_Template_Tag
|
||||
$this->project = $request->project;
|
||||
$this->request = $request;
|
||||
$this->scm = IDF_Scm::get($request->project);
|
||||
if ($wordwrap) $text = wordwrap($text, 69, "\n", true);
|
||||
if ($esc) $text = Pluf_esc($text);
|
||||
if ($autolink) {
|
||||
$text = preg_replace('#([a-z]+://[^\s\(\)]+)#i',
|
||||
'<a href="\1">\1</a>', $text);
|
||||
}
|
||||
if ($request->rights['hasIssuesAccess']) {
|
||||
$text = preg_replace_callback('#(issues?|bugs?|tickets?)\s+(\d+)((\s+and|\s+or|,)\s+(\d+)){0,}#im',
|
||||
$text = preg_replace_callback('#(issues?|bugs?|tickets?)\s+(\d+)(\#ic\d*){0,1}((\s+and|\s+or|,)\s+(\d+)(\#ic\d*){0,1}){0,}#im',
|
||||
array($this, 'callbackIssues'), $text);
|
||||
}
|
||||
if ($request->rights['hasSourceAccess']) {
|
||||
$text = preg_replace_callback('#(commit\s+)([0-9a-f]{1,40})#im',
|
||||
array($this, 'callbackCommit'), $text);
|
||||
$text = preg_replace_callback('#(commits?\s+)([0-9a-f]{1,40}(?:(?:\s+and|\s+or|,)\s+[0-9a-f]{1,40})*)\b#i',
|
||||
array($this, 'callbackCommits'), $text);
|
||||
$text = preg_replace_callback('#(src:)([^\s\(\)]+)#im',
|
||||
array($this, 'callbackSource'), $text);
|
||||
}
|
||||
if ($wordwrap) $text = Pluf_Text::wrapHtml($text, 69, "\n");
|
||||
if ($nl2br) $text = nl2br($text);
|
||||
if ($echo) {
|
||||
echo $text;
|
||||
@ -66,10 +66,14 @@ class IDF_Template_IssueComment extends Pluf_Template_Tag
|
||||
*/
|
||||
function callbackIssues($m)
|
||||
{
|
||||
if (count($m) == 3) {
|
||||
if (count($m) == 3 || count($m) == 4) {
|
||||
$issue = new IDF_Issue($m[2]);
|
||||
if ($issue->id > 0 and $issue->project == $this->project->id) {
|
||||
if (count($m) == 3) {
|
||||
return $this->linkIssue($issue, $m[1].' '.$m[2]);
|
||||
} else {
|
||||
return $this->linkIssue($issue, $m[1].' '.$m[2], $m[3]);
|
||||
}
|
||||
} else {
|
||||
return $m[0]; // not existing issue.
|
||||
}
|
||||
@ -96,29 +100,55 @@ class IDF_Template_IssueComment extends Pluf_Template_Tag
|
||||
}
|
||||
}
|
||||
|
||||
function callbackCommit($m)
|
||||
/**
|
||||
* General call back to convert commits to HTML links.
|
||||
*
|
||||
* @param array $m Single regex match.
|
||||
* @return string Content with converted commits.
|
||||
*/
|
||||
function callbackCommits($m)
|
||||
{
|
||||
if ($this->scm->testHash($m[2]) != 'commit') {
|
||||
$keyword = rtrim($m[1]);
|
||||
if ('commits' === $keyword) {
|
||||
// Multiple commits like 'commits 6e030e6, a25bfc1 and
|
||||
// 3c094f8'.
|
||||
return $m[1].preg_replace_callback('#\b[0-9a-f]{4,40}\b#i', array($this, 'callbackCommit'), $m[2]);
|
||||
} else if ('commit' === $keyword) {
|
||||
// Single commit like 'commit 6e030e6'.
|
||||
return $m[1].call_user_func(array($this, 'callbackCommit'), array($m[2]));
|
||||
}
|
||||
return $m[0];
|
||||
}
|
||||
$co = $this->scm->getCommit($m[2]);
|
||||
return '<a href="'.Pluf_HTTP_URL_urlForView('IDF_Views_Source::commit', array($this->project->shortname, $co->commit)).'">'.$m[1].$m[2].'</a>';
|
||||
|
||||
/**
|
||||
* Convert plaintext commit to HTML link. Called from callbackCommits.
|
||||
*
|
||||
* Regex callback for {@link IDF_Template_IssueComment::callbackCommits()}.
|
||||
*
|
||||
* @param array Single regex match.
|
||||
* @return string HTML A element with commit.
|
||||
*/
|
||||
function callbackCommit($m)
|
||||
{
|
||||
$co = $this->scm->getCommit($m[0]);
|
||||
if (!$co) {
|
||||
return $m[0]; // not a commit.
|
||||
}
|
||||
return '<a href="'
|
||||
.Pluf_HTTP_URL_urlForView('IDF_Views_Source::commit', array($this->project->shortname, $co->commit))
|
||||
.'">'.$m[0].'</a>';
|
||||
}
|
||||
|
||||
function callbackSource($m)
|
||||
{
|
||||
$branches = $this->scm->getBranches();
|
||||
if (count($branches) == 0) return $m[0];
|
||||
if (!$this->scm->isAvailable()) return $m[0];
|
||||
$file = $m[2];
|
||||
if ('commit' != $this->scm->testHash($branches[0], $file)) {
|
||||
return $m[0];
|
||||
}
|
||||
$request_file_info = $this->scm->getFileInfo($file, $branches[0]);
|
||||
$request_file_info = $this->scm->getPathInfo($file);
|
||||
if (!$request_file_info) {
|
||||
return $m[0];
|
||||
}
|
||||
if ($request_file_info->type != 'tree') {
|
||||
return $m[1].'<a href="'.Pluf_HTTP_URL_urlForView('IDF_Views_Source::tree', array($this->project->shortname, $branches[0], $file)).'">'.$m[2].'</a>';
|
||||
return $m[1].'<a href="'.Pluf_HTTP_URL_urlForView('IDF_Views_Source::tree', array($this->project->shortname, $this->scm->getMainBranch(), $file)).'">'.$m[2].'</a>';
|
||||
}
|
||||
return $m[0];
|
||||
}
|
||||
@ -130,10 +160,10 @@ class IDF_Template_IssueComment extends Pluf_Template_Tag
|
||||
* @param string Name of the link.
|
||||
* @return string Linked issue.
|
||||
*/
|
||||
public function linkIssue($issue, $title)
|
||||
public function linkIssue($issue, $title, $anchor='')
|
||||
{
|
||||
$ic = (in_array($issue->status, $this->project->getTagIdsByStatus('closed'))) ? 'issue-c' : 'issue-o';
|
||||
return '<a href="'.Pluf_HTTP_URL_urlForView('IDF_Views_Issue::view',
|
||||
array($this->project->shortname, $issue->id)).'" class="'.$ic.'" title="'.Pluf_esc($issue->summary).'">'.Pluf_esc($title).'</a>';
|
||||
array($this->project->shortname, $issue->id)).$anchor.'" class="'.$ic.'" title="'.Pluf_esc($issue->summary).'">'.Pluf_esc($title).'</a>';
|
||||
}
|
||||
}
|
||||
|
@ -91,6 +91,7 @@ class IDF_Template_MarkdownPrefilter extends Pluf_Text_HTML_Filter
|
||||
|
||||
public $allowed = array(
|
||||
'a' => array('href', 'title', 'rel'),
|
||||
'abbr' => array('title'),
|
||||
'address' => array(),
|
||||
'b' => array(),
|
||||
'blockquote' => array(),
|
||||
@ -102,9 +103,12 @@ class IDF_Template_MarkdownPrefilter extends Pluf_Text_HTML_Filter
|
||||
'dl' => array(),
|
||||
'dt' => array(),
|
||||
'em' => array(),
|
||||
'h1' => array(),
|
||||
'h2' => array(),
|
||||
'h3' => array(),
|
||||
'h1' => array('id'),
|
||||
'h2' => array('id'),
|
||||
'h3' => array('id'),
|
||||
'h4' => array('id'),
|
||||
'h5' => array('id'),
|
||||
'h6' => array('id'),
|
||||
'hr' => array(),
|
||||
'i' => array(),
|
||||
'img' => array('src', 'class', 'alt', 'height', 'width', 'style'),
|
||||
|
@ -39,4 +39,23 @@ class IDF_Tests_TestGit extends UnitTestCase
|
||||
$this->assertEqual('Fixed the middleware to correctly return a 404 error if the project is', $log[0]->title);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* parse a log encoded in iso 8859-1
|
||||
*/
|
||||
public function testParseIsoLog()
|
||||
{
|
||||
$log_lines = preg_split("/\015\012|\015|\012/", file_get_contents(dirname(__FILE__).'/data/git-log-iso-8859-1.txt'));
|
||||
$log = IDF_Scm_Git::parseLog($log_lines);
|
||||
$titles = array(
|
||||
'Quick Profiler entfernt',
|
||||
'Anwendungsmenu Divider eingefügt',
|
||||
'Anwendungen aufäumen'
|
||||
);
|
||||
foreach ($log as $change) {
|
||||
$this->assertEqual(array_shift($titles),
|
||||
IDF_Commit::toUTF8($change->title));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
19
src/IDF/Tests/data/git-log-iso-8859-1.txt
Normal file
19
src/IDF/Tests/data/git-log-iso-8859-1.txt
Normal file
@ -0,0 +1,19 @@
|
||||
commit 11531a9dbc64a65150f2f38fbea7cef9d478a123
|
||||
Author: unknown <a@(none)>
|
||||
Date: Fri Jul 3 01:44:11 2009 +0200
|
||||
|
||||
Quick Profiler entfernt
|
||||
|
||||
commit 11531a9dbc64a65150f2f38fbea7cef9d478a123
|
||||
Author: unknown <a@(none)>
|
||||
Date: Wed Jul 1 15:51:22 2009 +0200
|
||||
|
||||
Anwendungsmenu Divider eingefügt
|
||||
|
||||
commit 11531a9dbc64a65150f2f38fbea7cef9d478a123
|
||||
Author: unknown <a@(none)>
|
||||
Date: Wed Jul 1 15:05:41 2009 +0200
|
||||
|
||||
Anwendungen aufäumen
|
||||
|
||||
|
@ -56,6 +56,12 @@ class IDF_Upload extends Pluf_Model
|
||||
'size' => 250,
|
||||
'verbose' => __('summary'),
|
||||
),
|
||||
'changelog' =>
|
||||
array(
|
||||
'type' => 'Pluf_DB_Field_Text',
|
||||
'blank' => true,
|
||||
'verbose' => __('changes'),
|
||||
),
|
||||
'file' =>
|
||||
array(
|
||||
'type' => 'Pluf_DB_Field_File',
|
||||
@ -160,6 +166,7 @@ class IDF_Upload extends Pluf_Model
|
||||
function preDelete()
|
||||
{
|
||||
IDF_Timeline::remove($this);
|
||||
@unlink(Pluf::f('upload_path').'/'.$this->project->shortname.'/files/'.$this->file);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -182,7 +189,7 @@ class IDF_Upload extends Pluf_Model
|
||||
$out .= sprintf(__('<a href="%1$s" title="View download">Download %2$d</a>, %3$s'), $url, $this->id, Pluf_esc($this->summary)).'</td>';
|
||||
$out .= '</tr>';
|
||||
$out .= "\n".'<tr class="extra"><td colspan="2">
|
||||
<div class="helptext right">'.sprintf(__('Addition of <a href="%s">download %d</a>'), $url, $this->id).', '.__('by').' '.$user.'</div></td></tr>';
|
||||
<div class="helptext right">'.sprintf(__('Addition of <a href="%s">download %d</a>, by %s'), $url, $this->id, $user).'</div></td></tr>';
|
||||
return Pluf_Template::markSafe($out);
|
||||
}
|
||||
|
||||
|
@ -64,9 +64,11 @@ class IDF_Views_Admin
|
||||
$list_display = array(
|
||||
'shortname' => __('Short Name'),
|
||||
'name' => __('Name'),
|
||||
array('id', 'IDF_Views_Admin_projectSize', __('Repository Size')),
|
||||
);
|
||||
$pag->configure($list_display, array(),
|
||||
array('shortname'));
|
||||
$pag->extra_classes = array('', '', 'right');
|
||||
$pag->items_per_page = 25;
|
||||
$pag->no_results_text = __('No projects were found.');
|
||||
$pag->setFromRequest($request);
|
||||
@ -74,6 +76,7 @@ class IDF_Views_Admin
|
||||
array(
|
||||
'page_title' => $title,
|
||||
'projects' => $pag,
|
||||
'size' => IDF_Views_Admin_getForgeSize(),
|
||||
),
|
||||
$request);
|
||||
}
|
||||
@ -284,3 +287,88 @@ function IDF_Views_Admin_bool($field, $item)
|
||||
$text = ($item->$field) ? __('Yes') : __('No');
|
||||
return sprintf('<img src="'.Pluf::f('url_media').'/idf/img/%s.png" alt="%s" /> ', $img, $text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the size of the project.
|
||||
*
|
||||
* @param string Field
|
||||
* @param IDF_Project
|
||||
* @return string
|
||||
*/
|
||||
function IDF_Views_Admin_projectSize($field, $project)
|
||||
{
|
||||
$size = $project->getRepositorySize();
|
||||
if ($size == -1) {
|
||||
return '';
|
||||
}
|
||||
return Pluf_Utils::prettySize($size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a forge size.
|
||||
*
|
||||
* @return array Associative array with the size of each element
|
||||
*/
|
||||
function IDF_Views_Admin_getForgeSize()
|
||||
{
|
||||
$res = array();
|
||||
$res['repositories'] = 0;
|
||||
foreach (Pluf::factory('IDF_Project')->getList() as $prj) {
|
||||
$size = $prj->getRepositorySize();
|
||||
if ($size != -1) {
|
||||
$res['repositories'] += $size;
|
||||
}
|
||||
}
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').'du -sk '
|
||||
.escapeshellarg(Pluf::f('upload_path'));
|
||||
$out = split(' ', shell_exec($cmd), 2);
|
||||
$res['downloads'] = $out[0]*1024;
|
||||
$cmd = Pluf::f('idf_exec_cmd_prefix', '').'du -sk '
|
||||
.escapeshellarg(Pluf::f('upload_issue_path'));
|
||||
$out = split(' ', shell_exec($cmd), 2);
|
||||
$res['attachments'] = $out[0]*1024;
|
||||
$res['database'] = IDF_Views_Admin_getForgeDbSize();
|
||||
$res['total'] = $res['repositories'] + $res['downloads'] + $res['attachments'] + $res['database'];
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the database size as given by the database.
|
||||
*
|
||||
* @return int Database size
|
||||
*/
|
||||
function IDF_Views_Admin_getForgeDbSize()
|
||||
{
|
||||
$db = Pluf::db();
|
||||
if (Pluf::f('db_engine') == 'SQLite') {
|
||||
return filesize(Pluf::f('db_database'));
|
||||
}
|
||||
switch (Pluf::f('db_engine')) {
|
||||
case 'PostgreSQL':
|
||||
$sql = 'SELECT relname, pg_total_relation_size(relname) AS size FROM pg_class AS pgc, pg_namespace AS pgn
|
||||
WHERE pg_table_is_visible(pgc.oid) IS TRUE AND relkind = \'r\'
|
||||
AND pgc.relnamespace = pgn.oid
|
||||
AND pgn.nspname NOT IN (\'information_schema\', \'pg_catalog\')';
|
||||
break;
|
||||
case 'MySQL':
|
||||
default:
|
||||
$sql = 'SHOW TABLE STATUS FROM '.Pluf::f('db_database');
|
||||
break;
|
||||
}
|
||||
$rs = $db->select($sql);
|
||||
$total = 0;
|
||||
switch (Pluf::f('db_engine')) {
|
||||
case 'PostgreSQL':
|
||||
foreach ($rs as $table) {
|
||||
$total += $table['size'];
|
||||
}
|
||||
break;
|
||||
case 'MySQL':
|
||||
default:
|
||||
foreach ($rs as $table) {
|
||||
$total += $table['Data_length'] + $table['Index_length'];
|
||||
}
|
||||
break;
|
||||
}
|
||||
return $total;
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ class IDF_Views_Download
|
||||
$conf = new IDF_Conf();
|
||||
$conf->setProject($project);
|
||||
$st = preg_split("/\015\012|\015|\012/",
|
||||
$conf->getVal('labels_downloads_predefined', IDF_Form_UploadConf::init_predefined), -1, PREG_SPLIT_NO_EMPTY);
|
||||
$conf->getVal('labels_download_predefined', IDF_Form_UploadConf::init_predefined), -1, PREG_SPLIT_NO_EMPTY);
|
||||
$auto = '';
|
||||
foreach ($st as $s) {
|
||||
$v = '';
|
||||
@ -298,7 +298,7 @@ class IDF_Views_Download
|
||||
*/
|
||||
public static function getDownloadTags($project)
|
||||
{
|
||||
return $project->getTagsFromConfig('labels_downloads_predefined',
|
||||
return $project->getTagsFromConfig('labels_download_predefined',
|
||||
IDF_Form_UploadConf::init_predefined);
|
||||
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ class IDF_Views_Issue
|
||||
$pag->action = array('IDF_Views_Issue::index', array($prj->shortname));
|
||||
$pag->sort_order = array('modif_dtime', 'ASC'); // will be reverted
|
||||
$pag->sort_reverse_order = array('modif_dtime');
|
||||
$pag->sort_link_title = true;
|
||||
$pag->extra_classes = array('a-c', '', 'a-c', '');
|
||||
$list_display = array(
|
||||
'id' => __('Id'),
|
||||
@ -62,7 +63,7 @@ class IDF_Views_Issue
|
||||
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
|
||||
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
|
||||
);
|
||||
$pag->configure($list_display, array(), array('status', 'modif_dtime'));
|
||||
$pag->configure($list_display, array(), array('id', 'status', 'modif_dtime'));
|
||||
$pag->items_per_page = 10;
|
||||
$pag->no_results_text = __('No issues were found.');
|
||||
$pag->setFromRequest($request);
|
||||
@ -131,6 +132,7 @@ class IDF_Views_Issue
|
||||
$pag->action = array('IDF_Views_Issue::myIssues', array($prj->shortname, $match[2]));
|
||||
$pag->sort_order = array('modif_dtime', 'ASC'); // will be reverted
|
||||
$pag->sort_reverse_order = array('modif_dtime');
|
||||
$pag->sort_link_title = true;
|
||||
$pag->extra_classes = array('a-c', '', 'a-c', '');
|
||||
$list_display = array(
|
||||
'id' => __('Id'),
|
||||
@ -138,7 +140,7 @@ class IDF_Views_Issue
|
||||
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
|
||||
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
|
||||
);
|
||||
$pag->configure($list_display, array(), array('status', 'modif_dtime'));
|
||||
$pag->configure($list_display, array(), array('id', 'status', 'modif_dtime'));
|
||||
$pag->items_per_page = 10;
|
||||
$pag->no_results_text = __('No issues were found.');
|
||||
$pag->setFromRequest($request);
|
||||
@ -171,11 +173,8 @@ class IDF_Views_Issue
|
||||
$params);
|
||||
if (!isset($request->POST['preview']) and $form->isValid()) {
|
||||
$issue = $form->save();
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::index',
|
||||
array($prj->shortname));
|
||||
$urlissue = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::view',
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::view',
|
||||
array($prj->shortname, $issue->id));
|
||||
$request->user->setMessage(sprintf(__('<a href="%s">Issue %d</a> has been created.'), $urlissue, $issue->id));
|
||||
$to_emails = array();
|
||||
if (null != $issue->get_owner() and $issue->owner != $issue->submitter) {
|
||||
$to_emails[] = $issue->get_owner()->email;
|
||||
@ -201,6 +200,7 @@ class IDF_Views_Issue
|
||||
$email->sendMail();
|
||||
}
|
||||
if ($api) return $issue;
|
||||
$request->user->setMessage(sprintf(__('<a href="%s">Issue %d</a> has been created.'), $url, $issue->id));
|
||||
return new Pluf_HTTP_Response_Redirect($url);
|
||||
}
|
||||
} else {
|
||||
@ -291,11 +291,8 @@ class IDF_Views_Issue
|
||||
$params);
|
||||
if (!isset($request->POST['preview']) && $form->isValid()) {
|
||||
$issue = $form->save();
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::index',
|
||||
array($prj->shortname));
|
||||
$urlissue = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::view',
|
||||
array($prj->shortname, $issue->id));
|
||||
$request->user->setMessage(sprintf(__('<a href="%s">Issue %d</a> has been updated.'), $urlissue, $issue->id));
|
||||
$comments = $issue->get_comments_list(array('order' => 'id DESC'));
|
||||
$url .= '#ic' . $comments[0]->id;
|
||||
// Get the list of interested person + owner + submitter
|
||||
if (!Pluf_Model_InArray($issue->get_submitter(), $interested)) {
|
||||
$interested[] = $issue->get_submitter();
|
||||
@ -304,15 +301,13 @@ class IDF_Views_Issue
|
||||
!Pluf_Model_InArray($issue->get_owner(), $interested)) {
|
||||
$interested[] = $issue->get_owner();
|
||||
}
|
||||
$comments = $issue->get_comments_list(array('order' => 'id DESC'));
|
||||
$context = new Pluf_Template_Context(
|
||||
array(
|
||||
'issue' => $issue,
|
||||
'comments' => $comments,
|
||||
'project' => $prj,
|
||||
'url_base' => Pluf::f('url_base'),
|
||||
)
|
||||
);
|
||||
));
|
||||
$tmpl = new Pluf_Template('idf/issues/issue-updated-email.txt');
|
||||
$text_email = $tmpl->render($context);
|
||||
$email = new Pluf_Mail_Batch(Pluf::f('from_email'));
|
||||
@ -334,6 +329,7 @@ class IDF_Views_Issue
|
||||
$email->sendMail();
|
||||
}
|
||||
$email->close();
|
||||
$request->user->setMessage(sprintf(__('<a href="%s">Issue %d</a> has been updated.'), $url, $issue->id));
|
||||
return new Pluf_HTTP_Response_Redirect($url);
|
||||
}
|
||||
} else {
|
||||
@ -436,6 +432,7 @@ class IDF_Views_Issue
|
||||
$pag->action = array('IDF_Views_Issue::listStatus', array($prj->shortname, $status));
|
||||
$pag->sort_order = array('modif_dtime', 'ASC'); // will be reverted
|
||||
$pag->sort_reverse_order = array('modif_dtime');
|
||||
$pag->sort_link_title = true;
|
||||
$pag->extra_classes = array('a-c', '', 'a-c', '');
|
||||
$list_display = array(
|
||||
'id' => __('Id'),
|
||||
@ -443,7 +440,7 @@ class IDF_Views_Issue
|
||||
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
|
||||
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
|
||||
);
|
||||
$pag->configure($list_display, array(), array('status', 'modif_dtime'));
|
||||
$pag->configure($list_display, array(), array('id', 'status', 'modif_dtime'));
|
||||
$pag->items_per_page = 10;
|
||||
$pag->no_results_text = __('No issues were found.');
|
||||
$pag->setFromRequest($request);
|
||||
@ -494,6 +491,7 @@ class IDF_Views_Issue
|
||||
$pag->action = array('IDF_Views_Issue::listLabel', array($prj->shortname, $tag->id, $status));
|
||||
$pag->sort_order = array('modif_dtime', 'ASC'); // will be reverted
|
||||
$pag->sort_reverse_order = array('modif_dtime');
|
||||
$pag->sort_link_title = true;
|
||||
$pag->extra_classes = array('a-c', '', 'a-c', '');
|
||||
$list_display = array(
|
||||
'id' => __('Id'),
|
||||
@ -501,7 +499,7 @@ class IDF_Views_Issue
|
||||
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
|
||||
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
|
||||
);
|
||||
$pag->configure($list_display, array(), array('status', 'modif_dtime'));
|
||||
$pag->configure($list_display, array(), array('id', 'status', 'modif_dtime'));
|
||||
$pag->items_per_page = 10;
|
||||
$pag->no_results_text = __('No issues were found.');
|
||||
$pag->setFromRequest($request);
|
||||
|
@ -342,7 +342,7 @@ class IDF_Views_Project
|
||||
$conf->setVal($key, $val);
|
||||
}
|
||||
$request->user->setMessage(__('The documentation configuration has been saved.'));
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Project::adminDownloads',
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Project::adminWiki',
|
||||
array($prj->shortname));
|
||||
return new Pluf_HTTP_Response_Redirect($url);
|
||||
}
|
||||
@ -510,6 +510,7 @@ class IDF_Views_Project
|
||||
'remote_svn' => $remote_svn,
|
||||
'repository_access' => $prj->getRemoteAccessUrl(),
|
||||
'repository_type' => $repository_type,
|
||||
'repository_size' => $prj->getRepositorySize(),
|
||||
'page_title' => $title,
|
||||
'form' => $form,
|
||||
),
|
||||
|
@ -207,7 +207,7 @@ class IDF_Views_Review
|
||||
$files = array();
|
||||
$reviewers = array();
|
||||
foreach ($diff->files as $filename => $def) {
|
||||
$fileinfo = $scm->getFileInfo($filename, $patch->get_commit()->scm_id);
|
||||
$fileinfo = $scm->getPathInfo($filename, $patch->get_commit()->scm_id);
|
||||
$sql = new Pluf_SQL('cfile=%s', array($filename));
|
||||
$cts = $patch->get_filecomments_list(array('filter'=>$sql->gen(),
|
||||
'order'=>'creation_dtime ASC'));
|
||||
@ -215,7 +215,7 @@ class IDF_Views_Review
|
||||
$reviewers[] = $ct->get_submitter();
|
||||
}
|
||||
if (count($def['chunks'])) {
|
||||
$orig_file = ($fileinfo) ? $scm->getBlob($fileinfo) : '';
|
||||
$orig_file = ($fileinfo) ? $scm->getFile($fileinfo) : '';
|
||||
$files[$filename] = array(
|
||||
$diff->fileCompare($orig_file, $def, $filename),
|
||||
$form->f->{md5($filename)},
|
||||
|
@ -27,15 +27,19 @@ Pluf::loadFunction('Pluf_Shortcuts_GetObjectOr404');
|
||||
Pluf::loadFunction('Pluf_Shortcuts_GetFormForModel');
|
||||
|
||||
/**
|
||||
* View git repository.
|
||||
* View SCM repository.
|
||||
*/
|
||||
class IDF_Views_Source
|
||||
{
|
||||
/**
|
||||
* Extension supported by the syntax highlighter.
|
||||
*/
|
||||
public static $supportedExtenstions = array('c', 'cc', 'cpp', 'cs', 'css',
|
||||
'cyc', 'java', 'bsh', 'csh',
|
||||
'sh', 'cv', 'py', 'perl', 'php',
|
||||
'pl', 'pm', 'rb', 'js', 'html',
|
||||
'html', 'xhtml', 'xml', 'xsl');
|
||||
'html', 'vala', 'xhtml', 'xml',
|
||||
'xsl');
|
||||
|
||||
/**
|
||||
* Display help on how to checkout etc.
|
||||
@ -61,9 +65,14 @@ class IDF_Views_Source
|
||||
$title = sprintf(__('%1$s %2$s Change Log'), (string) $request->project,
|
||||
$this->getScmType($request));
|
||||
$scm = IDF_Scm::get($request->project);
|
||||
if (!$scm->isAvailable()) {
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::help',
|
||||
array($request->project->shortname));
|
||||
return new Pluf_HTTP_Response_Redirect($url);
|
||||
}
|
||||
$branches = $scm->getBranches();
|
||||
$commit = $match[2];
|
||||
if ('commit' != $scm->testHash($commit)) {
|
||||
if (!$scm->isValidRevision($commit)) {
|
||||
if (count($branches) == 0) {
|
||||
// Redirect to the project source help
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::help',
|
||||
@ -73,7 +82,7 @@ class IDF_Views_Source
|
||||
// Redirect to the first branch
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::changeLog',
|
||||
array($request->project->shortname,
|
||||
$branches[0]));
|
||||
$scm->getMainBranch()));
|
||||
return new Pluf_HTTP_Response_Redirect($url);
|
||||
}
|
||||
$changes = $scm->getChangeLog($commit, 25);
|
||||
@ -84,13 +93,15 @@ class IDF_Views_Source
|
||||
}
|
||||
$rchanges = new Pluf_Template_ContextVars($rchanges);
|
||||
$scmConf = $request->conf->getVal('scm', 'git');
|
||||
return Pluf_Shortcuts_RenderToResponse('idf/source/changelog.html',
|
||||
$in_branches = $scm->inBranches($commit, '');
|
||||
return Pluf_Shortcuts_RenderToResponse('idf/source/'.$scmConf.'/changelog.html',
|
||||
array(
|
||||
'page_title' => $title,
|
||||
'title' => $title,
|
||||
'changes' => $rchanges,
|
||||
'commit' => $commit,
|
||||
'branches' => $branches,
|
||||
'tree_in' => $in_branches,
|
||||
'scm' => $scmConf,
|
||||
),
|
||||
$request);
|
||||
@ -99,38 +110,33 @@ class IDF_Views_Source
|
||||
public $treeBase_precond = array('IDF_Precondition::accessSource');
|
||||
public function treeBase($request, $match)
|
||||
{
|
||||
$title = sprintf(__('%1$s %2$s Source Tree'), (string) $request->project,
|
||||
$this->getScmType($request));
|
||||
$title = sprintf(__('%1$s %2$s Source Tree'),
|
||||
$request->project, $this->getScmType($request));
|
||||
$scm = IDF_Scm::get($request->project);
|
||||
$commit = $match[2];
|
||||
$branches = $scm->getBranches();
|
||||
if (count($branches) == 0) {
|
||||
// Redirect to the project home
|
||||
if (!$scm->isAvailable()) {
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::help',
|
||||
array($request->project->shortname));
|
||||
return new Pluf_HTTP_Response_Redirect($url);
|
||||
}
|
||||
if ('commit' != $scm->testHash($commit)) {
|
||||
// Redirect to the first branch
|
||||
$commit = $match[2];
|
||||
$cobject = $scm->getCommit($commit);
|
||||
if (!$cobject) {
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
||||
array($request->project->shortname,
|
||||
$branches[0]));
|
||||
$scm->getMainBranch()));
|
||||
return new Pluf_HTTP_Response_Redirect($url);
|
||||
}
|
||||
$branches = $scm->getBranches();
|
||||
$in_branches = $scm->inBranches($commit, '');
|
||||
$cache = Pluf_Cache::factory();
|
||||
$key = sprintf('Project:%s::IDF_Views_Source::treeBase:%s::',
|
||||
$request->project->id, $commit);
|
||||
if (null === ($res=$cache->get($key))) {
|
||||
$res = new Pluf_Template_ContextVars($scm->filesAtCommit($commit));
|
||||
$res = new Pluf_Template_ContextVars($scm->getTree($commit));
|
||||
$cache->set($key, $res);
|
||||
}
|
||||
$cobject = $scm->getCommit($commit);
|
||||
$tree_in = in_array($commit, $branches);
|
||||
$scmConf = $request->conf->getVal('scm', 'git');
|
||||
$props = null;
|
||||
if ($scmConf === 'svn') {
|
||||
$props = $scm->getProperties($commit);
|
||||
}
|
||||
return Pluf_Shortcuts_RenderToResponse('idf/source/'.$scmConf.'/tree.html',
|
||||
array(
|
||||
'page_title' => $title,
|
||||
@ -138,7 +144,7 @@ class IDF_Views_Source
|
||||
'files' => $res,
|
||||
'cobject' => $cobject,
|
||||
'commit' => $commit,
|
||||
'tree_in' => $tree_in,
|
||||
'tree_in' => $in_branches,
|
||||
'branches' => $branches,
|
||||
'props' => $props,
|
||||
),
|
||||
@ -148,15 +154,21 @@ class IDF_Views_Source
|
||||
public $tree_precond = array('IDF_Precondition::accessSource');
|
||||
public function tree($request, $match)
|
||||
{
|
||||
$title = sprintf(__('%1$s %2$s Source Tree'), (string) $request->project,
|
||||
$this->getScmType($request));
|
||||
$title = sprintf(__('%1$s %2$s Source Tree'),
|
||||
$request->project, $this->getScmType($request));
|
||||
$scm = IDF_Scm::get($request->project);
|
||||
$branches = $scm->getBranches();
|
||||
$commit = $match[2];
|
||||
$request_file = $match[3];
|
||||
|
||||
if (!$scm->isAvailable()) {
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::help',
|
||||
array($request->project->shortname));
|
||||
return new Pluf_HTTP_Response_Redirect($url);
|
||||
}
|
||||
$branches = $scm->getBranches();
|
||||
$fburl = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
||||
array($request->project->shortname,
|
||||
$branches[0]));
|
||||
$scm->getMainBranch()));
|
||||
if (substr($request_file, -1) == '/') {
|
||||
$request_file = substr($request_file, 0, -1);
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::tree',
|
||||
@ -164,11 +176,11 @@ class IDF_Views_Source
|
||||
$request_file));
|
||||
return new Pluf_HTTP_Response_Redirect($url, 301);
|
||||
}
|
||||
if ('commit' != $scm->testHash($commit, $request_file)) {
|
||||
if (!$scm->isValidRevision($commit, $request_file)) {
|
||||
// Redirect to the first branch
|
||||
return new Pluf_HTTP_Response_Redirect($fburl);
|
||||
}
|
||||
$request_file_info = $scm->getFileInfo($request_file, $commit);
|
||||
$request_file_info = $scm->getPathInfo($request_file, $commit);
|
||||
if (!$request_file_info) {
|
||||
// Redirect to the first branch
|
||||
return new Pluf_HTTP_Response_Redirect($fburl);
|
||||
@ -177,7 +189,8 @@ class IDF_Views_Source
|
||||
$info = self::getRequestedFileMimeType($request_file_info,
|
||||
$commit, $scm);
|
||||
if (!self::isText($info)) {
|
||||
$rep = new Pluf_HTTP_Response($scm->getBlob($request_file_info, $commit),
|
||||
|
||||
$rep = new Pluf_HTTP_Response($scm->getFile($request_file_info),
|
||||
$info[0]);
|
||||
$rep->headers['Content-Disposition'] = 'attachment; filename="'.$info[1].'"';
|
||||
return $rep;
|
||||
@ -192,30 +205,25 @@ class IDF_Views_Source
|
||||
return $this->viewFile($request, $match, $extra);
|
||||
}
|
||||
}
|
||||
$bc = self::makeBreadCrumb($request->project, $commit, $request_file_info->file);
|
||||
|
||||
$bc = self::makeBreadCrumb($request->project, $commit, $request_file_info->fullpath);
|
||||
|
||||
$page_title = $bc.' - '.$title;
|
||||
$cobject = $scm->getCommit($commit);
|
||||
$tree_in = in_array($commit, $branches);
|
||||
try {
|
||||
$in_branches = $scm->inBranches($commit, $request_file);
|
||||
$cache = Pluf_Cache::factory();
|
||||
$key = sprintf('Project:%s::IDF_Views_Source::tree:%s::%s',
|
||||
$request->project->id, $commit, $request_file);
|
||||
if (null === ($res=$cache->get($key))) {
|
||||
$res = new Pluf_Template_ContextVars($scm->filesAtCommit($commit, $request_file));
|
||||
$res = new Pluf_Template_ContextVars($scm->getTree($commit, $request_file));
|
||||
$cache->set($key, $res);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return new Pluf_HTTP_Response_Redirect($fburl);
|
||||
}
|
||||
// try to find the previous level if it exists.
|
||||
$prev = split('/', $request_file);
|
||||
$l = array_pop($prev);
|
||||
$previous = substr($request_file, 0, -strlen($l.' '));
|
||||
$scmConf = $request->conf->getVal('scm', 'git');
|
||||
$props = null;
|
||||
if ($scmConf === 'svn') {
|
||||
$props = $scm->getProperties($commit, $request_file);
|
||||
}
|
||||
return Pluf_Shortcuts_RenderToResponse('idf/source/'.$scmConf.'/tree.html',
|
||||
array(
|
||||
'page_title' => $page_title,
|
||||
@ -226,7 +234,7 @@ class IDF_Views_Source
|
||||
'cobject' => $cobject,
|
||||
'base' => $request_file_info->file,
|
||||
'prev' => $previous,
|
||||
'tree_in' => $tree_in,
|
||||
'tree_in' => $in_branches,
|
||||
'branches' => $branches,
|
||||
'props' => $props,
|
||||
),
|
||||
@ -256,21 +264,29 @@ class IDF_Views_Source
|
||||
$scm = IDF_Scm::get($request->project);
|
||||
$commit = $match[2];
|
||||
$branches = $scm->getBranches();
|
||||
if ('commit' != $scm->testHash($commit)) {
|
||||
if (!$scm->isValidRevision($commit)) {
|
||||
// Redirect to the first branch
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
||||
array($request->project->shortname,
|
||||
$branches[0]));
|
||||
$scm->getMainBranch()));
|
||||
return new Pluf_HTTP_Response_Redirect($url);
|
||||
}
|
||||
$large = $scm->isCommitLarge($commit);
|
||||
$cobject = $scm->getCommit($commit, !$large);
|
||||
if (!$cobject) {
|
||||
// Redirect to the first branch
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
||||
array($request->project->shortname,
|
||||
$scm->getMainBranch()));
|
||||
return new Pluf_HTTP_Response_Redirect($url);
|
||||
}
|
||||
$title = sprintf(__('%s Commit Details'), (string) $request->project);
|
||||
$page_title = sprintf(__('%s Commit Details - %s'), (string) $request->project, $commit);
|
||||
$large = $scm->isCommitLarge($commit);
|
||||
$cobject = $scm->getCommit($commit, !$large);
|
||||
$rcommit = IDF_Commit::getOrAdd($cobject, $request->project);
|
||||
$diff = new IDF_Diff($cobject->changes);
|
||||
$diff->parse();
|
||||
$scmConf = $request->conf->getVal('scm', 'git');
|
||||
$in_branches = $scm->inBranches($commit, '');
|
||||
return Pluf_Shortcuts_RenderToResponse('idf/source/commit.html',
|
||||
array(
|
||||
'page_title' => $page_title,
|
||||
@ -279,6 +295,7 @@ class IDF_Views_Source
|
||||
'cobject' => $cobject,
|
||||
'commit' => $commit,
|
||||
'branches' => $branches,
|
||||
'tree_in' => $in_branches,
|
||||
'scm' => $scmConf,
|
||||
'rcommit' => $rcommit,
|
||||
'large_commit' => $large,
|
||||
@ -292,11 +309,11 @@ class IDF_Views_Source
|
||||
$scm = IDF_Scm::get($request->project);
|
||||
$commit = $match[2];
|
||||
$branches = $scm->getBranches();
|
||||
if ('commit' != $scm->testHash($commit)) {
|
||||
if (!$scm->isValidRevision($commit)) {
|
||||
// Redirect to the first branch
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
||||
array($request->project->shortname,
|
||||
$branches[0]));
|
||||
$scm->getMainBranch()));
|
||||
return new Pluf_HTTP_Response_Redirect($url);
|
||||
}
|
||||
$cobject = $scm->getCommit($commit, true);
|
||||
@ -317,20 +334,17 @@ class IDF_Views_Source
|
||||
$commit = $extra['commit'];
|
||||
$request_file = $extra['request_file'];
|
||||
$request_file_info = $extra['request_file_info'];
|
||||
$bc = self::makeBreadCrumb($request->project, $commit, $request_file_info->file);
|
||||
$bc = self::makeBreadCrumb($request->project, $commit, $request_file_info->fullpath);
|
||||
$page_title = $bc.' - '.$title;
|
||||
$cobject = $scm->getCommit($commit);
|
||||
$tree_in = in_array($commit, $branches);
|
||||
$in_branches = $scm->inBranches($commit, $request_file);
|
||||
// try to find the previous level if it exists.
|
||||
$prev = split('/', $request_file);
|
||||
$l = array_pop($prev);
|
||||
$previous = substr($request_file, 0, -strlen($l.' '));
|
||||
$scmConf = $request->conf->getVal('scm', 'git');
|
||||
$props = null;
|
||||
if ($scmConf === 'svn') {
|
||||
$props = $scm->getProperties($commit, $request_file);
|
||||
}
|
||||
$content = self::highLight($extra['mime'], $scm->getBlob($request_file_info, $commit));
|
||||
$content = self::highLight($extra['mime'], $scm->getFile($request_file_info));
|
||||
return Pluf_Shortcuts_RenderToResponse('idf/source/'.$scmConf.'/file.html',
|
||||
array(
|
||||
'page_title' => $page_title,
|
||||
@ -342,7 +356,7 @@ class IDF_Views_Source
|
||||
'fullpath' => $request_file,
|
||||
'base' => $request_file_info->file,
|
||||
'prev' => $previous,
|
||||
'tree_in' => $tree_in,
|
||||
'tree_in' => $in_branches,
|
||||
'branches' => $branches,
|
||||
'props' => $props,
|
||||
),
|
||||
@ -360,24 +374,24 @@ class IDF_Views_Source
|
||||
$branches = $scm->getBranches();
|
||||
$commit = $match[2];
|
||||
$request_file = $match[3];
|
||||
if ('commit' != $scm->testHash($commit, $request_file)) {
|
||||
if (!$scm->isValidRevision($commit)) {
|
||||
// Redirect to the first branch
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
||||
array($request->project->shortname,
|
||||
$branches[0]));
|
||||
$scm->getMainBranch()));
|
||||
return new Pluf_HTTP_Response_Redirect($url);
|
||||
}
|
||||
$request_file_info = $scm->getFileInfo($request_file, $commit);
|
||||
$request_file_info = $scm->getPathInfo($request_file, $commit);
|
||||
if (!$request_file_info or $request_file_info->type == 'tree') {
|
||||
// Redirect to the first branch
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
||||
array($request->project->shortname,
|
||||
$branches[0]));
|
||||
$scm->getMainBranch()));
|
||||
return new Pluf_HTTP_Response_Redirect($url);
|
||||
}
|
||||
$info = self::getRequestedFileMimeType($request_file_info,
|
||||
$commit, $scm);
|
||||
$rep = new Pluf_HTTP_Response($scm->getBlob($request_file_info, $commit),
|
||||
$rep = new Pluf_HTTP_Response($scm->getFile($request_file_info),
|
||||
$info[0]);
|
||||
$rep->headers['Content-Disposition'] = 'attachment; filename="'.$info[1].'"';
|
||||
return $rep;
|
||||
@ -393,11 +407,11 @@ class IDF_Views_Source
|
||||
$commit = trim($match[2]);
|
||||
$scm = IDF_Scm::get($request->project);
|
||||
$branches = $scm->getBranches();
|
||||
if ('commit' != $scm->testHash($commit)) {
|
||||
if (!$scm->isValidRevision($commit)) {
|
||||
// Redirect to the first branch
|
||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
||||
array($request->project->shortname,
|
||||
$branches[0]));
|
||||
$scm->getMainBranch()));
|
||||
return new Pluf_HTTP_Response_Redirect($url);
|
||||
}
|
||||
$base = $request->project->shortname.'-'.$commit;
|
||||
@ -424,7 +438,7 @@ class IDF_Views_Source
|
||||
return $mime;
|
||||
}
|
||||
return self::getMimeTypeFromContent($file_info->file,
|
||||
$scm->getBlob($file_info, $commit));
|
||||
$scm->getFile($file_info));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -502,15 +516,16 @@ class IDF_Views_Source
|
||||
if (0 === strpos($fileinfo[0], 'text/')) {
|
||||
return true;
|
||||
}
|
||||
$ext = 'mdtext php js cpp php-dist h gitignore sh py pl rb diff patch'
|
||||
$ext = 'mdtext php-dist h gitignore diff patch'
|
||||
.Pluf::f('idf_extra_text_ext', '');
|
||||
return (in_array($fileinfo[2], explode(' ', $ext)));
|
||||
$ext = array_merge(self::$supportedExtenstions, explode(' ' , $ext));
|
||||
return (in_array($fileinfo[2], $ext));
|
||||
}
|
||||
|
||||
public static function highLight($fileinfo, $content)
|
||||
{
|
||||
$pretty = '';
|
||||
if (IDF_Views_Source::isSupportedExtension($fileinfo[2])) {
|
||||
if (self::isSupportedExtension($fileinfo[2])) {
|
||||
$pretty = ' prettyprint';
|
||||
}
|
||||
$table = array();
|
||||
@ -524,13 +539,14 @@ class IDF_Views_Source
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string the extension to test
|
||||
* Test if an extension is supported by the syntax highlighter.
|
||||
*
|
||||
* @return
|
||||
* @param string The extension to test
|
||||
* @return bool
|
||||
*/
|
||||
public static function isSupportedExtension($extension)
|
||||
{
|
||||
return in_array($extension, IDF_Views_Source::$supportedExtenstions);
|
||||
return in_array($extension, self::$supportedExtenstions);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -124,7 +124,7 @@ class IDF_Views_User
|
||||
}
|
||||
$keys = $request->user->get_idf_key_list();
|
||||
if ($keys->count() > 0 and strlen($keys[0]->content) > 30) {
|
||||
$ssh_key = Pluf_Template::markSafe('<span class="mono">'.Pluf_esc(substr($keys[0]->content, 0, 30)).'...</span><br /><span class="helptext">'.__('Troncated for security reasons.').'</span>');
|
||||
$ssh_key = Pluf_Template::markSafe('<span class="mono">'.Pluf_esc(substr($keys[0]->content, 0, 30)).'...</span><br /><span class="helptext">'.__('Truncated for security reasons.').'</span>');
|
||||
} else {
|
||||
$ssh_key = __('You have not upload your public SSH key yet.');
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ class IDF_Views_Wiki
|
||||
array($prj->id, $match[2]));
|
||||
$pages = Pluf::factory('IDF_WikiPage')->getList(array('filter'=>$sql->gen()));
|
||||
if ($pages->count() != 1) {
|
||||
throw new Pluf_HTTP_Response_NotFound($request);
|
||||
return new Pluf_HTTP_Response_NotFound($request);
|
||||
}
|
||||
$page = $pages[0];
|
||||
$oldrev = false;
|
||||
@ -231,7 +231,7 @@ class IDF_Views_Wiki
|
||||
$oldrev = Pluf_Shortcuts_GetObjectOr404('IDF_WikiRevision',
|
||||
$request->GET['rev']);
|
||||
if ($oldrev->wikipage != $page->id or $oldrev->is_head == true) {
|
||||
throw new Pluf_HTTP_Response_NotFound($request);
|
||||
return new Pluf_HTTP_Response_NotFound($request);
|
||||
}
|
||||
}
|
||||
$ptags = self::getWikiTags($prj);
|
||||
@ -269,7 +269,7 @@ class IDF_Views_Wiki
|
||||
$page = $oldrev->get_wikipage();
|
||||
$prj->inOr404($page);
|
||||
if ($oldrev->is_head == true) {
|
||||
throw new Pluf_HTTP_Error404($request);
|
||||
return new Pluf_HTTP_Response_NotFound($request);
|
||||
}
|
||||
if ($request->method == 'POST') {
|
||||
$oldrev->delete();
|
||||
@ -310,7 +310,7 @@ class IDF_Views_Wiki
|
||||
array($prj->id, $match[2]));
|
||||
$pages = Pluf::factory('IDF_WikiPage')->getList(array('filter'=>$sql->gen()));
|
||||
if ($pages->count() != 1) {
|
||||
throw new Pluf_HTTP_Error404($request);
|
||||
return new Pluf_HTTP_Response_NotFound($request);
|
||||
}
|
||||
$page = $pages[0];
|
||||
$title = sprintf(__('Update %s'), $page->title);
|
||||
|
@ -196,7 +196,7 @@ class IDF_WikiPage extends Pluf_Model
|
||||
$user = $stag->start($this->get_submitter(), $request, '', false);
|
||||
$out .= sprintf(__('<a href="%1$s" title="View page">%2$s</a>, %3$s'), $url, Pluf_esc($this->title), Pluf_esc($this->summary)).'</td>';
|
||||
$out .= "\n".'<tr class="extra"><td colspan="2">
|
||||
<div class="helptext right">'.sprintf(__('Creation of <a href="%s">page %s</a>'), $url, Pluf_esc($this->title)).', '.__('by').' '.$user.'</div></td></tr>';
|
||||
<div class="helptext right">'.sprintf(__('Creation of <a href="%s">page %s</a>, by %s'), $url, Pluf_esc($this->title), $user).'</div></td></tr>';
|
||||
return Pluf_Template::markSafe($out);
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ class IDF_WikiRevision extends Pluf_Model
|
||||
}
|
||||
$out .= '</td></tr>';
|
||||
$out .= "\n".'<tr class="extra"><td colspan="2">
|
||||
<div class="helptext right">'.sprintf(__('Change of <a href="%s">%s</a>'), $url, Pluf_esc($page->title)).', '.__('by').' '.$user.'</div></td></tr>';
|
||||
<div class="helptext right">'.sprintf(__('Change of <a href="%s">%s</a>, by %s'), $url, Pluf_esc($page->title), $user).'</div></td></tr>';
|
||||
return Pluf_Template::markSafe($out);
|
||||
}
|
||||
|
||||
|
@ -161,13 +161,19 @@ $cfg['db_database'] = 'website'; # put absolute path to the db if you
|
||||
# are using SQLite.
|
||||
#
|
||||
# The extension of the downloads are limited. You can add extra
|
||||
# extensions here. It must start with a space.
|
||||
# extensions here. The list must start with a space.
|
||||
# $cfg['idf_extra_upload_ext'] = ' ext1 ext2';
|
||||
#
|
||||
# By default, the size of the downloads is limited to 2MB.
|
||||
# $cfg['max_upload_size'] = 2097152; // Size in bytes
|
||||
|
||||
# -- From this point you should not need to update anything. --
|
||||
#
|
||||
# Time zone
|
||||
# http://www.php.net/manual/en/timezones.php
|
||||
#
|
||||
# $cfg['time_zone'] = 'Europe/Berlin';
|
||||
|
||||
|
||||
$cfg['pear_path'] = '/usr/share/php';
|
||||
|
||||
$cfg['login_success_url'] = $cfg['url_base'].$cfg['idf_base'];
|
||||
|
@ -26,33 +26,28 @@ $base = Pluf::f('idf_base');
|
||||
|
||||
$ctl[] = array('regex' => '#^/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views',
|
||||
'method' => 'index');
|
||||
|
||||
$ctl[] = array('regex' => '#^/login/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views',
|
||||
'method' => 'login',
|
||||
'name' => 'login_view');
|
||||
|
||||
$ctl[] = array('regex' => '#^/preferences/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_User',
|
||||
'method' => 'myAccount');
|
||||
|
||||
$ctl[] = array('regex' => '#^/dashboard/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_User',
|
||||
'method' => 'dashboard',
|
||||
'name' => 'idf_dashboard');
|
||||
|
||||
$ctl[] = array('regex' => '#^/dashboard/submitted/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_User',
|
||||
'method' => 'dashboard',
|
||||
'params' => false,
|
||||
@ -60,105 +55,88 @@ $ctl[] = array('regex' => '#^/dashboard/submitted/$#',
|
||||
|
||||
$ctl[] = array('regex' => '#^/u/(.*)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_User',
|
||||
'method' => 'view');
|
||||
|
||||
$ctl[] = array('regex' => '#^/logout/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views',
|
||||
'method' => 'logout');
|
||||
|
||||
$ctl[] = array('regex' => '#^/help/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views',
|
||||
'method' => 'faq');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Project',
|
||||
'method' => 'home');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/timeline/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Project',
|
||||
'method' => 'timeline');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/feed/timeline/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Project',
|
||||
'method' => 'timelineFeed',
|
||||
'name' => 'idf_project_timeline_feed');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/feed/timeline/token/(.*)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Project',
|
||||
'method' => 'timelineFeed',
|
||||
'name' => 'idf_project_timeline_feed_auth');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Issue',
|
||||
'method' => 'index');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/search/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Issue',
|
||||
'method' => 'search');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/(\d+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Issue',
|
||||
'method' => 'view');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/(\d+)/star/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Issue',
|
||||
'method' => 'star');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/status/(\w+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Issue',
|
||||
'method' => 'listStatus');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/label/(\d+)/(\w+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Issue',
|
||||
'method' => 'listLabel');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/create/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Issue',
|
||||
'method' => 'create');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/my/(\w+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Issue',
|
||||
'method' => 'myIssues');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/attachment/(\d+)/(.*)$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Issue',
|
||||
'method' => 'getAttachment');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/view/attachment/(\d+)/(.*)$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Issue',
|
||||
'method' => 'viewAttachment');
|
||||
|
||||
@ -166,61 +144,51 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/view/attachment/(\d+)/(.*)$#',
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/help/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Source',
|
||||
'method' => 'help');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/tree/([^/]+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Source',
|
||||
'method' => 'treeBase');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/tree/([^/]+)/(.*)$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Source',
|
||||
'method' => 'tree');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/changes/([^/]+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Source',
|
||||
'method' => 'changeLog');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/commit/([^/]+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Source',
|
||||
'method' => 'commit');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/ddiff/([^/]+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Source',
|
||||
'method' => 'downloadDiff');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/download/([^/]+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Source',
|
||||
'method' => 'download');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/file/([^/]+)/(.*)$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Source',
|
||||
'method' => 'getFile');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/treerev/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Source_Svn',
|
||||
'method' => 'treeRev');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/changesrev/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Source_Svn',
|
||||
'method' => 'changelogRev');
|
||||
|
||||
@ -228,43 +196,36 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/changesrev/$#',
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Wiki',
|
||||
'method' => 'index');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/create/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Wiki',
|
||||
'method' => 'create');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/search/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Wiki',
|
||||
'method' => 'search');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/label/(\d+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Wiki',
|
||||
'method' => 'listLabel');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/update/(.*)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Wiki',
|
||||
'method' => 'update');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/delrev/(\d+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Wiki',
|
||||
'method' => 'deleteRev');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/page/(.*)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Wiki',
|
||||
'method' => 'view');
|
||||
|
||||
@ -272,37 +233,31 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/page/(.*)/$#',
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Download',
|
||||
'method' => 'index');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/label/(\d+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Download',
|
||||
'method' => 'listLabel');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/(\d+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Download',
|
||||
'method' => 'view');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/(\d+)/get/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Download',
|
||||
'method' => 'download');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/create/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Download',
|
||||
'method' => 'submit');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/(\d+)/delete/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Download',
|
||||
'method' => 'delete');
|
||||
|
||||
@ -310,25 +265,21 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/(\d+)/delete/$#',
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/review/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Review',
|
||||
'method' => 'index');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/review/(\d+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Review',
|
||||
'method' => 'view');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/review/create/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Review',
|
||||
'method' => 'create');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/review/getpatch/(\d+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Review',
|
||||
'method' => 'getPatch');
|
||||
|
||||
@ -337,43 +288,36 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/review/getpatch/(\d+)/$#',
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Project',
|
||||
'method' => 'admin');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/issues/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Project',
|
||||
'method' => 'adminIssues');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/downloads/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Project',
|
||||
'method' => 'adminDownloads');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/wiki/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Project',
|
||||
'method' => 'adminWiki');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/source/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Project',
|
||||
'method' => 'adminSource');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/members/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Project',
|
||||
'method' => 'adminMembers');
|
||||
|
||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/tabs/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Project',
|
||||
'method' => 'adminTabs');
|
||||
|
||||
@ -381,19 +325,16 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/tabs/$#',
|
||||
|
||||
$ctl[] = array('regex' => '#^/help/api/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views',
|
||||
'method' => 'faqApi');
|
||||
|
||||
$ctl[] = array('regex' => '#^/api/p/([\-\w]+)/issues/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Api',
|
||||
'method' => 'issuesIndex');
|
||||
|
||||
$ctl[] = array('regex' => '#^/api/p/([\-\w]+)/issues/create/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Api',
|
||||
'method' => 'issueCreate');
|
||||
|
||||
@ -401,43 +342,36 @@ $ctl[] = array('regex' => '#^/api/p/([\-\w]+)/issues/create/$#',
|
||||
|
||||
$ctl[] = array('regex' => '#^/admin/projects/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Admin',
|
||||
'method' => 'projects');
|
||||
|
||||
$ctl[] = array('regex' => '#^/admin/projects/(\d+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Admin',
|
||||
'method' => 'projectUpdate');
|
||||
|
||||
$ctl[] = array('regex' => '#^/admin/projects/create/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Admin',
|
||||
'method' => 'projectCreate');
|
||||
|
||||
$ctl[] = array('regex' => '#^/admin/projects/(\d+)/delete/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Admin',
|
||||
'method' => 'projectDelete');
|
||||
|
||||
$ctl[] = array('regex' => '#^/admin/users/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Admin',
|
||||
'method' => 'users');
|
||||
|
||||
$ctl[] = array('regex' => '#^/admin/users/notvalid/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Admin',
|
||||
'method' => 'usersNotValidated');
|
||||
|
||||
$ctl[] = array('regex' => '#^/admin/users/(\d+)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_Admin',
|
||||
'method' => 'userUpdate');
|
||||
|
||||
@ -445,53 +379,42 @@ $ctl[] = array('regex' => '#^/admin/users/(\d+)/$#',
|
||||
|
||||
$ctl[] = array('regex' => '#^/register/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views',
|
||||
'method' => 'register');
|
||||
|
||||
$ctl[] = array('regex' => '#^/register/k/(.*)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views',
|
||||
'method' => 'registerConfirmation');
|
||||
|
||||
$ctl[] = array('regex' => '#^/register/ik/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views',
|
||||
'method' => 'registerInputKey');
|
||||
|
||||
$ctl[] = array('regex' => '#^/password/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views',
|
||||
'method' => 'passwordRecoveryAsk');
|
||||
|
||||
$ctl[] = array('regex' => '#^/password/ik/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views',
|
||||
'method' => 'passwordRecoveryInputCode');
|
||||
|
||||
$ctl[] = array('regex' => '#^/password/k/(.*)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views',
|
||||
'method' => 'passwordRecovery');
|
||||
|
||||
$ctl[] = array('regex' => '#^/preferences/email/ik/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_User',
|
||||
'method' => 'changeEmailInputKey');
|
||||
|
||||
$ctl[] = array('regex' => '#^/preferences/email/ak/(.*)/$#',
|
||||
'base' => $base,
|
||||
'priority' => 4,
|
||||
'model' => 'IDF_Views_User',
|
||||
'method' => 'changeEmailDo');
|
||||
|
||||
|
||||
|
||||
|
||||
return $ctl;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-02-27 15:21+0100\n"
|
||||
"POT-Creation-Date: 2009-06-22 21:06+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -24,8 +24,9 @@ msgid "project"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Commit.php:62 IDF/IssueComment.php:65 IDF/IssueFile.php:57
|
||||
#: IDF/Issue.php:67 IDF/Review.php:71 IDF/Upload.php:79 IDF/WikiPage.php:78
|
||||
#: IDF/WikiRevision.php:79 IDF/Review/FileComment.php:69
|
||||
#: IDF/Issue.php:67 IDF/Review.php:71 IDF/Upload.php:85 IDF/WikiPage.php:78
|
||||
#: IDF/WikiRevision.php:79 IDF/Review/Comment.php:69
|
||||
#: IDF/Review/FileComment.php:69
|
||||
msgid "submitter"
|
||||
msgstr ""
|
||||
|
||||
@ -39,29 +40,28 @@ msgid "changelog"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Commit.php:99 IDF/IssueComment.php:79 IDF/IssueFile.php:96
|
||||
#: IDF/Issue.php:105 IDF/Review.php:99 IDF/Upload.php:100 IDF/WikiPage.php:100
|
||||
#: IDF/WikiRevision.php:92 IDF/Review/Patch.php:83
|
||||
#: IDF/Issue.php:105 IDF/Review.php:99 IDF/Upload.php:106 IDF/WikiPage.php:100
|
||||
#: IDF/WikiRevision.php:92 IDF/Review/Patch.php:83 IDF/Review/Comment.php:83
|
||||
#: IDF/Review/FileComment.php:76
|
||||
msgid "creation date"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Commit.php:170
|
||||
#: IDF/Commit.php:172
|
||||
#, php-format
|
||||
msgid "New Commit %s - %s (%s)"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Commit.php:205 IDF/Commit.php:232 IDF/Form/ReviewCreate.php:72
|
||||
#: IDF/Commit.php:239
|
||||
#, php-format
|
||||
msgid "Commit %s, by %s"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Commit.php:266 IDF/Form/ReviewCreate.php:74
|
||||
#: IDF/gettexttemplates/idf/source/base.html.php:5
|
||||
#: IDF/gettexttemplates/idf/source/changelog.html.php:5
|
||||
msgid "Commit"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Commit.php:205 IDF/IssueComment.php:173 IDF/Issue.php:196
|
||||
#: IDF/Upload.php:185 IDF/WikiPage.php:199 IDF/WikiRevision.php:189
|
||||
#: IDF/gettexttemplates/idf/source/changelog.html.php:6
|
||||
msgid "by"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Conf.php:61 IDF/Conf.php:61
|
||||
msgid "key"
|
||||
msgstr ""
|
||||
@ -70,29 +70,32 @@ msgstr ""
|
||||
msgid "value"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/IssueComment.php:51
|
||||
#: IDF/IssueComment.php:51 IDF/Review/Comment.php:55
|
||||
msgid "issue"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/IssueComment.php:58 IDF/IssueFile.php:49 IDF/Review/FileComment.php:62
|
||||
#: IDF/IssueComment.php:58 IDF/IssueFile.php:49 IDF/Review/Comment.php:62
|
||||
#: IDF/Review/FileComment.php:62
|
||||
msgid "comment"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/IssueComment.php:72 IDF/WikiRevision.php:85
|
||||
#: IDF/IssueComment.php:72 IDF/Upload.php:63 IDF/WikiRevision.php:85
|
||||
#: IDF/Review/Comment.php:76
|
||||
msgid "changes"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/IssueComment.php:73
|
||||
#: IDF/IssueComment.php:73 IDF/Review/Comment.php:77
|
||||
msgid "Serialized array of the changes in the issue."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/IssueComment.php:143 IDF/Issue.php:194
|
||||
#: IDF/IssueComment.php:143 IDF/Issue.php:194 IDF/Review/Comment.php:147
|
||||
#, php-format
|
||||
msgid ""
|
||||
"<a href=\"%1$s\" class=\"%2$s\" title=\"View issue\">Issue %3$d</a>, %4$s"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/IssueComment.php:151 IDF/IssueComment.php:207
|
||||
#: IDF/Review/Comment.php:155 IDF/Review/Comment.php:211
|
||||
#: IDF/gettexttemplates/idf/wiki/wiki-updated-email.txt.php:6
|
||||
#: IDF/gettexttemplates/idf/wiki/wiki-updated-email.txt.php:11
|
||||
#: IDF/gettexttemplates/idf/issues/issue-updated-email.txt.php:13
|
||||
@ -101,6 +104,7 @@ msgid "Summary:"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/IssueComment.php:153 IDF/IssueComment.php:209
|
||||
#: IDF/Review/Comment.php:157 IDF/Review/Comment.php:213
|
||||
#: IDF/gettexttemplates/idf/review/review-created-email.txt.php:6
|
||||
#: IDF/gettexttemplates/idf/review/review-updated-email.txt.php:9
|
||||
#: IDF/gettexttemplates/idf/issues/issue-updated-email.txt.php:7
|
||||
@ -112,6 +116,7 @@ msgid "Status:"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/IssueComment.php:155 IDF/IssueComment.php:211
|
||||
#: IDF/Review/Comment.php:159 IDF/Review/Comment.php:215
|
||||
#: IDF/gettexttemplates/idf/issues/issue-updated-email.txt.php:15
|
||||
#: IDF/gettexttemplates/idf/issues/view.html.php:12
|
||||
#: IDF/gettexttemplates/idf/issues/view.html.php:22
|
||||
@ -119,6 +124,7 @@ msgid "Owner:"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/IssueComment.php:157 IDF/IssueComment.php:213 IDF/WikiRevision.php:175
|
||||
#: IDF/Review/Comment.php:161 IDF/Review/Comment.php:217
|
||||
#: IDF/gettexttemplates/idf/wiki/view.html.php:15
|
||||
#: IDF/gettexttemplates/idf/wiki/wiki-created-email.txt.php:7
|
||||
#: IDF/gettexttemplates/idf/wiki/delete.html.php:13
|
||||
@ -131,7 +137,7 @@ msgstr ""
|
||||
#: IDF/gettexttemplates/idf/issues/view.html.php:13
|
||||
#: IDF/gettexttemplates/idf/issues/view.html.php:24
|
||||
#: IDF/gettexttemplates/idf/issues/issue-created-email.txt.php:9
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:15
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:16
|
||||
#: IDF/gettexttemplates/idf/downloads/delete.html.php:11
|
||||
#: IDF/gettexttemplates/idf/downloads/download-created-email.txt.php:7
|
||||
msgid "Labels:"
|
||||
@ -139,10 +145,10 @@ msgstr ""
|
||||
|
||||
#: IDF/IssueComment.php:173
|
||||
#, php-format
|
||||
msgid "Comment on <a href=\"%s\" class=\"%s\">issue %d</a>"
|
||||
msgid "Comment on <a href=\"%s\" class=\"%s\">issue %d</a>, by %s"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/IssueComment.php:195
|
||||
#: IDF/IssueComment.php:195 IDF/Review/Comment.php:199
|
||||
#, php-format
|
||||
msgid "%s: Comment on issue %d - %s"
|
||||
msgstr ""
|
||||
@ -172,7 +178,7 @@ msgid "Other"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/IssueFile.php:102 IDF/Issue.php:111 IDF/Review.php:105
|
||||
#: IDF/Upload.php:106 IDF/WikiPage.php:106
|
||||
#: IDF/Upload.php:112 IDF/WikiPage.php:106
|
||||
msgid "modification date"
|
||||
msgstr ""
|
||||
|
||||
@ -189,7 +195,7 @@ msgid ""
|
||||
"Interested users will get an email notification when the issue is changed."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Issue.php:92 IDF/Review.php:86 IDF/Upload.php:87 IDF/WikiPage.php:94
|
||||
#: IDF/Issue.php:92 IDF/Review.php:86 IDF/Upload.php:93 IDF/WikiPage.php:94
|
||||
msgid "labels"
|
||||
msgstr ""
|
||||
|
||||
@ -199,7 +205,7 @@ msgstr ""
|
||||
|
||||
#: IDF/Issue.php:196
|
||||
#, php-format
|
||||
msgid "Creation of <a href=\"%s\" class=\"%s\">issue %d</a>"
|
||||
msgid "Creation of <a href=\"%s\" class=\"%s\">issue %d</a>, by %s"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Issue.php:215
|
||||
@ -270,33 +276,33 @@ msgstr ""
|
||||
msgid "Lower case version of the name for fast searching."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Upload.php:64
|
||||
#: IDF/Upload.php:70
|
||||
msgid "file"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Upload.php:65
|
||||
#: IDF/Upload.php:71
|
||||
msgid "The path is relative to the upload path."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Upload.php:72
|
||||
#: IDF/Upload.php:78
|
||||
msgid "file size in bytes"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Upload.php:94
|
||||
#: IDF/Upload.php:100
|
||||
msgid "number of downloads"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Upload.php:182
|
||||
#: IDF/Upload.php:189
|
||||
#, php-format
|
||||
msgid "<a href=\"%1$s\" title=\"View download\">Download %2$d</a>, %3$s"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Upload.php:185
|
||||
#: IDF/Upload.php:192
|
||||
#, php-format
|
||||
msgid "Addition of <a href=\"%s\">download %d</a>"
|
||||
msgid "Addition of <a href=\"%s\">download %d</a>, by %s"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Upload.php:203
|
||||
#: IDF/Upload.php:210
|
||||
#, php-format
|
||||
msgid "%s: Download %d added - %s"
|
||||
msgstr ""
|
||||
@ -361,7 +367,7 @@ msgstr ""
|
||||
|
||||
#: IDF/WikiPage.php:199
|
||||
#, php-format
|
||||
msgid "Creation of <a href=\"%s\">page %s</a>"
|
||||
msgid "Creation of <a href=\"%s\">page %s</a>, by %s"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/WikiPage.php:218
|
||||
@ -383,7 +389,7 @@ msgstr ""
|
||||
|
||||
#: IDF/WikiRevision.php:189
|
||||
#, php-format
|
||||
msgid "Change of <a href=\"%s\">%s</a>"
|
||||
msgid "Change of <a href=\"%s\">%s</a>, by %s"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/WikiRevision.php:209
|
||||
@ -427,6 +433,16 @@ msgstr ""
|
||||
msgid "patch"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Review/Comment.php:177
|
||||
#, php-format
|
||||
msgid "Comment on <a href=\"%s\" class=\"%s\">issue %d</a>"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Review/Comment.php:177
|
||||
#: IDF/gettexttemplates/idf/source/changelog.html.php:6
|
||||
msgid "by"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Plugin/SyncSvn.php:75 IDF/Plugin/SyncMercurial.php:75
|
||||
#, php-format
|
||||
msgid "The repository %s already exists."
|
||||
@ -452,8 +468,8 @@ msgstr ""
|
||||
|
||||
#: IDF/Views/Wiki.php:62 IDF/Views/Wiki.php:109 IDF/Views/Wiki.php:150
|
||||
#: IDF/Views/Review.php:58 IDF/Views/User.php:83 IDF/Views/Issue.php:61
|
||||
#: IDF/Views/Issue.php:137 IDF/Views/Issue.php:249 IDF/Views/Issue.php:442
|
||||
#: IDF/Views/Issue.php:500 IDF/Views/Download.php:65
|
||||
#: IDF/Views/Issue.php:137 IDF/Views/Issue.php:247 IDF/Views/Issue.php:436
|
||||
#: IDF/Views/Issue.php:494 IDF/Views/Download.php:65
|
||||
#: IDF/Views/Download.php:272 IDF/Form/Upload.php:40
|
||||
#: IDF/Form/UpdateUpload.php:42 IDF/Form/IssueCreate.php:50
|
||||
#: IDF/Form/IssueUpdate.php:45 IDF/Form/ReviewCreate.php:45
|
||||
@ -511,7 +527,7 @@ msgstr ""
|
||||
msgid "Delete Old Revision of %s"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Wiki.php:316 IDF/Views/Admin.php:90 IDF/Views/Admin.php:242
|
||||
#: IDF/Views/Wiki.php:316 IDF/Views/Admin.php:93 IDF/Views/Admin.php:245
|
||||
#, php-format
|
||||
msgid "Update %s"
|
||||
msgstr ""
|
||||
@ -555,7 +571,7 @@ msgstr ""
|
||||
msgid "%s Project Summary"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Project.php:221 IDF/Views/Admin.php:98
|
||||
#: IDF/Views/Project.php:221 IDF/Views/Admin.php:101
|
||||
msgid "The project has been updated."
|
||||
msgstr ""
|
||||
|
||||
@ -635,21 +651,21 @@ msgid "This table shows the latest reviews."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Review.php:57 IDF/Views/User.php:81 IDF/Views/Issue.php:60
|
||||
#: IDF/Views/Issue.php:136 IDF/Views/Issue.php:248 IDF/Views/Issue.php:441
|
||||
#: IDF/Views/Issue.php:499
|
||||
#: IDF/Views/Issue.php:136 IDF/Views/Issue.php:246 IDF/Views/Issue.php:435
|
||||
#: IDF/Views/Issue.php:493
|
||||
msgid "Id"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Review.php:59 IDF/Views/User.php:84 IDF/Views/Issue.php:62
|
||||
#: IDF/Views/Issue.php:138 IDF/Views/Issue.php:250 IDF/Views/Issue.php:443
|
||||
#: IDF/Views/Issue.php:501 IDF/Form/IssueCreate.php:92
|
||||
#: IDF/Form/IssueUpdate.php:88 IDF/Form/ReviewCreate.php:101
|
||||
#: IDF/Views/Issue.php:138 IDF/Views/Issue.php:248 IDF/Views/Issue.php:437
|
||||
#: IDF/Views/Issue.php:495 IDF/Form/IssueCreate.php:92
|
||||
#: IDF/Form/IssueUpdate.php:88 IDF/Form/ReviewCreate.php:103
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Review.php:60 IDF/Views/User.php:85 IDF/Views/Issue.php:63
|
||||
#: IDF/Views/Issue.php:139 IDF/Views/Issue.php:251 IDF/Views/Issue.php:444
|
||||
#: IDF/Views/Issue.php:502
|
||||
#: IDF/Views/Issue.php:139 IDF/Views/Issue.php:249 IDF/Views/Issue.php:438
|
||||
#: IDF/Views/Issue.php:496
|
||||
msgid "Last Updated"
|
||||
msgstr ""
|
||||
|
||||
@ -732,27 +748,27 @@ msgstr ""
|
||||
msgid "Your new email address \"%s\" has been validated. Thank you!"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Source.php:46
|
||||
#: IDF/Views/Source.php:50
|
||||
#, php-format
|
||||
msgid "%s Source Help"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Source.php:61
|
||||
#: IDF/Views/Source.php:65
|
||||
#, php-format
|
||||
msgid "%1$s %2$s Change Log"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Source.php:102 IDF/Views/Source.php:151 IDF/Views/Source.php:312
|
||||
#: IDF/Views/Source.php:108 IDF/Views/Source.php:152 IDF/Views/Source.php:318
|
||||
#, php-format
|
||||
msgid "%1$s %2$s Source Tree"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Source.php:265
|
||||
#: IDF/Views/Source.php:269
|
||||
#, php-format
|
||||
msgid "%s Commit Details"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Source.php:266
|
||||
#: IDF/Views/Source.php:270
|
||||
#, php-format
|
||||
msgid "%s Commit Details - %s"
|
||||
msgstr ""
|
||||
@ -762,8 +778,8 @@ msgstr ""
|
||||
msgid "%s Open Issues"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:67 IDF/Views/Issue.php:143 IDF/Views/Issue.php:255
|
||||
#: IDF/Views/Issue.php:448 IDF/Views/Issue.php:506
|
||||
#: IDF/Views/Issue.php:67 IDF/Views/Issue.php:143 IDF/Views/Issue.php:253
|
||||
#: IDF/Views/Issue.php:442 IDF/Views/Issue.php:500
|
||||
msgid "No issues were found."
|
||||
msgstr ""
|
||||
|
||||
@ -791,78 +807,78 @@ msgstr ""
|
||||
msgid "Submit a new issue"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:178
|
||||
#, php-format
|
||||
msgid "<a href=\"%s\">Issue %d</a> has been created."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:197
|
||||
#: IDF/Views/Issue.php:194
|
||||
#, php-format
|
||||
msgid "Issue %s - %s (%s)"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:232
|
||||
#: IDF/Views/Issue.php:201
|
||||
#, php-format
|
||||
msgid "<a href=\"%s\">Issue %d</a> has been created."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:230
|
||||
#, php-format
|
||||
msgid "Search Issues - %s"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:244
|
||||
#: IDF/Views/Issue.php:242
|
||||
msgid "This table shows the found issues."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:274
|
||||
#: IDF/Views/Issue.php:272
|
||||
#, php-format
|
||||
msgid "Issue <a href=\"%s\">%d</a>: %s"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:298
|
||||
#, php-format
|
||||
msgid "<a href=\"%s\">Issue %d</a> has been updated."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:329
|
||||
#: IDF/Views/Issue.php:322
|
||||
#, php-format
|
||||
msgid "Updated Issue %s - %s (%s)"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:402
|
||||
#: IDF/Views/Issue.php:330
|
||||
#, php-format
|
||||
msgid "<a href=\"%s\">Issue %d</a> has been updated."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:396
|
||||
#, php-format
|
||||
msgid "View %s"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:422
|
||||
#: IDF/Views/Issue.php:416
|
||||
#, php-format
|
||||
msgid "%s Closed Issues"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:432
|
||||
#: IDF/Views/Issue.php:426
|
||||
msgid "This table shows the closed issues."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:474
|
||||
#: IDF/Views/Issue.php:468
|
||||
#, php-format
|
||||
msgid "%1$s Issues with Label %2$s"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:477
|
||||
#: IDF/Views/Issue.php:471
|
||||
#, php-format
|
||||
msgid "%1$s Closed Issues with Label %2$s"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:490
|
||||
#: IDF/Views/Issue.php:484
|
||||
#, php-format
|
||||
msgid "This table shows the issues with label %s."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:539
|
||||
#: IDF/Views/Issue.php:533
|
||||
msgid "The issue has been removed from your watch list."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:542
|
||||
#: IDF/Views/Issue.php:536
|
||||
msgid "The issue has been added to your watch list."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Issue.php:620
|
||||
#: IDF/Views/Issue.php:614
|
||||
msgid "On your watch list."
|
||||
msgstr ""
|
||||
|
||||
@ -875,7 +891,7 @@ msgstr ""
|
||||
msgid "This table shows the files to download."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Download.php:64 IDF/Views/Download.php:271 IDF/Form/Upload.php:49
|
||||
#: IDF/Views/Download.php:64 IDF/Views/Download.php:271 IDF/Form/Upload.php:59
|
||||
#: IDF/gettexttemplates/idf/source/mercurial/tree.html.php:6
|
||||
#: IDF/gettexttemplates/idf/source/svn/tree.html.php:6
|
||||
#: IDF/gettexttemplates/idf/source/git/tree.html.php:6
|
||||
@ -952,85 +968,89 @@ msgstr ""
|
||||
msgid "Short Name"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:66 IDF/Views/Admin.php:203
|
||||
#: IDF/Views/Admin.php:66 IDF/Views/Admin.php:206
|
||||
#: IDF/Form/Admin/ProjectCreate.php:48 IDF/Form/Admin/ProjectUpdate.php:42
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:71
|
||||
#: IDF/Views/Admin.php:67
|
||||
msgid "Repository Size"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:73
|
||||
msgid "No projects were found."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:122
|
||||
#: IDF/Views/Admin.php:125
|
||||
#: IDF/gettexttemplates/idf/gadmin/projects/base.html.php:4
|
||||
#: IDF/gettexttemplates/idf/gadmin/projects/create.html.php:16
|
||||
#: IDF/gettexttemplates/idf/index.html.php:5
|
||||
msgid "Create Project"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:128
|
||||
#: IDF/Views/Admin.php:131
|
||||
msgid "The project has been created."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:154
|
||||
#: IDF/Views/Admin.php:157
|
||||
#, php-format
|
||||
msgid "Delete %s Project"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:161
|
||||
#: IDF/Views/Admin.php:164
|
||||
msgid "The project has been deleted."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:191
|
||||
#: IDF/Views/Admin.php:194
|
||||
msgid "Not Validated User List"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:194
|
||||
#: IDF/Views/Admin.php:197
|
||||
#: IDF/gettexttemplates/idf/gadmin/users/base.html.php:3
|
||||
msgid "User List"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:197
|
||||
#: IDF/Views/Admin.php:200
|
||||
msgid "This table shows the users in the forge."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:202
|
||||
#: IDF/Views/Admin.php:205
|
||||
msgid "login"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:204 IDF/Form/Admin/UserUpdate.php:99
|
||||
#: IDF/Views/Admin.php:207 IDF/Form/Admin/UserUpdate.php:99
|
||||
msgid "Staff"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:205
|
||||
#: IDF/Views/Admin.php:208
|
||||
msgid "Admin"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:206 IDF/Form/Admin/UserUpdate.php:110
|
||||
#: IDF/Views/Admin.php:209 IDF/Form/Admin/UserUpdate.php:110
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:207
|
||||
#: IDF/Views/Admin.php:210
|
||||
msgid "Last Login"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:212
|
||||
#: IDF/Views/Admin.php:215
|
||||
msgid "No users were found."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:249
|
||||
#: IDF/Views/Admin.php:252
|
||||
msgid "You do not have the rights to update this user."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:265
|
||||
#: IDF/Views/Admin.php:268
|
||||
msgid "The user has been updated."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:284 IDF/gettexttemplates/idf/login_form.html.php:7
|
||||
#: IDF/Views/Admin.php:287 IDF/gettexttemplates/idf/login_form.html.php:7
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Views/Admin.php:284
|
||||
#: IDF/Views/Admin.php:287
|
||||
msgid "No"
|
||||
msgstr ""
|
||||
|
||||
@ -1045,44 +1065,51 @@ msgid ""
|
||||
"email."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/UserChangeEmail.php:80 IDF/Form/Upload.php:137
|
||||
#: IDF/Form/UserChangeEmail.php:80 IDF/Form/Upload.php:147
|
||||
#: IDF/Form/Register.php:114 IDF/Form/UserAccount.php:119
|
||||
#: IDF/Form/Admin/ProjectCreate.php:205 IDF/Form/Admin/ProjectUpdate.php:67
|
||||
#: IDF/Form/Admin/ProjectCreate.php:215 IDF/Form/Admin/ProjectUpdate.php:77
|
||||
#: IDF/Form/Admin/UserUpdate.php:129 IDF/Form/Admin/ProjectDelete.php:78
|
||||
#: IDF/Form/UpdateUpload.php:116 IDF/Form/WikiUpdate.php:178
|
||||
#: IDF/Form/TabsConf.php:92 IDF/Form/ReviewCommentFile.php:166
|
||||
#: IDF/Form/UpdateUpload.php:126 IDF/Form/WikiUpdate.php:178
|
||||
#: IDF/Form/TabsConf.php:97 IDF/Form/ReviewCommentFile.php:166
|
||||
#: IDF/Form/IssueCreate.php:233 IDF/Form/Password.php:61
|
||||
#: IDF/Form/IssueUpdate.php:232 IDF/Form/ReviewFileComment.php:77
|
||||
#: IDF/Form/WikiCreate.php:167 IDF/Form/MembersConf.php:64
|
||||
#: IDF/Form/ReviewCreate.php:185
|
||||
#: IDF/Form/ReviewCreate.php:187
|
||||
msgid "Cannot save the model from an invalid form."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/Upload.php:60 IDF/Form/UpdateUpload.php:61
|
||||
#: IDF/Form/Upload.php:49 IDF/Form/UpdateUpload.php:51
|
||||
#: IDF/Form/WikiUpdate.php:60 IDF/Form/ReviewCommentFile.php:69
|
||||
#: IDF/Form/IssueCreate.php:59 IDF/Form/WikiCreate.php:70
|
||||
#: IDF/Form/ReviewCreate.php:54
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/Upload.php:70 IDF/Form/UpdateUpload.php:71
|
||||
#: IDF/Form/WikiUpdate.php:104 IDF/Form/ReviewCommentFile.php:92
|
||||
#: IDF/Form/IssueCreate.php:120 IDF/Form/IssueUpdate.php:117
|
||||
#: IDF/Form/WikiCreate.php:93
|
||||
msgid "Labels"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/Upload.php:75
|
||||
#: IDF/Form/Upload.php:85
|
||||
msgid "For security reason, you cannot upload a file with this extension."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/Upload.php:108 IDF/Form/UpdateUpload.php:99
|
||||
#: IDF/Form/Upload.php:118 IDF/Form/UpdateUpload.php:109
|
||||
#: IDF/Form/IssueCreate.php:169
|
||||
#, php-format
|
||||
msgid "You cannot provide more than label from the %s class to an issue."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/Upload.php:109 IDF/Form/UpdateUpload.php:100
|
||||
#: IDF/Form/Upload.php:119 IDF/Form/UpdateUpload.php:110
|
||||
#: IDF/Form/WikiUpdate.php:162 IDF/Form/ReviewCommentFile.php:150
|
||||
#: IDF/Form/IssueCreate.php:163 IDF/Form/IssueCreate.php:170
|
||||
#: IDF/Form/WikiCreate.php:151
|
||||
msgid "You provided an invalid label."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/Upload.php:176
|
||||
#: IDF/Form/Upload.php:187
|
||||
#, php-format
|
||||
msgid "New download - %s (%s)"
|
||||
msgstr ""
|
||||
@ -1230,7 +1257,7 @@ msgstr ""
|
||||
msgid "The email \"%s\" is already used."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/UserAccount.php:240 IDF/Form/Admin/UserUpdate.php:211
|
||||
#: IDF/Form/UserAccount.php:240 IDF/Form/Admin/UserUpdate.php:214
|
||||
msgid "The passwords do not match. Please give them again."
|
||||
msgstr ""
|
||||
|
||||
@ -1264,7 +1291,8 @@ msgstr ""
|
||||
|
||||
#: IDF/Form/Admin/ProjectCreate.php:63
|
||||
msgid ""
|
||||
"It must be unique for each project and composed only of letters and digits."
|
||||
"It must be unique for each project and composed only of letters, digits and "
|
||||
"dash (-) like \"my-project\"."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/Admin/ProjectCreate.php:68
|
||||
@ -1293,31 +1321,31 @@ msgstr ""
|
||||
msgid "Project members"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/Admin/ProjectCreate.php:144
|
||||
#: IDF/Form/Admin/ProjectCreate.php:154
|
||||
msgid ""
|
||||
"Only a remote repository available throught http or https are allowed. For "
|
||||
"example \"http://somewhere.com/svn/trunk\"."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/Admin/ProjectCreate.php:153
|
||||
#: IDF/Form/Admin/ProjectCreate.php:163
|
||||
msgid ""
|
||||
"This shortname contains illegal characters, please use only letters and "
|
||||
"digits."
|
||||
"This shortname contains illegal characters, please use only letters, digits "
|
||||
"and dash (-)."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/Admin/ProjectCreate.php:156
|
||||
#: IDF/Form/Admin/ProjectCreate.php:166
|
||||
msgid "The shortname cannot start with the dash (-) character."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/Admin/ProjectCreate.php:159
|
||||
#: IDF/Form/Admin/ProjectCreate.php:169
|
||||
msgid "The shortname cannot end with the dash (-) character."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/Admin/ProjectCreate.php:164
|
||||
#: IDF/Form/Admin/ProjectCreate.php:174
|
||||
msgid "This shortname is already used. Please select another one."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/Admin/ProjectCreate.php:211
|
||||
#: IDF/Form/Admin/ProjectCreate.php:221
|
||||
msgid "Click on the Administer tab to set the description of your project."
|
||||
msgstr ""
|
||||
|
||||
@ -1353,7 +1381,11 @@ msgid ""
|
||||
"you can directly enable or disable his account here."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/Admin/UserUpdate.php:196
|
||||
#: IDF/Form/Admin/UserUpdate.php:183
|
||||
msgid "--- is not a valid first name."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/Admin/UserUpdate.php:199
|
||||
msgid ""
|
||||
"A user with this email already exists, please provide another email address."
|
||||
msgstr ""
|
||||
@ -1387,12 +1419,6 @@ msgid ""
|
||||
"The page name must contains only letters, digits and the dash (-) character."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/WikiUpdate.php:60 IDF/Form/ReviewCommentFile.php:69
|
||||
#: IDF/Form/IssueCreate.php:59 IDF/Form/WikiCreate.php:70
|
||||
#: IDF/Form/ReviewCreate.php:54
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/WikiUpdate.php:61 IDF/Form/ReviewCommentFile.php:70
|
||||
#: IDF/Form/WikiCreate.php:71
|
||||
msgid "This one line description is displayed in the list of pages."
|
||||
@ -1507,7 +1533,7 @@ msgid "Initial page creation"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/IssueCreate.php:69 IDF/Form/IssueUpdate.php:65
|
||||
#: IDF/Form/ReviewCreate.php:81
|
||||
#: IDF/Form/ReviewCreate.php:83
|
||||
msgid "The \"upload_issue_path\" configuration variable was not set."
|
||||
msgstr ""
|
||||
|
||||
@ -1527,7 +1553,7 @@ msgstr ""
|
||||
msgid "You need to provide a description of the issue."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/IssueCreate.php:203 IDF/Form/ReviewCreate.php:157
|
||||
#: IDF/Form/IssueCreate.php:203 IDF/Form/ReviewCreate.php:159
|
||||
msgid "You provided an invalid status."
|
||||
msgstr ""
|
||||
|
||||
@ -1562,6 +1588,13 @@ msgstr ""
|
||||
msgid "New Documentation Page %s - %s (%s)"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/MembersConf.php:104
|
||||
#, php-format
|
||||
msgid "The following login is invalid: %s."
|
||||
msgid_plural "The following login are invalids: %s."
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: IDF/Form/WikiConf.php:49
|
||||
msgid "Predefined documentation page labels"
|
||||
msgstr ""
|
||||
@ -1587,33 +1620,33 @@ msgstr ""
|
||||
msgid "Each issue may have at most one label with each of these classes"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/ReviewCreate.php:90
|
||||
#: IDF/Form/ReviewCreate.php:92
|
||||
msgid "Patch"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/ReviewCreate.php:117
|
||||
#: IDF/Form/ReviewCreate.php:119
|
||||
msgid "We were not able to parse your patch. Please provide a valid patch."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/ReviewCreate.php:126
|
||||
#: IDF/Form/ReviewCreate.php:128
|
||||
msgid "You provided an invalid commit."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/ReviewCreate.php:200
|
||||
#: IDF/Form/ReviewCreate.php:202
|
||||
msgid "Initial patch to be reviewed."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Form/ReviewCreate.php:220
|
||||
#: IDF/Form/ReviewCreate.php:222
|
||||
#, php-format
|
||||
msgid "New Code Review %s - %s (%s)"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Scm/Mercurial.php:123 IDF/Scm/Git.php:137
|
||||
#: IDF/Scm/Mercurial.php:125 IDF/Scm/Git.php:145
|
||||
#, php-format
|
||||
msgid "Folder %1$s not found in commit %2$s."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/Scm/Mercurial.php:140 IDF/Scm/Git.php:187
|
||||
#: IDF/Scm/Mercurial.php:142 IDF/Scm/Git.php:245
|
||||
#, php-format
|
||||
msgid "Not a valid tree: %s."
|
||||
msgstr ""
|
||||
@ -1787,6 +1820,10 @@ msgstr ""
|
||||
msgid "Change Log"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/source/base.html.php:6
|
||||
msgid "How To Get The Code"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/source/mercurial/file.html.php:3
|
||||
#: IDF/gettexttemplates/idf/source/mercurial/tree.html.php:3
|
||||
#: IDF/gettexttemplates/idf/source/svn/file.html.php:3
|
||||
@ -1838,6 +1875,7 @@ msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/source/mercurial/file.html.php:8
|
||||
#: IDF/gettexttemplates/idf/source/mercurial/tree.html.php:15
|
||||
#: IDF/gettexttemplates/idf/source/svn/tree.html.php:17
|
||||
#: IDF/gettexttemplates/idf/source/commit.html.php:13
|
||||
#: IDF/gettexttemplates/idf/source/git/file.html.php:8
|
||||
#: IDF/gettexttemplates/idf/source/git/tree.html.php:15
|
||||
@ -1924,12 +1962,14 @@ msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/source/svn/file.html.php:10
|
||||
#: IDF/gettexttemplates/idf/source/svn/tree.html.php:15
|
||||
#: IDF/gettexttemplates/idf/source/commit.html.php:14
|
||||
#: IDF/gettexttemplates/idf/source/changelog.html.php:8
|
||||
msgid "Revision:"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/source/svn/file.html.php:11
|
||||
#: IDF/gettexttemplates/idf/source/svn/tree.html.php:16
|
||||
#: IDF/gettexttemplates/idf/source/commit.html.php:15
|
||||
#: IDF/gettexttemplates/idf/source/changelog.html.php:9
|
||||
msgid "Go to revision"
|
||||
msgstr ""
|
||||
@ -2058,9 +2098,9 @@ msgstr ""
|
||||
#: IDF/gettexttemplates/idf/review/create.html.php:12
|
||||
#: IDF/gettexttemplates/idf/issues/view.html.php:18
|
||||
#: IDF/gettexttemplates/idf/issues/create.html.php:14
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:7
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:8
|
||||
#: IDF/gettexttemplates/idf/downloads/delete.html.php:7
|
||||
#: IDF/gettexttemplates/idf/downloads/submit.html.php:8
|
||||
#: IDF/gettexttemplates/idf/downloads/submit.html.php:9
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
@ -2163,7 +2203,7 @@ msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/gadmin/projects/update.html.php:18
|
||||
#: IDF/gettexttemplates/idf/wiki/view.html.php:11
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:9
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:10
|
||||
msgid "Trash"
|
||||
msgstr ""
|
||||
|
||||
@ -2229,6 +2269,34 @@ msgstr ""
|
||||
msgid "Change Project Details"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/gadmin/projects/index.html.php:3
|
||||
msgid "Space Usage Statistics"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/gadmin/projects/index.html.php:4
|
||||
msgid "Repositories:"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/gadmin/projects/index.html.php:5
|
||||
#: IDF/gettexttemplates/idf/issues/issue-updated-email.txt.php:17
|
||||
#: IDF/gettexttemplates/idf/issues/issue-created-email.txt.php:11
|
||||
msgid "Attachments:"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/gadmin/projects/index.html.php:6
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:15
|
||||
#: IDF/gettexttemplates/idf/downloads/delete.html.php:10
|
||||
msgid "Downloads:"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/gadmin/projects/index.html.php:7
|
||||
msgid "Database:"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/gadmin/projects/index.html.php:8
|
||||
msgid "Total Forge:"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/gadmin/projects/create.html.php:3
|
||||
msgid ""
|
||||
"You can select the type of repository you want. In the case of subversion, "
|
||||
@ -2265,7 +2333,7 @@ msgid "Welcome"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/admin/members.html.php:13
|
||||
#: IDF/gettexttemplates/idf/admin/source.html.php:7
|
||||
#: IDF/gettexttemplates/idf/admin/source.html.php:8
|
||||
#: IDF/gettexttemplates/idf/admin/tabs.html.php:10
|
||||
#: IDF/gettexttemplates/idf/admin/issue-tracking.html.php:8
|
||||
#: IDF/gettexttemplates/idf/admin/wiki.html.php:8
|
||||
@ -2292,6 +2360,10 @@ msgstr ""
|
||||
msgid "Repository access:"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/admin/source.html.php:7
|
||||
msgid "Repository size:"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/admin/tabs.html.php:3
|
||||
msgid ""
|
||||
"You can configure here the project tabs access rights and notification "
|
||||
@ -2426,7 +2498,7 @@ msgstr ""
|
||||
#: IDF/gettexttemplates/idf/wiki/delete.html.php:12
|
||||
#: IDF/gettexttemplates/idf/review/view.html.php:24
|
||||
#: IDF/gettexttemplates/idf/issues/view.html.php:20
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:13
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:14
|
||||
#: IDF/gettexttemplates/idf/downloads/delete.html.php:9
|
||||
msgid "Updated:"
|
||||
msgstr ""
|
||||
@ -2582,7 +2654,7 @@ msgstr ""
|
||||
#: IDF/gettexttemplates/idf/user/passrecovery-inputkey.html.php:6
|
||||
#: IDF/gettexttemplates/idf/user/changeemail.html.php:6
|
||||
#: IDF/gettexttemplates/idf/register/inputkey.html.php:6
|
||||
#: IDF/gettexttemplates/idf/downloads/submit.html.php:9
|
||||
#: IDF/gettexttemplates/idf/downloads/submit.html.php:10
|
||||
msgid "Instructions"
|
||||
msgstr ""
|
||||
|
||||
@ -2913,7 +2985,7 @@ msgid ""
|
||||
"If you are not interested any longer in taking\n"
|
||||
"part in the life of the software project or if\n"
|
||||
"you can't remember having requested the creation\n"
|
||||
"of an accout, please excuse us and simply ignore\n"
|
||||
"of an account, please excuse us and simply ignore\n"
|
||||
"this email. \n"
|
||||
"\n"
|
||||
"Yours faithfully,\n"
|
||||
@ -2967,6 +3039,7 @@ msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/review/view.html.php:28
|
||||
#: IDF/gettexttemplates/idf/issues/issue-created-email.txt.php:10
|
||||
#: IDF/gettexttemplates/idf/downloads/download-created-email.txt.php:9
|
||||
msgid "Description:"
|
||||
msgstr ""
|
||||
|
||||
@ -3101,11 +3174,6 @@ msgstr ""
|
||||
msgid "(No comments were given for this change.)"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/issues/issue-updated-email.txt.php:17
|
||||
#: IDF/gettexttemplates/idf/issues/issue-created-email.txt.php:11
|
||||
msgid "Attachments:"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/issues/issue-updated-email.txt.php:18
|
||||
#: IDF/gettexttemplates/idf/issues/issue-created-email.txt.php:12
|
||||
msgid "Issue:"
|
||||
@ -3243,32 +3311,31 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:5
|
||||
msgid "The form contains some errors. Please correct them to update the file."
|
||||
msgid "Changes"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:6
|
||||
msgid "The form contains some errors. Please correct them to update the file."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:7
|
||||
msgid "Update File"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:8
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:10
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:9
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:11
|
||||
msgid "Remove this file"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:11
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:12
|
||||
msgid "Delete this file"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:12
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:13
|
||||
#: IDF/gettexttemplates/idf/downloads/delete.html.php:8
|
||||
msgid "Uploaded:"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/downloads/view.html.php:14
|
||||
#: IDF/gettexttemplates/idf/downloads/delete.html.php:10
|
||||
msgid "Downloads:"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/downloads/delete.html.php:3
|
||||
msgid ""
|
||||
"<strong>Attention!</strong> If you want to delete a specific version of your "
|
||||
@ -3304,10 +3371,16 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/downloads/submit.html.php:6
|
||||
msgid "The form contains some errors. Please correct them to submit the file."
|
||||
#, php-format
|
||||
msgid ""
|
||||
"You can use the <a href=\"%%url%%\">Markdown syntax</a> for the changes."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/downloads/submit.html.php:7
|
||||
msgid "The form contains some errors. Please correct them to submit the file."
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/downloads/submit.html.php:8
|
||||
msgid "Submit File"
|
||||
msgstr ""
|
||||
|
||||
@ -3338,3 +3411,9 @@ msgstr ""
|
||||
#: IDF/Template/Markdown.php:61
|
||||
msgid "Create this documentation page"
|
||||
msgstr ""
|
||||
|
||||
#: IDF/gettexttemplates/idf/downloads/submit.html.php:6
|
||||
#, php-format
|
||||
msgid ""
|
||||
"You can use the <a href=\"%%url%%\">Markdown syntax</a> for the description."
|
||||
msgstr ""
|
||||
|
@ -40,6 +40,7 @@ $m['IDF_Review_FileComment'] = array('relate_to' => array('IDF_Review_Patch', 'P
|
||||
$m['IDF_Key'] = array('relate_to' => array('Pluf_User'));
|
||||
$m['IDF_Conf'] = array('relate_to' => array('IDF_Project'));
|
||||
$m['IDF_Commit'] = array('relate_to' => array('IDF_Project', 'Pluf_User'));
|
||||
$m['IDF_Scm_Cache_Git'] = array('relate_to' => array('IDF_Project'));
|
||||
|
||||
Pluf_Signal::connect('Pluf_Template_Compiler::construct_template_tags_modifiers',
|
||||
array('IDF_Middleware', 'updateTemplateTagsModifiers'));
|
||||
@ -53,7 +54,8 @@ Pluf_Signal::connect('IDF_Project::created',
|
||||
array('IDF_Plugin_SyncSvn', 'entry'));
|
||||
Pluf_Signal::connect('Pluf_User::passwordUpdated',
|
||||
array('IDF_Plugin_SyncSvn', 'entry'));
|
||||
|
||||
Pluf_Signal::connect('IDF_Project::preDelete',
|
||||
array('IDF_Plugin_SyncSvn', 'entry'));
|
||||
#
|
||||
# Mercurial synchronization
|
||||
Pluf_Signal::connect('IDF_Project::membershipsUpdated',
|
||||
|
@ -20,7 +20,12 @@
|
||||
<th>{trans 'Repository access:'}</th>
|
||||
<td>{$repository_access}
|
||||
</td>
|
||||
</tr>{if $remote_svn}
|
||||
</tr>{if $repository_size != -1}
|
||||
<tr>
|
||||
<th>{trans 'Repository size:'}</th>
|
||||
<td>{$repository_size|size}
|
||||
</td>
|
||||
</tr>{/if}{if $remote_svn}
|
||||
<tr>
|
||||
<th>{$form.f.svn_username.labelTag}:</th>
|
||||
<td>{if $form.f.svn_username.errors}{$form.f.svn_username.fieldErrors}{/if}
|
||||
|
@ -53,6 +53,15 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td colspan="2" class="helptext">
|
||||
{blocktrans}
|
||||
Only project members and admins have write access to the source.<br />
|
||||
If you restrict the access to the source, anonymous access is<br />
|
||||
not provided and the users must authenticate themselves with their<br />
|
||||
password or SSH key.{/blocktrans}
|
||||
</td></tr>
|
||||
<tr>
|
||||
<th><strong>{$form.f.review_access_rights.labelTag}:</strong></th>
|
||||
<td>{if $form.f.review_access_rights.errors}{$form.f.review_access_rights.fieldErrors}{/if}
|
||||
{$form.f.review_access_rights|unsafe}
|
||||
|
@ -73,15 +73,18 @@
|
||||
{include 'idf/js-hotkeys.html'}
|
||||
{block javascript}{/block}
|
||||
{if $project}
|
||||
<script type="text/javascript">{literal}
|
||||
<!-- //
|
||||
<script type="text/javascript" charset="utf-8">{literal}
|
||||
//<![CDATA[
|
||||
$(document).ready(function(){
|
||||
var frag = location.hash;
|
||||
if (frag.length > 3 && frag.substring(0, 3) == '#ic') {
|
||||
if ($('#preview').length) {
|
||||
location.hash = '#preview';
|
||||
}
|
||||
else if (frag.length > 3 && frag.substring(0, 3) == '#ic') {
|
||||
$(frag).addClass("issue-comment-focus");
|
||||
}
|
||||
});
|
||||
// -->{/literal}
|
||||
//]]>{/literal}
|
||||
</script>{/if}
|
||||
</body>
|
||||
</html>
|
||||
|
@ -75,15 +75,18 @@
|
||||
{include 'idf/js-hotkeys.html'}
|
||||
{block javascript}{/block}
|
||||
{if $project}
|
||||
<script type="text/javascript">{literal}
|
||||
<!-- //
|
||||
<script type="text/javascript" charset="utf-8">{literal}
|
||||
//<![CDATA[
|
||||
$(document).ready(function(){
|
||||
var frag = location.hash;
|
||||
if (frag.length > 3 && frag.substring(0, 3) == '#ic') {
|
||||
if ($('#preview').length) {
|
||||
location.hash = '#preview';
|
||||
}
|
||||
else if (frag.length > 3 && frag.substring(0, 3) == '#ic') {
|
||||
$(frag).addClass("issue-comment-focus");
|
||||
}
|
||||
});
|
||||
// -->{/literal}
|
||||
//]]>{/literal}
|
||||
</script>{/if}
|
||||
</body>
|
||||
</html>
|
@ -10,3 +10,8 @@
|
||||
{foreach $tags as $tag} {$tag.class|safe}:{$tag.name|safe}
|
||||
{/foreach}{/if}
|
||||
{trans 'Download:'} {$urlfile}
|
||||
{if $file.changelog}
|
||||
{trans 'Description:'}
|
||||
|
||||
{$file.changelog}
|
||||
{/if}
|
||||
|
@ -19,6 +19,12 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{$form.f.changelog.labelTag}:</th>
|
||||
<td>{if $form.f.changelog.errors}{$form.f.changelog.fieldErrors}{/if}
|
||||
{$form.f.changelog|unsafe}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><strong>{$form.f.file.labelTag}:</strong></th>
|
||||
<td>{if $form.f.file.errors}{$form.f.file.fieldErrors}{/if}
|
||||
{$form.f.file|unsafe}
|
||||
@ -50,6 +56,8 @@
|
||||
<p>{blocktrans}Each file must have a distinct name and file contents
|
||||
cannot be changed, so be sure to include release numbers in each file
|
||||
name.{/blocktrans}</p>
|
||||
{assign $url = 'http://daringfireball.net/projects/markdown/syntax'}
|
||||
<p>{blocktrans}You can use the <a href="{$url}">Markdown syntax</a> for the description.{/blocktrans}</p>
|
||||
</div>
|
||||
{/block}
|
||||
{block javascript}
|
||||
|
@ -6,7 +6,11 @@
|
||||
{if $deprecated}<p class="smaller">{blocktrans}<strong>Attention!</strong> This file is marked as deprecated, download it only if you are sure you need this specific version.{/blocktrans}</p>{/if}
|
||||
<a href="{url 'IDF_Views_Download::download', array($project.shortname, $file.id)}">{$file}</a> - {$file.filesize|size}
|
||||
</div>
|
||||
{if $file.changelog}
|
||||
<h2 class="changes">{trans 'Changes'}</h2>
|
||||
|
||||
{markdown $file.changelog, $request}
|
||||
{/if}
|
||||
|
||||
{if $form}
|
||||
{if $form.errors}
|
||||
@ -19,7 +23,7 @@
|
||||
{/if}
|
||||
|
||||
<form method="post" enctype="multipart/form-data" action=".">
|
||||
<table class="form" summary="">
|
||||
<table class="form download" summary="">
|
||||
<tr>
|
||||
<th><strong>{$form.f.summary.labelTag}:</strong></th>
|
||||
<td>{if $form.f.summary.errors}{$form.f.summary.fieldErrors}{/if}
|
||||
@ -27,6 +31,12 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{$form.f.changelog.labelTag}:</th>
|
||||
<td>{if $form.f.changelog.errors}{$form.f.changelog.fieldErrors}{/if}
|
||||
{$form.f.changelog|unsafe}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{$form.f.label1.labelTag}:</th>
|
||||
<td>
|
||||
{if $form.f.label1.errors}{$form.f.label1.fieldErrors}{/if}{$form.f.label1|unsafe}
|
||||
@ -39,7 +49,8 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>{aurl 'url', 'IDF_Views_Download::delete', array($project.shortname, $file.id)}
|
||||
<td><input type="submit" value="{trans 'Update File'}" name="submit" /> | <a href="{url 'IDF_Views_Download::index', array($project.shortname)}">{trans 'Cancel'}</a> <span class="dellink"><a href="{$url}" title="{trans 'Remove this file'}"><img src="{media '/idf/img/trash.png'}" style="vertical-align: text-bottom;" alt="{trans 'Trash'}" /></a> <a href="{$url}" title="{trans 'Remove this file'}">{trans 'Delete this file'}</a></span>
|
||||
<td>{* float left is a fix for Firefox < 3.5 *}
|
||||
<span style="float: left;"><input type="submit" value="{trans 'Update File'}" name="submit" /> | <a href="{url 'IDF_Views_Download::index', array($project.shortname)}">{trans 'Cancel'}</a></span> <span class="dellink"><a href="{$url}" title="{trans 'Remove this file'}"><img src="{media '/idf/img/trash.png'}" style="vertical-align: text-bottom;" alt="{trans 'Trash'}" /></a> <a href="{$url}" title="{trans 'Remove this file'}">{trans 'Delete this file'}</a></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -1,8 +1,23 @@
|
||||
{extends "idf/gadmin/projects/base.html"}
|
||||
|
||||
{block docclass}yui-t2{assign $inIndex=true}{/block}
|
||||
{block docclass}yui-t3{assign $inIndex=true}{/block}
|
||||
|
||||
{block body}
|
||||
{$projects.render}
|
||||
{/block}
|
||||
|
||||
{block context}
|
||||
<div class="issue-submit-info">
|
||||
<p><strong>{trans 'Space Usage Statistics'}</strong></p>
|
||||
<ul>
|
||||
<li>{trans 'Repositories:'} {$size['repositories']|size}</li>
|
||||
<li>{trans 'Attachments:'} {$size['attachments']|size}</li>
|
||||
<li>{trans 'Downloads:'} {$size['downloads']|size}</li>
|
||||
<li>{trans 'Database:'} {$size['database']|size}</li>
|
||||
<li><strong>{trans 'Total Forge:'} {$size['total']|size}</strong></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
|
||||
|
@ -35,9 +35,10 @@
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td> {aurl 'url', 'IDF_Views_Admin::projectDelete', array($project.id)}
|
||||
<input type="submit" value="{trans 'Update Project'}" name="submit" />
|
||||
| <a href="{url 'IDF_Views_Admin::projects'}">{trans 'Cancel'}</a> {if $isAdmin}
|
||||
<span class="dellink"><a href="{$url}" title="{trans 'Delete this project'}"><img src="{media '/idf/img/trash.png'}" style="vertical-align: text-bottom;" alt="{trans 'Trash'}" /></a> <a href="{$url}" title="{trans 'Delete this project'}">{trans 'Delete this project'}</a><br /><span class="note helptext">{trans 'You will be ask to confirm.'}</span></span>{/if}
|
||||
{* float left is a fix for Firefox < 3.5 *}
|
||||
<span style="float: left;"><input type="submit" value="{trans 'Update Project'}" name="submit" />
|
||||
| <a href="{url 'IDF_Views_Admin::projects'}">{trans 'Cancel'}</a></span> {if $isAdmin}
|
||||
<span class="dellink"><a href="{$url}" title="{trans 'Delete this project'}"><img src="{media '/idf/img/trash.png'}" style="vertical-align: text-bottom;" alt="{trans 'Trash'}" /></a> <a href="{$url}" title="{trans 'Delete this project'}">{trans 'Delete this project'}</a><br /><span class="note helptext">{trans 'You will be asked to confirm.'}</span></span>{/if}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -10,7 +10,7 @@
|
||||
<p><a href="{$url}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/add.png'}" alt="+" align="bottom" /></a> <a href="{$url}">{trans 'Create Project'}</a></p>{/if}
|
||||
{else}
|
||||
<ul>{foreach $projects as $p}
|
||||
<li><a href="{url 'IDF_Views_Project::home', array($p.shortname)}">{$p}</a>, {$p.shortdesc}</li>
|
||||
<li>{if $p.private}<img style="vertical-align: text-bottom;" src="{media '/idf/img/lock.png'}" alt="{trans 'Private project'}" /> {/if}<a href="{url 'IDF_Views_Project::home', array($p.shortname)}">{$p}</a>{if $p.shortdesc}, {$p.shortdesc}{/if}</li>
|
||||
{/foreach}</ul>
|
||||
{/if}
|
||||
{/block}
|
||||
|
@ -11,14 +11,14 @@
|
||||
{/if}
|
||||
|
||||
{if $preview}
|
||||
<h2 class="top">{trans 'Preview'}</h2>
|
||||
<h2 id="preview" class="top">{trans 'Preview'}</h2>
|
||||
<div class="issue-comment issue-comment-first issue-comment-last">
|
||||
<br /><pre class="issue-comment-text">{issuetext $preview, $request}</pre>
|
||||
</div>
|
||||
<hr />
|
||||
{/if}
|
||||
|
||||
<form method="post" enctype="multipart/form-data" action="{url 'IDF_Views_Issue::create', array($project.shortname)}" >
|
||||
<form method="post" enctype="multipart/form-data" action="{url 'IDF_Views_Issue::create', array($project.shortname)}#preview" >
|
||||
<table class="form" summary="">
|
||||
<tr>
|
||||
<th><strong>{$form.f.summary.labelTag}:</strong></th>
|
||||
@ -107,16 +107,19 @@ $(document).ready(function(){
|
||||
$("#form-show-0").click(function(){
|
||||
$("#form-attachment-1").show();
|
||||
$("#form-block-0").hide();
|
||||
return false;
|
||||
});
|
||||
$("#form-attachment-1 td").append("<span id=\"form-block-1\"><a id=\"form-show-1\" href=\"#\">{/literal}{trans 'Attach another file'}{literal}</a></span>");
|
||||
$("#form-show-1").click(function(){
|
||||
$("#form-attachment-2").show();
|
||||
$("#form-block-1").hide();
|
||||
return false;
|
||||
});
|
||||
$("#form-attachment-2 td").append("<span id=\"form-block-2\"><a id=\"form-show-2\" href=\"#\">{/literal}{trans 'Attach another file'}{literal}</a></span>");
|
||||
$("#form-show-2").click(function(){
|
||||
$("#form-attachment-3").show();
|
||||
$("#form-block-2").hide();
|
||||
return false;
|
||||
});
|
||||
var j=0;
|
||||
for (j=1;j<4;j=j+1) {
|
||||
|
@ -53,7 +53,7 @@
|
||||
{/if}
|
||||
|
||||
{if $preview}
|
||||
<h2>{trans 'Preview'}</h2>
|
||||
<h2 id="preview">{trans 'Preview'}</h2>
|
||||
<div class="issue-comment issue-comment-first issue-comment-last">
|
||||
<br /><pre class="issue-comment-text">{issuetext $preview, $request}</pre>
|
||||
</div>
|
||||
@ -160,16 +160,19 @@ $(document).ready(function(){
|
||||
$("#form-show-0").click(function(){
|
||||
$("#form-attachment-1").show();
|
||||
$("#form-block-0").hide();
|
||||
return false;
|
||||
});
|
||||
$("#form-attachment-1 td").append("<span id=\"form-block-1\"><a id=\"form-show-1\" href=\"#\">{/literal}{trans 'Attach another file'}{literal}</a></span>");
|
||||
$("#form-show-1").click(function(){
|
||||
$("#form-attachment-2").show();
|
||||
$("#form-block-1").hide();
|
||||
return false;
|
||||
});
|
||||
$("#form-attachment-2 td").append("<span id=\"form-block-2\"><a id=\"form-show-2\" href=\"#\">{/literal}{trans 'Attach another file'}{literal}</a></span>");
|
||||
$("#form-show-2").click(function(){
|
||||
$("#form-attachment-3").show();
|
||||
$("#form-block-2").hide();
|
||||
return false;
|
||||
});
|
||||
var j=0;
|
||||
for (j=1;j<4;j=j+1) {
|
||||
|
@ -18,7 +18,7 @@ and provide the following confirmation key:
|
||||
If you are not interested any longer in taking
|
||||
part in the life of the software project or if
|
||||
you can't remember having requested the creation
|
||||
of an accout, please excuse us and simply ignore
|
||||
of an account, please excuse us and simply ignore
|
||||
this email.
|
||||
|
||||
Yours faithfully,
|
||||
|
@ -1,10 +1,12 @@
|
||||
{extends "idf/base.html"}
|
||||
{block tabsource} class="active"{/block}
|
||||
{block subtabs}
|
||||
{if !$inHelp and array_key_exists($commit, $branches)}{assign $currentCommit = $commit}{else}{assign $currentCommit = $project.getScmRoot()}{/if}
|
||||
<div id="sub-tabs">
|
||||
<a {if $inSourceTree}class="active" {/if}href="{url 'IDF_Views_Source::treeBase', array($project.shortname, $project.getScmRoot())}">{trans 'Source Tree'}</a> |
|
||||
<a {if $inChangeLog}class="active" {/if}href="{url 'IDF_Views_Source::changeLog', array($project.shortname, $project.getScmRoot())}">{trans 'Change Log'}</a>
|
||||
{if $inCommit}| {trans 'Commit'}{/if}
|
||||
<a {if $inSourceTree}class="active" {/if}href="{url 'IDF_Views_Source::treeBase', array($project.shortname, $currentCommit)}">{trans 'Source Tree'}</a> |
|
||||
<a {if $inChangeLog}class="active" {/if}href="{url 'IDF_Views_Source::changeLog', array($project.shortname, $currentCommit)}">{trans 'Change Log'}</a>
|
||||
{if $inCommit}| {trans 'Commit'}{/if} |
|
||||
<a {if $inHelp}class="active" {/if}href="{url 'IDF_Views_Source::help', array($project.shortname)}">{trans 'How To Get The Code'}</a>
|
||||
</div>
|
||||
{/block}
|
||||
{block title}{$title}{/block}
|
||||
|
@ -27,22 +27,3 @@
|
||||
</tbody>
|
||||
</table>
|
||||
{/block}
|
||||
{block context}
|
||||
{if $scm != 'svn'}
|
||||
<p><strong>{trans 'Branches:'}</strong><br />
|
||||
{foreach $branches as $branch}
|
||||
{aurl 'url', 'IDF_Views_Source::changeLog', array($project.shortname, $branch)}
|
||||
<span class="label{if $commit == $branch} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br />
|
||||
{/foreach}
|
||||
</p>
|
||||
{else}
|
||||
<form class="star" action="{url 'IDF_Views_Source_Svn::changelogRev', array($project.shortname)}" method="get">
|
||||
<p><strong>{trans 'Revision:'}</strong> {$commit}</p>
|
||||
<p>
|
||||
<input accesskey="4" type="text" value="{$commit}" name="rev" size="5" />
|
||||
<input type="submit" name="s" value="{trans 'Go to revision'}" />
|
||||
</p>
|
||||
</form>
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
|
@ -38,13 +38,21 @@
|
||||
|
||||
{/block}
|
||||
{block context}
|
||||
{if $scm == 'git'}
|
||||
{if $scm != 'svn'}
|
||||
<p><strong>{trans 'Branches:'}</strong><br />
|
||||
{foreach $branches as $branch}
|
||||
{aurl 'url', 'IDF_Views_Source::commit', array($project.shortname, $branch)}
|
||||
<span class="label{if $commit == $branch} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br />
|
||||
{foreach $branches as $branch => $path}
|
||||
{aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $branch)}
|
||||
<span class="label{if in_array($branch, $tree_in)} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br />
|
||||
{/foreach}
|
||||
</p>
|
||||
{else}
|
||||
<form class="star" action="{url 'IDF_Views_Source_Svn::changelogRev', array($project.shortname)}" method="get">
|
||||
<p><strong>{trans 'Revision:'}</strong> {$commit}</p>
|
||||
<p>
|
||||
<input accesskey="4" type="text" value="{$commit}" name="rev" size="5" />
|
||||
<input type="submit" name="s" value="{trans 'Go to revision'}" />
|
||||
</p>
|
||||
</form>
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
|
10
src/IDF/templates/idf/source/git/changelog.html
Normal file
10
src/IDF/templates/idf/source/git/changelog.html
Normal file
@ -0,0 +1,10 @@
|
||||
{extends "idf/source/changelog.html"}
|
||||
{block context}
|
||||
<p><strong>{trans 'Branches:'}</strong><br />
|
||||
{foreach $branches as $branch => $path}
|
||||
{aurl 'url', 'IDF_Views_Source::changeLog', array($project.shortname, $branch)}
|
||||
<span class="label{if in_array($branch, $tree_in)} active{/if}"><a href="{$url}" class="label">{if $path}{$path}{else}{$branch}{/if}</a></span><br />
|
||||
{/foreach}
|
||||
</p>
|
||||
{/block}
|
||||
|
@ -23,9 +23,9 @@
|
||||
{/block}
|
||||
{block context}
|
||||
<p><strong>{trans 'Branches:'}</strong><br />
|
||||
{foreach $branches as $branch}
|
||||
{foreach $branches as $branch => $path}
|
||||
{aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $branch)}
|
||||
<span class="label{if $commit == $branch} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br />
|
||||
<span class="label{if in_array($branch, $tree_in)} active{/if}"><a href="{$url}" class="label">{if $path}{$path}{else}{$branch}{/if}</a></span><br />
|
||||
{/foreach}
|
||||
</p>
|
||||
{/block}
|
||||
|
@ -1,5 +1,5 @@
|
||||
{extends "idf/source/base.html"}
|
||||
{block docclass}yui-t2{/block}
|
||||
{block docclass}yui-t2{assign $inHelp=true}{/block}
|
||||
{block body}
|
||||
|
||||
<p>{blocktrans}The team behind {$project} is using
|
||||
@ -8,7 +8,7 @@ code.{/blocktrans}</p>
|
||||
|
||||
<h3>{trans 'Command-Line Access'}</h3>
|
||||
|
||||
<p><kbd>git clone {if $project.private}{$project.getWriteRemoteAccessUrl()}{else}{$project.getRemoteAccessUrl()}{/if}</kbd></p>
|
||||
<p><kbd>git clone {$project.getSourceAccessUrl($user)}</kbd></p>
|
||||
|
||||
{aurl 'url', 'IDF_Views_User::myAccount'}
|
||||
<p>{blocktrans}You may need to <a href="{$url}">provide your SSH key</a>. The synchronization of your SSH key can take a couple of minutes. You can learn more about <a href="http://www.google.com/search?q=public+ssh+key+authentication">SSH key authentification</a>.{/blocktrans}</p>
|
||||
@ -22,7 +22,7 @@ code.{/blocktrans}</p>
|
||||
git init
|
||||
git add .
|
||||
git commit -m "initial import"
|
||||
git remote add origin {$project.getWriteRemoteAccessUrl()}
|
||||
git remote add origin {$project.getWriteRemoteAccessUrl($url)}
|
||||
git push origin master
|
||||
</pre>
|
||||
|
||||
|
@ -47,15 +47,15 @@
|
||||
</tbody>
|
||||
</table>
|
||||
{aurl 'url', 'IDF_Views_Source::download', array($project.shortname, $commit)}
|
||||
<p class="right soft"><a href="{$url}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/package-grey.png'}" alt="{trans 'Archive'}" align="bottom" /></a> <a href="{$url}">{trans 'Download this version'}</a> {trans 'or'} <kbd>git clone {if $project.private}{$project.getWriteRemoteAccessUrl()}{else}{$project.getRemoteAccessUrl()}{/if}</kbd> <a href="{url 'IDF_Views_Source::help', array($project.shortname)}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/help.png'}" alt="{trans 'Help'}" /></a></p>
|
||||
<p class="right soft"><a href="{$url}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/package-grey.png'}" alt="{trans 'Archive'}" align="bottom" /></a> <a href="{$url}">{trans 'Download this version'}</a> {trans 'or'} <kbd>git clone {$project.getSourceAccessUrl($user)}</kbd> <a href="{url 'IDF_Views_Source::help', array($project.shortname)}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/help.png'}" alt="{trans 'Help'}" /></a></p>
|
||||
|
||||
|
||||
{/block}
|
||||
{block context}
|
||||
<p><strong>{trans 'Branches:'}</strong><br />
|
||||
{foreach $branches as $branch}
|
||||
{foreach $branches as $branch => $path}
|
||||
{aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $branch)}
|
||||
<span class="label{if $commit == $branch} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br />
|
||||
<span class="label{if in_array($branch, $tree_in)} active{/if}"><a href="{$url}" class="label">{if $path}{$path}{else}{$branch}{/if}</a></span><br />
|
||||
{/foreach}
|
||||
</p>
|
||||
{/block}
|
||||
|
10
src/IDF/templates/idf/source/mercurial/changelog.html
Normal file
10
src/IDF/templates/idf/source/mercurial/changelog.html
Normal file
@ -0,0 +1,10 @@
|
||||
{extends "idf/source/changelog.html"}
|
||||
{block context}
|
||||
<p><strong>{trans 'Branches:'}</strong><br />
|
||||
{foreach $branches as $branch => $path}
|
||||
{aurl 'url', 'IDF_Views_Source::changeLog', array($project.shortname, $branch)}
|
||||
<span class="label{if in_array($branch, $tree_in)} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br />
|
||||
{/foreach}
|
||||
</p>
|
||||
{/block}
|
||||
|
@ -24,9 +24,9 @@
|
||||
|
||||
{block context}
|
||||
<p><strong>{trans 'Branches:'}</strong><br />
|
||||
{foreach $branches as $branch}
|
||||
{foreach $branches as $branch => $path}
|
||||
{aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $branch)}
|
||||
<span class="label{if $commit == $branch} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br />
|
||||
<span class="label{if in_array($branch, $tree_in)} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br />
|
||||
{/foreach}
|
||||
</p>
|
||||
{/block}
|
||||
|
@ -1,5 +1,5 @@
|
||||
{extends "idf/source/base.html"}
|
||||
{block docclass}yui-t2{/block}
|
||||
{block docclass}yui-t2{assign $inHelp=true}{/block}
|
||||
{block body}
|
||||
|
||||
<p>{blocktrans}The team behind {$project} is using
|
||||
|
@ -48,9 +48,10 @@
|
||||
|
||||
{block context}
|
||||
<p><strong>{trans 'Branches:'}</strong><br />
|
||||
{foreach $branches as $branch}
|
||||
{foreach $branches as $branch => $path}
|
||||
{aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $branch)}
|
||||
<span class="label{if $commit == $branch} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br />
|
||||
<span class="label{if in_array($branch, $tree_in)} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br />
|
||||
{/foreach}
|
||||
</p>
|
||||
{/block}
|
||||
|
||||
|
11
src/IDF/templates/idf/source/svn/changelog.html
Normal file
11
src/IDF/templates/idf/source/svn/changelog.html
Normal file
@ -0,0 +1,11 @@
|
||||
{extends "idf/source/changelog.html"}
|
||||
{block context}
|
||||
<form class="star" action="{url 'IDF_Views_Source_Svn::changelogRev', array($project.shortname)}" method="get">
|
||||
<p><strong>{trans 'Revision:'}</strong> {$commit}</p>
|
||||
<p>
|
||||
<input accesskey="4" type="text" value="{$commit}" name="rev" size="5" />
|
||||
<input type="submit" name="s" value="{trans 'Go to revision'}" />
|
||||
</p>
|
||||
</form>
|
||||
{/block}
|
||||
|
@ -1,5 +1,5 @@
|
||||
{extends "idf/source/base.html"}
|
||||
{block docclass}yui-t2{/block}
|
||||
{block docclass}yui-t2{assign $inHelp=true}{/block}
|
||||
{block body}
|
||||
|
||||
<p>{blocktrans}The team behind {$project} is using
|
||||
|
@ -68,5 +68,12 @@
|
||||
<input type="hidden" name="sourcefile" value="{$base}"/>
|
||||
<input type="submit" name="s" value="{trans 'Go to revision'}" /></p>
|
||||
</form>
|
||||
<p><strong>{trans 'Branches:'}</strong><br />
|
||||
{foreach $branches as $branch => $path}
|
||||
{if $path}{aurl 'url', 'IDF_Views_Source::tree', array($project.shortname, 'HEAD', $path)}
|
||||
{else}{aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, 'HEAD')}{/if}
|
||||
<span class="label{if in_array($branch, $tree_in)} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br />
|
||||
{/foreach}
|
||||
</p>
|
||||
|
||||
{/block}
|
||||
|
@ -96,6 +96,7 @@ $(document).ready(function() {
|
||||
$("#form-show-0").click(function(){
|
||||
$(".pass-info").show();
|
||||
$("#form-block-0").hide();
|
||||
return false;
|
||||
});
|
||||
$(".pass-info").hide();
|
||||
});{/literal}
|
||||
|
@ -3,7 +3,7 @@
|
||||
{block body}
|
||||
|
||||
{if $preview}
|
||||
<h2 class="top">{trans 'Preview of the Page'}</h2>
|
||||
<h2 id="preview" class="top">{trans 'Preview of the Page'}</h2>
|
||||
|
||||
{markdown $preview, $request}
|
||||
{/if}
|
||||
|
@ -3,7 +3,7 @@
|
||||
{block body}
|
||||
|
||||
{if $preview}
|
||||
<h2 class="top">{trans 'Preview of the Page'}</h2>
|
||||
<h2 id="preview" class="top">{trans 'Preview of the Page'}</h2>
|
||||
|
||||
{markdown $preview, $request}
|
||||
{/if}
|
||||
|
@ -24,7 +24,7 @@ body {
|
||||
}
|
||||
|
||||
.top {
|
||||
margin-top: 0;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
a:link {
|
||||
@ -54,7 +54,6 @@ a:active{
|
||||
.dellink {
|
||||
float: right;
|
||||
position: relative;
|
||||
margin-top: -1.6em;
|
||||
}
|
||||
|
||||
.dellink a {
|
||||
@ -192,6 +191,10 @@ span.px-header-title {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
span.px-header-title a, span.px-header-title a:link, span.px-header-title a:visited, span.px-header-title a:active {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue
|
||||
*/
|
||||
@ -221,7 +224,9 @@ div.issue-comment-first {
|
||||
|
||||
div.issue-comment-signin {
|
||||
-moz-border-radius: 0 0 3px 3px;
|
||||
-webkit-border-radius: 0 0 3px 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
-webkit-border-top-left-radius: 0;
|
||||
-webkit-border-top-right-radius: 0;
|
||||
background-color: #d3d7cf;
|
||||
padding: 4px;
|
||||
}
|
||||
@ -302,6 +307,7 @@ h1.project-title {
|
||||
z-index: 100;
|
||||
text-align: right;
|
||||
padding-right: 5px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.note {
|
||||
@ -332,10 +338,16 @@ div.container {
|
||||
/**
|
||||
* Tabs
|
||||
*/
|
||||
#main-tabs {
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
#main-tabs a {
|
||||
background-color: #d3d7cf;
|
||||
-moz-border-radius: 3px 3px 0 0;
|
||||
-webkit-border-radius: 3px 3px 0 0;
|
||||
-webkit-border-radius: 3px;
|
||||
-webkit-border-bottom-left-radius: 0;
|
||||
-webkit-border-bottom-right-radius: 0;
|
||||
padding: 4px 4px 0 4px;
|
||||
text-decoration: none;
|
||||
color: #2e3436;
|
||||
@ -349,7 +361,8 @@ div.container {
|
||||
#sub-tabs {
|
||||
background-color: #a5e26a;
|
||||
-moz-border-radius: 0 3px 3px 3px;
|
||||
-webkit-border-radius: 0 3px 3px 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
-webkit-border-top-left-radius: 0;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
@ -616,13 +629,17 @@ div.download-file {
|
||||
background-repeat: no-repeat;
|
||||
background-position: 1em 1em;
|
||||
font-size: 140%;
|
||||
margin-bottom: 3em;
|
||||
margin-bottom: 1.5em;
|
||||
background-color: #bbe394;
|
||||
width: 40%;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
}
|
||||
|
||||
table.download {
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wiki
|
||||
*/
|
||||
@ -678,7 +695,9 @@ div.deprecated-page {
|
||||
padding-left: 0px;
|
||||
background-color: #eeeeec;
|
||||
-moz-border-radius: 3px 0 0 3px;
|
||||
-webkit-border-radius: 3px 0 0 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
-webkit-border-top-right-radius: 0;
|
||||
-webkit-border-bottom-right-radius: 0;
|
||||
color: #888a85;
|
||||
clear: both;
|
||||
background-image: url("../img/ceondo.png");
|
||||
|
BIN
www/media/idf/img/lock.png
Normal file
BIN
www/media/idf/img/lock.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 430 B |
Loading…
Reference in New Issue
Block a user