Continued the SCM backend refactor.
The new backend is near completion.
This commit is contained in:
parent
aab8720cac
commit
7c502b1745
@ -358,7 +358,7 @@ class IDF_Project extends Pluf_Model
|
|||||||
$conf = $this->getConf();
|
$conf = $this->getConf();
|
||||||
$scm = $conf->getVal('scm', 'git');
|
$scm = $conf->getVal('scm', 'git');
|
||||||
$scms = Pluf::f('allowed_scm');
|
$scms = Pluf::f('allowed_scm');
|
||||||
return call_user_func(array($scms[$scm], 'getRemoteAccessUrl'),
|
return call_user_func(array($scms[$scm], 'getAnonymousAccessUrl'),
|
||||||
$this);
|
$this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,13 +369,13 @@ class IDF_Project extends Pluf_Model
|
|||||||
* same as the one to read. For example, you do a checkout with
|
* same as the one to read. For example, you do a checkout with
|
||||||
* git-daemon and push with SSH.
|
* git-daemon and push with SSH.
|
||||||
*/
|
*/
|
||||||
public function getWriteRemoteAccessUrl()
|
public function getWriteRemoteAccessUrl($user)
|
||||||
{
|
{
|
||||||
$conf = $this->getConf();
|
$conf = $this->getConf();
|
||||||
$scm = $conf->getVal('scm', 'git');
|
$scm = $conf->getVal('scm', 'git');
|
||||||
$scms = Pluf::f('allowed_scm');
|
$scms = Pluf::f('allowed_scm');
|
||||||
return call_user_func(array($scms[$scm], 'getWriteRemoteAccessUrl'),
|
return call_user_func(array($scms[$scm], 'getAuthAccessUrl'),
|
||||||
$this);
|
$this, $user);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
157
src/IDF/Scm.php
157
src/IDF/Scm.php
@ -37,7 +37,9 @@
|
|||||||
*
|
*
|
||||||
* Note on caching: You must not cache ephemeral information like the
|
* Note on caching: You must not cache ephemeral information like the
|
||||||
* changelog, but you can cache the commit info (except with
|
* changelog, but you can cache the commit info (except with
|
||||||
* subversion where you can change commit info...).
|
* 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
|
* 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
|
* if you are parsing XML you need to correctly cast the results as
|
||||||
@ -84,7 +86,7 @@ class IDF_Scm
|
|||||||
* @param IDF_Project
|
* @param IDF_Project
|
||||||
* @return Object
|
* @return Object
|
||||||
*/
|
*/
|
||||||
public static function get($project=null)
|
public static function get($project)
|
||||||
{
|
{
|
||||||
// Get scm type from project conf ; defaults to git
|
// Get scm type from project conf ; defaults to git
|
||||||
// We will need to cache the factory
|
// We will need to cache the factory
|
||||||
@ -93,6 +95,29 @@ class IDF_Scm
|
|||||||
return call_user_func(array($scms[$scm], 'factory'), $project);
|
return call_user_func(array($scms[$scm], 'factory'), $project);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the URL of the git daemon.
|
||||||
|
*
|
||||||
|
* @param IDF_Project
|
||||||
|
* @return string URL
|
||||||
|
*/
|
||||||
|
public static function getAnonymousAccessUrl($project)
|
||||||
|
{
|
||||||
|
throw new Pluf_Exception_NotImplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* Check if the backend is available for display.
|
||||||
*
|
*
|
||||||
@ -103,10 +128,58 @@ class IDF_Scm
|
|||||||
throw new Pluf_Exception_NotImplemented();
|
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.
|
* Returns the list of branches.
|
||||||
*
|
*
|
||||||
* @return array For example array('trunk', '1.0branch')
|
* 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()
|
public function getBranches()
|
||||||
{
|
{
|
||||||
@ -116,7 +189,11 @@ class IDF_Scm
|
|||||||
/**
|
/**
|
||||||
* Returns the list of tags.
|
* Returns the list of tags.
|
||||||
*
|
*
|
||||||
* @return array For example array('v0.9', 'v1.0')
|
* The format is the same as for the branches.
|
||||||
|
*
|
||||||
|
* @see self::getBranches()
|
||||||
|
*
|
||||||
|
* @return array Tags
|
||||||
*/
|
*/
|
||||||
public function getTags()
|
public function getTags()
|
||||||
{
|
{
|
||||||
@ -201,67 +278,59 @@ class IDF_Scm
|
|||||||
/**
|
/**
|
||||||
* Given a revision and a file path, retrieve the file content.
|
* Given a revision and a file path, retrieve the file content.
|
||||||
*
|
*
|
||||||
* The third parameter is to only request the command that is used
|
* The $cmd_only parameter is to only request the command that is
|
||||||
* to get the file content. This is used when downloading a file
|
* used to get the file content. This is used when downloading a
|
||||||
* at a given revision as it can be passed to a
|
* file at a given revision as it can be passed to a
|
||||||
* Pluf_HTTP_Response_CommandPassThru reponse. This allows to
|
* Pluf_HTTP_Response_CommandPassThru reponse. This allows to
|
||||||
* stream a large response without buffering it in memory.
|
* stream a large response without buffering it in memory.
|
||||||
*
|
*
|
||||||
* The file definition can be a hash or a path depending on the
|
* The file definition is coming from getPathInfo().
|
||||||
* SCM.
|
|
||||||
*
|
*
|
||||||
* @param string File definition
|
* @see self::getPathInfo()
|
||||||
* @param string Revision ('')
|
*
|
||||||
|
* @param stdClass File definition
|
||||||
* @param bool Returns command only (false)
|
* @param bool Returns command only (false)
|
||||||
* @return string File content
|
* @return string File content
|
||||||
*/
|
*/
|
||||||
public function getFile($def, $rev='', $cmd_only=false)
|
public function getFile($def, $cmd_only=false)
|
||||||
{
|
{
|
||||||
throw new Pluf_Exception_NotImplemented();
|
throw new Pluf_Exception_NotImplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Equivalent to exec but with caching.
|
* Get information about a file or a path.
|
||||||
*
|
*
|
||||||
* @param string Command
|
* @param string File or path
|
||||||
* @param &array Output
|
* @param string Revision (null)
|
||||||
* @param &int Return value
|
* @return mixed False or stdClass with info
|
||||||
* @return string Last line of the output
|
|
||||||
*/
|
*/
|
||||||
public static function exec($command, &$output=array(), &$return=0)
|
public function getPathInfo($file, $rev=null)
|
||||||
{
|
{
|
||||||
$command = Pluf::f('idf_exec_cmd_prefix', '').$command;
|
throw new Pluf_Exception_NotImplemented();
|
||||||
$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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Equivalent to shell_exec but with caching.
|
* Given a revision and possible path returns additional properties.
|
||||||
*
|
*
|
||||||
* @param string Command
|
* @param string Revision
|
||||||
* @return string Output of the command
|
* @param string Path ('')
|
||||||
|
* @return mixed null or array of properties
|
||||||
*/
|
*/
|
||||||
public static function shell_exec($command)
|
public function getProperties($rev, $path='')
|
||||||
{
|
{
|
||||||
$command = Pluf::f('idf_exec_cmd_prefix', '').$command;
|
return null;
|
||||||
$key = md5($command);
|
}
|
||||||
$cache = Pluf_Cache::factory();
|
|
||||||
if (null === ($res=$cache->get($key))) {
|
/**
|
||||||
$res = shell_exec($command);
|
* Generate the command to create a zip archive at a given commit.
|
||||||
$cache->set($key, $res);
|
*
|
||||||
}
|
* @param string Commit
|
||||||
return $res;
|
* @param string Prefix ('repository/')
|
||||||
|
* @return string Command
|
||||||
|
*/
|
||||||
|
public function getArchiveCommand($commit, $prefix='repository/')
|
||||||
|
{
|
||||||
|
throw new Pluf_Exception_NotImplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,7 +61,7 @@ class IDF_Scm_Git extends IDF_Scm
|
|||||||
}
|
}
|
||||||
$res = array();
|
$res = array();
|
||||||
foreach ($out as $b) {
|
foreach ($out as $b) {
|
||||||
$res[] = substr($b, 2);
|
$res[substr($b, 2)] = '';
|
||||||
}
|
}
|
||||||
$this->cache['branches'] = $res;
|
$this->cache['branches'] = $res;
|
||||||
return $res;
|
return $res;
|
||||||
@ -69,9 +69,29 @@ class IDF_Scm_Git extends IDF_Scm
|
|||||||
|
|
||||||
public function getMainBranch()
|
public function getMainBranch()
|
||||||
{
|
{
|
||||||
return 'master';
|
$possible = array('master', 'main', 'trunk', 'local');
|
||||||
|
$branches = array_keys($this->getBranches());
|
||||||
|
foreach ($possible as $p) {
|
||||||
|
if (in_array($p, $branches)) {
|
||||||
|
return $p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $branches[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* Git "tree" is not the same as the tree we get here.
|
||||||
*
|
*
|
||||||
@ -152,25 +172,12 @@ class IDF_Scm_Git extends IDF_Scm
|
|||||||
return ($users->count() > 0) ? $users[0] : null;
|
return ($users->count() > 0) ? $users[0] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getAnonymousAccessUrl($project)
|
||||||
/**
|
|
||||||
* Returns the URL of the git daemon.
|
|
||||||
*
|
|
||||||
* @param IDF_Project
|
|
||||||
* @return string URL
|
|
||||||
*/
|
|
||||||
public static function getRemoteAccessUrl($project)
|
|
||||||
{
|
{
|
||||||
return sprintf(Pluf::f('git_remote_url'), $project->shortname);
|
return sprintf(Pluf::f('git_remote_url'), $project->shortname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function getAuthAccessUrl($project, $user)
|
||||||
* Returns the URL for SSH access
|
|
||||||
*
|
|
||||||
* @param IDF_Project
|
|
||||||
* @return string URL
|
|
||||||
*/
|
|
||||||
public static function getWriteRemoteAccessUrl($project)
|
|
||||||
{
|
{
|
||||||
return sprintf(Pluf::f('git_write_remote_url'), $project->shortname);
|
return sprintf(Pluf::f('git_write_remote_url'), $project->shortname);
|
||||||
}
|
}
|
||||||
@ -187,20 +194,25 @@ class IDF_Scm_Git extends IDF_Scm
|
|||||||
return new IDF_Scm_Git($rep, $project);
|
return new IDF_Scm_Git($rep, $project);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function isValidRevision($commit)
|
||||||
|
{
|
||||||
|
return ('commit' == $this->testHash($commit));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test a given object hash.
|
* Test a given object hash.
|
||||||
*
|
*
|
||||||
* @param string Object hash.
|
* @param string Object hash.
|
||||||
* @param null to be svn client compatible
|
|
||||||
* @return mixed false if not valid or 'blob', 'tree', 'commit'
|
* @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',
|
$cmd = sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' cat-file -t %s',
|
||||||
escapeshellarg($this->repo),
|
escapeshellarg($this->repo),
|
||||||
escapeshellarg($hash));
|
escapeshellarg($hash));
|
||||||
$ret = 0; $out = array();
|
$ret = 0; $out = array();
|
||||||
IDF_Scm::exec($cmd, $out, $ret);
|
exec($cmd, $out, $ret);
|
||||||
if ($ret != 0) return false;
|
if ($ret != 0) return false;
|
||||||
return trim($out[0]);
|
return trim($out[0]);
|
||||||
}
|
}
|
||||||
@ -257,14 +269,14 @@ class IDF_Scm_Git extends IDF_Scm
|
|||||||
* @param string Commit ('HEAD')
|
* @param string Commit ('HEAD')
|
||||||
* @return false Information
|
* @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_tmpl = 'GIT_DIR=%s '.Pluf::f('git_path', 'git').' ls-tree -r -t -l %s';
|
||||||
$cmd = sprintf($cmd_tmpl,
|
$cmd = sprintf($cmd_tmpl,
|
||||||
escapeshellarg($this->repo),
|
escapeshellarg($this->repo),
|
||||||
escapeshellarg($commit));
|
escapeshellarg($commit));
|
||||||
$out = array();
|
$out = array();
|
||||||
IDF_Scm::exec($cmd, $out);
|
exec($cmd, $out);
|
||||||
foreach ($out as $line) {
|
foreach ($out as $line) {
|
||||||
list($perm, $type, $hash, $size, $file) = preg_split('/ |\t/', $line, 5, PREG_SPLIT_NO_EMPTY);
|
list($perm, $type, $hash, $size, $file) = preg_split('/ |\t/', $line, 5, PREG_SPLIT_NO_EMPTY);
|
||||||
if ($totest == $file) {
|
if ($totest == $file) {
|
||||||
@ -276,19 +288,13 @@ class IDF_Scm_Git extends IDF_Scm
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getFile($def, $cmd_only=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)
|
|
||||||
{
|
{
|
||||||
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',
|
'GIT_DIR=%s '.Pluf::f('git_path', 'git').' cat-file blob %s',
|
||||||
escapeshellarg($this->repo),
|
escapeshellarg($this->repo),
|
||||||
escapeshellarg($request_file_info->hash)));
|
escapeshellarg($def->hash));
|
||||||
|
return ($cmd_only) ? $cmd : shell_exec($cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -345,7 +351,7 @@ class IDF_Scm_Git extends IDF_Scm
|
|||||||
"'commit %H%n'",
|
"'commit %H%n'",
|
||||||
escapeshellarg($commit));
|
escapeshellarg($commit));
|
||||||
$out = array();
|
$out = array();
|
||||||
IDF_Scm::exec($cmd, $out);
|
exec($cmd, $out);
|
||||||
$affected = count($out) - 2;
|
$affected = count($out) - 2;
|
||||||
$added = 0;
|
$added = 0;
|
||||||
$removed = 0;
|
$removed = 0;
|
||||||
@ -377,7 +383,7 @@ class IDF_Scm_Git extends IDF_Scm
|
|||||||
escapeshellarg($this->repo), $n, $this->mediumtree_fmt,
|
escapeshellarg($this->repo), $n, $this->mediumtree_fmt,
|
||||||
escapeshellarg($commit));
|
escapeshellarg($commit));
|
||||||
$out = array();
|
$out = array();
|
||||||
IDF_Scm::exec($cmd, $out);
|
exec($cmd, $out);
|
||||||
return self::parseLog($out, 4);
|
return self::parseLog($out, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,14 +442,7 @@ class IDF_Scm_Git extends IDF_Scm
|
|||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getArchiveCommand($commit, $prefix='repository/')
|
||||||
* 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/')
|
|
||||||
{
|
{
|
||||||
return sprintf(Pluf::f('idf_exec_cmd_prefix', '').
|
return sprintf(Pluf::f('idf_exec_cmd_prefix', '').
|
||||||
'GIT_DIR=%s '.Pluf::f('git_path', 'git').' archive --format=zip --prefix=%s %s',
|
'GIT_DIR=%s '.Pluf::f('git_path', 'git').' archive --format=zip --prefix=%s %s',
|
||||||
@ -471,11 +470,11 @@ class IDF_Scm_Git extends IDF_Scm
|
|||||||
{
|
{
|
||||||
$file->type = 'extern';
|
$file->type = 'extern';
|
||||||
$file->extern = '';
|
$file->extern = '';
|
||||||
$info = $this->getFileInfo('.gitmodules', $commit);
|
$info = $this->getPathInfo('.gitmodules', $commit);
|
||||||
if ($info == false) {
|
if ($info == false) {
|
||||||
return $file;
|
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)) {
|
if (preg_match('#\[submodule\s+\"'.$file->fullpath.'\"\]\s+path\s=\s(\S+)\s+url\s=\s(\S+)#mi', $gitmodules, $matches)) {
|
||||||
$file->extern = $matches[2];
|
$file->extern = $matches[2];
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ class IDF_Views_Source
|
|||||||
$scm = IDF_Scm::get($request->project);
|
$scm = IDF_Scm::get($request->project);
|
||||||
$branches = $scm->getBranches();
|
$branches = $scm->getBranches();
|
||||||
$commit = $match[2];
|
$commit = $match[2];
|
||||||
if ('commit' != $scm->testHash($commit)) {
|
if (!$scm->isValidRevision($commit)) {
|
||||||
if (count($branches) == 0) {
|
if (count($branches) == 0) {
|
||||||
// Redirect to the project source help
|
// Redirect to the project source help
|
||||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::help',
|
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::help',
|
||||||
@ -119,6 +119,7 @@ class IDF_Views_Source
|
|||||||
return new Pluf_HTTP_Response_Redirect($url);
|
return new Pluf_HTTP_Response_Redirect($url);
|
||||||
}
|
}
|
||||||
$branches = $scm->getBranches();
|
$branches = $scm->getBranches();
|
||||||
|
$in_branches = $scm->inBranches($commit, '');
|
||||||
$cache = Pluf_Cache::factory();
|
$cache = Pluf_Cache::factory();
|
||||||
$key = sprintf('Project:%s::IDF_Views_Source::treeBase:%s::',
|
$key = sprintf('Project:%s::IDF_Views_Source::treeBase:%s::',
|
||||||
$request->project->id, $commit);
|
$request->project->id, $commit);
|
||||||
@ -126,13 +127,9 @@ class IDF_Views_Source
|
|||||||
$res = new Pluf_Template_ContextVars($scm->getTree($commit));
|
$res = new Pluf_Template_ContextVars($scm->getTree($commit));
|
||||||
$cache->set($key, $res);
|
$cache->set($key, $res);
|
||||||
}
|
}
|
||||||
|
//$tree_in = in_array($commit, $branches);
|
||||||
$tree_in = in_array($commit, $branches);
|
|
||||||
$scmConf = $request->conf->getVal('scm', 'git');
|
$scmConf = $request->conf->getVal('scm', 'git');
|
||||||
$props = null;
|
$props = $scm->getProperties($commit);
|
||||||
if ($scmConf === 'svn') {
|
|
||||||
$props = $scm->getProperties($commit);
|
|
||||||
}
|
|
||||||
return Pluf_Shortcuts_RenderToResponse('idf/source/'.$scmConf.'/tree.html',
|
return Pluf_Shortcuts_RenderToResponse('idf/source/'.$scmConf.'/tree.html',
|
||||||
array(
|
array(
|
||||||
'page_title' => $title,
|
'page_title' => $title,
|
||||||
@ -140,7 +137,7 @@ class IDF_Views_Source
|
|||||||
'files' => $res,
|
'files' => $res,
|
||||||
'cobject' => $cobject,
|
'cobject' => $cobject,
|
||||||
'commit' => $commit,
|
'commit' => $commit,
|
||||||
'tree_in' => $tree_in,
|
'tree_in' => $in_branches,
|
||||||
'branches' => $branches,
|
'branches' => $branches,
|
||||||
'props' => $props,
|
'props' => $props,
|
||||||
),
|
),
|
||||||
@ -174,12 +171,12 @@ class IDF_Views_Source
|
|||||||
return new Pluf_HTTP_Response_Redirect($url, 301);
|
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
|
// Redirect to the first branch
|
||||||
return new Pluf_HTTP_Response_Redirect($fburl);
|
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) {
|
if (!$request_file_info) {
|
||||||
// Redirect to the first branch
|
// Redirect to the first branch
|
||||||
return new Pluf_HTTP_Response_Redirect($fburl);
|
return new Pluf_HTTP_Response_Redirect($fburl);
|
||||||
@ -190,7 +187,7 @@ class IDF_Views_Source
|
|||||||
$commit, $scm);
|
$commit, $scm);
|
||||||
if (!self::isText($info)) {
|
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]);
|
$info[0]);
|
||||||
$rep->headers['Content-Disposition'] = 'attachment; filename="'.$info[1].'"';
|
$rep->headers['Content-Disposition'] = 'attachment; filename="'.$info[1].'"';
|
||||||
return $rep;
|
return $rep;
|
||||||
@ -210,7 +207,7 @@ class IDF_Views_Source
|
|||||||
|
|
||||||
$page_title = $bc.' - '.$title;
|
$page_title = $bc.' - '.$title;
|
||||||
$cobject = $scm->getCommit($commit);
|
$cobject = $scm->getCommit($commit);
|
||||||
$tree_in = in_array($commit, $branches);
|
$in_branches = $scm->inBranches($commit, $request_file);
|
||||||
try {
|
try {
|
||||||
$cache = Pluf_Cache::factory();
|
$cache = Pluf_Cache::factory();
|
||||||
$key = sprintf('Project:%s::IDF_Views_Source::tree:%s::%s',
|
$key = sprintf('Project:%s::IDF_Views_Source::tree:%s::%s',
|
||||||
@ -243,7 +240,7 @@ class IDF_Views_Source
|
|||||||
'cobject' => $cobject,
|
'cobject' => $cobject,
|
||||||
'base' => $request_file_info->file,
|
'base' => $request_file_info->file,
|
||||||
'prev' => $previous,
|
'prev' => $previous,
|
||||||
'tree_in' => $tree_in,
|
'tree_in' => $in_branches,
|
||||||
'branches' => $branches,
|
'branches' => $branches,
|
||||||
'props' => $props,
|
'props' => $props,
|
||||||
),
|
),
|
||||||
@ -273,7 +270,7 @@ class IDF_Views_Source
|
|||||||
$scm = IDF_Scm::get($request->project);
|
$scm = IDF_Scm::get($request->project);
|
||||||
$commit = $match[2];
|
$commit = $match[2];
|
||||||
$branches = $scm->getBranches();
|
$branches = $scm->getBranches();
|
||||||
if ('commit' != $scm->testHash($commit)) {
|
if (!$scm->isValidRevision($commit)) {
|
||||||
// Redirect to the first branch
|
// Redirect to the first branch
|
||||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
||||||
array($request->project->shortname,
|
array($request->project->shortname,
|
||||||
@ -309,7 +306,7 @@ class IDF_Views_Source
|
|||||||
$scm = IDF_Scm::get($request->project);
|
$scm = IDF_Scm::get($request->project);
|
||||||
$commit = $match[2];
|
$commit = $match[2];
|
||||||
$branches = $scm->getBranches();
|
$branches = $scm->getBranches();
|
||||||
if ('commit' != $scm->testHash($commit)) {
|
if (!$scm->isValidRevision($commit)) {
|
||||||
// Redirect to the first branch
|
// Redirect to the first branch
|
||||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
||||||
array($request->project->shortname,
|
array($request->project->shortname,
|
||||||
@ -347,7 +344,7 @@ class IDF_Views_Source
|
|||||||
if ($scmConf === 'svn') {
|
if ($scmConf === 'svn') {
|
||||||
$props = $scm->getProperties($commit, $request_file);
|
$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',
|
return Pluf_Shortcuts_RenderToResponse('idf/source/'.$scmConf.'/file.html',
|
||||||
array(
|
array(
|
||||||
'page_title' => $page_title,
|
'page_title' => $page_title,
|
||||||
@ -377,14 +374,14 @@ class IDF_Views_Source
|
|||||||
$branches = $scm->getBranches();
|
$branches = $scm->getBranches();
|
||||||
$commit = $match[2];
|
$commit = $match[2];
|
||||||
$request_file = $match[3];
|
$request_file = $match[3];
|
||||||
if ('commit' != $scm->testHash($commit, $request_file)) {
|
if (!$scm->isValidRevision($commit)) {
|
||||||
// Redirect to the first branch
|
// Redirect to the first branch
|
||||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
||||||
array($request->project->shortname,
|
array($request->project->shortname,
|
||||||
$branches[0]));
|
$branches[0]));
|
||||||
return new Pluf_HTTP_Response_Redirect($url);
|
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') {
|
if (!$request_file_info or $request_file_info->type == 'tree') {
|
||||||
// Redirect to the first branch
|
// Redirect to the first branch
|
||||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
||||||
@ -394,7 +391,7 @@ class IDF_Views_Source
|
|||||||
}
|
}
|
||||||
$info = self::getRequestedFileMimeType($request_file_info,
|
$info = self::getRequestedFileMimeType($request_file_info,
|
||||||
$commit, $scm);
|
$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]);
|
$info[0]);
|
||||||
$rep->headers['Content-Disposition'] = 'attachment; filename="'.$info[1].'"';
|
$rep->headers['Content-Disposition'] = 'attachment; filename="'.$info[1].'"';
|
||||||
return $rep;
|
return $rep;
|
||||||
@ -410,7 +407,7 @@ class IDF_Views_Source
|
|||||||
$commit = trim($match[2]);
|
$commit = trim($match[2]);
|
||||||
$scm = IDF_Scm::get($request->project);
|
$scm = IDF_Scm::get($request->project);
|
||||||
$branches = $scm->getBranches();
|
$branches = $scm->getBranches();
|
||||||
if ('commit' != $scm->testHash($commit)) {
|
if (!$scm->isValidRevision($commit)) {
|
||||||
// Redirect to the first branch
|
// Redirect to the first branch
|
||||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
||||||
array($request->project->shortname,
|
array($request->project->shortname,
|
||||||
@ -441,7 +438,7 @@ class IDF_Views_Source
|
|||||||
return $mime;
|
return $mime;
|
||||||
}
|
}
|
||||||
return self::getMimeTypeFromContent($file_info->file,
|
return self::getMimeTypeFromContent($file_info->file,
|
||||||
$scm->getBlob($file_info, $commit));
|
$scm->getFile($file_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -451,7 +448,7 @@ class IDF_Views_Source
|
|||||||
* @param string File content
|
* @param string File content
|
||||||
* @return array Mime type found or 'application/octet-stream', basename, extension
|
* @return array Mime type found or 'application/octet-stream', basename, extension
|
||||||
*/
|
*/
|
||||||
public static function getMimeTypeFromContent($file, $filedata)
|
public static function getMimeTypeFromContent($file, &$filedata)
|
||||||
{
|
{
|
||||||
$info = pathinfo($file);
|
$info = pathinfo($file);
|
||||||
$res = array('application/octet-stream',
|
$res = array('application/octet-stream',
|
||||||
|
@ -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_Key'] = array('relate_to' => array('Pluf_User'));
|
||||||
$m['IDF_Conf'] = array('relate_to' => array('IDF_Project'));
|
$m['IDF_Conf'] = array('relate_to' => array('IDF_Project'));
|
||||||
$m['IDF_Commit'] = array('relate_to' => array('IDF_Project', 'Pluf_User'));
|
$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',
|
Pluf_Signal::connect('Pluf_Template_Compiler::construct_template_tags_modifiers',
|
||||||
array('IDF_Middleware', 'updateTemplateTagsModifiers'));
|
array('IDF_Middleware', 'updateTemplateTagsModifiers'));
|
||||||
|
@ -8,7 +8,7 @@ code.{/blocktrans}</p>
|
|||||||
|
|
||||||
<h3>{trans 'Command-Line Access'}</h3>
|
<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 {if $project.private}{$project.getWriteRemoteAccessUrl($user)}{else}{$project.getRemoteAccessUrl()}{/if}</kbd></p>
|
||||||
|
|
||||||
{aurl 'url', 'IDF_Views_User::myAccount'}
|
{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>
|
<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 init
|
||||||
git add .
|
git add .
|
||||||
git commit -m "initial import"
|
git commit -m "initial import"
|
||||||
git remote add origin {$project.getWriteRemoteAccessUrl()}
|
git remote add origin {$project.getWriteRemoteAccessUrl($url)}
|
||||||
git push origin master
|
git push origin master
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
@ -47,15 +47,15 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{aurl 'url', 'IDF_Views_Source::download', array($project.shortname, $commit)}
|
{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 {if $project.private}{$project.getWriteRemoteAccessUrl($user)}{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>
|
||||||
|
|
||||||
|
|
||||||
{/block}
|
{/block}
|
||||||
{block context}
|
{block context}
|
||||||
<p><strong>{trans 'Branches:'}</strong><br />
|
<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)}
|
{aurl 'url', 'IDF_Views_Source::tree', 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}
|
{/foreach}
|
||||||
</p>
|
</p>
|
||||||
{/block}
|
{/block}
|
||||||
|
Loading…
Reference in New Issue
Block a user