Merge branch 'cyy_repo'

This commit is contained in:
liyuchun
2022-07-27 00:32:59 +00:00
25 changed files with 428 additions and 483 deletions
+5 -1
View File
@@ -2,6 +2,10 @@ ALTER TABLE `zt_mr` CHANGE COLUMN `gitlabID` `hostID` mediumint(8) UNSIGNED NOT
ALTER TABLE `zt_mr` MODIFY COLUMN `sourceProject` varchar(50) NOT NULL AFTER `hostID`;
ALTER TABLE `zt_mr` MODIFY COLUMN `targetProject` varchar(50) NOT NULL AFTER `sourceBranch`;
UPDATE `zt_project` SET `status`='closed' WHERE `type` IN ('sprint', 'stage', 'kanban') AND `model`='' AND `status` = 'done';
ALTER TABLE `zt_repo` ADD COLUMN `serviceHost` varchar(50) NOT NULL AFTER `client`;
ALTER TABLE `zt_repo` ADD COLUMN `serviceProject` varchar(100) NOT NULL AFTER `serviceHost`;
UPDATE `zt_repo` SET `serviceHost` = `client`, `serviceProject` = `path` WHERE `SCM` = 'Gitlab';
UPDATE `zt_repo` SET `client` = '', `path` = '' WHERE `SCM` = 'Gitlab';
UPDATE `zt_workflowfield` SET `options`='user' WHERE `buildin`='1' AND `options`='8';
INSERT IGNORE INTO `zt_workflowfield` (`module`, `field`, `type`, `length`, `name`, `control`, `expression`, `options`, `default`, `rules`, `placeholder`, `order`, `searchOrder`, `exportOrder`, `canExport`, `canSearch`, `isValue`, `readonly`, `buildin`, `desc`, `createdBy`, `createdDate`, `editedBy`, `editedDate`) VALUES
@@ -9,4 +13,4 @@ INSERT IGNORE INTO `zt_workflowfield` (`module`, `field`, `type`, `length`, `nam
('testcase', 'execution', 'mediumint', '8', '所属执行', 'select', '', '44', '0', '', '', 4, 0, 0, '0', '1', '0', '1', 1, '', '', '2022-03-18 09:16:38', '', '0000-00-00 00:00:00'),
('task', 'execution', 'mediumint', '8', '所属执行', 'select', '', '44', '0', '', '', 4, 0, 0, '0', '1', '0', '1', 1, '', '', '2022-03-18 09:16:38', '', '0000-00-00 00:00:00'),
('bug', 'execution', 'mediumint', '8', '所属执行', 'select', '', '44', '0', '', '', 6, 0, 0, '0', '1', '0', '1', 1, '', '', '2022-03-18 09:16:38', '', '0000-00-00 00:00:00'),
('build', 'execution', 'mediumint', '8', '所属执行', 'select', '', '44', '0', '', '', 5, 0, 0, '0', '1', '0', '1', 1, '', '', '2022-03-18 09:16:38', '', '0000-00-00 00:00:00');
('build', 'execution', 'mediumint', '8', '所属执行', 'select', '', '44', '0', '', '', 5, 0, 0, '0', '1', '0', '1', 1, '', '', '2022-03-18 09:16:38', '', '0000-00-00 00:00:00');
+2
View File
@@ -1257,6 +1257,8 @@ CREATE TABLE IF NOT EXISTS `zt_repo` (
`encoding` varchar(20) NOT NULL,
`SCM` varchar(10) NOT NULL,
`client` varchar(100) NOT NULL,
`serviceHost` varchar(50) NOT NULL,
`serviceProject` varchar(100) NOT NULL,
`commits` mediumint(8) unsigned NOT NULL,
`account` varchar(30) NOT NULL,
`password` varchar(30) NOT NULL,
+290 -430
View File
@@ -1,27 +1,30 @@
<?php
class gitea
class Gitea
{
public $client;
public $projectID;
private $pageLimit = 50;
public $client;
public $root;
/**
* Construct
*
* @param string $client gitea api url.
* @param string $root id of gitea project.
* @param string $username null
* @param string $password token of gitea api.
* @param string $encoding
* @param string $client
* @param string $root
* @param string $username
* @param string $password
* @param string $encoding
* @access public
* @return void
*/
public function __construct($client, $root, $username, $password, $encoding = 'UTF-8')
{
putenv('LC_CTYPE=en_US.UTF-8');
$this->client = $client;
$this->root = rtrim($root, '/') . '/';
$this->token = $password;
$this->branch = isset($_COOKIE['repoBranch']) ? $_COOKIE['repoBranch'] : 'HEAD';
$this->root = rtrim($root, DIRECTORY_SEPARATOR);
$this->branch = isset($_COOKIE['repoBranch']) ? 'origin/' . $_COOKIE['repoBranch'] : '';
chdir($this->root);
exec("{$this->client} config core.quotepath false");
}
/**
@@ -35,50 +38,48 @@ class gitea
public function ls($path, $revision = 'HEAD')
{
if(!scm::checkRevision($revision)) return array();
$api = "contents";
$path = ltrim($path, '/');
if($path) $api .= "/$path";
$param = new stdclass();
$param->ref = $revision;
$param->recursive = 0;
if(!empty($this->branch)) $param->ref = $this->branch;
$path = ltrim($path, DIRECTORY_SEPARATOR);
$sub = '';
chdir($this->root);
if(!empty($path)) $sub = ":$path";
if(!empty($this->branch))$revision = $this->branch;
$cmd = escapeCmd("$this->client ls-tree -l $revision$sub");
$list = execCmd($cmd . ' 2>&1', 'array', $result);
if($result) return array();
$list = $this->fetch($api, $param, true);
if(empty($list)) return array();
$infos = array();
foreach($list as $file)
$infos = array();
foreach($list as $entry)
{
if(!isset($file->type)) continue;
list($mod, $kind, $revision, $size, $name) = preg_split('/[\t ]+/', $entry);
$info = new stdClass();
$info->name = $file->name;
$info->kind = $file->type;
/* Get commit info. */
$pathName = ltrim($path . DIRECTORY_SEPARATOR . $name, DIRECTORY_SEPARATOR);
$cmd = escapeCmd("$this->client log -1 $this->branch -- $pathName");
$commit = execCmd($cmd, 'array');
$logs = $this->parseLog($commit);
if($file->type == 'file')
if($size > 1024 * 1024)
{
$file = $this->files($file->path, $this->branch);
$info->revision = zget($file, 'revision', '');
$info->comment = zget($file, 'comment', '');
$info->account = zget($file, 'committer', '');
$info->date = zget($file, 'date', '');
$info->size = zget($file, 'size', '');
$size = round($size / (1024 * 1024), 2) . 'MB';
}
else if($size > 1024)
{
$size = round($size / 1024, 2) . 'KB';
}
else
{
$commits = $this->getCommitsByPath($file->path, '', '', 1, 1);
if(empty($commits) or !is_array($commits)) continue;
$commit = $commits[0];
$info->revision = $commit->sha;
$info->comment = $commit->commit->message;
$info->account = $commit->commit->author->name;
$info->date = date('Y-m-d H:i:s', strtotime($commit->commit->author->date));
$info->size = 0;
$size .= 'Bytes';
}
$info = new stdClass();
$info->name = $name;
$info->kind = $kind == 'tree' ? 'dir' : 'file';
$info->revision = $logs ? $logs[0]->revision : $revision;
$info->size = $size;
$info->account = $logs ? $logs[0]->committer : '';
$info->date = $logs ? $logs[0]->time : '';
$info->comment = $logs ? $logs[0]->comment : '';
$infos[] = $info;
unset($info);
}
@@ -86,45 +87,10 @@ class gitea
/* Sort by kind */
foreach($infos as $key => $info) $kinds[$key] = $info->kind;
if($infos) array_multisort($kinds, SORT_ASC, $infos);
return $infos;
}
/**
* Get files info.
*
* The API path requested is: "GET /projects/:id/repository/files/:file_path".
* Known issue of GitLab API: if a '%' in 'file_path', GitLab API will show a error 'file_path should be a valid file path'.
*
* @param string $path
* @param string $ref
* @access public
* @return object
* @doc https://docs.gitea.com/ee/api/repository_files.html
*/
public function files($path, $ref = 'master')
{
$path = urlencode($path);
$api = "contents/$path";
$file = $this->fetch($api, array('ref' => $ref));
if(!isset($file->name)) return false;
$commits = $this->getCommitsByPath($path, '', '', 1, 1);
$file->revision = $file->sha;
$file->size = $this->formatBytes($file->size);
if(!empty($commits))
{
$commit = $commits[0];
$file->revision = $commit->sha;
$file->committer = $commit->commit->author->name;
$file->comment = $commit->commit->message;
$file->date = date('Y-m-d H:i:s', strtotime($commit->commit->author->date));
}
return $file;
}
/**
* Get tags
*
@@ -135,69 +101,56 @@ class gitea
*/
public function tags($path, $revision = 'HEAD')
{
$api = "tags";
$tags = array();
if(!scm::checkRevision($revision)) return array();
$params = array();
$params['limit'] = $this->pageLimit;
for($page = 1; true; $page ++)
chdir($this->root);
$cmd = escapeCmd("$this->client tag --sort=taggerdate");
$list = execCmd($cmd . ' 2>&1', 'array', $result);
if($result) return array();
foreach($list as $key => $tag)
{
$params['page'] = $page;
$list = $this->fetch($api, $params);
if(empty($list) or $list == '[]') break;
foreach($list as $tag) $tags[] = $tag->name;
if(count($list) < $params['limit']) break;
if(!$tag) unset($list[$key]);
}
return $tags;
return $list;
}
/**
* Get branches.
* Get branch.
*
* @access public
* @return array
*/
public function branch()
{
/* Max size of limit in gitea API is 50. */
$params = array();
$params['limit'] = $this->pageLimit;
chdir($this->root);
/* Get local branch. */
$cmd = escapeCmd("$this->client branch -a");
$list = execCmd($cmd . ' 2>&1', 'array', $result);
if($result) return array();
/* Get default branch. */
$project = $this->fetch('');
$defaultBranch = $project->default_branch;
$defaultBranch = execCmd("$this->client symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'");
$defaultBranch = trim($defaultBranch);
$branches = array();
$default = array();
for($page = 1; true; $page ++)
foreach($list as $localBranch)
{
$params['page'] = $page;
$branchList = $this->fetch("branches", $params);
if(empty($branchList)) break;
$localBranch = trim($localBranch);
if(substr($localBranch, 0, 19) == 'remotes/origin/HEAD') continue;
if(substr($localBranch, 0, 1) == '*') $localBranch = substr($localBranch, 1);
if(substr($localBranch, 0, 15) == 'remotes/origin/') $localBranch = substr($localBranch, 15);
foreach($branchList as $branch)
{
if(!isset($branch->name)) continue;
if($branch->name == $defaultBranch)
{
$default[$branch->name] = $branch->name;
}
else
{
$branches[$branch->name] = $branch->name;
}
}
/* Last page. */
if(count($branchList) < $params['limit']) break;
$localBranch = trim($localBranch);
if(empty($localBranch))continue;
if($localBranch != $defaultBranch) $branches[$localBranch] = $localBranch;
}
if(empty($branches) and empty($default)) $branches['master'] = 'master';
asort($branches);
if($defaultBranch) $branches = array($defaultBranch => $defaultBranch) + $branches;
$branches = $default + $branches;
return $branches;
}
@@ -211,11 +164,18 @@ class gitea
*/
public function getLastLog($path, $count = 10)
{
return $this->log($path);
$path = ltrim($path, DIRECTORY_SEPARATOR);
$revision = $this->branch ? $this->branch : 'HEAD';
chdir($this->root);
$list = execCmd(escapeCmd("$this->client log -10 $revision -- $path"), 'array');
$logs = $this->parseLog($list);
return $logs;
}
/**
* Get logs.
* Get logs
*
* @param string $path
* @param string $fromRevision
@@ -231,13 +191,32 @@ class gitea
$path = ltrim($path, DIRECTORY_SEPARATOR);
$count = $count == 0 ? '' : "-n $count";
$list = $this->getCommitsByPath($path, $fromRevision, $toRevision, 1, 1);
foreach($list as $commit)
/* compatible with svn. */
if($fromRevision == 'HEAD' and $this->branch) $fromRevision = $this->branch;
if($toRevision == 'HEAD' and $this->branch) $toRevision = $this->branch;
if($fromRevision === $toRevision)
{
if(isset($commit->sha)) $commit->diffs = $this->getFilesByCommit($commit->sha);
$logs = array();
chdir($this->root);
$list = execCmd(escapeCmd("$this->client log --stat=1024 --name-status --stat-name-width=1000 -1 $fromRevision -- $path"), 'array');
$logs = $this->parseLog($list);
return $logs;
}
return $this->parseLog($list);
if(!$fromRevision)
{
$revisions = " $toRevision";
}
else
{
$revisions = "$fromRevision..$toRevision";
}
chdir($this->root);
$list = execCmd(escapeCmd("$this->client log --stat=1024 --name-status --stat-name-width=1000 $count $revisions -- $path"), 'array');
$logs = $this->parseLog($list);
return $logs;
}
/**
@@ -250,7 +229,46 @@ class gitea
*/
public function blame($path, $revision)
{
return array();
if(!scm::checkRevision($revision)) return array();
$path = ltrim($path, DIRECTORY_SEPARATOR);
chdir($this->root);
$list = execCmd(escapeCmd("$this->client blame -l $revision -- $path"), 'array');
$blames = array();
$revLine = 0;
$revision = '';
foreach($list as $line)
{
if(empty($line)) continue;
if($line[0] == '^') $line = substr($line, 1);
preg_match('/^([0-9a-f]{39,40})\s.*\((\S+)\s+([\d-]+)\s(.*)\s(\d+)\)(.*)$/U', $line, $matches);
if(isset($matches[1]) and $matches[1] != $revision)
{
$blame = array();
$blame['revision'] = $matches[1];
$blame['committer'] = $matches[2];
$blame['time'] = $matches[3];
$blame['line'] = $matches[5];
$blame['lines'] = 1;
$blame['content'] = strpos($matches[6], ' ') === false ? $matches[6] : substr($matches[6], 1);
$revision = $matches[1];
$revLine = $matches[5];
$blames[$revLine] = $blame;
}
elseif(isset($matches[5]))
{
$blame = array();
$blame['line'] = $matches[5];
$blame['content'] = strpos($matches[6], ' ') === false ? $matches[6] : substr($matches[6], 1);
$blames[$matches[5]] = $blame;
$blames[$revLine]['lines'] ++;
}
}
return $blames;
}
/**
@@ -259,19 +277,25 @@ class gitea
* @param string $path
* @param string $fromRevision
* @param string $toRevision
* @param string $fromProject
* @param string $extra
* @access public
* @return array
*/
public function diff($path, $fromRevision, $toRevision, $fromProject = '', $extra = '')
public function diff($path, $fromRevision, $toRevision, $extra = '')
{
if(!scm::checkRevision($fromRevision) and $extra != 'isBranchOrTag') return array();
if(!scm::checkRevision($toRevision) and $extra != 'isBranchOrTag') return array();
$diffApi = "{$this->root}git/commits/$toRevision.diff?token={$this->token}";
$diffs = commonModel::http($diffApi);
$lines = explode("\n", $diffs);
$path = ltrim($path, DIRECTORY_SEPARATOR);
chdir($this->root);
if($toRevision == 'HEAD' and $this->branch) $toRevision = $this->branch;
if($fromRevision == '^') $fromRevision = $toRevision . '^';
if(strpos($fromRevision, '^') !== false)
{
$list = execCmd(escapeCmd("$this->client log -2 $toRevision --pretty=format:%H -- $path"), 'array');
if(isset($list[1])) $fromRevision = $list[1];
}
$lines = execCmd(escapeCmd("$this->client diff $fromRevision $toRevision -- $path"), 'array');
return $lines;
}
@@ -286,9 +310,13 @@ class gitea
public function cat($entry, $revision = 'HEAD')
{
if(!scm::checkRevision($revision)) return false;
chdir($this->root);
if($revision == 'HEAD' and $this->branch) $revision = $this->branch;
$file = $this->files($entry, $revision);
return base64_decode($file->content);
$cmd = escapeCmd("$this->client show $revision:$entry");
$content = execCmd($cmd);
if(is_array($content)) $content = implode("\n", $content);
return $content;
}
/**
@@ -303,28 +331,33 @@ class gitea
{
if(!scm::checkRevision($revision)) return false;
$info = new stdclass();
$info->kind = 'dir';
$info->path = $entry;
$info->revision = $revision;
$info->root = '';
if($revision == 'HEAD' and $this->branch) $info->revision = $this->branch;
if($entry)
chdir($this->root);
if($revision == 'HEAD' and $this->branch) $revision = $this->branch;
$path = ltrim($entry, DIRECTORY_SEPARATOR);
$cmd = escapeCmd("$this->client ls-tree $revision -- $path");
$result = execCmd($cmd);
$kind = '';
if($result)
{
$parent = dirname($entry);
if($parent == '.') $parent = '/';
if($parent == '') $parent = '/';
$list = $this->tree($parent, 0);
$file = new stdclass();
foreach($list as $node) if($node->path == $entry) $file = $node;
$commits = $this->getCommitsByPath($entry, $revision, $revision);
if(!empty($commits)) $file->revision = zget($commits[0], 'sha', '');
$info->kind = (isset($file->type) and $file->type == 'tree') ? 'dir' : 'file';
$results = explode("\n", trim($result));
if(count($results) >= 2)
{
$kind = 'dir';
}
else
{
list($mode, $type) = explode(' ', $results[0]);
$kind = $type == 'tree' ? 'dir' : 'file';
}
}
$list = execCmd(escapeCmd("$this->client log -1 $revision --pretty=format:%H -- $path"), 'array');
$revision = $list[0];
$info = new stdclass();
$info->kind = $kind;
$info->path = $entry;
$info->revision = $revision;
$info->root = $this->root;
return $info;
}
@@ -333,11 +366,11 @@ class gitea
*
* @param string $cmd
* @access public
* @todo Exec commands by gitea api.
* @return array
*/
public function exec($cmd)
{
chdir($this->root);
return execCmd(escapeCmd("$this->client $cmd"), 'array');
}
@@ -489,280 +522,90 @@ class gitea
/**
* Get commits.
*
* @param string $version
* @param string $rversion
* @param int $count
* @param string $branch
* @access public
* @return array
*/
public function getCommits($version = '', $count = 0, $branch = '')
public function getCommits($revision = '', $count = 0, $branch = '')
{
if(!scm::checkRevision($version)) return array();
$api = "commits";
$commits = array();
$files = array();
if(!scm::checkRevision($revision)) return array();
if(empty($count)) $count = $this->pageLimit;
if($revision == 'HEAD' and $branch) $revision = $branch;
$revision = is_numeric($revision) ? "--skip=$revision $branch" : $revision;
$count = $count == 0 ? '' : "-n $count";
if(!empty($version) and $count == 1)
chdir($this->root);
if($branch)
{
$commits = $this->fetch($api, array('limit' => 1, 'sha' => $version));
$commit = $commits[0];
if(isset($commit->sha))
{
$log = new stdclass;
$log->committer = $commit->commit->author->name;
$log->revision = $commit->sha;
$log->comment = $commit->commit->message;
$log->time = date('Y-m-d H:i:s', strtotime($commit->commit->author->date));
$commits[$commit->sha] = $log;
$files[$commit->sha] = $this->getFilesByCommit($log->revision);
return array('commits' => $commits, 'files' => $files);
}
execCmd(escapeCmd("$this->client checkout $branch"));
execCmd(escapeCmd("$this->client pull"));
}
$params['sha'] = $branch;
if($version and $version != 'HEAD')
$list = execCmd(escapeCmd("$this->client log $count $revision -- ./"), 'array');
$commits = $this->parseLog($list);
$logs = array();
foreach($commits as $commit)
{
/* Get since param. */
if(substr($version, 0, 5) == 'since')
{
$since = true;
$version = substr($version, 5);
}
$hash = $commit->revision;
$log = new stdClass();
$log->committer = $commit->committer;
$log->revision = $commit->revision;
$log->comment = $commit->comment;
$log->time = $commit->time;
$logs['commits'][$hash] = $log;
$logs['files'][$hash] = array();
}
if(empty($logs)) return $logs;
$committedDate = $this->getCommittedDate($version);
if(!$committedDate) return array('commits' => array(), 'files' => array());
if(!empty($since))
$hash = '';
$files = execCmd(escapeCmd("$this->client whatchanged $count $revision --pretty=format:%an@_@%cd@_@%H@_@%s -- ./"), 'array');
foreach($files as $commit)
{
$commit = trim($commit);
if(empty($commit)) continue;
$parsedCommit = explode('@_@', $commit);
if(count($parsedCommit) == 4)
{
$params['since'] = $committedDate;
list($account, $date, $hash, $comment) = $parsedCommit;
}
else
{
$params['until'] = $committedDate;
$file = explode(' ', $commit);
$file = explode("\t", end($file));
if(!isset($file[1])) $file[1] = '';
list($action, $path) = $file;
$parsedFile = new stdclass();
$parsedFile->revision = $hash;
$parsedFile->path = '/' . trim($path);
$parsedFile->type = 'file';
$parsedFile->action = $action;
$logs['files'][$hash][] = $parsedFile;
}
}
$list = $this->fetch($api, $params);
foreach($list as $commit)
{
if(!isset($commit->commit) or !is_object($commit->commit)) continue;
$log = new stdclass;
$log->committer = $commit->commit->author->name;
$log->revision = $commit->sha;
$log->comment = $commit->commit->message;
$log->time = date('Y-m-d H:i:s', strtotime($commit->commit->author->date));
$commits[$commit->sha] = $log;
$files[$commit->sha] = $this->getFilesByCommit($log->revision);
}
return array('commits' => $commits, 'files' => $files);
return $logs;
}
/**
* getCommit
* Get clone url.
*
* @param int $sha
* @access public
* @return void
*/
public function getCommittedDate($sha)
{
if(!scm::checkRevision($sha)) return null;
if(!$sha or $sha == 'HEAD') return date('c');
global $dao;
$time = $dao->select('time')->from(TABLE_REPOHISTORY)->where('revision')->eq($sha)->fetch('time');
if($time) return date('c', strtotime($time));
$params = array();
$params['sha'] = $sha;
$params['limit'] = 1;
$result = $this->fetch("commits", $params);
return (isset($resulti[0]->created)) ? date('Y-m-d H:i:s', strtotime($result->created)) : false;
}
/**
* Get commits by path.
*
* @param string $path
* @param string $fromRevision
* @param string $toRevision
* @param int $perPage
* @access public
* @return array
*/
public function getCommitsByPath($path, $fromRevision = '', $toRevision = '', $perPage = 0, $limit = 0)
{
$path = ltrim($path, DIRECTORY_SEPARATOR);
$api = "commits";
if(!$limit) $limit = $this->pageLimit;
$param = new stdclass();
$param->path = urldecode($path);
$param->limit = $limit;
$param->sha = ($toRevision != 'HEAD' and $toRevision) ? $toRevision : $this->branch;
if($perPage) $param->page = $perPage;
return $this->fetch($api, $param);
}
/**
* Get diff files by reviesion.
*
* @param int $reviesion
* @access public
* @return array
*/
public function getDiffFiles($revision)
{
$diffApi = "{$this->root}git/commits/$revision.patch?token={$this->token}";
$diffs = commonModel::http($diffApi);
$newFiles = array();
$delFiles = array();
if(!empty($diffs))
{
$diffs = explode("\n", $diffs);
foreach($diffs as $row)
{
preg_match('/^(\s)(create|delete)\smode\s\d+\s(.+)$/', $row, $matches);
if(count($matches) == 4 and !in_array($matches[3], $newFiles) and !in_array($matches[3], $delFiles))
{
if($matches[2] == 'create')
{
$newFiles[] = $matches[3];
}
elseif($matches[2] == 'delete')
{
$delFiles[] = $matches[3];
}
}
}
}
return array('newFiles' => $newFiles, 'delFiles' => $delFiles);
}
/**
* Get files by commit.
*
* @param string $commit
* @access public
* @return void
*/
public function getFilesByCommit($revision)
{
if(!scm::checkRevision($revision)) return array();
$api = "git/commits/$revision";
$results = $this->fetch($api);
if(empty($results)) return array();
$diffFiles = $this->getDiffFiles($revision);
$files = array();
foreach($results->files as $row)
{
$file = new stdclass();
$file->revision = $revision;
$file->type = 'file';
$file->path = '/' . $row->filename;
$file->action = 'M';
if(in_array($row->filename, $diffFiles['newFiles']))
{
$file->action = 'A';
}
elseif(in_array($row->filename, $diffFiles['delFiles']))
{
$file->action = 'D';
}
$files[] = $file;
}
return $files;
}
/**
* Repository/tree api.
*
* @param string $path
* @param bool $recursive
* @access public
* @return mixed
*/
public function tree($path, $recursive = 1)
{
$api = "contents";
$params = array();
$params['path'] = ltrim($path, '/');
$params['ref'] = $this->branch;
$params['recursive'] = (int) $recursive;
return $this->fetch($api, $params);
}
/**
* Fetch data from gitea api.
*
* @param string $api
* @access public
* @return mixed
*/
public function fetch($api, $params = array(), $needToLoop = false)
{
$params = (array) $params;
$params['token'] = $this->token;
$params['limit'] = isset($params['limit']) ? $params['limit'] : $this->pageLimit;
$api = ltrim($api, '/');
$api = $this->root . $api . '?' . http_build_query($params);
if($needToLoop)
{
$allResults = array();
for($page = 1; true; $page++)
{
$results = json_decode(commonModel::http($api . "&page={$page}"));
if(!is_array($results)) break;
if(!empty($results)) $allResults = array_merge($allResults, $results);
if(count($results) < $this->pageLimit) break;
}
return $allResults;
}
else
{
$response = commonModel::http($api);
if(!empty(commonModel::$requestErrors))
{
commonModel::$requestErrors = array();
return array();
}
return json_decode($response);
}
}
/**
* Format bytes shown.
*
* @param int $size
* @static
* @access public
* @return string
*/
public static function formatBytes($size)
public function getCloneUrl()
{
if($size < 1024) return $size . 'Bytes';
if(round($size / (1024 * 1024), 2) > 1) return round($size / (1024 * 1024), 2) . 'G';
if(round($size / 1024, 2) > 1) return round($size / 1024, 2) . 'M';
return round($size, 2) . 'KB';
$url = new stdclass();
$remote = execCmd(escapeCmd("$this->client remote -v"), 'array');
$pregHttp = '/http(s)?:\/\/(www\.)?[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+(:\d+)*(\/\w+)*\.git/';
$pregSSH = '/ssh:\/\/git@[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+(:\d+)*(\/\w+)*\.git/';
if(preg_match($pregHttp, $remote[0], $matches)) $url->http = $matches[0];
if(preg_match($pregSSH, $remote[0], $matches)) $url->ssh = $matches[0];
return $url;
}
/**
@@ -776,39 +619,56 @@ class gitea
{
$parsedLogs = array();
$i = 0;
foreach($logs as $commit)
foreach($logs as $line)
{
if(!isset($commit->sha)) continue;
$parsedLog = new stdclass();
$parsedLog->revision = $commit->sha;
$parsedLog->committer = $commit->commit->author->name;
$parsedLog->time = date('Y-m-d H:i:s', strtotime($commit->commit->author->date));
$parsedLog->comment = $commit->commit->message;
$parsedLog->change = array();
foreach($commit->diffs as $diff)
if(strpos($line, 'commit ') === 0)
{
$parsedLog->change[$diff->path] = array();
$parsedLog->change[$diff->path]['action'] = $diff->action;
$parsedLog->change[$diff->path]['kind'] = $diff->type;
if(isset($log))
{
$log->comment = trim($comment);
$log->change = $changes;
$parsedLogs[$i] = $log;
$i++;
}
$log = new stdclass();
$comment = '';
$changes = array();
$log->revision = trim(preg_replace('/^commit/', '', $line));
}
$parsedLogs[] = $parsedLog;
elseif(strpos($line, 'Author:') === 0)
{
$account = preg_replace('/^Author:/', '', $line);
$log->committer = trim(preg_replace('/<[a-zA-Z0-9_\-\.]+@[a-zA-Z0-9_\-\.]+>/', '', $account));
}
elseif(strpos($line, 'Date:') === 0)
{
$date = trim(preg_replace('/^Date:/', '', $line));
$log->time = date('Y-m-d H:i:s', strtotime($date));
}
elseif(preg_match('/^\s{2,}/', $line))
{
$comment .= $line;
}
elseif(strpos($line, "\t") !== false)
{
list($action, $entry) = explode("\t", $line);
$entry = '/' . trim($entry);
$pathInfo = array();
$pathInfo['action'] = $action;
$pathInfo['kind'] = 'file';
$changes[$entry] = $pathInfo;
}
}
if(isset($log))
{
$log->comment = trim($comment);
$log->change = $changes;
$parsedLogs[$i] = $log;
}
return $parsedLogs;
}
/**
* Get download url.
*
* @param string $branch
* @param string $ext
* @access public
* @return string
*/
public function getDownloadUrl($branch = 'master', $ext = 'zip')
{
$params['token'] = $this->token;
return "{$this->root}archive/" . urlencode($branch) . ".{$ext}" . '?' . http_build_query($params);
}
}
+9 -3
View File
@@ -21,7 +21,7 @@ class GitRepo
$this->client = $client;
$this->root = rtrim($root, DIRECTORY_SEPARATOR);
$this->branch = isset($_COOKIE['repoBranch']) ? $_COOKIE['repoBranch'] : '';
$this->branch = isset($_COOKIE['repoBranch']) ? 'origin/' . $_COOKIE['repoBranch'] : '';
chdir($this->root);
exec("{$this->client} config core.quotepath false");
@@ -117,7 +117,7 @@ class GitRepo
}
/**
* Get branch
* Get branch.
*
* @access public
* @return array
@@ -127,17 +127,21 @@ class GitRepo
chdir($this->root);
/* Get local branch. */
$cmd = escapeCmd("$this->client branch");
$cmd = escapeCmd("$this->client branch -a");
$list = execCmd($cmd . ' 2>&1', 'array', $result);
if($result) return array();
/* Get default branch. */
$defaultBranch = execCmd("$this->client symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'");
$defaultBranch = trim($defaultBranch);
$branches = array();
foreach($list as $localBranch)
{
$localBranch = trim($localBranch);
if(substr($localBranch, 0, 19) == 'remotes/origin/HEAD') continue;
if(substr($localBranch, 0, 1) == '*') $localBranch = substr($localBranch, 1);
if(substr($localBranch, 0, 15) == 'remotes/origin/') $localBranch = substr($localBranch, 15);
$localBranch = trim($localBranch);
if(empty($localBranch))continue;
@@ -533,6 +537,8 @@ class GitRepo
$count = $count == 0 ? '' : "-n $count";
chdir($this->root);
if($branch) execCmd(escapeCmd("$this->client checkout $branch"), 'array');
$list = execCmd(escapeCmd("$this->client log $count $revision -- ./"), 'array');
$commits = $this->parseLog($list);
+2
View File
@@ -216,6 +216,8 @@ $lang->action->desc->fromsonarqube = '$date, created by <strong>$actor</s
$lang->action->desc->tolib = '$date, imported by <strong>$actor</strong> .' . "\n";
$lang->action->desc->updatetolib = '$date, updated to ' . $lang->testcase->common . ' by <strong>$actor</strong>.' . "\n";
$lang->action->desc->adjusttasktowait = '$date, System Reminder: The task status will be set to Not Started as the consumed work hour is adjusted to 0. ' . "\n";
$lang->action->desc->reopen = '$date, reopened by <strong>$actor</strong> .' . "\n";
$lang->action->desc->merged = '$date, merged by <strong>$actor</strong> .' . "\n";
/* Used to describe the history of operations related to parent-child tasks. */
$lang->action->desc->createchildren = '$date, <strong>$actor</strong> created a child task <strong>$extra</strong>。' . "\n";
+2
View File
@@ -216,6 +216,8 @@ $lang->action->desc->fromsonarqube = '$date, created by <strong>$actor</s
$lang->action->desc->tolib = '$date, imported by <strong>$actor</strong> .' . "\n";
$lang->action->desc->updatetolib = '$date, updated to ' . $lang->testcase->common . ' by <strong>$actor</strong>.' . "\n";
$lang->action->desc->adjusttasktowait = '$date, System Reminder: The task status will be set to Not Started as the consumed work hour is adjusted to 0. ' . "\n";
$lang->action->desc->reopen = '$date, reopened by <strong>$actor</strong> .' . "\n";
$lang->action->desc->merged = '$date, merged by <strong>$actor</strong> .' . "\n";
/* Used to describe the history of operations related to parent-child tasks. */
$lang->action->desc->createchildren = '$date, <strong>$actor</strong> created a child task <strong>$extra</strong>。' . "\n";
+2
View File
@@ -216,6 +216,8 @@ $lang->action->desc->fromsonarqube = '$date, created by <strong>$actor</s
$lang->action->desc->tolib = '$date, Importé par <strong>$actor</strong> .' . "\n";
$lang->action->desc->updatetolib = '$date, MàJ de ' . $lang->testcase->common . ' par <strong>$actor</strong>.' . "\n";
$lang->action->desc->adjusttasktowait = '$date, System Reminder: The task status will be set to Not Started as the consumed work hour is adjusted to 0. ' . "\n";
$lang->action->desc->reopen = '$date, reopened by <strong>$actor</strong> .' . "\n";
$lang->action->desc->merged = '$date, merged by <strong>$actor</strong> .' . "\n";
/* Used to describe the history of operations related to parent-child tasks. */
$lang->action->desc->createchildren = '$date, <strong>$actor</strong> a créé un sous-tâche <strong>$extra</strong>。' . "\n";
+2
View File
@@ -176,6 +176,8 @@ $lang->action->desc->run = '$date, by <strong>$actor</strong> execut
$lang->action->desc->syncprogram = '$date, started by <strong>$actor</strong>(starting the project sets the program status as Ongoing).' . "\n";
$lang->action->desc->syncproject = '$date, starting the execution sets the project status as Ongoing.' . "\n";
$lang->action->desc->syncexecution = '$date, starting the task sets the execution status as Ongoing.' . "\n";
$lang->action->desc->reopen = '$date, reopened by <strong>$actor</strong> .' . "\n";
$lang->action->desc->merged = '$date, merged by <strong>$actor</strong> .' . "\n";
/* Used to describe the history of operations related to parent-child tasks. */
$lang->action->desc->createchildren = '$date, <strong>$actor</strong> created a child task <strong>$extra</strong>。' . "\n";
+2
View File
@@ -216,6 +216,8 @@ $lang->action->desc->fromsonarqube = '$date, 由 <strong>$actor</strong>
$lang->action->desc->tolib = '$date, 由 <strong>$actor</strong> 导入。' . "\n";
$lang->action->desc->updatetolib = '$date, 由 <strong>$actor</strong> 从' . $lang->testcase->common . '更新。' . "\n";
$lang->action->desc->adjusttasktowait = '$date, 系统判断由于消耗工时调整为0,将任务状态置为未开始。' . "\n";
$lang->action->desc->reopen = '$date, 由 <strong>$actor</strong> 重新打开。' . "\n";
$lang->action->desc->merged = '$date, 由 <strong>$actor</strong> 合并。' . "\n";
/* 用来描述和父子任务相关的操作历史记录。*/
$lang->action->desc->createchildren = '$date, 由 <strong>$actor</strong> 创建子任务 <strong>$extra</strong>。' . "\n";
+32
View File
@@ -600,4 +600,36 @@ class giteaModel extends model
return $newBranches;
}
/**
* Check remote url.
*
* @param int $giteaID
* @param string $project
* @param string $client
* @param string $path
* @access public
* @return bool
*/
public function checkRemoteUrl($giteaID, $project, $client, $path)
{
if(chdir($path))
{
$url = new stdclass();
$remote = execCmd(escapeCmd("$client remote -v"), 'array');
$pregHttp = '/http(s)?:\/\/(www\.)?[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+(:\d+)*(\/\w+)*\.git/';
$pregSSH = '/ssh:\/\/git@[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+(:\d+)*(\/\w+)*\.git/';
if(preg_match($pregHttp, $remote[0], $matches)) $url->http = $matches[0];
if(preg_match($pregSSH, $remote[0], $matches)) $url->ssh = $matches[0];
$project = $this->apiGetSingleProject($giteaID, $project);
if(isset($project->clone_url))
{
if($project->clone_url == $url->http or $project->ssh_url == $url->ssh) return true;
}
}
return false;
}
}
+1 -1
View File
@@ -976,7 +976,7 @@ class mr extends control
public function ajaxGetRepoList($hostID, $projectID)
{
$host = $this->loadModel('pipeline')->getByID($hostID);
if($host->type != 'gitlab') $projectID =urldecode(base64_decode($projectID));
if($host->type != 'gitlab') $projectID = urldecode(base64_decode($projectID));
$repoList = $this->loadModel('repo')->getRepoListByClient($hostID, $projectID);
+1 -1
View File
@@ -15,6 +15,6 @@
.c-id {width: 60px;}
.c-title {min-width: 120px;}
.c-branch {width: 240px;}
.c-status {width: 100px;}
.c-status {width: 120px;}
.c-author {width: 100px;}
.c-date {width: 140px;}
+4 -6
View File
@@ -400,6 +400,8 @@ class mrModel extends model
$MR = $this->getByID($MRID);
$this->linkObjects($MR);
$this->loadModel('action')->create('mr', $MRID, 'edited');
if(dao::isError()) return array('result' => 'fail', 'message' => dao::getError());
return array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => helper::createLink('mr', 'browse'));
}
@@ -1018,13 +1020,9 @@ class mrModel extends model
$host = $this->loadModel('pipeline')->getByID($MR->hostID);
$scm = $host->type;
$this->loadModel('repo');
$repo = new stdclass;
$repo->SCM = $this->lang->repo->scmList[ucfirst($scm)];
$repo = $this->loadModel('repo')->getRepoByID($MR->repoID);
$repo->gitService = $host->id;
$repo->project = $MR->targetProject;
$repo->path = sprintf($this->config->repo->$scm->apiPath, $host->url, $MR->targetProject);
$repo->client = $host->url;
$repo->password = $host->token;
$repo->account = '';
$repo->encoding = $encoding;
@@ -1865,7 +1863,7 @@ class mrModel extends model
*/
public function logMergedAction($MR)
{
$this->loadModel('action');
$this->loadModel('action')->create('mr', $MR->id, 'merged');
$product = $this->getMRProduct($MR);
$stories = $this->getLinkList($MR->id, $product->id, 'story');
+9 -2
View File
@@ -54,7 +54,7 @@ $(function()
*/
function scmChanged(scm)
{
if(scm == 'Git')
if(scm == 'Git' || scm == 'Gitea')
{
$('.account-fields').addClass('hidden');
@@ -77,7 +77,14 @@ function scmChanged(scm)
else
{
$('tr.service').toggle(true);
$('tr.hide-service').toggle(false);
if(scm == 'Gitea')
{
$('tr.hide-service').toggle(true);
}
else
{
$('tr.hide-service').toggle(false);
}
var url = createLink('repo', 'ajaxGetHosts', "scm=" + scm);
$.get(url, function(response)
+9 -2
View File
@@ -38,7 +38,7 @@ $(function()
*/
function scmChanged(scm, isFirstRequest = false)
{
if(scm == 'Git')
if(scm == 'Git' || scm == 'Gitea')
{
$('.account-fields').addClass('hidden');
@@ -61,7 +61,14 @@ function scmChanged(scm, isFirstRequest = false)
else
{
$('tr.service').toggle(true);
$('tr.hide-service').toggle(false);
if(scm == 'Gitea')
{
$('tr.hide-service').toggle(true);
}
else
{
$('tr.hide-service').toggle(false);
}
if(!isFirstRequest)
{
+1
View File
@@ -199,6 +199,7 @@ $lang->repo->error->linkedJob = "Deletion of the repository failed. The curr
$lang->repo->error->clientPath = "The client installation directory cannot have spaces!";
$lang->repo->error->notFound = "The repository %ss URL %s does not exist. Please confirm if this repository has been deleted from the local server.";
$lang->repo->error->noWritable = '%s is not writable! Please check the privilege, or download will not be done.';
$lang->repo->error->unconnected = 'The directory does not match the repository';
$lang->repo->syncTips = '<strong>You may find the reference about how to set Git sync from <a target="_blank" href="https://www.zentao.pm/book/zentaomanual/free-open-source-project-management-software-git-105.html">here</a>.</strong>';
$lang->repo->encodingsTips = "The encodings of comments can be comma separated values, e.g. utf-8.";
+1
View File
@@ -199,6 +199,7 @@ $lang->repo->error->linkedJob = "Deletion of the repository failed. The curr
$lang->repo->error->clientPath = "The client installation directory cannot have spaces!";
$lang->repo->error->notFound = "The repository %ss URL %s does not exist. Please confirm if this repository has been deleted from the local server.";
$lang->repo->error->noWritable = '%s is not writable! Please check the privilege, or download will not be done.';
$lang->repo->error->unconnected = 'The directory does not match the repository';
$lang->repo->syncTips = '<strong>You may find the reference about how to set Git sync from <a target="_blank" href="https://www.zentao.pm/book/zentaomanual/free-open-source-project-management-software-git-105.html">here</a>.</strong>';
$lang->repo->encodingsTips = "The encodings of comments can be comma separated values, e.g. utf-8.";
+1
View File
@@ -199,6 +199,7 @@ $lang->repo->error->linkedJob = "Deletion of the repository failed. The curr
$lang->repo->error->clientPath = "The client installation directory cannot have spaces!";
$lang->repo->error->notFound = "The repository %ss URL %s does not exist. Please confirm if this repository has been deleted from the local server.";
$lang->repo->error->noWritable = '%s is not writable! Please check the privilege, or download will not be done.';
$lang->repo->error->unconnected = 'The directory does not match the repository';
$lang->repo->syncTips = '<strong>Vous pouvez trouver la référence sur la façon de définir la synchronisation Git à partir de la page se trouvant <a target="_blank" href="https://www.zentao.pm/book/zentaomanual/free-open-source-project-management-software-git-105.html">ici</a>.</strong>';
$lang->repo->encodingsTips = "Les encodages des commentaires de validation peuvent être des valeurs séparées par des virgulesex: utf-8";
+1
View File
@@ -189,6 +189,7 @@ $lang->repo->error->encoding = "The encoding maybe wrong. Vui lòng change
$lang->repo->error->deleted = "Deletion of the repository failed. The current repository has a commit record associated with the design.";
$lang->repo->error->clientPath = "The client installation directory cannot have spaces!";
$lang->repo->error->noWritable = '%s is not writable! Please check the privilege, or download will not be done.';
$lang->repo->error->unconnected = 'The directory does not match the repository';
$lang->repo->syncTips = '<strong>Bạn có thể tìm tham khảo làm sao thiết lập đồng bộ Git từ <a target="_blank" href="https://www.zentao.pm/book/zentaomanual/free-open-source-project-management-software-git-105.html">here</a>.</strong>';
$lang->repo->encodingsTips = "The encodings of commit comments, can be comma separated valuesví dụ: utf-8";
+1
View File
@@ -199,6 +199,7 @@ $lang->repo->error->linkedJob = "删除代码库失败,当前代码库与
$lang->repo->error->clientPath = "客户端安装目录不能有空格!";
$lang->repo->error->notFound = "代码库『%s』路径 %s 不存在,请确认此代码库是否已在本地服务器被删除";
$lang->repo->error->noWritable = '%s 不可写!请检查该目录权限,否则无法下载。';
$lang->repo->error->unconnected = '目录地址与仓库不匹配';
$lang->repo->syncTips = '请参照<a target="_blank" href="https://www.zentao.net/book/zentaopmshelp/207.html">这里</a>,设置代码库定时同步。';
$lang->repo->encodingsTips = "提交日志的编码,可以用逗号连接起来的多个,比如utf-8。";
+47 -25
View File
@@ -122,7 +122,8 @@ class repoModel extends model
$productIdList = $this->loadModel('product')->getProductIDByProject($projectID, false);
foreach($repos as $i => $repo)
{
$repo->acl = json_decode($repo->acl);
$repo->acl = json_decode($repo->acl);
$repo->codePath = $repo->path;
if(!$this->checkPriv($repo))
{
unset($repos[$i]);
@@ -166,7 +167,8 @@ class repoModel extends model
foreach($repos as $i => $repo)
{
if($repo->encrypt == 'base64') $repo->password = base64_decode($repo->password);
$repo->acl = json_decode($repo->acl);
$repo->acl = json_decode($repo->acl);
$repo->codePath = $repo->path;
if($type == 'haspriv' and !$this->checkPriv($repo)) unset($repos[$i]);
if(in_array(strtolower($repo->SCM), $this->config->repo->gitServiceList)) $repo = $this->processGitService($repo);
}
@@ -195,8 +197,8 @@ class repoModel extends model
$data = fixer::input('post')
->setIf($isPipelineServer, 'password', $this->post->serviceToken)
->setIf($isPipelineServer, 'path', $this->post->serviceProject)
->setIf($isPipelineServer, 'client', $this->post->serviceHost)
->setIf($isPipelineServer and $this->post->SCM == 'Gitlab', 'path', '')
->setIf($isPipelineServer and $this->post->SCM == 'Gitlab', 'client', '')
->setIf($isPipelineServer, 'extra', $this->post->serviceProject)
->setIf($isPipelineServer, 'prefix', '')
->setIf($this->post->SCM == 'Git', 'account', '')
@@ -206,12 +208,12 @@ class repoModel extends model
->join('product', ',')
->get();
if(in_array(strtolower($this->post->SCM), $this->config->repo->gitServiceList))
if($isPipelineServer)
{
$repo = $this->dao->select('id')->from(TABLE_REPO)
->where('SCM')->eq($this->post->SCM)
->andWhere('client')->eq($data->client)
->andWhere('path')->eq($data->path)
->andWhere('serviceHost')->eq($data->client)
->andWhere('serviceProject')->eq($data->path)
->fetch();
if(!empty($repo)) dao::$errors['serviceProject'] = sprintf($this->lang->error->unique, $this->lang->repo->serviceProject, $repo->name);
if(dao::isError()) return false;
@@ -219,6 +221,15 @@ class repoModel extends model
$data->acl = empty($data->acl) ? '' : json_encode($data->acl);
if($data->SCM == 'Gitea')
{
$relation = $this->loadModel('gitea')->checkRemoteUrl($data->serviceHost, $data->serviceProject, $data->client, $data->path);
if(!$relation)
{
dao::$errors['path'] = $this->lang->repo->error->unconnected;
return false;
}
}
if($data->SCM == 'Subversion')
{
$scm = $this->app->loadClass('scm');
@@ -230,10 +241,11 @@ class repoModel extends model
}
if($data->encrypt == 'base64') $data->password = base64_encode($data->password);
$this->dao->insert(TABLE_REPO)->data($data, $skip = 'serviceHost,serviceToken,serviceProject')
$this->dao->insert(TABLE_REPO)->data($data, $skip = 'serviceToken')
->batchCheck($this->config->repo->create->requiredFields, 'notempty')
->checkIF($isPipelineServer, 'serviceProject', 'notempty')
->checkIF($isPipelineServer, 'serviceHost,serviceProject', 'notempty')
->checkIF($data->SCM == 'Subversion', $this->config->repo->svn->requiredFields, 'notempty')
->checkIF($data->SCM == 'Gitea', $this->config->repo->gitea->requiredFields, 'notempty')
->checkIF($data->SCM == 'Git', 'path', 'unique', "`SCM` = 'Git'")
->checkIF($data->SCM == 'Subversion', 'path', 'unique', "`SCM` = 'Subversion'")
->autoCheck()
@@ -275,8 +287,8 @@ class repoModel extends model
$data = fixer::input('post')
->setIf($isPipelineServer, 'password', $this->post->serviceToken)
->setIf($isPipelineServer, 'path', $this->post->serviceProject)
->setIf($isPipelineServer, 'client', $this->post->serviceHost)
->setIf($isPipelineServer and $this->post->SCM == 'Gitlab', 'path', '')
->setIf($isPipelineServer and $this->post->SCM == 'Gitlab', 'client', '')
->setIf($isPipelineServer, 'extra', $this->post->serviceProject)
->setDefault('prefix', $repo->prefix)
->setIf($this->post->SCM == 'Gitlab', 'prefix', '')
@@ -304,12 +316,12 @@ class repoModel extends model
$data->prefix = '';
}
if(in_array(strtolower($this->post->SCM), $this->config->repo->gitServiceList))
if($isPipelineServer)
{
$repo = $this->dao->select('id')->from(TABLE_REPO)
->where('SCM')->eq($this->post->SCM)
->andWhere('client')->eq($data->client)
->andWhere('path')->eq($data->path)
->andWhere('serviceHost')->eq($data->client)
->andWhere('serviceProject')->eq($data->path)
->andWhere('id')->ne($id)
->fetch();
if(!empty($repo)) dao::$errors['serviceProject'] = sprintf($this->lang->error->unique, $this->lang->repo->serviceProject, $repo->name);
@@ -320,7 +332,7 @@ class repoModel extends model
if(!$this->checkConnection()) return false;
if($data->encrypt == 'base64') $data->password = base64_encode($data->password);
$this->dao->update(TABLE_REPO)->data($data, $skip = 'serviceHost,serviceToken,serviceProject')
$this->dao->update(TABLE_REPO)->data($data, $skip = 'serviceToken')
->batchCheck($this->config->repo->edit->requiredFields, 'notempty')
->checkIF($data->SCM == 'Subversion', $this->config->repo->svn->requiredFields, 'notempty')
->checkIF($data->SCM == 'Gitlab', 'extra', 'notempty')
@@ -463,6 +475,7 @@ class repoModel extends model
if(!$repo) return false;
if($repo->encrypt == 'base64') $repo->password = base64_decode($repo->password);
$repo->codePath = $repo->path;
if(in_array(strtolower($repo->SCM), $this->config->repo->gitServiceList)) $repo = $this->processGitService($repo);
$repo->acl = json_decode($repo->acl);
return $repo;
@@ -1285,7 +1298,7 @@ class repoModel extends model
*/
public function checkClient()
{
if(in_array(strtolower($this->post->SCM), $this->config->repo->gitServiceList)) return true;
if($this->post->SCM == 'Gitlab') return true;
if(!$this->config->features->checkClient) return true;
if(!$this->post->client)
@@ -1409,7 +1422,7 @@ class repoModel extends model
return false;
}
}
elseif($scm == 'Git')
elseif(in_array($scm, array('Git', 'Gitea')))
{
if(!is_dir($path))
{
@@ -2035,13 +2048,22 @@ class repoModel extends model
*/
public function processGitService($repo)
{
$service = $this->loadModel('pipeline')->getByID($repo->client);
$service = $this->loadModel('pipeline')->getByID($repo->serviceHost);
if($repo->SCM == 'Gitlab')
{
$project = $this->loadModel('gitlab')->apiGetSingleProject($repo->serviceHost, $repo->serviceProject);
$repo->gitService = $service ? $service->id : 0;
$repo->project = $service ? $repo->path : ''; // The projectID in gitlab.
$repo->path = $service ? sprintf($this->config->repo->{$service->type}->apiPath, $service->url, $repo->path) : '';
$repo->client = $service ? $service->url : '';
$repo->password = $service ? $service->token : '';
$repo->path = $service ? sprintf($this->config->repo->{$service->type}->apiPath, $service->url, $repo->serviceProject) : '';
$repo->client = $service ? $service->url : '';
$repo->password = $service ? $service->token : '';
$repo->codePath = $project ? $project->web_url : $repo->path;
}
elseif($repo->SCM == 'Gitea')
{
$repo->codePath = $service ? "{$service->url}/{$repo->serviceProject}" : $repo->path;
}
$repo->gitService = $repo->serviceHost;
$repo->project = $repo->serviceProject;
return $repo;
}
@@ -2056,8 +2078,8 @@ class repoModel extends model
{
return $this->dao->select('*')->from(TABLE_REPO)->where('deleted')->eq('0')
->andWhere('synced')->eq(1)
->andWhere('client')->eq($gitlabID)
->beginIF($projectID)->andWhere('path')->eq($projectID)->fi()
->andWhere('serviceHost')->eq($gitlabID)
->beginIF($projectID)->andWhere('serviceProject')->eq($projectID)->fi()
->fetchAll();
}
+1 -5
View File
@@ -19,9 +19,7 @@ if(isset($entry)) $pathInfo .= '&type=file';
<table class='table table-fixed'>
<thead>
<tr>
<?php if($repo->SCM != 'Gitea'):?>
<th class='c-checkbox w-40px'></th>
<?php endif;?>
<th class='c-version'><?php echo $lang->repo->revisionA?></th>
<?php if($repo->SCM != 'Subversion'):?>
<th class='c-commit'><?php echo $lang->repo->commit?></th>
@@ -34,14 +32,12 @@ if(isset($entry)) $pathInfo .= '&type=file';
<tbody>
<?php foreach($revisions as $log):?>
<tr>
<?php if($repo->SCM != 'Gitea'):?>
<td>
<div class='checkbox-primary'>
<input type='checkbox' name='revision[]' value="<?php echo $log->revision?>" />
<label></label>
</div>
</td>
<?php endif;?>
<td class='versions'><span class="revision"><?php echo html::a($this->repo->createLink('revision', "repoID=$repoID&objectID=$objectID&revision={$log->revision}" . $pathInfo), $repo->SCM != 'Subversion' ? substr($log->revision, 0, 10) : $log->revision, '', "data-app='{$this->app->tab}'");?></span></td>
<?php if($repo->SCM != 'Subversion'):?>
<td><?php echo $log->commit?></td>
@@ -54,7 +50,7 @@ if(isset($entry)) $pathInfo .= '&type=file';
</tbody>
</table>
<div class='table-footer'>
<?php if($repo->SCM != 'Gitea' and common::hasPriv('repo', 'diff')) echo html::submitButton($lang->repo->diff, '', count($revisions) < 2 ? 'disabled btn btn-primary' : 'btn btn-primary')?>
<?php if(common::hasPriv('repo', 'diff')) echo html::submitButton($lang->repo->diff, '', count($revisions) < 2 ? 'disabled btn btn-primary' : 'btn btn-primary')?>
<?php echo html::a($this->repo->createLink('log', "repoID=$repoID&objectID=$objectID&entry=" . $this->repo->encodePath($path) . "&revision=HEAD&type=$logType"), $lang->repo->allLog, '', "class='allLogs' data-app='{$this->app->tab}'");?>
<div class='pull-right'>
<ul id="repoPageSize" class="pager" data-ride="pager" data-elements="size_menu" data-rec-total="<?php echo $pager->recTotal;?>" data-rec-per-page="<?php echo $pager->recPerPage;?>" data-page="<?php echo $pager->pageID;?>"></ul>
+1 -5
View File
@@ -51,9 +51,7 @@
<table class='table table-fixed' id='logList'>
<thead>
<tr>
<?php if($repo->SCM != 'Gitea'):?>
<th class='w-40px'></th>
<?php endif;?>
<th class='w-110px'><?php echo $lang->repo->revision?></th>
<?php if($repo->SCM != 'Subversion'):?>
<th class='w-90px'><?php echo $lang->repo->commit?></th>
@@ -66,14 +64,12 @@
<tbody>
<?php foreach($logs as $log):?>
<tr>
<?php if($repo->SCM != 'Gitea'):?>
<td>
<div class='checkbox-primary'>
<input type='checkbox' name='revision[]' value="<?php echo $log->revision?>" />
<label></label>
</div>
</td>
<?php endif;?>
<td class='versions'><?php echo html::a($this->repo->createLink('revision', "repoID=$repoID&objectID=$objectID&revision=" . $log->revision), substr($log->revision, 0, 10), '', "data-app='{$app->tab}'");?></td>
<?php if($repo->SCM != 'Subversion'):?>
<td><?php echo $log->commit?></td>
@@ -86,7 +82,7 @@
</tbody>
</table>
<div class='table-footer'>
<?php if($repo->SCM != 'Gitea' and common::hasPriv('repo', 'diff')) echo html::submitButton($lang->repo->diff, '', count($logs) < 2 ? 'disabled btn btn-primary' : 'btn btn-primary')?>
<?php if(common::hasPriv('repo', 'diff')) echo html::submitButton($lang->repo->diff, '', count($logs) < 2 ? 'disabled btn btn-primary' : 'btn btn-primary')?>
<?php $pager->show('right', 'pagerjs');?>
</div>
</form>
+1 -1
View File
@@ -52,7 +52,7 @@
}
?>
<td class='text' title='<?php echo $productNames;?>'><?php echo $productNames;?></td>
<td class='text' title='<?php echo $repo->path; ?>'><?php echo $repo->path; ?></td>
<td class='text' title='<?php echo $repo->codePath;?>'><?php echo $repo->codePath;?></td>
<td class='text-left c-actions'>
<?php
common::printIcon('repo', 'edit', "repoID=$repo->id&objectID=$objectID", '', 'list', 'edit');
+1 -1
View File
@@ -57,7 +57,7 @@ $version = " <span class=\"label label-info\">$revisionName</span>";
<div class='panel-actions'>
<?php if($suffix != 'binary' and strpos($config->repo->images, "|$suffix|") === false):?>
<?php
if($repo->SCM != 'Gitea' and common::hasPriv('repo', 'blame')) echo html::a($this->repo->createLink('blame', "repoID=$repoID&objectID=$objectID&entry=$encodePath&revision=$revision&encoding=$encoding"), html::icon('random') . $lang->repo->blame, '', "class='btn btn-sm btn-primary' data-app='{$app->tab}'");
if(common::hasPriv('repo', 'blame')) echo html::a($this->repo->createLink('blame', "repoID=$repoID&objectID=$objectID&entry=$encodePath&revision=$revision&encoding=$encoding"), html::icon('random') . $lang->repo->blame, '', "class='btn btn-sm btn-primary' data-app='{$app->tab}'");
if(common::hasPriv('repo', 'download')) echo html::a($this->repo->createLink('download', "repoID=$repoID&path=$encodePath&fromRevision=$revision"), html::icon('download-alt') . $lang->repo->download, 'hiddenwin', "class='btn btn-sm btn-primary'");
?>
<?php endif;?>