From 990ef6699a1ab8a0f6efb70e7173f59786f4190d Mon Sep 17 00:00:00 2001 From: wangyidong Date: Wed, 26 Feb 2020 13:42:26 +0800 Subject: [PATCH] * code for task #6858. --- db/update12.1.sql | 4 +- lib/scm/{git.class.php => parsegit.class.php} | 6 +- lib/scm/scm.class.php | 1 + module/git/control.php | 6 +- module/git/model.php | 83 ++++++------ module/install/lang/en.php | 3 + module/install/lang/zh-cn.php | 3 + module/integration/control.php | 4 +- module/repo/model.php | 68 ++++------ module/svn/control.php | 8 +- module/svn/model.php | 119 ++++++++---------- 11 files changed, 142 insertions(+), 163 deletions(-) rename lib/scm/{git.class.php => parsegit.class.php} (98%) diff --git a/db/update12.1.sql b/db/update12.1.sql index 8cb74ee761..370fdfd798 100644 --- a/db/update12.1.sql +++ b/db/update12.1.sql @@ -62,7 +62,9 @@ CREATE TABLE `zt_cibuild` ( ALTER TABLE `zt_cijob` ADD `svnFolder` varchar(255) COLLATE 'utf8_general_ci' NOT NULL AFTER `triggerType`; INSERT INTO `zt_cron` (`m`, `h`, `dom`, `mon`, `dow`, `command`, `remark`, `type`, `buildin`, `status`, `lastTime`) VALUES -('*/5', '*', '*', '*', '*', 'moduleName=ci&methodName=checkBuildStatus', '同步Jenkins任务状态', 'zentao', 1, 'normal', '0000-00-00 00:00:00'); +('1', '1', '*', '*', '*', 'moduleName=ci&methodName=buildTodayJob', '创建周期性任务', 'zentao', 1, 'normal', '0000-00-00 00:00:00'), +('*/5', '*', '*', '*', '*', 'moduleName=ci&methodName=checkBuildStatus', '同步Jenkins任务状态', 'zentao', 1, 'normal', '0000-00-00 00:00:00'), +('*/5', '*', '*', '*', '*', 'moduleName=ci&methodName=exec', '执行Jenkins任务', 'zentao', 1, 'normal', '0000-00-00 00:00:00'); ALTER TABLE `zt_cibuild` RENAME TO `zt_compile`; ALTER TABLE `zt_cijob` RENAME TO `zt_integration`; diff --git a/lib/scm/git.class.php b/lib/scm/parsegit.class.php similarity index 98% rename from lib/scm/git.class.php rename to lib/scm/parsegit.class.php index 07e49f79b7..e184b804b8 100644 --- a/lib/scm/git.class.php +++ b/lib/scm/parsegit.class.php @@ -1,5 +1,5 @@ root); - $list = execCmd(escapeCmd("$this->client log --stat=1024 --name-status -1 $fromRevision -- $path"), 'array'); + $list = execCmd(escapeCmd("$this->client log --stat=1024 --name-status --stat-name-width=1000 -1 $fromRevision -- $path"), 'array'); $logs = $this->parseLog($list); return $logs; } @@ -139,7 +139,7 @@ class Git $revisions = "$fromRevision..$toRevision"; } chdir($this->root); - $list = execCmd(escapeCmd("$this->client log $count $revisions -- $path"), 'array'); + $list = execCmd(escapeCmd("$this->client log --stat=1024 --name-status --stat-name-width=1000 $count $revisions -- $path"), 'array'); $logs = $this->parseLog($list); return $logs; diff --git a/lib/scm/scm.class.php b/lib/scm/scm.class.php index 05d29c1a5f..2c231d6b26 100644 --- a/lib/scm/scm.class.php +++ b/lib/scm/scm.class.php @@ -6,6 +6,7 @@ class scm public function setEngine($repo) { $className = $repo->SCM; + if($className == 'Git') $className = 'ParseGit'; if(!class_exists($className)) require(strtolower($className) . '.class.php'); $this->engine = new $className($repo->client, $repo->path, $repo->account, $repo->password, $repo->encoding); } diff --git a/module/git/control.php b/module/git/control.php index 614ef8c217..b94baca7fe 100644 --- a/module/git/control.php +++ b/module/git/control.php @@ -37,10 +37,9 @@ class git extends control $path = helper::safe64Decode($path); if(common::hasPriv('repo', 'diff')) { - $repos = $this->loadModel('repo')->getAllRepos(); + $repos = $this->loadModel('repo')->getListBySCM('Git', 'haspriv'); foreach($repos as $repo) { - if($repo->SCM != 'Git') continue; if(strpos($path, $repo->path) === 0) { $entry = $this->repo->encodePath(str_replace($repo->path, '', $path)); @@ -72,10 +71,9 @@ class git extends control $path = helper::safe64Decode($path); if(common::hasPriv('repo', 'view')) { - $repos = $this->loadModel('repo')->getList(); + $repos = $this->loadModel('repo')->getListBySCM('Git', 'haspriv'); foreach($repos as $repo) { - if($repo->SCM != 'Git') continue; if(strpos($path, $repo->path) === 0) { $entry = $this->repo->encodePath(str_replace($repo->path, '', $path)); diff --git a/module/git/model.php b/module/git/model.php index 496555e9a7..c5f0099467 100644 --- a/module/git/model.php +++ b/module/git/model.php @@ -134,7 +134,7 @@ class gitModel extends model $this->saveLastRevision($latestRevision); $this->printLog("save revision $latestRevision"); $this->deleteRestartFile(); - $this->printLog("\n\nrepo ' . $repo->id . ': ' . $repo->path . ' finished"); + $this->printLog("\n\nrepo #" . $repo->id . ': ' . $repo->path . " finished"); } // exe ci jobs in log @@ -191,7 +191,7 @@ class gitModel extends model $paths = array(); foreach($repos as $repo) { - if(strtolower($repo->SCM) == 'git' && !isset($paths[$repo->path])) + if(!isset($paths[$repo->path])) { unset($repo->acl); unset($repo->desc); @@ -200,6 +200,29 @@ class gitModel extends model } } + if(isset($this->config->git->repos)) + { + foreach($this->config->git->repos as $i => $repo) + { + $repoPath = $repo['path']; + if(empty($repoPath)) continue; + if(isset($paths[$repoPath])) continue; + + $gitRepo = new stdclass(); + $gitRepo->id = "c{$i}"; + $gitRepo->client = $this->config->git->client; + $gitRepo->path = $repoPath; + $gitRepo->prefix = ''; + $gitRepo->SCM = 'Git'; + $gitRepo->account = ''; + $gitRepo->password = ''; + $gitRepo->encoding = zget($repo, 'encoding', $this->config->git->client); + + $gitRepos[] = $gitRepo; + $paths[$repoPath] = $repoPath; + } + } + if(empty($gitRepos)) echo "You must set one git repo.\n"; $this->repos = $gitRepos; @@ -214,15 +237,11 @@ class gitModel extends model */ public function getRepos() { - $repos = array(); - if(!$this->config->git->repos) return $repos; + $repos = $this->setRepos(); + $repoPairs = array(); + foreach($repos as $repo) $repoPairs[] = $repo->path; - foreach($this->config->git->repos as $repo) - { - if(empty($repo['path'])) continue; - $repos[] = $repo['path']; - } - return $repos; + return $repoPairs; } /** @@ -305,7 +324,7 @@ class gitModel extends model { $scm = $this->app->loadClass('scm'); $scm->setEngine($repo); - return $scm->tags('/'); + return $scm->tags(''); } /** @@ -318,40 +337,22 @@ class gitModel extends model */ public function getRepoLogs($repo, $fromRevision) { - $parsedLogs = array(); + $scm = $this->app->loadClass('scm'); + $scm->setEngine($repo); + $logs = $scm->log('', $fromRevision); + if(empty($logs)) return false; - /* The git log command. */ - chdir($this->repoRoot); - exec("{$this->client} config core.quotepath false"); - if($fromRevision) + foreach($logs as $log) { - $cmd = "$this->client log --stat=1024 --stat-name-width=1000 --name-status $fromRevision..HEAD"; - } - else - { - $cmd = "$this->client log --stat=1024 --stat-name-width=1000 --name-status"; - } - exec($cmd, $list, $return); + $log->author = $log->committer; + $log->msg = $log->comment; + $log->date = $log->time; - if(!$list and $return) - { - echo "Some error occers: \nThe command is $cmd\n"; - return false; + /* Process files. */ + $log->files = array(); + foreach($log->change as $file => $info) $log->files[$info['action']][] = $file; } - if(!$list and !$return) return array(); - - /* Process logs. */ - $logs = array(); - $i = 0; - - foreach($list as $line) - { - if(strpos($line, 'commit ') === 0) $i++; - $logs[$i][] = $line; - } - - foreach($logs as $log) $parsedLogs[] = $this->convertLog($log); - return $parsedLogs; + return $logs; } /** diff --git a/module/install/lang/en.php b/module/install/lang/en.php index a48f366334..bc4bce4ee2 100644 --- a/module/install/lang/en.php +++ b/module/install/lang/en.php @@ -165,6 +165,9 @@ $lang->install->cronList['moduleName=mail&methodName=asyncSend'] = 'Asynchr $lang->install->cronList['moduleName=webhook&methodName=asyncSend'] = 'Asynchronize sending Webhook'; $lang->install->cronList['moduleName=admin&methodName=deleteLog'] = 'Delete overdue logs'; $lang->install->cronList['moduleName=todo&methodName=createCycle'] = 'Create recurring todos'; +$lang->install->cronList['moduleName=ci&methodName=buildTodayJob'] = 'Create recurring jenkins'; +$lang->install->cronList['moduleName=ci&methodName=checkBuildStatus'] = 'Synchronize Jenkins Status'; +$lang->install->cronList['moduleName=ci&methodName=exec'] = 'Execute Jenkins'; $lang->install->success = "Installed!"; $lang->install->login = 'Login ZenTao'; diff --git a/module/install/lang/zh-cn.php b/module/install/lang/zh-cn.php index ad902e9657..074a934aed 100644 --- a/module/install/lang/zh-cn.php +++ b/module/install/lang/zh-cn.php @@ -165,6 +165,9 @@ $lang->install->cronList['moduleName=mail&methodName=asyncSend'] = '异步 $lang->install->cronList['moduleName=webhook&methodName=asyncSend'] = '异步发送Webhook'; $lang->install->cronList['moduleName=admin&methodName=deleteLog'] = '删除过期日志'; $lang->install->cronList['moduleName=todo&methodName=createCycle'] = '生成周期性待办'; +$lang->install->cronList['moduleName=ci&methodName=buildTodayJob'] = '创建周期性任务'; +$lang->install->cronList['moduleName=ci&methodName=checkBuildStatus'] = '同步Jenkins任务状态'; +$lang->install->cronList['moduleName=ci&methodName=exec'] = '执行Jenkins任务'; $lang->install->success = "安装成功"; $lang->install->login = '登录禅道管理系统'; diff --git a/module/integration/control.php b/module/integration/control.php index f30cd385c2..6eb3ca7c43 100644 --- a/module/integration/control.php +++ b/module/integration/control.php @@ -73,7 +73,7 @@ class integration extends control $this->view->position[] = html::a(inlink('browse'), $this->lang->ci->job); $this->view->position[] = $this->lang->integration->create; - $repoList = $this->loadModel('repo')->getAllRepos(); + $repoList = $this->loadModel('repo')->getList(); $repoPairs = array(0 => ''); $repoTypes = array(); foreach($repoList as $repo) @@ -112,7 +112,7 @@ class integration extends control $this->view->position[] = $this->lang->integration->edit; $repo = $this->loadModel('repo')->getRepoByID($job->repo); - $repoList = $this->loadModel('repo')->getAllRepos(); + $repoList = $this->repo->getList(); $repoPairs = array(0 => '', $repo->id => $repo->name); $repoTypes[$repo->id] = $repo->SCM; foreach($repoList as $repo) diff --git a/module/repo/model.php b/module/repo/model.php index c7e21f700e..b4bf2d59f6 100644 --- a/module/repo/model.php +++ b/module/repo/model.php @@ -139,10 +139,9 @@ class repoModel extends model * @access public * @return array */ - public function getList($orderBy = 'id_desc', $pager = null, $decode = true) + public function getList($orderBy = 'id_desc', $pager = null) { - $repos = $this->dao->select('*')->from(TABLE_REPO) - ->where('deleted')->eq('0') + $repos = $this->dao->select('*')->from(TABLE_REPO)->where('deleted')->eq('0') ->orderBy($orderBy) ->page($pager) ->fetchAll('id'); @@ -156,6 +155,31 @@ class repoModel extends model return $repos; } + /** + * Get list by SCM. + * + * @param strint $scm + * @param string $type + * @access public + * @return array + */ + public function getListBySCM($scm, $type = 'all') + { + $repos = $this->dao->select('*')->from(TABLE_REPO)->where('deleted')->eq('0') + ->andWhere('SCM')->eq($scm) + ->orderBy('id') + ->fetchAll(); + + foreach($repos as $i => $repo) + { + if($repo->encrypt == 'base64') $repo->password = base64_decode($repo->password); + $repo->acl = json_decode($repo->acl); + if($type == 'haspriv' and !$this->checkPriv($repo)) unset($repos[$i]); + } + + return $repos; + } + /** * Create a repo. * @@ -187,24 +211,6 @@ class repoModel extends model return $this->dao->lastInsertID(); } - /** - * Get all repos. - * - * @access public - * @return array - */ - public function getAllRepos() - { - $repos = $this->dao->select('*')->from(TABLE_REPO)->where('deleted')->eq(0)->fetchAll(); - foreach($repos as $i => $repo) - { - $repo->acl = json_decode($repo->acl); - if(!$this->checkPriv($repo)) unset($repos[$i]); - } - - return $repos; - } - /** * Update a repo. * @@ -928,26 +934,6 @@ class repoModel extends model return $replaceLines; } - /** - * list repos for sync - * - * @return mixed - */ - public function getListBySCM($scm) - { - $repos = $this->dao->select('*')->from(TABLE_REPO)->where('deleted')->eq('0') - ->andWhere('SCM')->eq($scm) - ->orderBy('id') - ->fetchAll(); - - foreach($repos as $repo) - { - if($repo->encrypt == 'base64') $repo->password = base64_decode($repo->password); - } - - return $repos; - } - /** * Parse the comment of git, extract object id list from it. * diff --git a/module/svn/control.php b/module/svn/control.php index 1479b892dc..b194f3a77f 100644 --- a/module/svn/control.php +++ b/module/svn/control.php @@ -37,10 +37,9 @@ class svn extends control $url = helper::safe64Decode($url); if(common::hasPriv('repo', 'diff')) { - $repos = $this->loadModel('repo')->getAllRepos(); - foreach($repos as $repo) + $svnRepos = $this->loadModel('repo')->getListBySCM('Subversion', 'haspriv'); + foreach($svnRepos as $repo) { - if($repo->SCM != 'Subversion') continue; if(strpos(strtolower($url), strtolower($repo->path)) === 0) { $entry = $this->repo->encodePath(str_ireplace($repo->path, '', $url)); @@ -72,10 +71,9 @@ class svn extends control $url = helper::safe64Decode($url); if(common::hasPriv('repo', 'view')) { - $repos = $this->loadModel('repo')->getList(); + $repos = $this->loadModel('repo')->getListBySCM('Subversion', 'haspriv'); foreach($repos as $repo) { - if($repo->SCM != 'Subversion') continue; if(strpos(strtolower($url), strtolower($repo->path)) === 0) { $entry = $this->repo->encodePath(str_ireplace(strtolower($repo->path), '', $url)); diff --git a/module/svn/model.php b/module/svn/model.php index 49de19df1c..e93c585c89 100644 --- a/module/svn/model.php +++ b/module/svn/model.php @@ -135,7 +135,7 @@ class svnModel extends model $this->saveLastRevision($savedRevision); $this->printLog("save revision $savedRevision"); $this->deleteRestartFile(); - $this->printLog("\n\nrepo ' . $repo->id . ': ' . $repo->path . ' finished"); + $this->printLog("\n\nrepo #" . $repo->id . ': ' . $repo->path . " finished"); } // exe ci jobs in log @@ -157,6 +157,13 @@ class svnModel extends model if(!is_dir($this->logRoot)) mkdir($this->logRoot); } + /** + * Set the tag file of a repo. + * + * @param string $repoId + * @access public + * @return void + */ public function setTagFile($repoId) { $this->setLogRoot(); @@ -200,12 +207,34 @@ class svnModel extends model foreach($repos as $repo) { - if(strtolower($repo->SCM) === 'subversion' && !isset($paths[$repo->path])) + if(isset($paths[$repo->path])) continue; + + unset($repo->acl); + unset($repo->desc); + $svnRepos[] = $repo; + $paths[$repo->path] = $repo->path; + } + + if(isset($this->config->svn->repos)) + { + foreach($this->config->svn->repos as $i => $repo) { - unset($repo->acl); - unset($repo->desc); - $svnRepos[] = $repo; - $paths[$repo->path] = $repo->path; + $repoPath = $repo['path']; + if(empty($repoPath)) continue; + if(isset($paths[$repoPath])) continue; + + $svnRepo = new stdclass(); + $svnRepo->id = "c{$i}"; + $svnRepo->client = $this->config->svn->client; + $svnRepo->path = $repoPath; + $svnRepo->prefix = ''; + $svnRepo->SCM = 'Subversion'; + $svnRepo->account = $repo['username']; + $svnRepo->password = $repo['password']; + $svnRepo->encoding = zget($repo, 'encoding', $this->config->svn->client); + + $svnRepos[] = $svnRepo; + $paths[$repoPath] = $repoPath; } } @@ -286,18 +315,6 @@ class svnModel extends model $this->logFile = $this->logRoot . $repoId . '.log'; } - /** - * Set the tag file of a repo. - * - * @param string $repoId - * @access public - * @return void - */ - public function setTagFile($repoId) - { - $this->tagFile = $this->logRoot . $repoId . '.tag'; - } - /** * set the root path of a repo. * @@ -307,11 +324,10 @@ class svnModel extends model */ public function setRepoRoot($repo) { - $cmd = $this->client . " info --xml $repo->path"; - $info = `$cmd`; - $info = simplexml_load_string($info); - $repoRoot = $info->entry->repository->root; - $this->repoRoot = $repoRoot; + $scm = $this->app->loadClass('scm'); + $scm->setEngine($repo); + $info = $scm->info(''); + $this->repoRoot = $info->root; } /** @@ -338,53 +354,24 @@ class svnModel extends model */ public function getRepoLogs($repo, $fromRevision) { - $parsedLogs = array(); - /* The svn log command. */ - $cmd = $this->client . " log -r $fromRevision:HEAD -v --xml $repo->path"; - $rawLogs = `$cmd`; - $logs = @simplexml_load_string($rawLogs); // Convert it to object. - if(!$logs) - { - echo "Some error occers: \nThe command is $cmd\n the svn logs is $rawLogs\n"; - return false; - } + $scm = $this->app->loadClass('scm'); + $scm->setEngine($repo); + $logs = $scm->log('', $fromRevision); + if(empty($logs)) return false; /* Process logs. */ - foreach($logs->logentry as $entry) $parsedLogs[] = $this->convertLog($entry); - return $parsedLogs; - } - - /** - * Convert log from xml format to object. - * - * @param object $log - * @access public - * @return object - */ - public function convertLog($log) - { - /* Get author, revision, msg, date attributes. */ - $parsedLog = new stdClass(); - $parsedLog->author = (string)$log->author; - $parsedLog->revision = (int)$log['revision']; - $parsedLog->msg = trim((string)$log->msg); - $parsedLog->date = date('Y-m-d H:i:s', strtotime($log->date)); - - /* Process files. */ - $parsedLog->files = array(); - foreach ($log->paths as $key => $paths) + foreach($logs as $log) { - $parsedFiles = array(); - foreach($paths as $path) - { - $action = (string)$path['action']; - $parsedFiles[$action][] = (string)$path; - } - } - $parsedLog->files = $parsedFiles; + $log->author = $log->committer; + $log->msg = $log->comment; + $log->date = $log->time; - return $parsedLog; + /* Process files. */ + $log->files = array(); + foreach($log->change as $file => $info) $log->files[$info['action']][] = $file; + } + return $logs; } /** @@ -739,7 +726,7 @@ class svnModel extends model if(file_exists($this->restartFile)) return array(); $tags = array(); - foreach(json_decode(file_get_contents($this->tagFile)), $tag) $tags[$tag] = $tag; + foreach(json_decode(file_get_contents($this->tagFile)) as $tag) $tags[$tag] = $tag; return $tags; }