diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md deleted file mode 100644 index c2f33e73..00000000 --- a/.github/CONTRIBUTING.md +++ /dev/null @@ -1,41 +0,0 @@ -Contributions to PHPCI are very much encouraged, and we do our best to make it as welcoming and simple as possible. - -### Before You Start -Before you start, please make sure that you are aware of, and agree to, the following conditions of contribution: - -* By making a contribution to PHPCI, you accept that you are granting copyright ownership for that contribution to Block 8 Limited - the company responsible for PHPCI. In countries where copyright reassignment is not permitted, you grant Block 8 Limited a perpetual, non-exclusive licence to use your contribution in any way and for any purpose. - -* By making a contribution to PHPCI, you accept that your code will be released under the open-source [BSD 2-Clause Licence](https://github.com/Block8/PHPCI/blob/master/LICENSE.md). - -Block 8 are committed to PHPCI being a truly free and open source project, providing easy to use continuous integration and testing to as many developers as possible. We may, at our sole discretion, provide paid services based upon PHPCI - but PHPCI will always remain free (as in cost, and freedom) and open source. - -### The Contribution Process - -1. If you are thinking of making a large change or feature addition, [open an issue](/Block8/PHPCI/issues) titled "Intent to implement: ". Describe your idea in detail and discuss it with the community. It might be that someone already has a plan, could help you out, or your idea may simply not be suitable for the project at this time. -2. Fork the PHPCI project on Github -3. Add a feature or fix a bug - We recommend that you do this on a branch within your repository. -4. Create a pull request containing just the one change you want to contribute back to PHPCI. If you have more than one feature or bug fix, please create separate branches within your repository, and then submit a separate pull request for each one. Your pull request should use the template detailed below. -5. We'll then review your pull request and give any necessary feedback, this could be: - * Suggestions to improve your implementation - * Questions - * Issues/bugs related to the change - * Coding standards pointers -6. Once everyone is happy with the submission, we'll merge it back into PHPCI. Your change will then be included in the next project release. - -### Not sure what to start with? -We maintain two labels within our issue tracker that may be of interest to new contributors: - -* [The "Easy Fix" List](https://github.com/Block8/PHPCI/labels/flag:easy-fix) -* [The "Priority" List](https://github.com/Block8/PHPCI/labels/flag:priority) - -### Coding Standards -We require that all contributions meet at least the following guidelines: - -* PSR-1 & PSR-2 compliance for all code -* Doc-blocks for all classes and methods -* All files must contain the standard file-level docblock, including the copyright, license and link tags. - -All pull requests will be checked against these standards. If you're modifying a file as part of your change which does not comply with the above, please make the necessary changes to bring it into compliance prior to submitting the pull request. - -### Other Requirements -When you're adding new features or functionality, or you're updating existing functionality, please ensure that the relevant documentation is also either created or updated on the Wiki. diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 16692061..00000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,28 +0,0 @@ -Before submitting your issue, please make sure that you've checked all of the checkboxes below. - -- [ ] You're running the [latest release](https://github.com/Block8/PHPCI/releases/latest) version of PHPCI. -- [ ] Ensure that you're running at least PHP 5.3.6, you can check this by running `php -v` -- [ ] You've run `composer install --no-dev -o` from the root of your installation. -- [ ] You have set up either the PHPCI [Worker](https://github.com/Block8/PHPCI/wiki/Run-Builds-Using-a-Worker), [Daemon](https://github.com/Block8/PHPCI/wiki/Run-Builds-Using-a-Daemon) or [Cron Job](https://github.com/Block8/PHPCI/wiki/Run-Builds-Using-Cron) to run builds. - -To help us better understand your issue, please answer the following. - -### Expected behaviour - -*Please describe what you're expecting to see happen.* - -### Actual behaviour - -*Please describe what you're actually seeing happen.* - -### Steps to reproduce - -*If your issue requires any specific steps to reproduce, please outline them here.* - -### Environment info -Operating System: -PHP Version: -MySQL Version: - -### Logs or other output that would be helpful -(If logs are large, please upload as attachment). \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 65d060ab..00000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,23 +0,0 @@ -Contribution Type: bug fix | new plugin | new feature | refactor | cosmetic -Link to Intent to Implement: -Link to Bug: - -This pull request affects the following areas: - -* [ ] Front-End -* [ ] Builder -* [ ] Build Plugins - -**In raising this pull request, I confirm the following (please check boxes):** - -- [ ] I have read and understood the [contributing guidelines](/.github/CONTRIBUTING.md)? -- [ ] I have checked that another pull request for this purpose does not exist. -- [ ] I have considered, and confirmed that this submission will be valuable to others. -- [ ] I have created or updated the relevant documentation for this change on the PHPCI Wiki. -- [ ] Do the PHPCI tests pass? - - -Detailed description of change: - - - diff --git a/Dockerfile b/Dockerfile index 5fb6df83..af646d09 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,4 @@ RUN git config --global user.email "hello@php.ci" ADD ./ /phpci -RUN php -r "readfile('https://getcomposer.org/installer');" | php -RUN mv composer.phar /phpci/composer - CMD /phpci/daemonise phpci:daemonise diff --git a/PHPCI/Application.php b/PHPCI/Application.php index a6eb646c..ee1f6e15 100644 --- a/PHPCI/Application.php +++ b/PHPCI/Application.php @@ -51,7 +51,7 @@ class Application extends b8\Application return false; }; - $skipAuth = array($this, 'shouldSkipAuth'); + $skipAuth = [$this, 'shouldSkipAuth']; // Handler for the route we're about to register, checks for a valid session where necessary: $routeHandler = function (&$route, Response &$response) use (&$request, $validateSession, $skipAuth) { @@ -135,18 +135,9 @@ class Application extends b8\Application */ protected function setLayoutVariables(View &$layout) { - $groups = array(); - $groupStore = b8\Store\Factory::getStore('ProjectGroup'); - $groupList = $groupStore->getWhere(array(), 100, 0, array(), array('title' => 'ASC')); - - foreach ($groupList['items'] as $group) { - $thisGroup = array('title' => $group->getTitle()); - $projects = b8\Store\Factory::getStore('Project')->getByGroupId($group->getId()); - $thisGroup['projects'] = $projects['items']; - $groups[] = $thisGroup; - } - - $layout->groups = $groups; + /** @var \PHPCI\Store\ProjectStore $projectStore */ + $projectStore = b8\Store\Factory::getStore('Project'); + $layout->projects = $projectStore->getAll(); } /** diff --git a/PHPCI/BuildFactory.php b/PHPCI/BuildFactory.php index 91e618a8..ecc37c43 100644 --- a/PHPCI/BuildFactory.php +++ b/PHPCI/BuildFactory.php @@ -36,44 +36,38 @@ class BuildFactory /** * Takes a generic build and returns a type-specific build model. - * @param Build $build The build from which to get a more specific build type. + * @param Build $base The build from which to get a more specific build type. * @return Build */ - public static function getBuild(Build $build) + public static function getBuild(Build $base) { - $project = $build->getProject(); - - if (!empty($project)) { - switch ($project->getType()) { - case 'remote': - $type = 'RemoteGitBuild'; - break; - case 'local': - $type = 'LocalBuild'; - break; - case 'github': - $type = 'GithubBuild'; - break; - case 'bitbucket': - $type = 'BitbucketBuild'; - break; - case 'gitlab': - $type = 'GitlabBuild'; - break; - case 'hg': - $type = 'MercurialBuild'; - break; - case 'svn': - $type = 'SubversionBuild'; - break; - default: - return $build; - } - - $class = '\\PHPCI\\Model\\Build\\' . $type; - $build = new $class($build->getDataArray()); + switch($base->getProject()->getType()) + { + case 'remote': + $type = 'RemoteGitBuild'; + break; + case 'local': + $type = 'LocalBuild'; + break; + case 'github': + $type = 'GithubBuild'; + break; + case 'bitbucket': + $type = 'BitbucketBuild'; + break; + case 'gitlab': + $type = 'GitlabBuild'; + break; + case 'hg': + $type = 'MercurialBuild'; + break; + case 'svn': + $type = 'SubversionBuild'; + break; } - return $build; + $type = '\\PHPCI\\Model\\Build\\' . $type; + + return new $type($base->getDataArray()); } } diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index 1aed3d3f..904aa506 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -188,14 +188,6 @@ class Builder implements LoggerAwareInterface $this->build->sendStatusPostback(); $success = true; - $previous_build = $this->build->getProject()->getPreviousBuild($this->build->getBranch()); - - $previous_state = Build::STATUS_NEW; - - if ($previous_build) { - $previous_state = $previous_build->getStatus(); - } - try { // Set up the build: $this->setupBuild(); @@ -213,41 +205,34 @@ class Builder implements LoggerAwareInterface $this->build->setStatus(Build::STATUS_FAILED); } + // Complete stage plugins are always run + $this->pluginExecutor->executePlugins($this->config, 'complete'); if ($success) { $this->pluginExecutor->executePlugins($this->config, 'success'); - - if ($previous_state == Build::STATUS_FAILED) { - $this->pluginExecutor->executePlugins($this->config, 'fixed'); - } - $this->buildLogger->logSuccess(Lang::get('build_success')); } else { $this->pluginExecutor->executePlugins($this->config, 'failure'); - - if ($previous_state == Build::STATUS_SUCCESS || $previous_state == Build::STATUS_NEW) { - $this->pluginExecutor->executePlugins($this->config, 'broken'); - } - $this->buildLogger->logFailure(Lang::get('build_failed')); } + + // Clean up: + $this->buildLogger->log(Lang::get('removing_build')); + + $cmd = 'rm -Rf "%s"'; + if (IS_WIN) { + $cmd = 'rmdir /S /Q "%s"'; + } + $this->executeCommand($cmd, $this->buildPath); } catch (\Exception $ex) { $this->build->setStatus(Build::STATUS_FAILED); $this->buildLogger->logFailure(Lang::get('exception') . $ex->getMessage()); - }finally{ - // Complete stage plugins are always run - $this->pluginExecutor->executePlugins($this->config, 'complete'); } // Update the build in the database, ping any external services, etc. $this->build->sendStatusPostback(); $this->build->setFinished(new \DateTime()); - - // Clean up: - $this->buildLogger->log(Lang::get('removing_build')); - $this->build->removeBuildDirectory(); - $this->store->save($this->build); } @@ -278,14 +263,12 @@ class Builder implements LoggerAwareInterface /** * Find a binary required by a plugin. - * @param string $binary - * @param bool $quiet - * + * @param $binary * @return null|string */ - public function findBinary($binary, $quiet = false) + public function findBinary($binary) { - return $this->commandExecutor->findBinary($binary, $quiet = false); + return $this->commandExecutor->findBinary($binary, $this->buildPath); } /** @@ -304,7 +287,8 @@ class Builder implements LoggerAwareInterface */ protected function setupBuild() { - $this->buildPath = $this->build->getBuildPath(); + $this->buildPath = PHPCI_DIR . 'PHPCI/build/' . $this->build->getId() . '/'; + $this->build->currentBuildPath = $this->buildPath; $this->interpolator->setupInterpolationVars( $this->build, @@ -312,8 +296,6 @@ class Builder implements LoggerAwareInterface PHPCI_URL ); - $this->commandExecutor->setBuildPath($this->buildPath); - // Create a working copy of the project: if (!$this->build->createWorkingCopy($this, $this->buildPath)) { throw new \Exception(Lang::get('could_not_create_working')); diff --git a/PHPCI/Command/CreateBuildCommand.php b/PHPCI/Command/CreateBuildCommand.php deleted file mode 100644 index 01260080..00000000 --- a/PHPCI/Command/CreateBuildCommand.php +++ /dev/null @@ -1,85 +0,0 @@ -projectStore = $projectStore; - $this->buildService = $buildService; - } - - /** - * {@inheritDoc} - */ - protected function configure() - { - $this - ->setName('phpci:create-build') - ->setDescription(Lang::get('create_build_project')) - ->addArgument('projectId', InputArgument::REQUIRED, Lang::get('project_id_argument')) - ->addOption('commit', null, InputOption::VALUE_OPTIONAL, Lang::get('commit_id_option')) - ->addOption('branch', null, InputOption::VALUE_OPTIONAL, Lang::get('branch_name_option')); - } - - /** - * {@inheritDoc} - */ - public function execute(InputInterface $input, OutputInterface $output) - { - $projectId = $input->getArgument('projectId'); - $commitId = $input->getOption('commit'); - $branch = $input->getOption('branch'); - - $project = $this->projectStore->getById($projectId); - if (empty($project)) { - throw new \InvalidArgumentException('Project does not exist: ' . $projectId); - } - - try { - $this->buildService->createBuild($project, $commitId, $branch); - $output->writeln(Lang::get('build_created')); - } catch (\Exception $e) { - $output->writeln(sprintf('%s', Lang::get('failed'))); - $output->writeln(sprintf('%s', $e->getMessage())); - } - } -} diff --git a/PHPCI/Command/DaemonCommand.php b/PHPCI/Command/DaemonCommand.php index cb303eff..e51f31f1 100644 --- a/PHPCI/Command/DaemonCommand.php +++ b/PHPCI/Command/DaemonCommand.php @@ -1,5 +1,4 @@ - * @package PHPCI - * @subpackage Console - */ +* Daemon that loops and call the run-command. +* @author Gabriel Baker +* @package PHPCI +* @subpackage Console +*/ class DaemonCommand extends Command { - /** - * @var Logger + * @var \Monolog\Logger */ protected $logger; - /** - * @var string - */ - protected $pidFilePath; - - /** - * @var string - */ - protected $logFilePath; - - /** - * @var ProcessControlInterface - */ - protected $processControl; - - public function __construct(Logger $logger, ProcessControlInterface $processControl = null, $name = null) + public function __construct(Logger $logger, $name = null) { parent::__construct($name); $this->logger = $logger; - $this->processControl = $processControl ?: Factory::getInstance(); } protected function configure() @@ -61,30 +40,17 @@ class DaemonCommand extends Command ->setName('phpci:daemon') ->setDescription('Initiates the daemon to run commands.') ->addArgument( - 'state', InputArgument::REQUIRED, 'start|stop|status' - ) - ->addOption( - 'pid-file', 'p', InputOption::VALUE_REQUIRED, - 'Path of the PID file', - implode(DIRECTORY_SEPARATOR, - array(PHPCI_DIR, 'daemon', 'daemon.pid')) - ) - ->addOption( - 'log-file', 'l', InputOption::VALUE_REQUIRED, - 'Path of the log file', - implode(DIRECTORY_SEPARATOR, - array(PHPCI_DIR, 'daemon', 'daemon.log')) - ); + 'state', + InputArgument::REQUIRED, + 'start|stop|status' + ); } /** - * Loops through running. - */ + * Loops through running. + */ protected function execute(InputInterface $input, OutputInterface $output) { - $this->pidFilePath = $input->getOption('pid-file'); - $this->logFilePath = $input->getOption('log-file'); - $state = $input->getArgument('state'); switch ($state) { @@ -95,108 +61,64 @@ class DaemonCommand extends Command $this->stopDaemon(); break; case 'status': - $this->statusDaemon($output); + $this->statusDaemon(); break; default: - $this->output->writeln("Not a valid choice, please use start, stop or status"); + echo "Not a valid choice, please use start stop or status"; break; } + } protected function startDaemon() { - $pid = $this->getRunningPid(); - if ($pid) { - $this->logger->notice("Daemon already started", array('pid' => $pid)); + + if (file_exists(PHPCI_DIR.'/daemon/daemon.pid')) { + echo "Already started\n"; + $this->logger->warning("Daemon already started"); return "alreadystarted"; } - $this->logger->info("Trying to start the daemon"); - + $logfile = PHPCI_DIR."/daemon/daemon.log"; $cmd = "nohup %s/daemonise phpci:daemonise > %s 2>&1 &"; - $command = sprintf($cmd, PHPCI_DIR, $this->logFilePath); - $output = $exitCode = null; - exec($command, $output, $exitCode); - - if ($exitCode !== 0) { - $this->logger->error(sprintf("daemonise exited with status %d", $exitCode)); - return "notstarted"; - } - - for ($i = 0; !($pid = $this->getRunningPid()) && $i < 5; $i++) { - sleep(1); - } - - if (!$pid) { - $this->logger->error("Could not start the daemon"); - return "notstarted"; - } - - $this->logger->notice("Daemon started", array('pid' => $pid)); - return "started"; + $command = sprintf($cmd, PHPCI_DIR, $logfile); + $this->logger->info("Daemon started"); + exec($command); } protected function stopDaemon() { - $pid = $this->getRunningPid(); - if (!$pid) { - $this->logger->notice("Cannot stop the daemon as it is not started"); + + if (!file_exists(PHPCI_DIR.'/daemon/daemon.pid')) { + echo "Not started\n"; + $this->logger->warning("Can't stop daemon as not started"); return "notstarted"; } - $this->logger->info("Trying to terminate the daemon", array('pid' => $pid)); - $this->processControl->kill($pid); - - for ($i = 0; ($pid = $this->getRunningPid()) && $i < 5; $i++) { - sleep(1); - } - - if ($pid) { - $this->logger->warning("The daemon is resiting, trying to kill it", array('pid' => $pid)); - $this->processControl->kill($pid, true); - - for ($i = 0; ($pid = $this->getRunningPid()) && $i < 5; $i++) { - sleep(1); - } - } - - if (!$pid) { - $this->logger->notice("Daemon stopped"); - return "stopped"; - } - - $this->logger->error("Could not stop the daemon"); + $cmd = "kill $(cat %s/daemon/daemon.pid)"; + $command = sprintf($cmd, PHPCI_DIR); + exec($command); + $this->logger->info("Daemon stopped"); + unlink(PHPCI_DIR.'/daemon/daemon.pid'); } - protected function statusDaemon(OutputInterface $output) + protected function statusDaemon() { - $pid = $this->getRunningPid(); - if ($pid) { - $output->writeln(sprintf('The daemon is running, PID: %d', $pid)); + + if (!file_exists(PHPCI_DIR.'/daemon/daemon.pid')) { + echo "Not running\n"; + return "notrunning"; + } + + $pid = trim(file_get_contents(PHPCI_DIR.'/daemon/daemon.pid')); + $pidcheck = sprintf("/proc/%s", $pid); + if (is_dir($pidcheck)) { + echo "Running\n"; return "running"; } - $output->writeln('The daemon is not running'); + unlink(PHPCI_DIR.'/daemon/daemon.pid'); + echo "Not running\n"; return "notrunning"; } - - /** Check if there is a running daemon - * - * @return int|null - */ - protected function getRunningPid() - { - if (!file_exists($this->pidFilePath)) { - return; - } - - $pid = intval(trim(file_get_contents($this->pidFilePath))); - - if($this->processControl->isRunning($pid, true)) { - return $pid; - } - - // Not found, remove the stale PID file - unlink($this->pidFilePath); - } } diff --git a/PHPCI/Command/InstallCommand.php b/PHPCI/Command/InstallCommand.php index 5f5cbd67..04e0f2dd 100644 --- a/PHPCI/Command/InstallCommand.php +++ b/PHPCI/Command/InstallCommand.php @@ -16,12 +16,10 @@ use b8\Config; use b8\Store\Factory; use PHPCI\Helper\Lang; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Helper\DialogHelper; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use PHPCI\Service\UserService; -use Symfony\Component\Console\Question\ConfirmationQuestion; /** * Install console command - Installs PHPCI. @@ -48,9 +46,6 @@ class InstallCommand extends Command ->addOption('admin-pass', null, InputOption::VALUE_OPTIONAL, Lang::get('admin_pass')) ->addOption('admin-mail', null, InputOption::VALUE_OPTIONAL, Lang::get('admin_email')) ->addOption('config-path', null, InputOption::VALUE_OPTIONAL, Lang::get('config_path'), $defaultPath) - ->addOption('queue-disabled', null, InputOption::VALUE_NONE, 'Don\'t ask for queue details') - ->addOption('queue-server', null, InputOption::VALUE_OPTIONAL, 'Beanstalkd queue server hostname') - ->addOption('queue-name', null, InputOption::VALUE_OPTIONAL, 'Beanstalkd queue name') ->setDescription(Lang::get('install_phpci')); } @@ -234,45 +229,10 @@ class InstallCommand extends Command } $phpci['url'] = $url; - $phpci['worker'] = $this->getQueueInformation($input, $output, $dialog); return $phpci; } - /** - * If the user wants to use a queue, get the necessary details. - * @param InputInterface $input - * @param OutputInterface $output - * @param DialogHelper $dialog - * @return array - */ - protected function getQueueInformation(InputInterface $input, OutputInterface $output, DialogHelper $dialog) - { - if ($input->getOption('queue-disabled')) { - return null; - } - - $rtn = []; - - $helper = $this->getHelper('question'); - $question = new ConfirmationQuestion('Use beanstalkd to manage build queue? ', true); - - if (!$helper->ask($input, $output, $question)) { - $output->writeln('Skipping beanstalkd configuration.'); - return null; - } - - if (!$rtn['host'] = $input->getOption('queue-server')) { - $rtn['host'] = $dialog->ask($output, 'Enter your beanstalkd hostname [localhost]: ', 'localhost'); - } - - if (!$rtn['queue'] = $input->getOption('queue-name')) { - $rtn['queue'] = $dialog->ask($output, 'Enter the queue (tube) name to use [phpci]: ', 'phpci'); - } - - return $rtn; - } - /** * Load configuration for DB form CLI options or ask info to user. * @@ -363,9 +323,7 @@ class InstallCommand extends Command { $output->write(Lang::get('setting_up_db')); - $phinxBinary = escapeshellarg(PHPCI_DIR . 'vendor/bin/phinx'); - $phinxScript = escapeshellarg(PHPCI_DIR . 'phinx.php'); - shell_exec($phinxBinary . ' migrate -c ' . $phinxScript); + shell_exec(PHPCI_DIR . 'vendor/bin/phinx migrate -c "' . PHPCI_DIR . 'phinx.php"'); $output->writeln(''.Lang::get('ok').''); } diff --git a/PHPCI/Command/RebuildCommand.php b/PHPCI/Command/RebuildCommand.php index 4c24b359..165d94c7 100644 --- a/PHPCI/Command/RebuildCommand.php +++ b/PHPCI/Command/RebuildCommand.php @@ -75,8 +75,7 @@ class RebuildCommand extends Command $store = Factory::getStore('Build'); $service = new BuildService($store); - $builds = $store->getLatestBuilds(null, 1); - $lastBuild = array_shift($builds); + $lastBuild = array_shift($store->getLatestBuilds(null, 1)); $service->createDuplicateBuild($lastBuild); $runner->run(new ArgvInput(array()), $output); diff --git a/PHPCI/Command/RebuildQueueCommand.php b/PHPCI/Command/RebuildQueueCommand.php deleted file mode 100644 index 4b0af6d8..00000000 --- a/PHPCI/Command/RebuildQueueCommand.php +++ /dev/null @@ -1,85 +0,0 @@ - -* @package PHPCI -* @subpackage Console -*/ -class RebuildQueueCommand extends Command -{ - /** - * @var OutputInterface - */ - protected $output; - - /** - * @var Logger - */ - protected $logger; - - /** - * @param \Monolog\Logger $logger - * @param string $name - */ - public function __construct(Logger $logger, $name = null) - { - parent::__construct($name); - $this->logger = $logger; - } - - protected function configure() - { - $this - ->setName('phpci:rebuild-queue') - ->setDescription('Rebuilds the PHPCI worker queue.'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $this->output = $output; - - // For verbose mode we want to output all informational and above - // messages to the symphony output interface. - if ($input->hasOption('verbose') && $input->getOption('verbose')) { - $this->logger->pushHandler( - new OutputLogHandler($this->output, Logger::INFO) - ); - } - - $store = Factory::getStore('Build'); - $result = $store->getByStatus(0); - - $this->logger->addInfo(Lang::get('found_n_builds', count($result['items']))); - - $buildService = new BuildService($store); - - while (count($result['items'])) { - $build = array_shift($result['items']); - $build = BuildFactory::getBuild($build); - - $this->logger->addInfo('Added build #' . $build->getId() . ' to queue.'); - $buildService->addBuildToQueue($build); - } - } -} diff --git a/PHPCI/Command/RunCommand.php b/PHPCI/Command/RunCommand.php index c2c352e6..0cbd8e6a 100644 --- a/PHPCI/Command/RunCommand.php +++ b/PHPCI/Command/RunCommand.php @@ -166,7 +166,7 @@ class RunCommand extends Command $build->setStatus(Build::STATUS_FAILED); $build->setFinished(new \DateTime()); $store->save($build); - $build->removeBuildDirectory(); + $this->removeBuildDirectory($build); continue; } @@ -175,4 +175,19 @@ class RunCommand extends Command return $rtn; } + + protected function removeBuildDirectory($build) + { + $buildPath = PHPCI_DIR . 'PHPCI/build/' . $build->getId() . '/'; + + if (is_dir($buildPath)) { + $cmd = 'rm -Rf "%s"'; + + if (IS_WIN) { + $cmd = 'rmdir /S /Q "%s"'; + } + + shell_exec($cmd); + } + } } diff --git a/PHPCI/Command/UpdateCommand.php b/PHPCI/Command/UpdateCommand.php index 13e31f79..8170675a 100644 --- a/PHPCI/Command/UpdateCommand.php +++ b/PHPCI/Command/UpdateCommand.php @@ -9,7 +9,6 @@ namespace PHPCI\Command; -use b8\Config; use Monolog\Logger; use PHPCI\Helper\Lang; use Symfony\Component\Console\Command\Command; @@ -60,9 +59,19 @@ class UpdateCommand extends Command protected function verifyInstalled(OutputInterface $output) { - $config = Config::getInstance(); - $phpciUrl = $config->get('phpci.url'); + if (!file_exists(PHPCI_DIR . 'PHPCI/config.yml')) { + $output->writeln(''.Lang::get('not_installed').''); + $output->writeln(''.Lang::get('install_instead').''); + return false; + } - return !empty($phpciUrl); + $content = file_get_contents(PHPCI_DIR . 'PHPCI/config.yml'); + if (empty($content)) { + $output->writeln(''.Lang::get('not_installed').''); + $output->writeln(''.Lang::get('install_instead').''); + return false; + } + + return true; } } diff --git a/PHPCI/Command/WorkerCommand.php b/PHPCI/Command/WorkerCommand.php deleted file mode 100644 index 5ceb6a84..00000000 --- a/PHPCI/Command/WorkerCommand.php +++ /dev/null @@ -1,87 +0,0 @@ - -* @package PHPCI -* @subpackage Console -*/ -class WorkerCommand extends Command -{ - /** - * @var OutputInterface - */ - protected $output; - - /** - * @var Logger - */ - protected $logger; - - /** - * @param \Monolog\Logger $logger - * @param string $name - */ - public function __construct(Logger $logger, $name = null) - { - parent::__construct($name); - $this->logger = $logger; - } - - protected function configure() - { - $this - ->setName('phpci:worker') - ->setDescription('Runs the PHPCI build worker.') - ->addOption('debug', null, null, 'Run PHPCI in Debug Mode'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $this->output = $output; - - // For verbose mode we want to output all informational and above - // messages to the symphony output interface. - if ($input->hasOption('verbose') && $input->getOption('verbose')) { - $this->logger->pushHandler( - new OutputLogHandler($this->output, Logger::INFO) - ); - } - - // Allow PHPCI to run in "debug mode" - if ($input->hasOption('debug') && $input->getOption('debug')) { - $output->writeln('Debug mode enabled.'); - define('PHPCI_DEBUG_MODE', true); - } - - $config = Config::getInstance()->get('phpci.worker', []); - - if (empty($config['host']) || empty($config['queue'])) { - $error = 'The worker is not configured. You must set a host and queue in your config.yml file.'; - throw new \Exception($error); - } - - $worker = new BuildWorker($config['host'], $config['queue']); - $worker->setLogger($this->logger); - $worker->setMaxJobs(Config::getInstance()->get('phpci.worker.max_jobs', -1)); - $worker->startWorker(); - } -} diff --git a/PHPCI/Controller/BuildController.php b/PHPCI/Controller/BuildController.php index 55ccbb37..bf898d2d 100644 --- a/PHPCI/Controller/BuildController.php +++ b/PHPCI/Controller/BuildController.php @@ -13,7 +13,6 @@ use b8; use b8\Exception\HttpException\NotFoundException; use b8\Http\Response\JsonResponse; use PHPCI\BuildFactory; -use PHPCI\Helper\AnsiConverter; use PHPCI\Helper\Lang; use PHPCI\Model\Build; use PHPCI\Model\Project; @@ -63,42 +62,24 @@ class BuildController extends \PHPCI\Controller $this->view->plugins = $this->getUiPlugins(); $this->view->build = $build; - $this->view->data = $this->getBuildData($build); + $this->view->data = json_encode($this->getBuildData($build)); $this->layout->title = Lang::get('build_n', $buildId); $this->layout->subtitle = $build->getProjectTitle(); - switch ($build->getStatus()) { - case 0: - $this->layout->skin = 'blue'; - break; - - case 1: - $this->layout->skin = 'yellow'; - break; - - case 2: - $this->layout->skin = 'green'; - break; - - case 3: - $this->layout->skin = 'red'; - break; - } - - $rebuild = Lang::get('rebuild_now'); - $rebuildLink = PHPCI_URL . 'build/rebuild/' . $build->getId(); - - $delete = Lang::get('delete_build'); - $deleteLink = PHPCI_URL . 'build/delete/' . $build->getId(); - - $actions = "{$rebuild} "; + $nav = array( + 'title' => Lang::get('build_n', $buildId), + 'icon' => 'cog', + 'links' => array( + 'build/rebuild/' . $build->getId() => Lang::get('rebuild_now'), + ), + ); if ($this->currentUserIsAdmin()) { - $actions .= " {$delete}"; + $nav['links']['build/delete/' . $build->getId()] = Lang::get('delete_build'); } - $this->layout->actions = $actions; + $this->layout->nav = $nav; } /** @@ -162,7 +143,7 @@ class BuildController extends \PHPCI\Controller /** * Get build data from database and json encode it: */ - protected function getBuildData(Build $build) + protected function getBuildData($build) { $data = array(); $data['status'] = (int)$build->getStatus(); @@ -170,19 +151,6 @@ class BuildController extends \PHPCI\Controller $data['created'] = !is_null($build->getCreated()) ? $build->getCreated()->format('Y-m-d H:i:s') : null; $data['started'] = !is_null($build->getStarted()) ? $build->getStarted()->format('Y-m-d H:i:s') : null; $data['finished'] = !is_null($build->getFinished()) ? $build->getFinished()->format('Y-m-d H:i:s') : null; - $data['duration'] = $build->getDuration(); - - /** @var \PHPCI\Store\BuildErrorStore $errorStore */ - $errorStore = b8\Store\Factory::getStore('BuildError'); - $errors = $errorStore->getErrorsForBuild($build->getId(), $this->getParam('since', null)); - - $errorView = new b8\View('Build/errors'); - $errorView->build = $build; - $errorView->errors = $errors; - - $data['errors'] = $errorStore->getErrorTotalForBuild($build->getId()); - $data['error_html'] = $errorView->render(); - $data['since'] = (new \DateTime())->format('Y-m-d H:i:s'); return $data; } @@ -200,10 +168,6 @@ class BuildController extends \PHPCI\Controller $build = $this->buildService->createDuplicateBuild($copy); - if ($this->buildService->queueError) { - $_SESSION['global_error'] = Lang::get('add_to_queue_failed'); - } - $response = new b8\Http\Response\RedirectResponse(); $response->setHeader('Location', PHPCI_URL.'build/view/' . $build->getId()); return $response; @@ -234,7 +198,11 @@ class BuildController extends \PHPCI\Controller */ protected function cleanLog($log) { - return AnsiConverter::convert($log); + $log = str_replace('[0;32m', '', $log); + $log = str_replace('[0;31m', '', $log); + $log = str_replace('[0m', '', $log); + + return $log; } /** diff --git a/PHPCI/Controller/BuildStatusController.php b/PHPCI/Controller/BuildStatusController.php index 62cb9ba7..06f9400b 100644 --- a/PHPCI/Controller/BuildStatusController.php +++ b/PHPCI/Controller/BuildStatusController.php @@ -15,7 +15,6 @@ use b8\Store; use PHPCI\BuildFactory; use PHPCI\Model\Project; use PHPCI\Model\Build; -use PHPCI\Service\BuildStatusService; /** * Build Status Controller - Allows external access to build status information / images. @@ -25,9 +24,10 @@ use PHPCI\Service\BuildStatusService; */ class BuildStatusController extends \PHPCI\Controller { - /* @var \PHPCI\Store\ProjectStore */ + /** + * @var \PHPCI\Store\ProjectStore + */ protected $projectStore; - /* @var \PHPCI\Store\BuildStore */ protected $buildStore; /** @@ -70,69 +70,11 @@ class BuildStatusController extends \PHPCI\Controller return $status; } - /** - * Displays projects information in ccmenu format - * - * @param $projectId - * @return bool - * @throws \Exception - * @throws b8\Exception\HttpException - */ - public function ccxml($projectId) - { - /* @var Project $project */ - $project = $this->projectStore->getById($projectId); - $xml = new \SimpleXMLElement(''); - - if (!$project instanceof Project || !$project->getAllowPublicStatus()) { - return $this->renderXml($xml); - } - - try { - $branchList = $this->buildStore->getBuildBranches($projectId); - - if (!$branchList) { - $branchList = array($project->getBranch()); - } - - foreach ($branchList as $branch) { - $buildStatusService = new BuildStatusService($branch, $project, $project->getLatestBuild($branch)); - if ($attributes = $buildStatusService->toArray()) { - $projectXml = $xml->addChild('Project'); - foreach ($attributes as $attributeKey => $attributeValue) { - $projectXml->addAttribute($attributeKey, $attributeValue); - } - } - } - } catch (\Exception $e) { - $xml = new \SimpleXMLElement(''); - } - - return $this->renderXml($xml); - } - - /** - * @param \SimpleXMLElement $xml - * @return bool - */ - protected function renderXml(\SimpleXMLElement $xml = null) - { - $this->response->setHeader('Content-Type', 'text/xml'); - $this->response->setContent($xml->asXML()); - $this->response->flush(); - echo $xml->asXML(); - - return true; - } - /** * Returns the appropriate build status image in SVG format for a given project. */ public function image($projectId) { - $style = $this->getParam('style', 'plastic'); - $label = $this->getParam('label', 'build'); - $status = $this->getStatus($projectId); if (is_null($status)) { @@ -142,13 +84,7 @@ class BuildStatusController extends \PHPCI\Controller } $color = ($status == 'passing') ? 'green' : 'red'; - $image = file_get_contents(sprintf( - 'http://img.shields.io/badge/%s-%s-%s.svg?style=%s', - $label, - $status, - $color, - $style - )); + $image = file_get_contents('http://img.shields.io/badge/build-' . $status . '-' . $color . '.svg'); $this->response->disableLayout(); $this->response->setHeader('Content-Type', 'image/svg+xml'); diff --git a/PHPCI/Controller/GroupController.php b/PHPCI/Controller/GroupController.php deleted file mode 100644 index 898f9e41..00000000 --- a/PHPCI/Controller/GroupController.php +++ /dev/null @@ -1,120 +0,0 @@ - - * @package PHPCI - * @subpackage Web - */ -class GroupController extends Controller -{ - /** - * @var \PHPCI\Store\ProjectGroupStore - */ - protected $groupStore; - - /** - * Set up this controller. - */ - public function init() - { - $this->groupStore = b8\Store\Factory::getStore('ProjectGroup'); - } - - /** - * List project groups. - */ - public function index() - { - $this->requireAdmin(); - - $groups = array(); - $groupList = $this->groupStore->getWhere(array(), 100, 0, array(), array('title' => 'ASC')); - - foreach ($groupList['items'] as $group) { - $thisGroup = array( - 'title' => $group->getTitle(), - 'id' => $group->getId(), - ); - $projects = b8\Store\Factory::getStore('Project')->getByGroupId($group->getId()); - $thisGroup['projects'] = $projects['items']; - $groups[] = $thisGroup; - } - - $this->view->groups = $groups; - } - - /** - * Add or edit a project group. - * @param null $groupId - * @return void|b8\Http\Response\RedirectResponse - */ - public function edit($groupId = null) - { - $this->requireAdmin(); - - if (!is_null($groupId)) { - $group = $this->groupStore->getById($groupId); - } else { - $group = new ProjectGroup(); - } - - if ($this->request->getMethod() == 'POST') { - $group->setTitle($this->getParam('title')); - $this->groupStore->save($group); - - $response = new b8\Http\Response\RedirectResponse(); - $response->setHeader('Location', PHPCI_URL.'group'); - return $response; - } - - $form = new Form(); - $form->setMethod('POST'); - $form->setAction(PHPCI_URL . 'group/edit' . (!is_null($groupId) ? '/' . $groupId : '')); - - $title = new Form\Element\Text('title'); - $title->setContainerClass('form-group'); - $title->setClass('form-control'); - $title->setLabel('Group Title'); - $title->setValue($group->getTitle()); - - $submit = new Form\Element\Submit(); - $submit->setValue('Save Group'); - - $form->addField($title); - $form->addField($submit); - - $this->view->form = $form; - } - - /** - * Delete a project group. - * @param $groupId - * @return b8\Http\Response\RedirectResponse - */ - public function delete($groupId) - { - $this->requireAdmin(); - $group = $this->groupStore->getById($groupId); - - $this->groupStore->delete($group); - $response = new b8\Http\Response\RedirectResponse(); - $response->setHeader('Location', PHPCI_URL.'group'); - return $response; - } -} diff --git a/PHPCI/Controller/HomeController.php b/PHPCI/Controller/HomeController.php index 4241d324..65abf79a 100644 --- a/PHPCI/Controller/HomeController.php +++ b/PHPCI/Controller/HomeController.php @@ -23,20 +23,15 @@ use PHPCI\Model\Build; class HomeController extends \PHPCI\Controller { /** - * @var \PHPCI\Store\BuildStore + * @var \b8\Store\BuildStore */ protected $buildStore; /** - * @var \PHPCI\Store\ProjectStore + * @var \b8\Store\ProjectStore */ protected $projectStore; - /** - * @var \PHPCI\Store\ProjectGroupStore - */ - protected $groupStore; - /** * Initialise the controller, set up stores and services. */ @@ -44,7 +39,6 @@ class HomeController extends \PHPCI\Controller { $this->buildStore = b8\Store\Factory::getStore('Build'); $this->projectStore = b8\Store\Factory::getStore('Project'); - $this->groupStore = b8\Store\Factory::getStore('ProjectGroup'); } /** @@ -53,6 +47,9 @@ class HomeController extends \PHPCI\Controller public function index() { $this->layout->title = Lang::get('dashboard'); + + $projects = $this->projectStore->getWhere(array(), 50, 0, array(), array('title' => 'ASC')); + $builds = $this->buildStore->getLatestBuilds(null, 10); foreach ($builds as &$build) { @@ -60,7 +57,8 @@ class HomeController extends \PHPCI\Controller } $this->view->builds = $builds; - $this->view->groups = $this->getGroupInfo(); + $this->view->projects = $projects['items']; + $this->view->summary = $this->getSummaryHtml($projects); return $this->view->render(); } @@ -94,22 +92,12 @@ class HomeController extends \PHPCI\Controller protected function getSummaryHtml($projects) { $summaryBuilds = array(); - $successes = array(); - $failures = array(); - $counts = array(); + $successes = array(); + $failures = array(); - foreach ($projects as $project) { + foreach ($projects['items'] as $project) { $summaryBuilds[$project->getId()] = $this->buildStore->getLatestBuilds($project->getId()); - $count = $this->buildStore->getWhere( - array('project_id' => $project->getId()), - 1, - 0, - array(), - array('id' => 'DESC') - ); - $counts[$project->getId()] = $count['count']; - $success = $this->buildStore->getLastBuildByStatus($project->getId(), Build::STATUS_SUCCESS); $failure = $this->buildStore->getLastBuildByStatus($project->getId(), Build::STATUS_FAILED); @@ -118,11 +106,10 @@ class HomeController extends \PHPCI\Controller } $summaryView = new b8\View('SummaryTable'); - $summaryView->projects = $projects; - $summaryView->builds = $summaryBuilds; + $summaryView->projects = $projects['items']; + $summaryView->builds = $summaryBuilds; $summaryView->successful = $successes; - $summaryView->failed = $failures; - $summaryView->counts = $counts; + $summaryView->failed = $failures; return $summaryView->render(); } @@ -143,24 +130,4 @@ class HomeController extends \PHPCI\Controller return $view->render(); } - - /** - * Get a summary of the project groups we have, and what projects they have in them. - * @return array - */ - protected function getGroupInfo() - { - $rtn = array(); - $groups = $this->groupStore->getWhere(array(), 100, 0, array(), array('title' => 'ASC')); - - foreach ($groups['items'] as $group) { - $thisGroup = array('title' => $group->getTitle()); - $projects = $this->projectStore->getByGroupId($group->getId()); - $thisGroup['projects'] = $projects['items']; - $thisGroup['summary'] = $this->getSummaryHtml($thisGroup['projects']); - $rtn[] = $thisGroup; - } - - return $rtn; - } } diff --git a/PHPCI/Controller/PluginController.php b/PHPCI/Controller/PluginController.php index 64cb1463..20675e46 100644 --- a/PHPCI/Controller/PluginController.php +++ b/PHPCI/Controller/PluginController.php @@ -23,6 +23,24 @@ use PHPCI\Plugin\Util\PluginInformationCollection; */ class PluginController extends \PHPCI\Controller { + protected $required = array( + 'php', + 'ext-pdo', + 'ext-pdo_mysql', + 'block8/b8framework', + 'ircmaxell/password-compat', + 'swiftmailer/swiftmailer', + 'symfony/yaml', + 'symfony/console', + 'psr/log', + 'monolog/monolog', + 'pimple/pimple', + 'robmorgan/phinx', + ); + + protected $canInstall; + protected $composerPath; + /** * List all enabled plugins, installed and recommend packages. * @return string @@ -31,8 +49,12 @@ class PluginController extends \PHPCI\Controller { $this->requireAdmin(); + $this->view->canWrite = is_writable(APPLICATION_PATH . 'composer.json'); + $this->view->required = $this->required; + $json = $this->getComposerJson(); $this->view->installedPackages = $json['require']; + $this->view->suggestedPackages = $json['suggest']; $pluginInfo = new PluginInformationCollection(); $pluginInfo->add(FilesPluginInformation::newFromDir( @@ -49,6 +71,49 @@ class PluginController extends \PHPCI\Controller return $this->view->render(); } + /** + * Remove a given package. + */ + public function remove() + { + $this->requireAdmin(); + + $package = $this->getParam('package', null); + $json = $this->getComposerJson(); + + $response = new b8\Http\Response\RedirectResponse(); + + if (!in_array($package, $this->required)) { + unset($json['require'][$package]); + $this->setComposerJson($json); + + $response->setHeader('Location', PHPCI_URL . 'plugin?r=' . $package); + return $response; + } + + $response->setHeader('Location', PHPCI_URL); + return $response; + } + + /** + * Install a given package. + */ + public function install() + { + $this->requireAdmin(); + + $package = $this->getParam('package', null); + $version = $this->getParam('version', '*'); + + $json = $this->getComposerJson(); + $json['require'][$package] = $version; + $this->setComposerJson($json); + + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', PHPCI_URL . 'plugin?w=' . $package); + return $response; + } + /** * Get the json-decoded contents of the composer.json file. * @return mixed @@ -58,4 +123,83 @@ class PluginController extends \PHPCI\Controller $json = file_get_contents(APPLICATION_PATH . 'composer.json'); return json_decode($json, true); } + + /** + * Convert array to json and save composer.json + * + * @param $array + */ + protected function setComposerJson($array) + { + if (defined('JSON_PRETTY_PRINT')) { + $json = json_encode($array, JSON_PRETTY_PRINT); + } else { + $json = json_encode($array); + } + + file_put_contents(APPLICATION_PATH . 'composer.json', $json); + } + + /** + * Find a system binary. + * @param $binary + * @return null|string + */ + protected function findBinary($binary) + { + if (is_string($binary)) { + $binary = array($binary); + } + + foreach ($binary as $bin) { + // Check project root directory: + if (is_file(APPLICATION_PATH . $bin)) { + return APPLICATION_PATH . $bin; + } + + // Check Composer bin dir: + if (is_file(APPLICATION_PATH . 'vendor/bin/' . $bin)) { + return APPLICATION_PATH . 'vendor/bin/' . $bin; + } + + // Use "which" + $which = trim(shell_exec('which ' . $bin)); + + if (!empty($which)) { + return $which; + } + } + + return null; + } + + /** + * Perform a search on packagist.org. + */ + public function packagistSearch() + { + $searchQuery = $this->getParam('q', ''); + $http = new \b8\HttpClient(); + $http->setHeaders(array('User-Agent: PHPCI/1.0 (+https://www.phptesting.org)')); + $res = $http->get('https://packagist.org/search.json', array('q' => $searchQuery)); + + $response = new b8\Http\Response\JsonResponse(); + $response->setContent($res['body']); + return $response; + } + + /** + * Look up available versions of a given package on packagist.org + */ + public function packagistVersions() + { + $name = $this->getParam('p', ''); + $http = new \b8\HttpClient(); + $http->setHeaders(array('User-Agent: PHPCI/1.0 (+https://www.phptesting.org)')); + $res = $http->get('https://packagist.org/packages/'.$name.'.json'); + + $response = new b8\Http\Response\JsonResponse(); + $response->setContent($res['body']); + return $response; + } } diff --git a/PHPCI/Controller/ProjectController.php b/PHPCI/Controller/ProjectController.php index 72be46e5..f2f63b26 100644 --- a/PHPCI/Controller/ProjectController.php +++ b/PHPCI/Controller/ProjectController.php @@ -86,7 +86,7 @@ class ProjectController extends PHPCI\Controller $this->view->builds = $builds[0]; $this->view->total = $builds[1]; $this->view->project = $project; - $this->view->branch = urldecode($branch); + $this->view->branch = urldecode($branch); $this->view->branches = $this->projectStore->getKnownBranches($projectId); $this->view->page = $page; $this->view->pages = $pages; @@ -116,10 +116,6 @@ class ProjectController extends PHPCI\Controller $email = $_SESSION['phpci_user']->getEmail(); $build = $this->buildService->createBuild($project, null, urldecode($branch), $email); - if ($this->buildService->queueError) { - $_SESSION['global_error'] = Lang::get('add_to_queue_failed'); - } - $response = new b8\Http\Response\RedirectResponse(); $response->setHeader('Location', PHPCI_URL.'build/view/' . $build->getId()); return $response; @@ -224,7 +220,6 @@ class ProjectController extends PHPCI\Controller 'build_config' => $this->getParam('build_config', null), 'allow_public_status' => $this->getParam('allow_public_status', 0), 'branch' => $this->getParam('branch', null), - 'group' => $this->getParam('group_id', null), ); $project = $this->projectService->createProject($title, $type, $reference, $options); @@ -287,9 +282,7 @@ class ProjectController extends PHPCI\Controller 'ssh_public_key' => $this->getParam('pubkey', null), 'build_config' => $this->getParam('build_config', null), 'allow_public_status' => $this->getParam('allow_public_status', 0), - 'archived' => $this->getParam('archived', 0), 'branch' => $this->getParam('branch', null), - 'group' => $this->getParam('group_id', null), ); $project = $this->projectService->updateProject($project, $title, $type, $reference, $options); @@ -358,32 +351,12 @@ class ProjectController extends PHPCI\Controller $field->setClass('form-control')->setContainerClass('form-group')->setValue('master'); $form->addField($field); - $field = Form\Element\Select::create('group_id', 'Project Group', true); - $field->setClass('form-control')->setContainerClass('form-group')->setValue(1); - - $groups = array(); - $groupStore = b8\Store\Factory::getStore('ProjectGroup'); - $groupList = $groupStore->getWhere(array(), 100, 0, array(), array('title' => 'ASC')); - - foreach ($groupList['items'] as $group) { - $groups[$group->getId()] = $group->getTitle(); - } - - $field->setOptions($groups); - $form->addField($field); - $field = Form\Element\Checkbox::create('allow_public_status', Lang::get('allow_public_status'), false); $field->setContainerClass('form-group'); $field->setCheckedValue(1); $field->setValue(0); $form->addField($field); - $field = Form\Element\Checkbox::create('archived', Lang::get('archived'), false); - $field->setContainerClass('form-group'); - $field->setCheckedValue(1); - $field->setValue(0); - $form->addField($field); - $field = new Form\Element\Submit(); $field->setValue(Lang::get('save_project')); $field->setContainerClass('form-group'); diff --git a/PHPCI/Controller/SessionController.php b/PHPCI/Controller/SessionController.php index b68d61f7..540b043f 100644 --- a/PHPCI/Controller/SessionController.php +++ b/PHPCI/Controller/SessionController.php @@ -43,23 +43,15 @@ class SessionController extends \PHPCI\Controller $isLoginFailure = false; if ($this->request->getMethod() == 'POST') { - $token = $this->getParam('token'); - if (!isset($token, $_SESSION['login_token']) || $token !== $_SESSION['login_token']) { - $isLoginFailure = true; + $user = $this->userStore->getByEmail($this->getParam('email')); + + if ($user && password_verify($this->getParam('password', ''), $user->getHash())) { + $_SESSION['phpci_user_id'] = $user->getId(); + $response = new b8\Http\Response\RedirectResponse(); + $response->setHeader('Location', $this->getLoginRedirect()); + return $response; } else { - unset($_SESSION['login_token']); - - $user = $this->userStore->getByEmail($this->getParam('email')); - - if ($user && password_verify($this->getParam('password', ''), $user->getHash())) { - session_regenerate_id(true); - $_SESSION['phpci_user_id'] = $user->getId(); - $response = new b8\Http\Response\RedirectResponse(); - $response->setHeader('Location', $this->getLoginRedirect()); - return $response; - } else { - $isLoginFailure = true; - } + $isLoginFailure = true; } } @@ -86,15 +78,9 @@ class SessionController extends \PHPCI\Controller $pwd->setClass('btn-success'); $form->addField($pwd); - $tokenValue = $this->generateToken(); - $_SESSION['login_token'] = $tokenValue; - $token = new b8\Form\Element\Hidden('token'); - $token->setValue($tokenValue); - $form->addField($token); - $this->view->form = $form->render(); $this->view->failed = $isLoginFailure; - + return $this->view->render(); } @@ -194,20 +180,4 @@ class SessionController extends \PHPCI\Controller return $rtn; } - - /** Generate a random token. - * - * @return string - */ - protected function generateToken() - { - if (function_exists('openssl_random_pseudo_bytes')) { - return bin2hex(openssl_random_pseudo_bytes(16)); - } - - return sprintf("%04x", mt_rand(0, 0xFFFF)) - . sprintf("%04x", mt_rand(0, 0xFFFF)) - . sprintf("%04x", mt_rand(0, 0xFFFF)) - . sprintf("%04x", mt_rand(0, 0xFFFF)); - } } diff --git a/PHPCI/Controller/SettingsController.php b/PHPCI/Controller/SettingsController.php index 645e19a4..3c5ab5f4 100644 --- a/PHPCI/Controller/SettingsController.php +++ b/PHPCI/Controller/SettingsController.php @@ -40,7 +40,7 @@ class SettingsController extends Controller parent::init(); $parser = new Parser(); - $yaml = file_get_contents(PHPCI_CONFIG_FILE); + $yaml = file_get_contents(APPLICATION_PATH . 'PHPCI/config.yml'); $this->settings = $parser->parse($yaml); } @@ -76,7 +76,6 @@ class SettingsController extends Controller $authSettings = $this->settings['phpci']['authentication_settings']; } - $this->view->configFile = PHPCI_CONFIG_FILE; $this->view->basicSettings = $this->getBasicForm($basicSettings); $this->view->buildSettings = $this->getBuildForm($buildSettings); $this->view->github = $this->getGithubForm(); @@ -242,7 +241,7 @@ class SettingsController extends Controller { $dumper = new Dumper(); $yaml = $dumper->dump($this->settings, 4); - file_put_contents(PHPCI_CONFIG_FILE, $yaml); + file_put_contents(APPLICATION_PATH . 'PHPCI/config.yml', $yaml); if (error_get_last()) { $error_get_last = error_get_last(); @@ -329,7 +328,7 @@ class SettingsController extends Controller $field->setContainerClass('form-group'); $form->addField($field); - $field = new Form\Element\Password('smtp_password'); + $field = new Form\Element\Text('smtp_password'); $field->setRequired(false); $field->setLabel(Lang::get('smtp_password')); $field->setClass('form-control'); @@ -351,7 +350,7 @@ class SettingsController extends Controller $form->addField($field); $field = new Form\Element\Select('smtp_encryption'); - $field->setOptions(array('' => Lang::get('none'), 'tls' => Lang::get('tls'), 'ssl' => Lang::get('ssl'))); + $field->setOptions(['' => Lang::get('none'), 'tls' => Lang::get('tls'), 'ssl' => Lang::get('ssl')]); $field->setRequired(false); $field->setLabel(Lang::get('use_smtp_encryption')); $field->setContainerClass('form-group'); @@ -387,7 +386,7 @@ class SettingsController extends Controller */ protected function canWriteConfig() { - return is_writeable(PHPCI_CONFIG_FILE); + return is_writeable(APPLICATION_PATH . 'PHPCI/config.yml'); } /** @@ -406,13 +405,13 @@ class SettingsController extends Controller $field->setLabel(Lang::get('failed_after')); $field->setClass('form-control'); $field->setContainerClass('form-group'); - $field->setOptions(array( + $field->setOptions([ 300 => Lang::get('5_mins'), 900 => Lang::get('15_mins'), 1800 => Lang::get('30_mins'), 3600 => Lang::get('1_hour'), 10800 => Lang::get('3_hours'), - )); + ]); $field->setValue(1800); $form->addField($field); @@ -444,7 +443,7 @@ class SettingsController extends Controller $field->setClass('form-control'); $field->setContainerClass('form-group'); $field->setOptions(Lang::getLanguageOptions()); - $field->setValue(Lang::getLanguage()); + $field->setValue('en'); $form->addField($field); diff --git a/PHPCI/Controller/UserController.php b/PHPCI/Controller/UserController.php index 19a7313f..8d09ecd0 100644 --- a/PHPCI/Controller/UserController.php +++ b/PHPCI/Controller/UserController.php @@ -123,7 +123,6 @@ class UserController extends Controller $lang->setLabel(Lang::get('language')); $lang->setRequired(true); $lang->setOptions(Lang::getLanguageOptions()); - $lang->setValue(Lang::getLanguage()); $form->addField($lang); $submit = new Form\Element\Submit(); diff --git a/PHPCI/Controller/WebhookController.php b/PHPCI/Controller/WebhookController.php index 4b444d03..cef7dc53 100644 --- a/PHPCI/Controller/WebhookController.php +++ b/PHPCI/Controller/WebhookController.php @@ -2,7 +2,7 @@ /** * PHPCI - Continuous Integration for PHP * - * @copyright Copyright 2014-2015, Block 8 Limited. + * @copyright Copyright 2014, Block 8 Limited. * @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md * @link https://www.phptesting.org/ */ @@ -11,39 +11,31 @@ namespace PHPCI\Controller; use b8; use b8\Store; -use Exception; use PHPCI\BuildFactory; -use PHPCI\Model\Project; use PHPCI\Service\BuildService; -use PHPCI\Store\BuildStore; -use PHPCI\Store\ProjectStore; /** * Webhook Controller - Processes webhook pings from BitBucket, Github, Gitlab, etc. - * * @author Dan Cryer * @author Sami Tikka * @author Alex Russell - * @author Guillaume Perréal * @package PHPCI * @subpackage Web - * - * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ -class WebhookController extends \b8\Controller +class WebhookController extends \PHPCI\Controller { /** - * @var BuildStore + * @var \PHPCI\Store\BuildStore */ protected $buildStore; /** - * @var ProjectStore + * @var \PHPCI\Store\ProjectStore */ protected $projectStore; /** - * @var BuildService + * @var \PHPCI\Service\BuildService */ protected $buildService; @@ -57,397 +49,289 @@ class WebhookController extends \b8\Controller $this->buildService = new BuildService($this->buildStore); } - /** Handle the action, Ensuring to return a JsonResponse. - * - * @param string $action - * @param mixed $actionParams - * - * @return \b8\Http\Response + /** + * Called by Bitbucket POST service. */ - public function handleAction($action, $actionParams) + public function bitbucket($project) { $response = new b8\Http\Response\JsonResponse(); - try { - $data = parent::handleAction($action, $actionParams); - if (isset($data['responseCode'])) { - $response->setResponseCode($data['responseCode']); - unset($data['responseCode']); - } - $response->setContent($data); - } catch (Exception $ex) { - $response->setResponseCode(500); - $response->setContent(array('status' => 'failed', 'error' => $ex->getMessage())); - } - return $response; - } + $response->setContent(array('status' => 'ok')); - /** - * Called by Bitbucket. - */ - public function bitbucket($projectId) - { - $project = $this->fetchProject($projectId, 'bitbucket'); - - // Support both old services and new webhooks - if ($payload = $this->getParam('payload')) { - return $this->bitbucketService(json_decode($payload, true), $project); - } - - $payload = json_decode(file_get_contents("php://input"), true); - - if (empty($payload['push']['changes'])) { - // Invalid event from bitbucket - return [ - 'status' => 'failed', - 'commits' => [] - ]; - } - - return $this->bitbucketWebhook($payload, $project); - } - - /** - * Bitbucket webhooks. - */ - protected function bitbucketWebhook($payload, $project) - { - $results = array(); - $status = 'failed'; - foreach ($payload['push']['changes'] as $commit) { - try { - $email = $commit['new']['target']['author']['raw']; - $email = substr($email, 0, strpos($email, '>')); - $email = substr($email, strpos($email, '<') + 1); - - $results[$commit['new']['target']['hash']] = $this->createBuild( - $project, - $commit['new']['target']['hash'], - $commit['new']['name'], - $email, - $commit['new']['target']['message'] - ); - $status = 'ok'; - } catch (Exception $ex) { - $results[$commit['new']['target']['hash']] = array('status' => 'failed', 'error' => $ex->getMessage()); - } - } - - return array('status' => $status, 'commits' => $results); - } - - /** - * Bitbucket POST service. - */ - protected function bitbucketService($payload, $project) - { $payload = json_decode($this->getParam('payload'), true); - $results = array(); - $status = 'failed'; foreach ($payload['commits'] as $commit) { try { $email = $commit['raw_author']; $email = substr($email, 0, strpos($email, '>')); $email = substr($email, strpos($email, '<') + 1); - $results[$commit['raw_node']] = $this->createBuild( - $project, - $commit['raw_node'], - $commit['branch'], - $email, - $commit['message'] - ); - $status = 'ok'; - } catch (Exception $ex) { - $results[$commit['raw_node']] = array('status' => 'failed', 'error' => $ex->getMessage()); + $this->createBuild($project, $commit['raw_node'], $commit['branch'], $email, $commit['message']); + } catch (\Exception $ex) { + $response->setResponseCode(500); + $response->setContent(array('status' => 'failed', 'error' => $ex->getMessage())); + break; } } - return array('status' => $status, 'commits' => $results); + return $response; } /** * Called by POSTing to /webhook/git/?branch=&commit= * - * @param string $projectId + * @param string $project */ - public function git($projectId) + public function git($project) { - $project = $this->fetchProject($projectId, array('local', 'remote')); - $branch = $this->getParam('branch', $project->getBranch()); + $response = new b8\Http\Response\JsonResponse(); + $response->setContent(array('status' => 'ok')); + + $branch = $this->getParam('branch'); $commit = $this->getParam('commit'); $commitMessage = $this->getParam('message'); $committer = $this->getParam('committer'); - return $this->createBuild($project, $commit, $branch, $committer, $commitMessage); + try { + if (empty($branch)) { + $branch = 'master'; + } + + if (empty($commit)) { + $commit = null; + } + + if (empty($commitMessage)) { + $commitMessage = null; + } + + if (empty($committer)) { + $committer = null; + } + + $this->createBuild($project, $commit, $branch, $committer, $commitMessage); + } catch (\Exception $ex) { + $response->setResponseCode(500); + $response->setContent(array('status' => 'failed', 'error' => $ex->getMessage())); + } + + return $response; } /** * Called by Github Webhooks: */ - public function github($projectId) + public function github($project) { - $project = $this->fetchProject($projectId, 'github'); + $response = new b8\Http\Response\JsonResponse(); + $response->setContent(array('status' => 'ok')); switch ($_SERVER['CONTENT_TYPE']) { case 'application/json': $payload = json_decode(file_get_contents('php://input'), true); break; + case 'application/x-www-form-urlencoded': $payload = json_decode($this->getParam('payload'), true); break; + default: - return array('status' => 'failed', 'error' => 'Content type not supported.', 'responseCode' => 401); + $response->setResponseCode(401); + $response->setContent(array('status' => 'failed', 'error' => 'Content type not supported.')); + return $response; } // Handle Pull Request web hooks: if (array_key_exists('pull_request', $payload)) { - return $this->githubPullRequest($project, $payload); + return $this->githubPullRequest($project, $payload, $response); } // Handle Push web hooks: if (array_key_exists('commits', $payload)) { - return $this->githubCommitRequest($project, $payload); + return $this->githubCommitRequest($project, $payload, $response); } - return array('status' => 'ignored', 'message' => 'Unusable payload.'); + return $response; } /** * Handle the payload when Github sends a commit webhook. - * - * @param Project $project + * @param $project * @param array $payload - * @param b8\Http\Response\JsonResponse $response - * - * @return b8\Http\Response\JsonResponse */ - protected function githubCommitRequest(Project $project, array $payload) + protected function githubCommitRequest($project, array $payload, b8\Http\Response\JsonResponse $response) { // Github sends a payload when you close a pull request with a - // non-existent commit. We don't want this. + // non-existant commit. We don't want this. if (array_key_exists('after', $payload) && $payload['after'] === '0000000000000000000000000000000000000000') { - return array('status' => 'ignored'); + return $response; } - if (isset($payload['commits']) && is_array($payload['commits'])) { - // If we have a list of commits, then add them all as builds to be tested: + try { - $results = array(); - $status = 'failed'; - foreach ($payload['commits'] as $commit) { - if (!$commit['distinct']) { - $results[$commit['id']] = array('status' => 'ignored'); - continue; - } + if (isset($payload['commits']) && is_array($payload['commits'])) { + // If we have a list of commits, then add them all as builds to be tested: + + foreach ($payload['commits'] as $commit) { + if (!$commit['distinct']) { + continue; + } - try { $branch = str_replace('refs/heads/', '', $payload['ref']); $committer = $commit['committer']['email']; - $results[$commit['id']] = $this->createBuild( - $project, - $commit['id'], - $branch, - $committer, - $commit['message'] - ); - $status = 'ok'; - } catch (Exception $ex) { - $results[$commit['id']] = array('status' => 'failed', 'error' => $ex->getMessage()); + $this->createBuild($project, $commit['id'], $branch, $committer, $commit['message']); } + } elseif (substr($payload['ref'], 0, 10) == 'refs/tags/') { + // If we don't, but we're dealing with a tag, add that instead: + $branch = str_replace('refs/tags/', 'Tag: ', $payload['ref']); + $committer = $payload['pusher']['email']; + $message = $payload['head_commit']['message']; + $this->createBuild($project, $payload['after'], $branch, $committer, $message); } - return array('status' => $status, 'commits' => $results); + + } catch (\Exception $ex) { + $response->setResponseCode(500); + $response->setContent(array('status' => 'failed', 'error' => $ex->getMessage())); + } - if (substr($payload['ref'], 0, 10) == 'refs/tags/') { - // If we don't, but we're dealing with a tag, add that instead: - $branch = str_replace('refs/tags/', 'Tag: ', $payload['ref']); - $committer = $payload['pusher']['email']; - $message = $payload['head_commit']['message']; - return $this->createBuild($project, $payload['after'], $branch, $committer, $message); - } - - return array('status' => 'ignored', 'message' => 'Unusable payload.'); + return $response; } /** * Handle the payload when Github sends a Pull Request webhook. - * - * @param Project $project + * @param $projectId * @param array $payload */ - protected function githubPullRequest(Project $project, array $payload) + protected function githubPullRequest($projectId, array $payload, b8\Http\Response\JsonResponse $response) { // We only want to know about open pull requests: if (!in_array($payload['action'], array('opened', 'synchronize', 'reopened'))) { - return array('status' => 'ok'); + return $response; } - $headers = array(); - $token = \b8\Config::getInstance()->get('phpci.github.token'); + try { + $headers = array(); + $token = \b8\Config::getInstance()->get('phpci.github.token'); - if (!empty($token)) { - $headers[] = 'Authorization: token ' . $token; - } - - $url = $payload['pull_request']['commits_url']; - $http = new \b8\HttpClient(); - $http->setHeaders($headers); - $response = $http->get($url); - - // Check we got a success response: - if (!$response['success']) { - throw new Exception('Could not get commits, failed API request.'); - } - - $results = array(); - $status = 'failed'; - foreach ($response['body'] as $commit) { - // Skip all but the current HEAD commit ID: - $id = $commit['sha']; - if ($id != $payload['pull_request']['head']['sha']) { - $results[$id] = array('status' => 'ignored', 'message' => 'not branch head'); - continue; + if (!empty($token)) { + $headers[] = 'Authorization: token ' . $token; } - try { + $url = $payload['pull_request']['commits_url']; + $http = new \b8\HttpClient(); + $http->setHeaders($headers); + $response = $http->get($url); + + // Check we got a success response: + if (!$response['success']) { + $message = 'Could not get commits, failed API request.'; + $response->setResponseCode(500); + $response->setContent(array('status' => 'failed', 'error' => $message)); + return $response; + } + + foreach ($response['body'] as $commit) { $branch = str_replace('refs/heads/', '', $payload['pull_request']['base']['ref']); $committer = $commit['commit']['author']['email']; $message = $commit['commit']['message']; - $remoteUrlKey = $payload['pull_request']['head']['repo']['private'] ? 'ssh_url' : 'clone_url'; - $extra = array( 'build_type' => 'pull_request', 'pull_request_id' => $payload['pull_request']['id'], 'pull_request_number' => $payload['number'], 'remote_branch' => $payload['pull_request']['head']['ref'], - 'remote_url' => $payload['pull_request']['head']['repo'][$remoteUrlKey], + 'remote_url' => $payload['pull_request']['head']['repo']['clone_url'], ); - $results[$id] = $this->createBuild($project, $id, $branch, $committer, $message, $extra); - $status = 'ok'; - } catch (Exception $ex) { - $results[$id] = array('status' => 'failed', 'error' => $ex->getMessage()); + $this->createBuild($projectId, $commit['sha'], $branch, $committer, $message, $extra); } + } catch (\Exception $ex) { + $response->setResponseCode(500); + $response->setContent(array('status' => 'failed', 'error' => $ex->getMessage())); } - return array('status' => $status, 'commits' => $results); + return $response; } /** * Called by Gitlab Webhooks: */ - public function gitlab($projectId) + public function gitlab($project) { - $project = $this->fetchProject($projectId, 'gitlab'); + $response = new b8\Http\Response\JsonResponse(); + $response->setContent(array('status' => 'ok')); $payloadString = file_get_contents("php://input"); $payload = json_decode($payloadString, true); - // build on merge request events - if (isset($payload['object_kind']) && $payload['object_kind'] == 'merge_request') { - $attributes = $payload['object_attributes']; - if ($attributes['state'] == 'opened' || $attributes['state'] == 'reopened') { - $branch = $attributes['source_branch']; - $commit = $attributes['last_commit']; - $committer = $commit['author']['email']; + try { - return $this->createBuild($project, $commit['id'], $branch, $committer, $commit['message']); - } - } - // build on push events - if (isset($payload['commits']) && is_array($payload['commits'])) { - // If we have a list of commits, then add them all as builds to be tested: + // build on merge request events + if (isset($payload['object_kind']) && $payload['object_kind'] == 'merge_request') { + $attributes = $payload['object_attributes']; + if ($attributes['state'] == 'opened' || $attributes['state'] == 'reopened') { - $results = array(); - $status = 'failed'; - foreach ($payload['commits'] as $commit) { - try { - $branch = str_replace('refs/heads/', '', $payload['ref']); + $branch = $attributes['source_branch']; + $commit = $attributes['last_commit']; $committer = $commit['author']['email']; - $results[$commit['id']] = $this->createBuild( - $project, - $commit['id'], - $branch, - $committer, - $commit['message'] - ); - $status = 'ok'; - } catch (Exception $ex) { - $results[$commit['id']] = array('status' => 'failed', 'error' => $ex->getMessage()); + + $this->createBuild($project, $commit['id'], $branch, $committer, $commit['message']); } } - return array('status' => $status, 'commits' => $results); + + // build on push events + if (isset($payload['commits']) && is_array($payload['commits'])) { + // If we have a list of commits, then add them all as builds to be tested: + + foreach ($payload['commits'] as $commit) { + $branch = str_replace('refs/heads/', '', $payload['ref']); + $committer = $commit['author']['email']; + $this->createBuild($project, $commit['id'], $branch, $committer, $commit['message']); + } + } + + } catch (\Exception $ex) { + $response->setResponseCode(500); + $response->setContent(array('status' => 'failed', 'error' => $ex->getMessage())); } - return array('status' => 'ignored', 'message' => 'Unusable payload.'); + return $response; } /** * Wrapper for creating a new build. - * - * @param Project $project - * @param string $commitId - * @param string $branch - * @param string $committer - * @param string $commitMessage - * @param array $extra - * - * @return array - * - * @throws Exception + * @param $projectId + * @param $commitId + * @param $branch + * @param $committer + * @param $commitMessage + * @param null $extra + * @return bool + * @throws \Exception */ - protected function createBuild( - Project $project, - $commitId, - $branch, - $committer, - $commitMessage, - array $extra = null - ) { + protected function createBuild($projectId, $commitId, $branch, $committer, $commitMessage, $extra = null) + { // Check if a build already exists for this commit ID: - $builds = $this->buildStore->getByProjectAndCommit($project->getId(), $commitId); + $builds = $this->buildStore->getByProjectAndCommit($projectId, $commitId); if ($builds['count']) { - return array( - 'status' => 'ignored', - 'message' => sprintf('Duplicate of build #%d', $builds['items'][0]->getId()) - ); + return true; + } + + $project = $this->projectStore->getById($projectId); + + if (empty($project)) { + throw new \Exception('Project does not exist:' . $projectId); } // If not, create a new build job for it: $build = $this->buildService->createBuild($project, $commitId, $branch, $committer, $commitMessage, $extra); + $build = BuildFactory::getBuild($build); - return array('status' => 'ok', 'buildID' => $build->getID()); - } + // Send a status postback if the build type provides one: + $build->sendStatusPostback(); - /** - * Fetch a project and check its type. - * - * @param int $projectId - * @param array|string $expectedType - * - * @return Project - * - * @throws Exception If the project does not exist or is not of the expected type. - */ - protected function fetchProject($projectId, $expectedType) - { - $project = $this->projectStore->getById($projectId); - - if (empty($projectId)) { - throw new Exception('Project does not exist: ' . $projectId); - } - - if (is_array($expectedType) - ? !in_array($project->getType(), $expectedType) - : $project->getType() !== $expectedType - ) { - throw new Exception('Wrong project type: ' . $project->getType()); - } - - return $project; + return true; } } diff --git a/PHPCI/ErrorHandler.php b/PHPCI/ErrorHandler.php deleted file mode 100644 index d268965d..00000000 --- a/PHPCI/ErrorHandler.php +++ /dev/null @@ -1,68 +0,0 @@ - 'Warning', - E_NOTICE => 'Notice', - E_USER_ERROR => 'User Error', - E_USER_WARNING => 'User Warning', - E_USER_NOTICE => 'User Notice', - E_STRICT => 'Runtime Notice', - E_RECOVERABLE_ERROR => 'Catchable Fatal Error', - E_DEPRECATED => 'Deprecated', - E_USER_DEPRECATED => 'User Deprecated', - ); - - /** - * Registers an instance of the error handler to throw ErrorException. - */ - public static function register() - { - $handler = new static(); - set_error_handler(array($handler, 'handleError')); - } - - /** - * @param integer $level - * @param string $message - * @param string $file - * @param integer $line - * - * @throws \ErrorException - * - * @internal - */ - public function handleError($level, $message, $file, $line) - { - if (error_reporting() & $level === 0) { - return; - } - - $exceptionLevel = isset($this->levels[$level]) ? $this->levels[$level] : $level; - throw new \ErrorException( - sprintf('%s: %s in %s line %d', $exceptionLevel, $message, $file, $line), - 0, - $level, - $file, - $line - ); - } -} diff --git a/PHPCI/Helper/AnsiConverter.php b/PHPCI/Helper/AnsiConverter.php deleted file mode 100644 index 7df6663c..00000000 --- a/PHPCI/Helper/AnsiConverter.php +++ /dev/null @@ -1,55 +0,0 @@ -convert($text); - } - - /** - * Do not instantiate this class. - */ - private function __construct() - { - } -} diff --git a/PHPCI/Helper/BaseCommandExecutor.php b/PHPCI/Helper/BaseCommandExecutor.php index b3b47f7b..28247ebc 100644 --- a/PHPCI/Helper/BaseCommandExecutor.php +++ b/PHPCI/Helper/BaseCommandExecutor.php @@ -9,9 +9,9 @@ namespace PHPCI\Helper; -use Exception; -use PHPCI\Logging\BuildLogger; +use \PHPCI\Logging\BuildLogger; use Psr\Log\LogLevel; +use PHPCI\Helper\Lang; /** * Handles running system commands with variables. @@ -20,7 +20,7 @@ use Psr\Log\LogLevel; abstract class BaseCommandExecutor implements CommandExecutor { /** - * @var BuildLogger + * @var \PHPCI\Logging\BuildLogger */ protected $logger; @@ -62,7 +62,9 @@ abstract class BaseCommandExecutor implements CommandExecutor $this->logger = $logger; $this->quiet = $quiet; $this->verbose = $verbose; + $this->lastOutput = array(); + $this->rootDir = $rootDir; } @@ -76,7 +78,6 @@ abstract class BaseCommandExecutor implements CommandExecutor $this->lastOutput = array(); $command = call_user_func_array('sprintf', $args); - $this->logger->logDebug($command); if ($this->quiet) { $this->logger->log('Executing: ' . $command); @@ -90,7 +91,8 @@ abstract class BaseCommandExecutor implements CommandExecutor ); $pipes = array(); - $process = proc_open($command, $descriptorSpec, $pipes, $this->buildPath, null); + + $process = proc_open($command, $descriptorSpec, $pipes, dirname($this->buildPath), null); if (is_resource($process)) { fclose($pipes[0]); @@ -144,12 +146,13 @@ abstract class BaseCommandExecutor implements CommandExecutor /** * Find a binary required by a plugin. * @param string $binary - * @param bool $quiet + * @param null $buildPath * @return null|string */ - public function findBinary($binary, $quiet = false) + public function findBinary($binary, $buildPath = null) { - $composerBin = $this->getComposerBinDir(realpath($this->buildPath)); + $binaryPath = null; + $composerBin = $this->getComposerBinDir(realpath($buildPath)); if (is_string($binary)) { $binary = array($binary); @@ -159,31 +162,32 @@ abstract class BaseCommandExecutor implements CommandExecutor $this->logger->log(Lang::get('looking_for_binary', $bin), LogLevel::DEBUG); if (is_dir($composerBin) && is_file($composerBin.'/'.$bin)) { + $this->logger->log(Lang::get('found_in_path', $composerBin, $bin), LogLevel::DEBUG); - return $composerBin . '/' . $bin; + $binaryPath = $composerBin . '/' . $bin; + break; } if (is_file($this->rootDir . $bin)) { $this->logger->log(Lang::get('found_in_path', 'root', $bin), LogLevel::DEBUG); - return $this->rootDir . $bin; + $binaryPath = $this->rootDir . $bin; + break; } if (is_file($this->rootDir . 'vendor/bin/' . $bin)) { $this->logger->log(Lang::get('found_in_path', 'vendor/bin', $bin), LogLevel::DEBUG); - return $this->rootDir . 'vendor/bin/' . $bin; + $binaryPath = $this->rootDir . 'vendor/bin/' . $bin; + break; } $findCmdResult = $this->findGlobalBinary($bin); if (is_file($findCmdResult)) { $this->logger->log(Lang::get('found_in_path', '', $bin), LogLevel::DEBUG); - return $findCmdResult; + $binaryPath = $findCmdResult; + break; } } - - if ($quiet) { - return; - } - throw new Exception(Lang::get('could_not_find', implode('/', $binary))); + return $binaryPath; } /** @@ -215,13 +219,4 @@ abstract class BaseCommandExecutor implements CommandExecutor } return null; } - - /** - * Set the buildPath property. - * @param string $path - */ - public function setBuildPath($path) - { - $this->buildPath = $path; - } } diff --git a/PHPCI/Helper/BuildInterpolator.php b/PHPCI/Helper/BuildInterpolator.php index 1e7222bb..fbadbc30 100644 --- a/PHPCI/Helper/BuildInterpolator.php +++ b/PHPCI/Helper/BuildInterpolator.php @@ -38,7 +38,6 @@ class BuildInterpolator $this->interpolation_vars['%COMMIT%'] = $build->getCommitId(); $this->interpolation_vars['%SHORT_COMMIT%'] = substr($build->getCommitId(), 0, 7); $this->interpolation_vars['%COMMIT_EMAIL%'] = $build->getCommitterEmail(); - $this->interpolation_vars['%COMMIT_MESSAGE%'] = $build->getCommitMessage(); $this->interpolation_vars['%COMMIT_URI%'] = $build->getCommitLink(); $this->interpolation_vars['%BRANCH%'] = $build->getBranch(); $this->interpolation_vars['%BRANCH_URI%'] = $build->getBranchLink(); @@ -50,7 +49,6 @@ class BuildInterpolator $this->interpolation_vars['%BUILD_URI%'] = $phpCiUrl . "build/view/" . $build->getId(); $this->interpolation_vars['%PHPCI_COMMIT%'] = $this->interpolation_vars['%COMMIT%']; $this->interpolation_vars['%PHPCI_SHORT_COMMIT%'] = $this->interpolation_vars['%SHORT_COMMIT%']; - $this->interpolation_vars['%PHPCI_COMMIT_MESSAGE%'] = $this->interpolation_vars['%COMMIT_MESSAGE%']; $this->interpolation_vars['%PHPCI_COMMIT_EMAIL%'] = $this->interpolation_vars['%COMMIT_EMAIL%']; $this->interpolation_vars['%PHPCI_COMMIT_URI%'] = $this->interpolation_vars['%COMMIT_URI%']; $this->interpolation_vars['%PHPCI_PROJECT%'] = $this->interpolation_vars['%PROJECT%']; @@ -63,7 +61,6 @@ class BuildInterpolator putenv('PHPCI=1'); putenv('PHPCI_COMMIT=' . $this->interpolation_vars['%COMMIT%']); putenv('PHPCI_SHORT_COMMIT=' . $this->interpolation_vars['%SHORT_COMMIT%']); - putenv('PHPCI_COMMIT_MESSAGE=' . $this->interpolation_vars['%COMMIT_MESSAGE%']); putenv('PHPCI_COMMIT_EMAIL=' . $this->interpolation_vars['%COMMIT_EMAIL%']); putenv('PHPCI_COMMIT_URI=' . $this->interpolation_vars['%COMMIT_URI%']); putenv('PHPCI_PROJECT=' . $this->interpolation_vars['%PROJECT%']); diff --git a/PHPCI/Helper/CommandExecutor.php b/PHPCI/Helper/CommandExecutor.php index 4f0028eb..d83f0c6b 100644 --- a/PHPCI/Helper/CommandExecutor.php +++ b/PHPCI/Helper/CommandExecutor.php @@ -26,17 +26,8 @@ interface CommandExecutor /** * Find a binary required by a plugin. * @param string $binary - * @param bool $quiet Returns null instead of throwing an execption. - * + * @param string $buildPath the current build path * @return null|string - * - * @throws \Exception when no binary has been found and $quiet is false. */ - public function findBinary($binary, $quiet = false); - - /** - * Set the buildPath property. - * @param string $path - */ - public function setBuildPath($path); + public function findBinary($binary, $buildPath = null); } diff --git a/PHPCI/Helper/Diff.php b/PHPCI/Helper/Diff.php index 5dcb5388..e50c7eaf 100644 --- a/PHPCI/Helper/Diff.php +++ b/PHPCI/Helper/Diff.php @@ -26,15 +26,11 @@ class Diff */ public function getLinePositions($diff) { - if (empty($diff)) { - return null; - } - $rtn = array(); $diffLines = explode(PHP_EOL, $diff); - while (count($diffLines)) { + while (1) { $line = array_shift($diffLines); if (substr($line, 0, 2) == '@@') { diff --git a/PHPCI/Helper/Github.php b/PHPCI/Helper/Github.php index 67173eb4..00d959df 100644 --- a/PHPCI/Helper/Github.php +++ b/PHPCI/Helper/Github.php @@ -48,18 +48,24 @@ class Github $res = $http->get($url, $params); foreach ($res['body'] as $item) { + $results[] = $item; + } foreach ($res['headers'] as $header) { + if (preg_match('/^Link: <([^>]+)>; rel="next"/', $header, $r)) { + $host = parse_url($r[1]); parse_str($host['query'], $params); $results = $this->makeRecursiveRequest($host['path'], $params, $results); break; + } + } return $results; diff --git a/PHPCI/Helper/Lang.php b/PHPCI/Helper/Lang.php index 42027cee..c86de1aa 100644 --- a/PHPCI/Helper/Lang.php +++ b/PHPCI/Helper/Lang.php @@ -156,7 +156,7 @@ class Lang return null; } - require($langFile); + require_once($langFile); if (is_null($strings) || !is_array($strings) || !count($strings)) { return null; diff --git a/PHPCI/Helper/LoginIsDisabled.php b/PHPCI/Helper/LoginIsDisabled.php index ec23858c..d30fcd9f 100644 --- a/PHPCI/Helper/LoginIsDisabled.php +++ b/PHPCI/Helper/LoginIsDisabled.php @@ -12,7 +12,7 @@ namespace PHPCI\Helper; use b8\Config; /** -* Login Is Disabled Helper - Checks if login is disabled in the view +* Login Is Disabled Helper - Checks if login is disalbed in the view * @author Stephen Ball * @package PHPCI * @subpackage Web @@ -20,7 +20,7 @@ use b8\Config; class LoginIsDisabled { /** - * Checks if + * Checks if * @param $method * @param array $params * @return mixed|null diff --git a/PHPCI/Helper/MailerFactory.php b/PHPCI/Helper/MailerFactory.php index c84c068d..641c06b9 100644 --- a/PHPCI/Helper/MailerFactory.php +++ b/PHPCI/Helper/MailerFactory.php @@ -71,7 +71,7 @@ class MailerFactory } else { // Check defaults - switch ($configName) { + switch($configName) { case 'smtp_address': return "localhost"; case 'default_mailto_address': diff --git a/PHPCI/Helper/SshKey.php b/PHPCI/Helper/SshKey.php index 932686f2..47bd85bd 100644 --- a/PHPCI/Helper/SshKey.php +++ b/PHPCI/Helper/SshKey.php @@ -39,9 +39,9 @@ class SshKey $return = array('private_key' => '', 'public_key' => ''); - $output = @shell_exec('ssh-keygen -t rsa -b 2048 -f '.$keyFile.' -N "" -C "deploy@phpci"'); + if ($this->canGenerateKeys()) { + shell_exec('ssh-keygen -q -t rsa -b 2048 -f '.$keyFile.' -N "" -C "deploy@phpci"'); - if (!empty($output)) { $pub = file_get_contents($keyFile . '.pub'); $prv = file_get_contents($keyFile); @@ -56,4 +56,16 @@ class SshKey return $return; } + + /** + * Checks whether or not we can generate keys, by quietly test running ssh-keygen. + * @return bool + */ + public function canGenerateKeys() + { + $keygen = @shell_exec('ssh-keygen --help'); + $canGenerateKeys = !empty($keygen); + + return $canGenerateKeys; + } } diff --git a/PHPCI/Languages/lang.da.php b/PHPCI/Languages/lang.da.php index d7a0df59..5010f28e 100644 --- a/PHPCI/Languages/lang.da.php +++ b/PHPCI/Languages/lang.da.php @@ -39,7 +39,6 @@ PHPCI', 'reset_email_title' => 'PHPCI Adgangskode-nulstilling for %s', 'reset_invalid' => 'Ugyldig anmodning om adgangskode-nulstilling.', 'email_address' => 'Email-addresse', - 'login' => 'Login / Email Address', 'password' => 'Adgangskode', 'log_in' => 'Log ind', @@ -113,8 +112,6 @@ i din foretrukne hosting-platform.', (hvis du ikke har mulighed for at tilføje en phpci.yml fil i projektets repository)', 'default_branch' => 'Default branch navn', 'allow_public_status' => 'Tillad offentlig status-side og -billede for dette projekt?', - 'archived' => 'Archived', - 'archived_menu' => 'Archived', 'save_project' => 'Gem Projekt', 'error_mercurial' => 'Mercurial repository-URL skal starte med http:// eller https://', @@ -128,7 +125,6 @@ i din foretrukne hosting-platform.', 'all_branches' => 'Alle branches', 'builds' => 'Builds', 'id' => 'ID', - 'date' => 'Date', 'project' => 'Projekt', 'commit' => 'Commit', 'branch' => 'Branch', @@ -196,20 +192,14 @@ Services sektionen under dit Bitbucket-repository.', 'end' => 'Slut', 'from' => 'Fra', 'to' => 'Til', + 'suite' => 'Suite', + 'test' => 'Test', 'result' => 'Resultat', 'ok' => 'OK', 'took_n_seconds' => 'Tog %d sekunder', 'build_created' => 'Build Oprettet', 'build_started' => 'Build Startet', 'build_finished' => 'Build Afsluttet', - 'test_message' => 'Message', - 'test_no_message' => 'No message', - 'test_success' => 'Successful: %d', - 'test_fail' => 'Failures: %d', - 'test_skipped' => 'Skipped: %d', - 'test_error' => 'Errors: %d', - 'test_todo' => 'Todos: %d', - 'test_total' => '%d test(s)', // Users 'name' => 'Navn', @@ -305,15 +295,15 @@ du kører composer update.', Kontrollér venligst nedenstående fejl før du fortsætter.', 'must_be_valid_email' => 'Skal være en gyldig email-adresse.', 'must_be_valid_url' => 'Skal være en gyldig URL.', - 'enter_name' => 'Administrator-navn: ', - 'enter_email' => 'Administrators email-adresse: ', - 'enter_password' => 'Administrator-adgangskode: ', - 'enter_phpci_url' => 'Din PHPCI URL (eksempelvis "http://phpci.local"): ', + 'enter_name' => 'Administrator-navn:', + 'enter_email' => 'Administrators email-adresse:', + 'enter_password' => 'Administrator-adgangskode:', + 'enter_phpci_url' => 'Din PHPCI URL (eksempelvis "http://phpci.local"):', - 'enter_db_host' => 'Indtast dit MySQL-hostnavn [localhost]: ', - 'enter_db_name' => 'Indtast dit MySQL database-navn [phpci]: ', - 'enter_db_user' => 'Indtast dit MySQL-brugernavn [phpci]: ', - 'enter_db_pass' => 'Indtast dit MySQL-password: ', + 'enter_db_host' => 'Indtast dit MySQL-hostnavn [localhost]:', + 'enter_db_name' => 'Indtast dit MySQL database-navn [phpci]:', + 'enter_db_user' => 'Indtast dit MySQL-brugernavn [phpci]:', + 'enter_db_pass' => 'Indtast dit MySQL-password:', 'could_not_connect' => 'PHPCI kunne ikke forbinde til MySQL med de angivning oplysninger. Forsøg igen.', 'setting_up_db' => 'Indlæser database...', 'user_created' => 'Brugerkonto oprettet!', @@ -340,12 +330,6 @@ Kontrollér venligst nedenstående fejl før du fortsætter.', 'create_admin_user' => 'Tilføj en administrator', 'incorrect_format' => 'Forkert format', - // Create Build Command - 'create_build_project' => 'Create a build for a project', - 'project_id_argument' => 'A project ID', - 'commit_id_option' => 'Commit ID to build', - 'branch_name_option' => 'Branch to build', - // Run Command 'run_all_pending' => 'Kør alle PHPCI builds i køen.', 'finding_builds' => 'Finder builds der skal køres', diff --git a/PHPCI/Languages/lang.de.php b/PHPCI/Languages/lang.de.php index 8e5bb3b2..c40ef23d 100644 --- a/PHPCI/Languages/lang.de.php +++ b/PHPCI/Languages/lang.de.php @@ -39,7 +39,6 @@ PHPCI', 'reset_email_title' => 'PHPCI Passwort zurücksetzen für %s', 'reset_invalid' => 'Fehlerhafte Anfrage für das Zurücksetzen eines Passwortes', 'email_address' => 'Emailadresse', - 'login' => 'Login / Emailadresse', 'password' => 'Passwort', 'log_in' => 'Einloggen', @@ -102,7 +101,6 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'remote' => 'Externe URL', 'local' => 'Lokaler Pfad', 'hg' => 'Mercurial', - 'svn' => 'Subversion', 'where_hosted' => 'Wo wird Ihr Projekt gehostet?', 'choose_github' => 'Wählen Sie ein GitHub Repository:', @@ -115,8 +113,6 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab (falls Sie Ihrem Projektrepository kein phpci.yml hinzufügen können)', 'default_branch' => 'Name des Standardbranches', 'allow_public_status' => 'Öffentliche Statusseite und -bild für dieses Projekt einschalten?', - 'archived' => 'Archiviert', - 'archived_menu' => 'Archiviert', 'save_project' => 'Projekt speichern', 'error_mercurial' => 'Mercurial Repository-URL muss mit http://, oder https:// beginnen', @@ -130,7 +126,6 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'all_branches' => 'Alle Branches', 'builds' => 'Builds', 'id' => 'ID', - 'date' => 'Datum', 'project' => 'Projekt', 'commit' => 'Commit', 'branch' => 'Branch', @@ -151,9 +146,6 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'webhooks_help_bitbucket' => 'Um für dieses Projekt automatisch einen Build zu starten, wenn neue Commits gepushed werden, fügen Sie die untenstehende URL als "POST" Service in der Services-Sektion Ihres Bitbucket Repositories hinzu.', // View Build - 'errors' => 'Fehler', - 'information' => 'Information', - 'build_x_not_found' => 'Build mit ID %d existiert nicht.', 'build_n' => 'Build %d', 'rebuild_now' => 'Build neu starten', @@ -188,14 +180,6 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'phpmd' => 'PHP Mess Detector', 'phpspec' => 'PHP Spec', 'phpunit' => 'PHP Unit', - 'technical_debt' => 'Technische Schulden', - 'behat' => 'Behat', - - 'codeception_feature' => 'Feature', - 'codeception_suite' => 'Suite', - 'codeception_time' => 'Zeit', - 'codeception_synopsis' => '%1$d Tests in %2$f Sekunden ausgeführt. - %3$d Fehler.', 'file' => 'Datei', 'line' => 'Zeile', @@ -206,20 +190,14 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'end' => 'Ende', 'from' => 'Von', 'to' => 'Bis', + 'suite' => 'Suite', + 'test' => 'Test', 'result' => 'Resultat', 'ok' => 'OK', 'took_n_seconds' => 'Benötigte %d Sekunden', 'build_created' => 'Build erstellt', 'build_started' => 'Build gestartet', 'build_finished' => 'Build abgeschlossen', - 'test_message' => 'Nachricht', - 'test_no_message' => 'Keine Nachricht', - 'test_success' => 'Erfolgreich: %d', - 'test_fail' => 'Fehlschläge: %d', - 'test_skipped' => 'Übersprungen: %d', - 'test_error' => 'Fehler: %d', - 'test_todo' => 'Todos: %d', - 'test_total' => '%d Test(s)', // Users 'name' => 'Name', @@ -295,19 +273,6 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'search_packagist_for_more' => 'Packagist nach mehr Packages durchsuchen', 'search' => 'Suchen »', - // Summary plugin - 'build-summary' => 'Zusammenfassung', - 'stage' => 'Abschnitt', - 'duration' => 'Dauer', - 'plugin' => 'Plugin', - 'stage_setup' => 'Vorbereitung', - 'stage_test' => 'Test', - 'stage_complete' => 'Vollständig', - 'stage_success' => 'Erfolg', - 'stage_failure' => 'Fehlschlag', - 'stage_broken' => 'Defekt', - 'stage_fixed' => 'Behoben', - // Installer 'installation_url' => 'PHPCI Installations-URL', 'db_host' => 'Datenbankserver', @@ -328,9 +293,9 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab Bitte überprüfen Sie die Fehler, bevor Sie fortfahren,', 'must_be_valid_email' => 'Muss eine gültige Emailadresse sein.', 'must_be_valid_url' => 'Muss eine valide URL sein.', - 'enter_name' => 'Name des Administrators: ', - 'enter_email' => 'Emailadresse des Administrators: ', - 'enter_password' => 'Passwort des Administrators: ', + 'enter_name' => 'Name des Administrators:', + 'enter_email' => 'Emailadresse des Administrators:', + 'enter_password' => 'Passwort des Administrators:', 'enter_phpci_url' => 'Ihre PHPCI-URL (z.B. "http://phpci.local"): ', 'enter_db_host' => 'Bitte geben Sie Ihren MySQL-Host ein [localhost]: ', @@ -363,12 +328,6 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'create_admin_user' => 'Administratorenbenutzer erstellen', 'incorrect_format' => 'Falsches Format', - // Create Build Command - 'create_build_project' => 'Create a build for a project', - 'project_id_argument' => 'A project ID', - 'commit_id_option' => 'Commit ID to build', - 'branch_name_option' => 'Branch to build', - // Run Command 'run_all_pending' => 'Führe alle ausstehenden PHPCI Builds aus.', 'finding_builds' => 'Suche verarbeitbare Builds', @@ -416,18 +375,5 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab 'build_file_missing' => 'Angegebene Builddatei existiert nicht.', 'property_file_missing' => 'Angegebene Eigenschaftsdatei existiert nicht.', 'could_not_process_report' => 'Konnte den von diesem Tool erstellten Bericht nicht verarbeiten.', - 'shell_not_enabled' => 'Das Shell-Plugin ist nicht aktiviert. Bitte aktivieren Sie es via config.yml.', - - // Error Levels: - 'critical' => 'Kritisch', - 'high' => 'Hoch', - 'normal' => 'Normal', - 'low' => 'Niedrig', - - // Plugins that generate errors: - 'php_mess_detector' => 'PHP Mess Detector', - 'php_code_sniffer' => 'PHP Code Sniffer', - 'php_unit' => 'PHP Unit', - 'php_cpd' => 'PHP Copy/Paste Detector', - 'php_docblock_checker' => 'PHP Docblock Checker', + 'shell_not_enabled' => 'Das Shell-Plugin ist nicht aktiviert. Bitte aktivieren Sie es via config.yml.' ); diff --git a/PHPCI/Languages/lang.el.php b/PHPCI/Languages/lang.el.php index 45ee4bee..c611a87d 100644 --- a/PHPCI/Languages/lang.el.php +++ b/PHPCI/Languages/lang.el.php @@ -39,7 +39,6 @@ PHPCI', 'reset_email_title' => 'PHPCI Επαναφορά Κωδικού για %s', 'reset_invalid' => 'Μη έγκυρο αίτημα επαναφοράς κωδικού πρόσβασης.', 'email_address' => 'Διεύθυνση email', - 'login' => 'Login / Email Address', 'password' => 'Κωδικός πρόσβασης', 'log_in' => 'Είσοδος', @@ -114,8 +113,6 @@ PHPCI', (αν δεν μπορείτε να προσθέσετε ένα αρχείο phpci.yml στο αποθετήριο έργων)', 'default_branch' => 'Προκαθορισμένο όνομα διακλάδωσης', 'allow_public_status' => 'Ενεργοποίηση της σελίδας δημόσιας κατάστασης και την εικόνα για το έργο αυτό;', - 'archived' => 'Archived', - 'archived_menu' => 'Archived', 'save_project' => 'Αποθήκευση έργου', 'error_mercurial' => 'Ο σύνδεσμος URL του ευμετάβλητου αποθετηρίου πρέπει να ξεκινάει με http:// ή https://', @@ -129,7 +126,6 @@ PHPCI', 'all_branches' => 'Όλες οι διακλαδώσεις', 'builds' => 'Κατασκευές', 'id' => 'Αριθμός αναγνώρισης', - 'date' => 'Date', 'project' => 'Έργο', 'commit' => 'Συνεισφορά', 'branch' => 'Διακλάδωση', @@ -173,7 +169,6 @@ Services του Bitbucket αποθετηρίου σας.', 'codeception_errors' => 'Λάθη Codeception', 'phpmd_warnings' => 'Προειδοποιήσεις PHPMD', 'phpcs_warnings' => 'Προειδοποιήσεις PHPCS ', - 'codeception_errors' => 'Λάθη Codeception', 'phpcs_errors' => 'Λάθη PHPCS', 'phplint_errors' => 'Λάθη Lint', 'phpunit_errors' => 'Λάθη PHPUnit ', @@ -197,20 +192,14 @@ Services του Bitbucket αποθετηρίου σας.', 'end' => 'Τέλος', 'from' => 'Από', 'to' => 'Προς', + 'suite' => 'Σουίτα', + 'test' => 'Τέστ', 'result' => 'Αποτέλεσμα', 'ok' => 'ΟΚ', 'took_n_seconds' => 'Χρειάστηκαν %d δευτερόλεπτα', 'build_created' => 'Η κατασκευή δημιουργήθηκε', 'build_started' => 'Η κατασκευή άρχισε', 'build_finished' => 'Η κατασκευή ολοκληρώθηκε', - 'test_message' => 'Message', - 'test_no_message' => 'No message', - 'test_success' => 'Successful: %d', - 'test_fail' => 'Failures: %d', - 'test_skipped' => 'Skipped: %d', - 'test_error' => 'Errors: %d', - 'test_todo' => 'Todos: %d', - 'test_total' => '%d test(s)', // Users 'name' => 'Όνομα', @@ -307,15 +296,15 @@ Services του Bitbucket αποθετηρίου σας.', Παρακαλούμε διαβάστε τα παραπάνω λάθη πριν συνεχίσετε.', 'must_be_valid_email' => 'Πρέπει να είναι μια έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου.', 'must_be_valid_url' => 'Πρέπει να είναι μια έγκυρη διεύθυνση URL.', - 'enter_name' => 'Όνομα διαχειριστή: ', - 'enter_email' => 'Ηλ. Διεύθυνση διαχειριστή: ', - 'enter_password' => 'Κωδικός πρόσβασης διαχειριστή: ', + 'enter_name' => 'Όνομα διαχειριστή:', + 'enter_email' => 'Ηλ. Διεύθυνση διαχειριστή:', + 'enter_password' => 'Κωδικός πρόσβασης διαχειριστή:', 'enter_phpci_url' => 'Ο URL σύνδεσμος σας για το PHPCI ("http://phpci.local" για παράδειγμα): ', - 'enter_db_host' => 'Παρακαλώ εισάγετε τον MySQL οικοδεσπότη σας [localhost]: ', + 'enter_db_host' => 'Παρακαλώ εισάγετε τον MySQL οικοδεσπότη σας [localhost]:', 'enter_db_name' => 'Παρακαλώ εισάγετε το όνομα της MySQL βάσης δεδομένων σας [phpci]: ', - 'enter_db_user' => 'Παρακαλώ εισάγετε το όνομα χρήστη της MySQL σας [phpci]: ', - 'enter_db_pass' => 'Παρακαλώ εισάγετε τον κωδικό χρήστη της MySQL σας: ', + 'enter_db_user' => 'Παρακαλώ εισάγετε το όνομα χρήστη της MySQL σας [phpci]:', + 'enter_db_pass' => 'Παρακαλώ εισάγετε τον κωδικό χρήστη της MySQL σας:', 'could_not_connect' => 'Το PHPCI δεν μπόρεσε να συνδεθεί με την MySQL με τα στοχεία που δώσατε. Παρακαλώ δοκιμάστε ξανά.', 'setting_up_db' => 'Γίνεται ρύθμιση της βάσης δεδομένων σας ...', 'user_created' => 'Λογαριασμός χρήστη δημιουργήθηκε!', @@ -342,12 +331,6 @@ Services του Bitbucket αποθετηρίου σας.', 'create_admin_user' => 'Δημιουργήστε ένα χρήστη διαχειριστή', 'incorrect_format' => 'Λανθασμένη μορφοποίηση', - // Create Build Command - 'create_build_project' => 'Create a build for a project', - 'project_id_argument' => 'A project ID', - 'commit_id_option' => 'Commit ID to build', - 'branch_name_option' => 'Branch to build', - // Run Command 'run_all_pending' => 'Εκτελέστε όλες τις εκκρεμείς PHPCI κατασκευές.', 'finding_builds' => 'Αναζήτηση κατασκευών για επεξεργασία', diff --git a/PHPCI/Languages/lang.en.php b/PHPCI/Languages/lang.en.php index 63df75d2..ec2306e0 100644 --- a/PHPCI/Languages/lang.en.php +++ b/PHPCI/Languages/lang.en.php @@ -39,7 +39,6 @@ PHPCI', 'reset_email_title' => 'PHPCI Password Reset for %s', 'reset_invalid' => 'Invalid password reset request.', 'email_address' => 'Email Address', - 'login' => 'Login / Email Address', 'password' => 'Password', 'log_in' => 'Log in', @@ -115,8 +114,6 @@ PHPCI', (if you cannot add a phpci.yml file in the project repository)', 'default_branch' => 'Default branch name', 'allow_public_status' => 'Enable public status page and image for this project?', - 'archived' => 'Archived', - 'archived_menu' => 'Archived', 'save_project' => 'Save Project', 'error_mercurial' => 'Mercurial repository URL must be start with http:// or https://', @@ -130,7 +127,6 @@ PHPCI', 'all_branches' => 'All Branches', 'builds' => 'Builds', 'id' => 'ID', - 'date' => 'Date', 'project' => 'Project', 'commit' => 'Commit', 'branch' => 'Branch', @@ -154,9 +150,6 @@ PHPCI', Services section of your Bitbucket repository.', // View Build - 'errors' => 'Errors', - 'information' => 'Information', - 'build_x_not_found' => 'Build with ID %d does not exist.', 'build_n' => 'Build %d', 'rebuild_now' => 'Rebuild Now', @@ -194,12 +187,6 @@ PHPCI', 'technical_debt' => 'Technical Debt', 'behat' => 'Behat', - 'codeception_feature' => 'Feature', - 'codeception_suite' => 'Suite', - 'codeception_time' => 'Time', - 'codeception_synopsis' => '%1$d tests carried out in %2$f seconds. - %3$d failures.', - 'file' => 'File', 'line' => 'Line', 'class' => 'Class', @@ -209,20 +196,14 @@ PHPCI', 'end' => 'End', 'from' => 'From', 'to' => 'To', + 'suite' => 'Suite', + 'test' => 'Test', 'result' => 'Result', 'ok' => 'OK', 'took_n_seconds' => 'Took %d seconds', 'build_created' => 'Build Created', 'build_started' => 'Build Started', 'build_finished' => 'Build Finished', - 'test_message' => 'Message', - 'test_no_message' => 'No message', - 'test_success' => 'Successful: %d', - 'test_fail' => 'Failures: %d', - 'test_skipped' => 'Skipped: %d', - 'test_error' => 'Errors: %d', - 'test_todo' => 'Todos: %d', - 'test_total' => '%d test(s)', // Users 'name' => 'Name', @@ -299,19 +280,6 @@ PHPCI', 'search_packagist_for_more' => 'Search Packagist for more packages', 'search' => 'Search »', - // Summary plugin - 'build-summary' => 'Summary', - 'stage' => 'Stage', - 'duration' => 'Duration', - 'plugin' => 'Plugin', - 'stage_setup' => 'Setup', - 'stage_test' => 'Test', - 'stage_complete' => 'Complete', - 'stage_success' => 'Success', - 'stage_failure' => 'Failure', - 'stage_broken' => 'Broken', - 'stage_fixed' => 'Fixed', - // Installer 'installation_url' => 'PHPCI Installation URL', 'db_host' => 'Database Host', @@ -332,9 +300,9 @@ PHPCI', Please review the errors above before continuing.', 'must_be_valid_email' => 'Must be a valid email address.', 'must_be_valid_url' => 'Must be a valid URL.', - 'enter_name' => 'Admin Name: ', - 'enter_email' => 'Admin Email: ', - 'enter_password' => 'Admin Password: ', + 'enter_name' => 'Admin Name:', + 'enter_email' => 'Admin Email:', + 'enter_password' => 'Admin Password:', 'enter_phpci_url' => 'Your PHPCI URL ("http://phpci.local" for example): ', 'enter_db_host' => 'Please enter your MySQL host [localhost]: ', @@ -367,15 +335,6 @@ PHPCI', 'create_admin_user' => 'Create an admin user', 'incorrect_format' => 'Incorrect format', - // Create Build Command - 'create_build_project' => 'Create a build for a project', - 'project_id_argument' => 'A project ID', - 'commit_id_option' => 'Commit ID to build', - 'branch_name_option' => 'Branch to build', - 'add_to_queue_failed' => 'Build created successfully, but failed to add to build queue. This usually happens - when PHPCI is set to use a beanstalkd server that does not exist, - or your beanstalkd server has stopped.', - // Run Command 'run_all_pending' => 'Run all pending PHPCI builds.', 'finding_builds' => 'Finding builds to process', @@ -423,22 +382,5 @@ PHPCI', 'build_file_missing' => 'Specified build file does not exist.', 'property_file_missing' => 'Specified property file does not exist.', 'could_not_process_report' => 'Could not process the report generated by this tool.', - 'shell_not_enabled' => 'The shell plugin is not enabled. Please enable it via config.yml.', - - - // Error Levels: - 'critical' => 'Critical', - 'high' => 'High', - 'normal' => 'Normal', - 'low' => 'Low', - - // Plugins that generate errors: - 'php_mess_detector' => 'PHP Mess Detector', - 'php_code_sniffer' => 'PHP Code Sniffer', - 'php_unit' => 'PHP Unit', - 'php_cpd' => 'PHP Copy/Paste Detector', - 'php_docblock_checker' => 'PHP Docblock Checker', - 'behat' => 'Behat', - 'technical_debt' => 'Technical Debt', - + 'shell_not_enabled' => 'The shell plugin is not enabled. Please enable it via config.yml.' ); diff --git a/PHPCI/Languages/lang.es.php b/PHPCI/Languages/lang.es.php deleted file mode 100644 index 1b7b33f7..00000000 --- a/PHPCI/Languages/lang.es.php +++ /dev/null @@ -1,387 +0,0 @@ - 'Español', - 'language' => 'Lenguaje', - - // Log in: - 'log_in_to_phpci' => 'Ingresar a PHPCI', - 'login_error' => 'Email o contraseña incorrectos', - 'forgotten_password_link' => '¿Olvidaste tu contraseña?', - 'reset_emailed' => 'Te hemos enviado un email para reiniciar tu contraseña.', - 'reset_header' => '¡No te preocupes!
Solo tienes que ingresar tu dirección de email - y te enviaremos por email un enlace para reiniciar tu contraseña.', - 'reset_email_address' => 'Ingresa tu dirección de email:', - 'reset_send_email' => 'Enviar enlace', - 'reset_enter_password' => 'Ingresa una nueva contraseña', - 'reset_new_password' => 'Nueva contraseña:', - 'reset_change_password' => 'Cambiar contraseña', - 'reset_no_user_exists' => 'No existe ningún usuario con ese email, por favor intenta nuevamente.', - 'reset_email_body' => 'Hola %s, - -Has recibido este correo porque tú, o alguien más, ha solicitado reiniciar la contraseña de PHPCI - -Si fuiste tú, por favor haz click en el siguiente enlace para reiniciar tu contraseña: %ssession/reset-password/%d/%s - -De lo contrario, por favor ignora este correo y ninguna acción será realizada. - -Gracias, - -PHPCI', - - 'reset_email_title' => 'Reiniciar contraseña de PHPCI para %s', - 'reset_invalid' => 'Pedido inválido.', - 'email_address' => 'Dirección de email', - 'password' => 'Contraseña', - 'log_in' => 'Ingresar', - - - // Top Nav - 'toggle_navigation' => 'Activar navegación', - 'n_builds_pending' => '%d builds pendientes', - 'n_builds_running' => '%d builds ejecutándose', - 'edit_profile' => 'Editar Perfil', - 'sign_out' => 'Cerrar Sesión', - 'branch_x' => 'Rama: %s', - 'created_x' => 'Creada el: %s', - 'started_x' => 'Comenzó: %s', - - // Sidebar - 'hello_name' => 'Hola, %s', - 'dashboard' => 'Escritorio', - 'admin_options' => 'Opciones de Admin.', - 'add_project' => 'Agregar Proyecto', - 'settings' => 'Configuración', - 'manage_users' => 'Administrar Usuarios', - 'plugins' => 'Plugins', - 'view' => 'Vista', - 'build_now' => 'Ejecutar Build', - 'edit_project' => 'Editar Proyecto', - 'delete_project' => 'Eliminar Proyecto', - - // Project Summary: - 'no_builds_yet' => '¡No existen builds aún!', - 'x_of_x_failed' => '%d de los últimos %d builds fallaron.', - 'x_of_x_failed_short' => '%d / %d fallaron.', - 'last_successful_build' => ' El último build exitoso fue %s.', - 'never_built_successfully' => ' Este proyecto nunca tuvo un build exitoso.', - 'all_builds_passed' => 'Todos los últimos %d builds pasaron.', - 'all_builds_passed_short' => '%d / %d pasaron.', - 'last_failed_build' => ' El último build en fallar fue %s.', - 'never_failed_build' => ' Este proyecto no tiene ningún build fallido.', - 'view_project' => 'Ver Proyecto', - - // Timeline: - 'latest_builds' => 'Últimos builds', - 'pending' => 'Pediente', - 'running' => 'Ejecutando', - 'success' => 'Éxito', - 'successful' => 'Exitoso', - 'failed' => 'Falló', - 'manual_build' => 'Build Manual', - - // Add/Edit Project: - 'new_project' => 'Nuevo Proyecto', - 'project_x_not_found' => 'El Proyecto con ID %d no existe.', - 'project_details' => 'Detalles del Proyecto', - 'public_key_help' => 'Para facilitarte, hemos generado un par de llaves SSH para que uses en este proyecto. - Para usarlo, sólo agrega la siguiente llave pública a la sección de "deploy keys" - de tu plataforma de hosting de versionado de código.', - 'select_repository_type' => 'Selecciona tipo de repositorio...', - 'github' => 'GitHub', - 'bitbucket' => 'Bitbucket', - 'gitlab' => 'GitLab', - 'remote' => 'URL Remota', - 'local' => 'Path local', - 'hg' => 'Mercurial', - 'svn' => 'Subversion', - - 'where_hosted' => '¿Dónde está alojado tu proyecto?', - 'choose_github' => 'Selecciona un repositorio de GitHub:', - - 'repo_name' => 'Nombre del repositorio / URL (Remoto) o Ruta (Local)', - 'project_title' => 'Titulo del proyecto', - 'project_private_key' => 'Clave privada a usar para acceder al repositorio - (dejar en blanco para remotos locales o anónimos)', - 'build_config' => 'Configuración PHPCI para builds del proyecto - (en caso que no puedas agregar el archivo phpci.yml al repositorio)', - 'default_branch' => 'Nombre de la rama por defecto', - 'allow_public_status' => '¿Activar página pública con el estado del proyecto?', - 'archived' => 'Archivado', - 'archived_menu' => 'Archivado', - 'save_project' => 'Guardar Proyecto', - - 'error_mercurial' => 'La URL del repositorio de Mercurial debe comenzar con http:// or https://', - 'error_remote' => 'La URL del repositorio debe comenzar con git://, http:// or https://', - 'error_gitlab' => 'El nombre del repositorio de GitLab debe tener el formato "user@domain.tld:owner/repo.git"', - 'error_github' => 'El nombre del repositorio debe tener el formato "owner/repo"', - 'error_bitbucket' => 'El nombre del repo debe tener el formato "owner/repo"', - 'error_path' => 'La ruta especificada no existe.', - - // View Project: - 'all_branches' => 'Todas las ramas', - 'builds' => 'Builds', - 'id' => 'ID', - 'project' => 'Proyecto', - 'commit' => 'Commit', - 'branch' => 'Rama', - 'status' => 'Estado', - 'prev_link' => '« Anterior', - 'next_link' => 'Siguiente »', - 'public_key' => 'Llave pública', - 'delete_build' => 'Eliminar Build', - - 'webhooks' => 'Webhooks', - 'webhooks_help_github' => 'Para compilar automáticamente este proyecto cada vez que se realiza un commit, agreagar la siguiente URL - como un nuevo "webhook" en la sección Webhooks - and Services de tu repositorio en GitHub.', - - 'webhooks_help_gitlab' => 'Para compilar automáticamente este proyecto, cada vez que se realiza un commit, agreagar la siguiente URL - como una "WebHook URL" en la sección "web hooks" de tu repositorio en GitLab.', - - 'webhooks_help_bitbucket' => 'Para compilar automáticamente este proyecto, cada vez que se realiza un commit, agreagar la siguiente URL - como un servicio "POST" en la sección - - Services de tu repositorio en Bitbucket.', - - // View Build - 'build_x_not_found' => 'El build con ID %d no existe.', - 'build_n' => 'Build %d', - 'rebuild_now' => 'Rebuild Ahora', - - - 'committed_by_x' => 'Commit hecho por %s', - 'commit_id_x' => 'Commit: %s', - - 'chart_display' => 'Este gráfico será mostrado una vez que el build se haya completado.', - - 'build' => 'Build', - 'lines' => 'Líneas', - 'comment_lines' => 'Líneas de comentario', - 'noncomment_lines' => 'Líneas no comentario', - 'logical_lines' => 'Líneas lógicas', - 'lines_of_code' => 'Líneas de código', - 'build_log' => 'Log', - 'quality_trend' => 'Tendencia de calidad', - 'codeception_errors' => 'Errores de Codeception', - 'phpmd_warnings' => 'PHPMD Warnings', - 'phpcs_warnings' => 'PHPCS Warnings', - 'phpcs_errors' => 'PHPCS Errors', - 'phplint_errors' => 'Lint Errors', - 'phpunit_errors' => 'PHPUnit Errors', - 'phpdoccheck_warnings' => 'Docblocks faltantes', - 'issues' => 'Incidencias', - - 'codeception' => 'Codeception', - 'phpcpd' => 'PHP Copy/Paste Detector', - 'phpcs' => 'PHP Code Sniffer', - 'phpdoccheck' => 'Missing Docblocks', - 'phpmd' => 'PHP Mess Detector', - 'phpspec' => 'PHP Spec', - 'phpunit' => 'PHP Unit', - 'technical_debt' => 'Deuda Técnica', - 'behat' => 'Behat', - - 'file' => 'Archivo', - 'line' => 'Línea', - 'class' => 'Clase', - 'method' => 'Método', - 'message' => 'Mensaje', - 'start' => 'Inicio', - 'end' => 'Fin', - 'from' => 'De', - 'to' => 'Para', - 'suite' => 'Suite', - 'test' => 'Test', - 'result' => 'Resultado', - 'ok' => 'OK', - 'took_n_seconds' => 'Tomó %d segundos', - 'build_created' => 'Build Creado', - 'build_started' => 'Build Comenzado', - 'build_finished' => 'Build Terminado', - - // Users - 'name' => 'Nombre', - 'password_change' => 'Contraseña (dejar en blanco si no quiere cambiarla)', - 'save' => 'Guardar »', - 'update_your_details' => 'Actualizar los detalles', - 'your_details_updated' => 'Tus detalles han sido actualizados.', - 'add_user' => 'Agregar Usuario', - 'is_admin' => '¿Es Admin?', - 'yes' => 'Si', - 'no' => 'No', - 'edit' => 'Editar', - 'edit_user' => 'Editar Usuario', - 'delete_user' => 'Delete Usuario', - 'user_n_not_found' => 'Usuario con ID %d no existe.', - 'is_user_admin' => '¿Es un usuario administrador?', - 'save_user' => 'Guardar Usuario', - - // Settings: - 'settings_saved' => 'Tu configuración ha sido guardada.', - 'settings_check_perms' => 'Tu configuración no fue guardada, verificar los permisos del archivo config.yml.', - 'settings_cannot_write' => 'PHPCI no puede escribir en el archivo config.yml file, la configuración no será guardada correctamente - hasta no corregir esto.', - 'settings_github_linked' => 'Tu cuenta GitHub ha sido conectada.', - 'settings_github_not_linked' => 'No se pudo conectar a tu cuenta GitHub.', - 'build_settings' => 'Configuración del Build ', - 'github_application' => 'Aplicación GitHub', - 'github_sign_in' => 'Antes de comenzar a utilizar GitHub, tienes que ingresar y permitir - el acceso a tu cuenta a PHPCI.', - 'github_phpci_linked' => 'PHPCI ha sido conectado a tu cuenta GitHub.', - 'github_where_to_find' => 'Donde encontrar estos...', - 'github_where_help' => 'Si eres priopietario de la aplicaión que quieres usar, puedes encontrar esta información en - el área de configuración de aplicaciones.', - - 'email_settings' => 'Configuraciones de Email', - 'email_settings_help' => 'Para que PHPCI pueda enviar email con el status de los builds, - debes configurar las siguientes propiedades SMTP.', - - 'application_id' => 'ID de aplicación', - 'application_secret' => 'Application Secret', - - 'smtp_server' => 'Servidor SMTP', - 'smtp_port' => 'Puerto SMTP', - 'smtp_username' => 'Usuario SMTP', - 'smtp_password' => 'Contraseña SMTP', - 'from_email_address' => 'Dirección de email DE', - 'default_notification_address' => 'Dirección de correo de notificación por defecto', - 'use_smtp_encryption' => 'Usar encriptación SMTP?', - 'none' => 'None', - 'ssl' => 'SSL', - 'tls' => 'TLS', - - 'failed_after' => 'Considerar el build como fallido luego de ', - '5_mins' => '5 Minutos', - '15_mins' => '15 Minutos', - '30_mins' => '30 Minutos', - '1_hour' => '1 Hora', - '3_hours' => '3 Horas', - - // Plugins - 'cannot_update_composer' => 'PHPCI no puede actualizar composer.json porque no tiene permisos de escritura.', - 'x_has_been_removed' => '%s ha sido elimiando.', - 'x_has_been_added' => '%s ha sido agregado a composer.json y será instalado la próxima vez que ejecutes composer update.', - 'enabled_plugins' => 'Activar Plugins', - 'provided_by_package' => 'Provisto por Paquete', - 'installed_packages' => 'Paquetes Instalados', - 'suggested_packages' => 'Paquetes Sugeridos', - 'title' => 'Título', - 'description' => 'Descripción', - 'version' => 'Versión', - 'install' => 'Instalar »', - 'remove' => 'Eliminar »', - 'search_packagist_for_more' => 'Buscar más paquetes en Packagist', - 'search' => 'Buscar »', - - // Installer - 'installation_url' => 'URL de la instalación PHPCI', - 'db_host' => 'Host', - 'db_name' => 'Nombre de la base de datos', - 'db_user' => 'Usuario de la base de datos', - 'db_pass' => 'Clave de la base de datos', - 'admin_name' => 'Nombre del Admin', - 'admin_pass' => 'Clave del Admin', - 'admin_email' => 'Email de Admin', - 'config_path' => 'Ruta al archivo config', - 'install_phpci' => 'Instalar PHPCI', - 'welcome_to_phpci' => 'Bienvenido a PHPCI', - 'please_answer' => 'Por favor, responde las siguientes preguntas:', - 'phpci_php_req' => 'PHPCI requiere al menos PHP 5.3.8 para funcionar.', - 'extension_required' => 'Extensión requerida: %s', - 'function_required' => 'PHPCI debe poder invocar la función %s(). Está deshabilitada en php.ini?', - 'requirements_not_met' => 'PHPCI no pudo ser instalado, ya que no se cumplen todos los requerimientos. - Por favor, corrige los errores antes de continuar.', - 'must_be_valid_email' => 'Debe ser una dirección de correos válida.', - 'must_be_valid_url' => 'Debe ser una URL válida.', - 'enter_name' => 'Nombre del Admin:', - 'enter_email' => 'Email del Admin:', - 'enter_password' => 'Contraseña de Admin:', - 'enter_phpci_url' => 'La URL de PHPCI ("Por ejemplo: http://phpci.local"): ', - - 'enter_db_host' => 'Por favor, ingresa el servidor MySQL [localhost]: ', - 'enter_db_name' => 'Por favor, ingresa el nombre de la base de datos MySQL [phpci]: ', - 'enter_db_user' => 'Por favor, ingresa el usuario MySQL [phpci]: ', - 'enter_db_pass' => 'Por favor, ingresa la contraseña MySQL: ', - 'could_not_connect' => 'PHPCI no pudo conectarse a MySQL con los datos dados. Por favor, intenta nuevamente.', - 'setting_up_db' => 'Configurando base de datos... ', - 'user_created' => '¡Cuenta de usuario creada!', - 'failed_to_create' => 'PHPCI no pudo crear la cuenta de admin.', - 'config_exists' => 'El archivo config de PHPCI ya existe y no es vacío.', - 'update_instead' => 'Si está intentando actualizar PHPCI, por favor, utiliza phpci:update.', - - // Update - 'update_phpci' => 'Actuliza la base de datos para reflejar los modelos actualizados.', - 'updating_phpci' => 'Actualizando base de datos PHPCI: ', - 'not_installed' => 'PHPCI no está instalado.', - 'install_instead' => 'Por favor, instala PHPCI via phpci:install.', - - // Poll Command - 'poll_github' => 'Chequear en GitHub si se necesita comenzar un Build.', - 'no_token' => 'No se encontró ningún token GitHub', - 'finding_projects' => 'Buscando proyectos para chequear', - 'found_n_projects' => 'Se encontraron %d proyectos', - 'last_commit_is' => 'El último commit en GitHub para %s es %s', - 'adding_new_build' => 'Último commit es diferente a la base de datos, agregando nuevo build.', - 'finished_processing_builds' => 'Fin de procesamiento de builds.', - - // Create Admin - 'create_admin_user' => 'Crear un usuario Admin', - 'incorrect_format' => 'Formato incorrecto', - - // Run Command - 'run_all_pending' => 'Ejecutar todos los builds PHPCI pendientes.', - 'finding_builds' => 'Buscando builds a procesar', - 'found_n_builds' => 'Se encontraron %d builds', - 'skipping_build' => 'Saltando Build %d - Build del proyecto ya en ejecución.', - 'marked_as_failed' => 'Build %d falló debido a timeout.', - - // Builder - 'missing_phpci_yml' => 'Este proyecto no contiene el archivo phpci.yml o está vacío.', - 'build_success' => 'BUILD EXITOSO', - 'build_failed' => 'BUILD FALLIDO', - 'removing_build' => 'Eliminando Build.', - 'exception' => 'Excepción: ', - 'could_not_create_working' => 'Imposible crear copia de trabajo.', - 'working_copy_created' => 'Copia de trabajo creada: %s', - 'looking_for_binary' => 'Buscando binario: %s', - 'found_in_path' => 'Encontrado en %s: %s', - 'running_plugin' => 'EJECUTANDO PLUGIN: %s', - 'plugin_success' => 'PLUGIN: EXITO', - 'plugin_failed' => 'PLUGIN: FALLÓ', - 'plugin_missing' => 'No existe el plugin: %s', - 'tap_version' => 'TapParser únicamente soporta la verisón 13 de TAP', - 'tap_error' => 'Cadena de caracteres TAP inválida, el número de tests no coincide con la cuenta de tests declarada.', - - // Build Plugins: - 'no_tests_performed' => 'No se ejecutaron tests.', - 'could_not_find' => 'No se encontró %s', - 'no_campfire_settings' => 'No se especificaron parámetros de conexión para el plugin Campfire', - 'failed_to_wipe' => 'Imposible eliminar directorio existente %s antes de copiarlo', - 'passing_build' => 'Build Exitoso', - 'failing_build' => 'Build Fallido', - 'log_output' => 'Log de Salida: ', - 'n_emails_sent' => '%d emails enviados.', - 'n_emails_failed' => '%d emails no pudieron ser enviados.', - 'unable_to_set_env' => 'Imposible setear variable de entorno', - 'tag_created' => 'Tag creado por PHPCI: %s', - 'x_built_at_x' => 'Build de %PROJECT_TITLE% en %BUILD_URI%', - 'hipchat_settings' => 'Por favor, definir room y authToken para el plugin hipchat_notify', - 'irc_settings' => 'Debes configurar un servidor, room y apodo.', - 'invalid_command' => 'Comando inválido', - 'import_file_key' => 'Sentencia de importación debe contener una llave \'file\'', - 'cannot_open_import' => 'Imposible abrir archivo de importación SQL: %s', - 'unable_to_execute' => 'Imposible ejecutar archivo SQL', - 'phar_internal_error' => 'Error interno en plugin Phar', - 'build_file_missing' => 'El archivo de build especificado no existe.', - 'property_file_missing' => 'El archivo de propiedades especificado no existe.', - 'could_not_process_report' => 'Imposible procesar el reporte generado por la herramienta.', - 'shell_not_enabled' => 'El plugin shell no está habilitado. Por favor, habilitalo desde config.yml.' -); diff --git a/PHPCI/Languages/lang.fr.php b/PHPCI/Languages/lang.fr.php index a0f2cab8..45cc3958 100644 --- a/PHPCI/Languages/lang.fr.php +++ b/PHPCI/Languages/lang.fr.php @@ -39,7 +39,6 @@ PHPCI', 'reset_email_title' => 'Réinitialisation du mot de passe PHPCI pour %s', 'reset_invalid' => 'Requête de réinitialisation de mot de passe invalide.', 'email_address' => 'Adresse email', - 'login' => 'Login / Email Address', 'password' => 'Mot de passe', 'log_in' => 'Connexion', @@ -114,8 +113,6 @@ PHPCI', (si vous ne pouvez pas ajouter de fichier phpci.yml à la racine du dépôt)', 'default_branch' => 'Nom de la branche par défaut', 'allow_public_status' => 'Activer la page de statut publique et l\'image pour ce projet ?', - 'archived' => 'Archived', - 'archived_menu' => 'Archived', 'save_project' => 'Enregistrer le projet', 'error_mercurial' => 'Les URLs de dépôt Mercurial doivent commencer par http:// ou https://', @@ -129,7 +126,6 @@ PHPCI', 'all_branches' => 'Toutes les branches', 'builds' => 'Builds', 'id' => 'ID', - 'date' => 'Date', 'project' => 'Projet', 'commit' => 'Commit', 'branch' => 'Branche', @@ -197,20 +193,14 @@ PHPCI', 'end' => 'Fin', 'from' => 'À partir de', 'to' => 'jusque', + 'suite' => 'Suite', + 'test' => 'Test', 'result' => 'Resultat', 'ok' => 'OK', 'took_n_seconds' => 'Exécuté en %d secondes', 'build_created' => 'Build créé', 'build_started' => 'Build démarré', 'build_finished' => 'Build terminé', - 'test_message' => 'Message', - 'test_no_message' => 'Pas de message', - 'test_success' => 'Réussi(s): %d', - 'test_fail' => 'Echec(s): %d', - 'test_skipped' => 'Passé(s): %d', - 'test_error' => 'Erreurs: %d', - 'test_todo' => 'Todos: %d', - 'test_total' => '%d test(s)', // Users 'name' => 'Nom', @@ -273,7 +263,7 @@ PHPCI', // Plugins 'cannot_update_composer' => 'PHPCI ne peut pas mettre à jour le fichier composer.json pour vous, il n\'est pas modifiable.', 'x_has_been_removed' => '%s a été supprimé.', - 'x_has_been_added' => '%s a été ajouté au fichier composer.json pour vous et il sera installé la prochaine fois + 'x_has_been_added' => '%s a été ajouté au fichier composer.json poru vous et il sera installé la prochaine fois que vous lancerez "composer update".', 'enabled_plugins' => 'Plugins activés', 'provided_by_package' => 'Fournis par le paquet', @@ -287,17 +277,6 @@ PHPCI', 'search_packagist_for_more' => 'Rechercher sur Packagist pour trouver plus de paquets', 'search' => 'Rechercher »', - // Summary plugin - 'build-summary' => 'Résumé', - 'stage' => 'Étape', - 'duration' => 'Durée', - 'plugin' => 'Plugin', - 'stage_setup' => 'Préparation', - 'stage_test' => 'Test', - 'stage_complete' => 'Terminé', - 'stage_success' => 'Succes', - 'stage_failure' => 'Échec', - // Installer 'installation_url' => 'URL d\'installation de PHPCI', 'db_host' => 'Hôte de la BDD', @@ -318,9 +297,9 @@ PHPCI', Merci de corriger les erreurs ci-dessus avant de continuer.', 'must_be_valid_email' => 'Doit être une adresse email valide.', 'must_be_valid_url' => 'Doit être une URL valide.', - 'enter_name' => 'Nom de l\'admin: ', - 'enter_email' => 'Email de l\'admin: ', - 'enter_password' => 'Mot de passe de l\'admin: ', + 'enter_name' => 'Nom de l\'admin :', + 'enter_email' => 'Email de l\'admin :', + 'enter_password' => 'Mot de passe de l\'admin :', 'enter_phpci_url' => 'Votre URL vers PHPCI (par exemple "http://phpci.local"): ', 'enter_db_host' => 'Merci d\'entrer le nom d\'hôte MySQL [localhost]: ', @@ -353,12 +332,6 @@ PHPCI', 'create_admin_user' => 'Créer un utilisateur admin', 'incorrect_format' => 'Format incorrect', - // Create Build Command - 'create_build_project' => 'Créer un build projet', - 'project_id_argument' => 'ID du projet', - 'commit_id_option' => 'ID du commit', - 'branch_name_option' => 'Branche', - // Run Command 'run_all_pending' => 'Démarrage de tout les builds PHPCI en attente.', 'finding_builds' => 'Découverte des builds à traiter', diff --git a/PHPCI/Languages/lang.it.php b/PHPCI/Languages/lang.it.php index d254fbcd..c5c4e01b 100644 --- a/PHPCI/Languages/lang.it.php +++ b/PHPCI/Languages/lang.it.php @@ -39,7 +39,6 @@ PHPCI', 'reset_email_title' => 'Ripristino della password di PHPCI per %s', 'reset_invalid' => 'Richeista di ripristino password non valida.', 'email_address' => 'Indirizzo Email', - 'login' => 'Login / Email Address', 'password' => 'Password', 'log_in' => 'Accedi', @@ -113,8 +112,6 @@ PHPCI', (se non puoi aggiungere il file phpci.yml nel repository di questo progetto)', 'default_branch' => 'Nome del branch di default', 'allow_public_status' => 'Vuoi rendere pubblica la pagina dello stato e l\'immagine per questo progetto?', - 'archived' => 'Archived', - 'archived_menu' => 'Archived', 'save_project' => 'Salva il Progetto', 'error_mercurial' => 'L\'URL del repository Mercurial URL deve iniziare con http:// o https://', @@ -129,7 +126,6 @@ PHPCI', 'all_branches' => 'Tutti i Branche', 'builds' => 'Builds', 'id' => 'ID', - 'date' => 'Data', 'project' => 'Progetto', 'commit' => 'Commit', 'branch' => 'Branch', @@ -199,20 +195,14 @@ PHPCI', 'end' => 'Finisci', 'from' => 'Da', 'to' => 'A', + 'suite' => 'Suite', + 'test' => 'Test', 'result' => 'Risultati', 'ok' => 'OK', 'took_n_seconds' => 'Sono stati impiegati %d seconds', 'build_created' => 'Build Creata', 'build_started' => 'Build Avviata', 'build_finished' => 'Build Terminata', - 'test_message' => 'Message', - 'test_no_message' => 'No message', - 'test_success' => 'Successful: %d', - 'test_fail' => 'Failures: %d', - 'test_skipped' => 'Skipped: %d', - 'test_error' => 'Errors: %d', - 'test_todo' => 'Todos: %d', - 'test_total' => '%d test(s)', // Users 'name' => 'Nome', @@ -309,9 +299,9 @@ PHPCI', Per favore controlla gli errori riportati prima di proseguire.', 'must_be_valid_email' => 'Deve essere un indirizzo email valido.', 'must_be_valid_url' => 'Deve essere un URL valido.', - 'enter_name' => 'Nome dell\'amministratore: ', - 'enter_email' => 'Email dell\'amministratore: ', - 'enter_password' => 'Password dell\'amministratore: ', + 'enter_name' => 'Nome dell\'amministratore:', + 'enter_email' => 'Email dell\'amministratore:', + 'enter_password' => 'Password dell\'amministratore:', 'enter_phpci_url' => 'L\'URL di PHPCI ("http://phpci.locale" ad esempio): ', 'enter_db_host' => 'Per favore inserisci l\'host MySQL [localhost]: ', @@ -344,12 +334,6 @@ PHPCI', 'create_admin_user' => 'Crea un nuovo utente amministrarore', 'incorrect_format' => 'Formato errato', - // Create Build Command - 'create_build_project' => 'Create a build for a project', - 'project_id_argument' => 'A project ID', - 'commit_id_option' => 'Commit ID to build', - 'branch_name_option' => 'Branch to build', - // Run Command 'run_all_pending' => 'Esegui tutte le build in attesa su PHPCI.', 'finding_builds' => 'Ricerca delel build da processare', diff --git a/PHPCI/Languages/lang.nl.php b/PHPCI/Languages/lang.nl.php index 96d9f5d5..f38272c4 100644 --- a/PHPCI/Languages/lang.nl.php +++ b/PHPCI/Languages/lang.nl.php @@ -39,7 +39,6 @@ PHPCI', 'reset_email_title' => 'PHPCI wachtwoord reset voor %s', 'reset_invalid' => 'Ongeldig wachtwoord reset verzoek', 'email_address' => 'E-mailadres', - 'login' => 'Login / Email Address', 'password' => 'Wachtwoord', 'log_in' => 'Log in', @@ -114,8 +113,6 @@ van je gekozen source code hosting platform', (indien je geen phpci.yml bestand aan de project repository kan toevoegen)', 'default_branch' => 'Standaard branch naam', 'allow_public_status' => 'Publieke statuspagina en afbeelding beschikbaar maken voor dit project?', - 'archived' => 'Archived', - 'archived_menu' => 'Archived', 'save_project' => 'Project opslaan', 'error_mercurial' => 'Mercurial repository URL dient te starten met http:// of https://', @@ -129,7 +126,6 @@ van je gekozen source code hosting platform', 'all_branches' => 'Alle brances', 'builds' => 'Builds', 'id' => 'ID', - 'date' => 'Datum', 'project' => 'Project', 'commit' => 'Commit', 'branch' => 'Branch', @@ -197,20 +193,14 @@ Services sectie van je Bitbucket repository toegevoegd worden.', 'end' => 'Einde', 'from' => 'Van', 'to' => 'Tot', + 'suite' => 'Suite', + 'test' => 'Test', 'result' => 'Resultaat', 'ok' => 'OK', 'took_n_seconds' => 'Duurde %d seconden', 'build_created' => 'Build aangemaakt', 'build_started' => 'Build gestart', 'build_finished' => 'Build beëindigd', - 'test_message' => 'Message', - 'test_no_message' => 'No message', - 'test_success' => 'Successful: %d', - 'test_fail' => 'Failures: %d', - 'test_skipped' => 'Skipped: %d', - 'test_error' => 'Errors: %d', - 'test_todo' => 'Todos: %d', - 'test_total' => '%d test(s)', // Users 'name' => 'Naam', @@ -307,15 +297,15 @@ keer je composer update uitvoert.', Gelieve de fouten na te kijken vooraleer verder te gaan.', 'must_be_valid_email' => 'Moet een geldig e-mailadres zijn.', 'must_be_valid_url' => 'Moet een geldige URL zijn.', - 'enter_name' => 'Administrator naam: ', - 'enter_email' => 'Administrator e-mailadres: ', - 'enter_password' => 'Administrator wachtwoord: ', - 'enter_phpci_url' => 'Je PHPCI URL (bijvoorbeeld "http://phpci.local"): ', + 'enter_name' => 'Administrator naam:', + 'enter_email' => 'Administrator e-mailadres:', + 'enter_password' => 'Administrator wachtwoord:', + 'enter_phpci_url' => 'Je PHPCI URL (bijvoorbeeld "http://phpci.local")', - 'enter_db_host' => 'Vul je MySQL host in [localhost]: ', - 'enter_db_name' => 'Vul je MySQL databasenaam in [phpci]: ', - 'enter_db_user' => 'Vul je MySQL gebruikersnaam in [phpci]: ', - 'enter_db_pass' => 'Vul je MySQL watchtwoord in: ', + 'enter_db_host' => 'Vul je MySQL host in [localhost]:', + 'enter_db_name' => 'Vul je MySQL databasenaam in [phpci]:', + 'enter_db_user' => 'Vul je MySQL gebruikersnaam in [phpci]:', + 'enter_db_pass' => 'Vul je MySQL watchtwoord in:', 'could_not_connect' => 'PHPCI kon met deze gegevens geen verbinding maken met MySQL. Gelieve opnieuw te proberen.', 'setting_up_db' => 'Database wordt aangemaakt...', 'user_created' => 'Gebruikersprofiel aangemaakt!', @@ -342,12 +332,6 @@ Gelieve de fouten na te kijken vooraleer verder te gaan.', 'create_admin_user' => 'Administrator-gebruiker aanmaken', 'incorrect_format' => 'Incorrect formaat', - // Create Build Command - 'create_build_project' => 'Create a build for a project', - 'project_id_argument' => 'A project ID', - 'commit_id_option' => 'Commit ID to build', - 'branch_name_option' => 'Branch to build', - // Run Command 'run_all_pending' => 'Voer alle wachtende PHPCI builds uit.', 'finding_builds' => 'Zoekt builds om te verwerken', diff --git a/PHPCI/Languages/lang.pl.php b/PHPCI/Languages/lang.pl.php index e1d3c3bf..4aafc9cf 100644 --- a/PHPCI/Languages/lang.pl.php +++ b/PHPCI/Languages/lang.pl.php @@ -39,7 +39,6 @@ PHPCI', 'reset_email_title' => 'Reset Hasła PHPCI dla %s', 'reset_invalid' => 'Prośba o zmianę hasła jest nieważna.', 'email_address' => 'Adres email', - 'login' => 'Login / Email Address', 'password' => 'Hasło', 'log_in' => 'Zaloguj się', @@ -102,7 +101,6 @@ od wybranego kodu źródłowego platformy hostingowej.', 'remote' => 'Zdalny URL ', 'local' => 'Lokalna Ścieżka ', 'hg' => 'Mercurial', - 'svn' => 'Subversion', 'where_hosted' => 'Gdzie hostowany jest Twój projekt?', 'choose_github' => 'Wybierz repozytorium GitHub:', @@ -115,8 +113,6 @@ od wybranego kodu źródłowego platformy hostingowej.', (jeśli nie możesz dodać pliku phpci.yml do repozytorium projektu)', 'default_branch' => 'Domyślna nazwa gałęzi', 'allow_public_status' => 'Włączyć status publiczny dla tego projektu?', - 'archived' => 'W archiwum', - 'archived_menu' => 'W archiwum', 'save_project' => 'Zachowaj Projekt', 'error_mercurial' => 'URL repozytorium Mercurialnego powinno zaczynać się od http:// and https://', @@ -130,7 +126,6 @@ od wybranego kodu źródłowego platformy hostingowej.', 'all_branches' => 'Wszystkie Gałęzie', 'builds' => 'Budowania', 'id' => 'ID', - 'date' => 'Data', 'project' => 'Projekt', 'commit' => 'Commit', 'branch' => 'Gałąź', @@ -186,10 +181,8 @@ Services repozytoria Bitbucket.', 'phpcs' => 'PHP Code Sniffer', 'phpdoccheck' => 'Brakuje sekcji DocBlock', 'phpmd' => 'PHP Mess Detector', - 'phpspec' => 'PHPSpec', - 'phpunit' => 'PHPUnit', - 'technical_debt' => 'Dług technologiczny', - 'behat' => 'Behat', + 'phpspec' => 'Speck PHP', + 'phpunit' => 'Jednostka PHP', 'file' => 'Plik', 'line' => 'Linia', @@ -200,20 +193,14 @@ Services repozytoria Bitbucket.', 'end' => 'Koniec', 'from' => 'Od', 'to' => 'Do', + 'suite' => 'Zestaw ', + 'test' => 'Test', 'result' => 'Wynik', 'ok' => 'OK', 'took_n_seconds' => 'Zajęło %d sekund', 'build_created' => 'Budowanie Stworzone', 'build_started' => 'Budowanie Rozpoczęte', 'build_finished' => 'Budowanie Zakończone', - 'test_message' => 'Wiadomość', - 'test_no_message' => 'Brak wiadomości', - 'test_success' => 'Powodzenie: %d', - 'test_fail' => 'Niepowodzenia: %d', - 'test_skipped' => 'Pominęte: %d', - 'test_error' => 'Błędy: %d', - 'test_todo' => 'Do zrobienia: %d', - 'test_total' => '%d test(ów)', // Users 'name' => 'Nazwa', @@ -308,15 +295,15 @@ wywołaniu polecenia composer update.', Przejrzyj powyższą listę błędów przed kontynuowaniem.', 'must_be_valid_email' => 'Poprawny adres email jest wymagany.', 'must_be_valid_url' => 'Poprawny URL jest wymagany.', - 'enter_name' => 'Imię Admina: ', - 'enter_email' => 'Email Admina: ', - 'enter_password' => 'Hasło Admina: ', - 'enter_phpci_url' => 'URL PHPCI (na przykład "http://phpci.local"): ', + 'enter_name' => 'Imię Admina:', + 'enter_email' => 'Email Admina:', + 'enter_password' => 'Hasło Admina:', + 'enter_phpci_url' => 'URL PHPCI (na przykład "http://phpci.local"):', - 'enter_db_host' => 'Wpisz hosta MySQL [host lokalny]: ', - 'enter_db_name' => 'Wpisz nazwę bazy danych MySQL [phpci]: ', - 'enter_db_user' => 'Wpisz nazwę użytkownika MySQL [phpci]: ', - 'enter_db_pass' => 'Wpisz hasło MySQL: ', + 'enter_db_host' => 'Wpisz hosta MySQL [host lokalny]:', + 'enter_db_name' => 'Wpisz nazwę bazy danych MySQL [phpci]:', + 'enter_db_user' => 'Wpisz nazwę użytkownika MySQL [phpci]:', + 'enter_db_pass' => 'Wpisz hasło MySQL:', 'could_not_connect' => 'Z podanymi ustawieniami PHPCI nie udało się połączyć z MySQL. Spróbuj ponownie.', 'setting_up_db' => 'Ustawianie Twojej bazy danych...', 'user_created' => 'Utworzono konto użytkownika!', @@ -343,12 +330,6 @@ Przejrzyj powyższą listę błędów przed kontynuowaniem.', 'create_admin_user' => 'Utwórz admina', 'incorrect_format' => 'Niepoprawny format', - // Create Build Command - 'create_build_project' => 'Utwórz budowanie dla projektu', - 'project_id_argument' => 'ID projektu', - 'commit_id_option' => 'ID Commita do budowania', - 'branch_name_option' => 'Gałąź do budowania', - // Run Command 'run_all_pending' => 'Uruchom wszystkie oczekujące budowy w PHPCI', 'finding_builds' => 'Szukam budów do przetwarzania.', diff --git a/PHPCI/Languages/lang.ru.php b/PHPCI/Languages/lang.ru.php index 0a7acff2..00b2783e 100644 --- a/PHPCI/Languages/lang.ru.php +++ b/PHPCI/Languages/lang.ru.php @@ -38,10 +38,10 @@ PHPCI', 'reset_email_title' => 'Сброс пароля PHPCI для %s', 'reset_invalid' => 'Некорректный запрос на сброс пароля.', 'email_address' => 'Email', - 'login' => 'Логин / Email', 'password' => 'Пароль', 'log_in' => 'Войти', + // Top Nav 'toggle_navigation' => 'Скрыть/показать панель навигации', 'n_builds_pending' => '%d сборок ожидает', @@ -99,7 +99,6 @@ PHPCI', 'remote' => 'Внешний URL', 'local' => 'Локальный путь', 'hg' => 'Mercurial', - 'svn' => 'Subversion', 'where_hosted' => 'Расположение проекта', 'choose_github' => 'Выберите GitHub репозиторий:', @@ -107,13 +106,11 @@ PHPCI', 'repo_name' => 'Репозиторий / Внешний URL / Локальный путь', 'project_title' => 'Название проекта', 'project_private_key' => 'Приватный ключ для доступа к репозиторию - (оставьте поле пустым для локального использования и/или анонимного доступа)', + (оставьте поле пустым для локального использования и/или анонимного доступа)', 'build_config' => 'Конфигурация сборки проекта для PHPCI - (если вы не добавили файл phpci.yml в репозиторий вашего проекта)', + (если вы не добавили файл phpci.yml в репозиторий вашего проекта)', 'default_branch' => 'Ветка по умолчанию', 'allow_public_status' => 'Разрешить публичный статус и изображение (статуса) для проекта', - 'archived' => 'Архивный', - 'archived_menu' => 'Архив', 'save_project' => 'Сохранить проект', 'error_mercurial' => 'URL репозитория Mercurial должен начинаться с http:// или https://', @@ -127,7 +124,6 @@ PHPCI', 'all_branches' => 'Все ветки', 'builds' => 'Сборки', 'id' => 'ID', - 'date' => 'Дата', 'project' => 'Проект', 'commit' => 'Коммит', 'branch' => 'Ветка', @@ -139,13 +135,13 @@ PHPCI', 'webhooks' => 'Webhooks', 'webhooks_help_github' => 'Чтобы Автоматически собирать этот проект при публикации новых коммитов, добавьте URL ниже в качестве нового хука в разделе настроек Webhooks - and Services вашего GitHub репозитория.', + and Services вашего GitHub репозитория.', 'webhooks_help_gitlab' => 'Чтобы Автоматически собирать этот проект при публикации новых коммитов, добавьте URL ниже в качестве "WebHook URL" в разделе "Web Hooks" вашего GitLab репозитория.', 'webhooks_help_bitbucket' => 'Чтобы Автоматически собирать этот проект при публикации новых коммитов, добавьте URL ниже как "POST" сервис в разделе - Services вашего Bitbucket репозитория.', + Services вашего Bitbucket репозитория.', // View Build 'build_x_not_found' => 'Сборки с ID %d не существует.', @@ -182,37 +178,24 @@ PHPCI', 'phpmd' => 'PHP Mess Detector', 'phpspec' => 'PHP Spec', 'phpunit' => 'PHP Unit', - 'technical_debt' => 'Технические долги', - 'behat' => 'Behat', - - 'codeception_feature' => 'Свойство', - 'codeception_suite' => 'Набор', - 'codeception_time' => 'Время', - 'codeception_synopsis' => 'Тестов выполнено: %1$d (за %2$f сек.). Провалов: %3$d.', 'file' => 'Файл', 'line' => 'Строка', 'class' => 'Класс', 'method' => 'Метод', 'message' => 'Сообщение', - 'start' => 'Начало', + 'start' => 'Запуск', 'end' => 'Конец', - 'from' => 'Из', - 'to' => 'В', + 'from' => 'От', + 'to' => 'До', + 'suite' => 'Комплект', + 'test' => 'Тест', 'result' => 'Результат', 'ok' => 'OK', 'took_n_seconds' => 'Заняло секунд: %d', 'build_created' => 'Сборка создана', 'build_started' => 'Сборка запущена', 'build_finished' => 'Сборка окончена', - 'test_message' => 'Message', - 'test_no_message' => 'No message', - 'test_success' => 'Успешно: %d', - 'test_fail' => 'Провалено: %d', - 'test_skipped' => 'Пропущено: %d', - 'test_error' => 'Ошибок: %d', - 'test_todo' => 'Todo: %d', - 'test_total' => 'Тестов: %d', // Users 'name' => 'Имя', @@ -287,19 +270,6 @@ PHPCI', 'search_packagist_for_more' => 'Искать на Packagist', 'search' => 'Искать »', - // Summary plugin - 'build-summary' => 'Сводка', - 'stage' => 'Этап', - 'duration' => 'Продолжительность', - 'plugin' => 'Плагин', - 'stage_setup' => 'Установка', - 'stage_test' => 'тестирование', - 'stage_complete' => 'Завершение', - 'stage_success' => 'Успешное завершение', - 'stage_failure' => 'Провал', - 'stage_broken' => 'Поломка', - 'stage_fixed' => 'Исправление', - // Installer 'installation_url' => 'URL-адрес PHPCI для установки', 'db_host' => 'Хост базы данных', @@ -320,9 +290,9 @@ PHPCI', Пожалуйста, просмотрите возникшие ошибки перед тем, как продолжить.', 'must_be_valid_email' => 'Должен быть корректным email-адресом.', 'must_be_valid_url' => 'Должен быть корректным URL-адресом.', - 'enter_name' => 'Имя администратора: ', - 'enter_email' => 'Email администратора: ', - 'enter_password' => 'Пароль администратора: ', + 'enter_name' => 'Имя администратора:', + 'enter_email' => 'Email администратора:', + 'enter_password' => 'Пароль администратора:', 'enter_phpci_url' => 'URL-адрес вашего PHPCI (например: "http://phpci.local"): ', 'enter_db_host' => 'Пожалуйста, введите хост MySQL [localhost]: ', @@ -355,12 +325,6 @@ PHPCI', 'create_admin_user' => 'Добавить аккаунт администратора', 'incorrect_format' => 'Неверный формат', - // Create Build Command - 'create_build_project' => 'Создать сборку проекта', - 'project_id_argument' => 'ID проекта', - 'commit_id_option' => 'ID коммита для сборки', - 'branch_name_option' => 'Ветка для сборки', - // Run Command 'run_all_pending' => 'Запустить все ожидающие PHPCI сборки.', 'finding_builds' => 'Поиск сборок для запуска', diff --git a/PHPCI/Languages/lang.uk.php b/PHPCI/Languages/lang.uk.php index 54ced220..f51bd885 100644 --- a/PHPCI/Languages/lang.uk.php +++ b/PHPCI/Languages/lang.uk.php @@ -8,7 +8,7 @@ */ $strings = array( - 'language_name' => 'Українська', + 'language_name' => 'Український', 'language' => 'Мова', // Log in: @@ -20,10 +20,10 @@ $strings = array( і вам буде надіслано листа із посиланням на скидання паролю.', 'reset_email_address' => 'Введіть свою email адресу:', 'reset_send_email' => 'Скидання пароля', - 'reset_enter_password' => 'Введіть, будь ласка, новий пароль', + 'reset_enter_password' => 'Введіть будь-ласка новий пароль', 'reset_new_password' => 'Новий пароль:', 'reset_change_password' => 'Змінити пароль', - 'reset_no_user_exists' => 'Не існує користувача з такою email адресою, будь ласка, повторіть знову.', + 'reset_no_user_exists' => 'Не існує користувача з такою email адресою, будь-ласка повторіть знову.', 'reset_email_body' => 'Привіт, %s, Ви отримали цей лист, тому що ви або хтось інший запросили скидання пароля в PHPCI. @@ -39,7 +39,6 @@ PHPCI', 'reset_email_title' => 'Скидання пароль PHPCI для %s', 'reset_invalid' => 'Невірний запит скидання паролю.', 'email_address' => 'Email адреса', - 'login' => 'Логин / Email адреса', 'password' => 'Пароль', 'log_in' => 'Увійти', @@ -63,7 +62,7 @@ PHPCI', 'manage_users' => 'Управління користувачами', 'plugins' => 'Плагіни', 'view' => 'Переглянути', - 'build_now' => 'Зібрати', + 'build_now' => 'Збірати', 'edit_project' => 'Редагувати проект', 'delete_project' => 'Видалити проект', @@ -113,8 +112,6 @@ PHPCI', (якщо ви не додали файл phpci.yml до репозиторію вашого проекту)', 'default_branch' => 'Назва гілки за замовчуванням', 'allow_public_status' => 'Увімкнути публічну сторінку статусу та зображення для цього проекта?', - 'archived' => 'Архівний', - 'archived_menu' => 'Архів', 'save_project' => 'Зберегти проект', 'error_mercurial' => 'URL репозиторію Mercurial повинен починатись із http:// або https://', @@ -128,7 +125,6 @@ PHPCI', 'all_branches' => 'Усі гілки', 'builds' => 'Збірки', 'id' => 'ID', - 'date' => 'Дата', 'project' => 'Проект', 'commit' => 'Комміт', 'branch' => 'Гілка', @@ -189,7 +185,7 @@ PHPCI', 'phpunit' => 'PHP Unit', 'file' => 'Файл', - 'line' => 'Рядок', + 'line' => 'Строка', 'class' => 'Клас', 'method' => 'Метод', 'message' => 'Повідомлення', @@ -197,20 +193,14 @@ PHPCI', 'end' => 'Кінець', 'from' => 'Від', 'to' => 'До', + 'suite' => 'Комплект', + 'test' => 'Тест', 'result' => 'Результат', 'ok' => 'OK', 'took_n_seconds' => 'Зайняло %d секунд', 'build_created' => 'Збірка створена', 'build_started' => 'Збірка розпочата', 'build_finished' => 'Збірка завершена', - 'test_message' => 'Message', - 'test_no_message' => 'No message', - 'test_success' => 'Successful: %d', - 'test_fail' => 'Failures: %d', - 'test_skipped' => 'Skipped: %d', - 'test_error' => 'Errors: %d', - 'test_todo' => 'Todos: %d', - 'test_total' => '%d test(s)', // Users 'name' => 'Ім’я', @@ -307,15 +297,15 @@ PHPCI', Будь ласка, продивіться наявні помилки перед тим, як продовжити.', 'must_be_valid_email' => 'Повинно бути коректною email адресою.', 'must_be_valid_url' => 'Повинно бути коректним URL.', - 'enter_name' => 'Ім’я адміністратора: ', - 'enter_email' => 'Email адміністратора: ', - 'enter_password' => 'Пароль адміністратора: ', - 'enter_phpci_url' => 'URL адреса вашого PHPCI (наприклад, "http://phpci.local"): ', + 'enter_name' => 'Ім’я адміністратора:', + 'enter_email' => 'Email адміністратора:', + 'enter_password' => 'Пароль адміністратора:', + 'enter_phpci_url' => 'URL адреса вашого PHPCI (наприклад, "http://phpci.local"):', - 'enter_db_host' => 'Будь ласка, введіть хост MySQL [localhost]: ', - 'enter_db_name' => 'Будь ласка, введить ім’я бази даних MySQL [phpci]: ', - 'enter_db_user' => 'Будь ласка, введить ім’я користувача MySQL [phpci]: ', - 'enter_db_pass' => 'Будь ласка, введить ваш пароль MySQL: ', + 'enter_db_host' => 'Будь ласка, введіть хост MySQL [localhost]:', + 'enter_db_name' => 'Будь ласка, введить ім’я бази даних MySQL [phpci]:', + 'enter_db_user' => 'Будь ласка, введить ім’я користувача MySQL [phpci]:', + 'enter_db_pass' => 'Будь ласка, введить ваш пароль MySQL:', 'could_not_connect' => 'PHPCI не може підключитися до MySQL із наданими параметрами. Будь ласка, спробуйте ще раз.', 'setting_up_db' => 'Налаштування вашої бази даних...', 'user_created' => 'Аккаунт користувача створено!', @@ -342,12 +332,6 @@ PHPCI', 'create_admin_user' => 'Створити аккаунт адміністратора', 'incorrect_format' => 'Невірний формат', - // Create Build Command - 'create_build_project' => 'Create a build for a project', - 'project_id_argument' => 'A project ID', - 'commit_id_option' => 'Commit ID to build', - 'branch_name_option' => 'Branch to build', - // Run Command 'run_all_pending' => 'Запустити всі PHPCI збірки, які очікують.', 'finding_builds' => 'Пошук збірок для обробки', diff --git a/PHPCI/Logging/BuildLogger.php b/PHPCI/Logging/BuildLogger.php index a68e9e6d..73f3b464 100644 --- a/PHPCI/Logging/BuildLogger.php +++ b/PHPCI/Logging/BuildLogger.php @@ -67,7 +67,7 @@ class BuildLogger implements LoggerAwareInterface } } - /** + /** * Add a success-coloured message to the log. * @param string */ @@ -98,17 +98,6 @@ class BuildLogger implements LoggerAwareInterface ); } - /** - * Add a debug message to the log. - * @param string - */ - public function logDebug($message) - { - if (defined('PHPCI_DEBUG_MODE') && PHPCI_DEBUG_MODE) { - $this->log("\033[0;33m" . $message . "\033[0m"); - } - } - /** * Sets a logger instance on the object * diff --git a/PHPCI/Logging/Handler.php b/PHPCI/Logging/Handler.php index e22351da..ebfa2620 100644 --- a/PHPCI/Logging/Handler.php +++ b/PHPCI/Logging/Handler.php @@ -70,6 +70,7 @@ class Handler public function handleError($level, $message, $file, $line) { if (error_reporting() & $level) { + $exception_level = isset($this->levels[$level]) ? $this->levels[$level] : $level; throw new \ErrorException( @@ -139,6 +140,7 @@ class Handler protected function log(\Exception $exception) { if (null !== $this->logger) { + $message = sprintf( '%s: %s (uncaught exception) at %s line %s', get_class($exception), diff --git a/PHPCI/Logging/LoggerConfig.php b/PHPCI/Logging/LoggerConfig.php index fd929aeb..69617ee6 100644 --- a/PHPCI/Logging/LoggerConfig.php +++ b/PHPCI/Logging/LoggerConfig.php @@ -9,7 +9,6 @@ namespace PHPCI\Logging; -use Monolog\ErrorHandler; use Monolog\Logger; /** @@ -20,7 +19,6 @@ class LoggerConfig { const KEY_ALWAYS_LOADED = "_"; private $config; - private $cache = array(); /** * The filepath is expected to return an array which will be @@ -58,20 +56,9 @@ class LoggerConfig */ public function getFor($name) { - if (isset($this->cache[$name])) { - return $this->cache[$name]; - } - $handlers = $this->getHandlers(self::KEY_ALWAYS_LOADED); - if ($name !== self::KEY_ALWAYS_LOADED) { - $handlers = array_merge($handlers, $this->getHandlers($name)); - } - - $logger = new Logger($name, $handlers); - ErrorHandler::register($logger); - $this->cache[$name] = $logger; - - return $logger; + $handlers = array_merge($handlers, $this->getHandlers($name)); + return new Logger($name, $handlers); } /** diff --git a/PHPCI/Migrations/20140730143702_fix_database_columns.php b/PHPCI/Migrations/20140730143702_fix_database_columns.php index a1ac2493..809fc878 100644 --- a/PHPCI/Migrations/20140730143702_fix_database_columns.php +++ b/PHPCI/Migrations/20140730143702_fix_database_columns.php @@ -20,7 +20,7 @@ class FixDatabaseColumns extends AbstractMigration $build->changeColumn('project_id', 'integer', array('null' => false)); $build->changeColumn('commit_id', 'string', array('limit' => 50, 'null' => false)); $build->changeColumn('status', 'integer', array('null' => false)); - $build->changeColumn('log', 'text', array('null' => true)); + $build->changeColumn('log', 'text', array('null' => true, 'default' => '')); $build->changeColumn('branch', 'string', array('limit' => 50, 'null' => false, 'default' => 'master')); $build->changeColumn('created', 'datetime', array('null' => true)); $build->changeColumn('started', 'datetime', array('null' => true)); diff --git a/PHPCI/Migrations/20150131075425_archive_project.php b/PHPCI/Migrations/20150131075425_archive_project.php deleted file mode 100644 index 796fd48b..00000000 --- a/PHPCI/Migrations/20150131075425_archive_project.php +++ /dev/null @@ -1,26 +0,0 @@ -table('project'); - $project->addColumn('archived', 'boolean'); - $project->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - $project = $this->table('project'); - $project->removeColumn('archived'); - $project->save(); - } -} \ No newline at end of file diff --git a/PHPCI/Migrations/20150203105015_fix_column_types.php b/PHPCI/Migrations/20150203105015_fix_column_types.php index 53db2ad6..f9bcf68a 100644 --- a/PHPCI/Migrations/20150203105015_fix_column_types.php +++ b/PHPCI/Migrations/20150203105015_fix_column_types.php @@ -14,6 +14,7 @@ class FixColumnTypes extends AbstractMigration $build = $this->table('build'); $build->changeColumn('log', 'text', array( 'null' => true, + 'default' => '', 'limit' => MysqlAdapter::TEXT_MEDIUM, )); diff --git a/PHPCI/Migrations/20150324174958_unique_email_and_name_user_fields.php b/PHPCI/Migrations/20150324174958_unique_email_and_name_user_fields.php deleted file mode 100644 index f8d24ba0..00000000 --- a/PHPCI/Migrations/20150324174958_unique_email_and_name_user_fields.php +++ /dev/null @@ -1,30 +0,0 @@ -table('user'); - $user_table - ->addIndex('email', array('unique' => true)) - ->addIndex('name', array('unique' => true)) - ->save(); - } - - /** - * Migrate Down. - */ - public function down() - { - $user_table = $this->table('user'); - $user_table - ->removeIndex('email', array('unique' => true)) - ->removeIndex('name', array('unique' => true)) - ->save(); - } -} diff --git a/PHPCI/Migrations/20151008140800_add_project_groups.php b/PHPCI/Migrations/20151008140800_add_project_groups.php deleted file mode 100644 index f6035014..00000000 --- a/PHPCI/Migrations/20151008140800_add_project_groups.php +++ /dev/null @@ -1,29 +0,0 @@ -table('project_group'); - $table->addColumn('title', 'string', array('limit' => 100, 'null' => false)); - $table->save(); - - $group = new \PHPCI\Model\ProjectGroup(); - $group->setTitle('Projects'); - - /** @var \PHPCI\Model\ProjectGroup $group */ - $group = \b8\Store\Factory::getStore('ProjectGroup')->save($group); - - $table = $this->table('project'); - $table->addColumn('group_id', 'integer', array( - 'signed' => true, - 'null' => false, - 'default' => $group->getId(), - )); - - $table->addForeignKey('group_id', 'project_group', 'id', array('delete'=> 'RESTRICT', 'update' => 'CASCADE')); - $table->save(); - } -} diff --git a/PHPCI/Migrations/20151009100610_remove_unique_name_index.php b/PHPCI/Migrations/20151009100610_remove_unique_name_index.php deleted file mode 100644 index 283dfbc0..00000000 --- a/PHPCI/Migrations/20151009100610_remove_unique_name_index.php +++ /dev/null @@ -1,40 +0,0 @@ -table('user'); - - if ($user->hasIndex('name', array('unique' => true))) { - $user->removeIndex('name', array('unique' => true)); - $user->save(); - } - - $user->addIndex('name', array('unique' => false)); - $user->save(); - } -} diff --git a/PHPCI/Migrations/20151014091859_errors_table.php b/PHPCI/Migrations/20151014091859_errors_table.php deleted file mode 100644 index a064f6e5..00000000 --- a/PHPCI/Migrations/20151014091859_errors_table.php +++ /dev/null @@ -1,24 +0,0 @@ -table('build_error'); - $table->addColumn('build_id', 'integer', array('signed' => true)); - $table->addColumn('plugin', 'string', array('limit' => 100)); - $table->addColumn('file', 'string', array('limit' => 250, 'null' => true)); - $table->addColumn('line_start', 'integer', array('signed' => false, 'null' => true)); - $table->addColumn('line_end', 'integer', array('signed' => false, 'null' => true)); - $table->addColumn('severity', 'integer', array('signed' => false, 'limit' => MysqlAdapter::INT_TINY)); - $table->addColumn('message', 'string', array('limit' => 250)); - $table->addColumn('created_date', 'datetime'); - $table->addIndex(array('build_id', 'created_date'), array('unique' => false)); - $table->addForeignKey('build_id', 'build', 'id', array('delete'=> 'CASCADE', 'update' => 'CASCADE')); - $table->save(); - - } -} diff --git a/PHPCI/Migrations/20151015124825_convert_errors.php b/PHPCI/Migrations/20151015124825_convert_errors.php deleted file mode 100644 index 3622bf14..00000000 --- a/PHPCI/Migrations/20151015124825_convert_errors.php +++ /dev/null @@ -1,183 +0,0 @@ -metaStore = \b8\Store\Factory::getStore('BuildMeta'); - $this->errorStore = \b8\Store\Factory::getStore('BuildError'); - - while ($count == 100) { - $data = $this->metaStore->getErrorsForUpgrade(100); - $count = count($data); - - /** @var \PHPCI\Model\BuildMeta $meta */ - foreach ($data as $meta) { - try { - switch ($meta->getMetaKey()) { - case 'phpmd-data': - $this->processPhpMdMeta($meta); - break; - - case 'phpcs-data': - $this->processPhpCsMeta($meta); - break; - - case 'phpdoccheck-data': - $this->processPhpDocCheckMeta($meta); - break; - - case 'phpcpd-data': - $this->processPhpCpdMeta($meta); - break; - - case 'technicaldebt-data': - $this->processTechnicalDebtMeta($meta); - break; - } - } catch (\Exception $ex) {} - - $this->metaStore->delete($meta); - } - } - } - - protected function processPhpMdMeta(BuildMeta $meta) - { - $data = json_decode($meta->getMetaValue(), true); - - if (is_array($data) && count($data)) { - foreach ($data as $error) { - $buildError = new BuildError(); - $buildError->setBuildId($meta->getBuildId()); - $buildError->setPlugin('php_mess_detector'); - $buildError->setCreatedDate(new \DateTime()); - $buildError->setFile($error['file']); - $buildError->setLineStart($error['line_start']); - $buildError->setLineEnd($error['line_end']); - $buildError->setSeverity(BuildError::SEVERITY_HIGH); - $buildError->setMessage($error['message']); - - $this->errorStore->save($buildError); - } - } - } - - protected function processPhpCsMeta(BuildMeta $meta) - { - $data = json_decode($meta->getMetaValue(), true); - - if (is_array($data) && count($data)) { - foreach ($data as $error) { - $buildError = new BuildError(); - $buildError->setBuildId($meta->getBuildId()); - $buildError->setPlugin('php_code_sniffer'); - $buildError->setCreatedDate(new \DateTime()); - $buildError->setFile($error['file']); - $buildError->setLineStart($error['line']); - $buildError->setLineEnd($error['line']); - $buildError->setMessage($error['message']); - - switch ($error['type']) { - case 'ERROR': - $buildError->setSeverity(BuildError::SEVERITY_HIGH); - break; - - case 'WARNING': - $buildError->setSeverity(BuildError::SEVERITY_LOW); - break; - } - - $this->errorStore->save($buildError); - } - } - } - - protected function processPhpDocCheckMeta(BuildMeta $meta) - { - $data = json_decode($meta->getMetaValue(), true); - - if (is_array($data) && count($data)) { - foreach ($data as $error) { - $buildError = new BuildError(); - $buildError->setBuildId($meta->getBuildId()); - $buildError->setPlugin('php_docblock_checker'); - $buildError->setCreatedDate(new \DateTime()); - $buildError->setFile($error['file']); - $buildError->setLineStart($error['line']); - $buildError->setLineEnd($error['line']); - - switch ($error['type']) { - case 'method': - $buildError->setMessage($error['class'] . '::' . $error['method'] . ' is missing a docblock.'); - $buildError->setSeverity(BuildError::SEVERITY_NORMAL); - break; - - case 'class': - $buildError->setMessage('Class ' . $error['class'] . ' is missing a docblock.'); - $buildError->setSeverity(BuildError::SEVERITY_LOW); - break; - } - - $this->errorStore->save($buildError); - } - } - } - - protected function processPhpCpdMeta(BuildMeta $meta) - { - $data = json_decode($meta->getMetaValue(), true); - - if (is_array($data) && count($data)) { - foreach ($data as $error) { - $buildError = new BuildError(); - $buildError->setBuildId($meta->getBuildId()); - $buildError->setPlugin('php_cpd'); - $buildError->setCreatedDate(new \DateTime()); - $buildError->setFile($error['file']); - $buildError->setLineStart($error['line_start']); - $buildError->setLineEnd($error['line_end']); - $buildError->setSeverity(BuildError::SEVERITY_NORMAL); - $buildError->setMessage('Copy and paste detected.'); - - $this->errorStore->save($buildError); - } - } - } - - protected function processTechnicalDebtMeta(BuildMeta $meta) - { - $data = json_decode($meta->getMetaValue(), true); - - if (is_array($data) && count($data)) { - foreach ($data as $error) { - $buildError = new BuildError(); - $buildError->setBuildId($meta->getBuildId()); - $buildError->setPlugin('technical_debt'); - $buildError->setCreatedDate(new \DateTime()); - $buildError->setFile($error['file']); - $buildError->setLineStart($error['line']); - $buildError->setSeverity(BuildError::SEVERITY_NORMAL); - $buildError->setMessage($error['message']); - - $this->errorStore->save($buildError); - } - } - } -} diff --git a/PHPCI/Migrations/20160623100223_project_table_defaults.php b/PHPCI/Migrations/20160623100223_project_table_defaults.php deleted file mode 100644 index 079db327..00000000 --- a/PHPCI/Migrations/20160623100223_project_table_defaults.php +++ /dev/null @@ -1,18 +0,0 @@ -table('project') - ->changeColumn('build_config', MysqlAdapter::PHINX_TYPE_TEXT, array('null' => true)) - ->changeColumn('archived', MysqlAdapter::PHINX_TYPE_INTEGER, array( - 'length' => MysqlAdapter::INT_TINY, - 'default' => 0, - )) - ->save(); - } -} diff --git a/PHPCI/Model/Base/BuildBase.php b/PHPCI/Model/Base/BuildBase.php index 7c0fcdd3..119290e2 100644 --- a/PHPCI/Model/Base/BuildBase.php +++ b/PHPCI/Model/Base/BuildBase.php @@ -118,7 +118,7 @@ class BuildBase extends Model 'default' => null, ), 'log' => array( - 'type' => 'mediumtext', + 'type' => 'text', 'nullable' => true, 'default' => null, ), @@ -621,18 +621,6 @@ class BuildBase extends Model return $this->setProjectId($value->getId()); } - /** - * Get BuildError models by BuildId for this Build. - * - * @uses \PHPCI\Store\BuildErrorStore::getByBuildId() - * @uses \PHPCI\Model\BuildError - * @return \PHPCI\Model\BuildError[] - */ - public function getBuildBuildErrors() - { - return Factory::getStore('BuildError', 'PHPCI')->getByBuildId($this->getId()); - } - /** * Get BuildMeta models by BuildId for this Build. * diff --git a/PHPCI/Model/Base/BuildErrorBase.php b/PHPCI/Model/Base/BuildErrorBase.php deleted file mode 100644 index 6364bb29..00000000 --- a/PHPCI/Model/Base/BuildErrorBase.php +++ /dev/null @@ -1,503 +0,0 @@ - null, - 'build_id' => null, - 'plugin' => null, - 'file' => null, - 'line_start' => null, - 'line_end' => null, - 'severity' => null, - 'message' => null, - 'created_date' => null, - ); - - /** - * @var array - */ - protected $getters = array( - // Direct property getters: - 'id' => 'getId', - 'build_id' => 'getBuildId', - 'plugin' => 'getPlugin', - 'file' => 'getFile', - 'line_start' => 'getLineStart', - 'line_end' => 'getLineEnd', - 'severity' => 'getSeverity', - 'message' => 'getMessage', - 'created_date' => 'getCreatedDate', - - // Foreign key getters: - 'Build' => 'getBuild', - ); - - /** - * @var array - */ - protected $setters = array( - // Direct property setters: - 'id' => 'setId', - 'build_id' => 'setBuildId', - 'plugin' => 'setPlugin', - 'file' => 'setFile', - 'line_start' => 'setLineStart', - 'line_end' => 'setLineEnd', - 'severity' => 'setSeverity', - 'message' => 'setMessage', - 'created_date' => 'setCreatedDate', - - // Foreign key setters: - 'Build' => 'setBuild', - ); - - /** - * @var array - */ - public $columns = array( - 'id' => array( - 'type' => 'int', - 'length' => 11, - 'primary_key' => true, - 'auto_increment' => true, - 'default' => null, - ), - 'build_id' => array( - 'type' => 'int', - 'length' => 11, - 'default' => null, - ), - 'plugin' => array( - 'type' => 'varchar', - 'length' => 100, - 'default' => null, - ), - 'file' => array( - 'type' => 'varchar', - 'length' => 250, - 'nullable' => true, - 'default' => null, - ), - 'line_start' => array( - 'type' => 'int', - 'length' => 11, - 'nullable' => true, - 'default' => null, - ), - 'line_end' => array( - 'type' => 'int', - 'length' => 11, - 'nullable' => true, - 'default' => null, - ), - 'severity' => array( - 'type' => 'tinyint', - 'length' => 3, - 'default' => null, - ), - 'message' => array( - 'type' => 'varchar', - 'length' => 250, - 'default' => null, - ), - 'created_date' => array( - 'type' => 'datetime', - 'default' => null, - ), - ); - - /** - * @var array - */ - public $indexes = array( - 'PRIMARY' => array('unique' => true, 'columns' => 'id'), - 'build_id' => array('columns' => 'build_id, created_date'), - ); - - /** - * @var array - */ - public $foreignKeys = array( - 'build_error_ibfk_1' => array( - 'local_col' => 'build_id', - 'update' => 'CASCADE', - 'delete' => 'CASCADE', - 'table' => 'build', - 'col' => 'id' - ), - ); - - /** - * Get the value of Id / id. - * - * @return int - */ - public function getId() - { - $rtn = $this->data['id']; - - return $rtn; - } - - /** - * Get the value of BuildId / build_id. - * - * @return int - */ - public function getBuildId() - { - $rtn = $this->data['build_id']; - - return $rtn; - } - - /** - * Get the value of Plugin / plugin. - * - * @return string - */ - public function getPlugin() - { - $rtn = $this->data['plugin']; - - return $rtn; - } - - /** - * Get the value of File / file. - * - * @return string - */ - public function getFile() - { - $rtn = $this->data['file']; - - return $rtn; - } - - /** - * Get the value of LineStart / line_start. - * - * @return int - */ - public function getLineStart() - { - $rtn = $this->data['line_start']; - - return $rtn; - } - - /** - * Get the value of LineEnd / line_end. - * - * @return int - */ - public function getLineEnd() - { - $rtn = $this->data['line_end']; - - return $rtn; - } - - /** - * Get the value of Severity / severity. - * - * @return int - */ - public function getSeverity() - { - $rtn = $this->data['severity']; - - return $rtn; - } - - /** - * Get the value of Message / message. - * - * @return string - */ - public function getMessage() - { - $rtn = $this->data['message']; - - return $rtn; - } - - /** - * Get the value of CreatedDate / created_date. - * - * @return \DateTime - */ - public function getCreatedDate() - { - $rtn = $this->data['created_date']; - - if (!empty($rtn)) { - $rtn = new \DateTime($rtn); - } - - return $rtn; - } - - /** - * Set the value of Id / id. - * - * Must not be null. - * @param $value int - */ - public function setId($value) - { - $this->_validateNotNull('Id', $value); - $this->_validateInt('Id', $value); - - if ($this->data['id'] === $value) { - return; - } - - $this->data['id'] = $value; - - $this->_setModified('id'); - } - - /** - * Set the value of BuildId / build_id. - * - * Must not be null. - * @param $value int - */ - public function setBuildId($value) - { - $this->_validateNotNull('BuildId', $value); - $this->_validateInt('BuildId', $value); - - if ($this->data['build_id'] === $value) { - return; - } - - $this->data['build_id'] = $value; - - $this->_setModified('build_id'); - } - - /** - * Set the value of Plugin / plugin. - * - * Must not be null. - * @param $value string - */ - public function setPlugin($value) - { - $this->_validateNotNull('Plugin', $value); - $this->_validateString('Plugin', $value); - - if ($this->data['plugin'] === $value) { - return; - } - - $this->data['plugin'] = $value; - - $this->_setModified('plugin'); - } - - /** - * Set the value of File / file. - * - * @param $value string - */ - public function setFile($value) - { - $this->_validateString('File', $value); - - if ($this->data['file'] === $value) { - return; - } - - $this->data['file'] = $value; - - $this->_setModified('file'); - } - - /** - * Set the value of LineStart / line_start. - * - * @param $value int - */ - public function setLineStart($value) - { - $this->_validateInt('LineStart', $value); - - if ($this->data['line_start'] === $value) { - return; - } - - $this->data['line_start'] = $value; - - $this->_setModified('line_start'); - } - - /** - * Set the value of LineEnd / line_end. - * - * @param $value int - */ - public function setLineEnd($value) - { - $this->_validateInt('LineEnd', $value); - - if ($this->data['line_end'] === $value) { - return; - } - - $this->data['line_end'] = $value; - - $this->_setModified('line_end'); - } - - /** - * Set the value of Severity / severity. - * - * Must not be null. - * @param $value int - */ - public function setSeverity($value) - { - $this->_validateNotNull('Severity', $value); - $this->_validateInt('Severity', $value); - - if ($this->data['severity'] === $value) { - return; - } - - $this->data['severity'] = $value; - - $this->_setModified('severity'); - } - - /** - * Set the value of Message / message. - * - * Must not be null. - * @param $value string - */ - public function setMessage($value) - { - $this->_validateNotNull('Message', $value); - $this->_validateString('Message', $value); - - if ($this->data['message'] === $value) { - return; - } - - $this->data['message'] = $value; - - $this->_setModified('message'); - } - - /** - * Set the value of CreatedDate / created_date. - * - * Must not be null. - * @param $value \DateTime - */ - public function setCreatedDate($value) - { - $this->_validateNotNull('CreatedDate', $value); - $this->_validateDate('CreatedDate', $value); - - if ($this->data['created_date'] === $value) { - return; - } - - $this->data['created_date'] = $value; - - $this->_setModified('created_date'); - } - - /** - * Get the Build model for this BuildError by Id. - * - * @uses \PHPCI\Store\BuildStore::getById() - * @uses \PHPCI\Model\Build - * @return \PHPCI\Model\Build - */ - public function getBuild() - { - $key = $this->getBuildId(); - - if (empty($key)) { - return null; - } - - $cacheKey = 'Cache.Build.' . $key; - $rtn = $this->cache->get($cacheKey, null); - - if (empty($rtn)) { - $rtn = Factory::getStore('Build', 'PHPCI')->getById($key); - $this->cache->set($cacheKey, $rtn); - } - - return $rtn; - } - - /** - * Set Build - Accepts an ID, an array representing a Build or a Build model. - * - * @param $value mixed - */ - public function setBuild($value) - { - // Is this an instance of Build? - if ($value instanceof \PHPCI\Model\Build) { - return $this->setBuildObject($value); - } - - // Is this an array representing a Build item? - if (is_array($value) && !empty($value['id'])) { - return $this->setBuildId($value['id']); - } - - // Is this a scalar value representing the ID of this foreign key? - return $this->setBuildId($value); - } - - /** - * Set Build - Accepts a Build model. - * - * @param $value \PHPCI\Model\Build - */ - public function setBuildObject(\PHPCI\Model\Build $value) - { - return $this->setBuildId($value->getId()); - } -} diff --git a/PHPCI/Model/Base/BuildMetaBase.php b/PHPCI/Model/Base/BuildMetaBase.php index dc018819..0ac8fa93 100644 --- a/PHPCI/Model/Base/BuildMetaBase.php +++ b/PHPCI/Model/Base/BuildMetaBase.php @@ -99,7 +99,7 @@ class BuildMetaBase extends Model 'default' => null, ), 'meta_value' => array( - 'type' => 'mediumtext', + 'type' => 'text', 'default' => null, ), ); diff --git a/PHPCI/Model/Base/ProjectBase.php b/PHPCI/Model/Base/ProjectBase.php index 0dc0c0eb..305cafbf 100644 --- a/PHPCI/Model/Base/ProjectBase.php +++ b/PHPCI/Model/Base/ProjectBase.php @@ -44,8 +44,6 @@ class ProjectBase extends Model 'build_config' => null, 'ssh_public_key' => null, 'allow_public_status' => null, - 'archived' => null, - 'group_id' => null, ); /** @@ -64,11 +62,8 @@ class ProjectBase extends Model 'build_config' => 'getBuildConfig', 'ssh_public_key' => 'getSshPublicKey', 'allow_public_status' => 'getAllowPublicStatus', - 'archived' => 'getArchived', - 'group_id' => 'getGroupId', // Foreign key getters: - 'Group' => 'getGroup', ); /** @@ -87,11 +82,8 @@ class ProjectBase extends Model 'build_config' => 'setBuildConfig', 'ssh_public_key' => 'setSshPublicKey', 'allow_public_status' => 'setAllowPublicStatus', - 'archived' => 'setArchived', - 'group_id' => 'setGroupId', // Foreign key setters: - 'Group' => 'setGroup', ); /** @@ -156,16 +148,6 @@ class ProjectBase extends Model 'type' => 'int', 'length' => 11, ), - 'archived' => array( - 'type' => 'tinyint', - 'length' => 1, - 'default' => null, - ), - 'group_id' => array( - 'type' => 'int', - 'length' => 11, - 'default' => 1, - ), ); /** @@ -174,20 +156,12 @@ class ProjectBase extends Model public $indexes = array( 'PRIMARY' => array('unique' => true, 'columns' => 'id'), 'idx_project_title' => array('columns' => 'title'), - 'group_id' => array('columns' => 'group_id'), ); /** * @var array */ public $foreignKeys = array( - 'project_ibfk_1' => array( - 'local_col' => 'group_id', - 'update' => 'CASCADE', - 'delete' => '', - 'table' => 'project_group', - 'col' => 'id' - ), ); /** @@ -322,30 +296,6 @@ class ProjectBase extends Model return $rtn; } - /** - * Get the value of Archived / archived. - * - * @return int - */ - public function getArchived() - { - $rtn = $this->data['archived']; - - return $rtn; - } - - /** - * Get the value of GroupId / group_id. - * - * @return int - */ - public function getGroupId() - { - $rtn = $this->data['group_id']; - - return $rtn; - } - /** * Set the value of Id / id. * @@ -556,103 +506,6 @@ class ProjectBase extends Model $this->_setModified('allow_public_status'); } - /** - * Set the value of Archived / archived. - * - * Must not be null. - * @param $value int - */ - public function setArchived($value) - { - $this->_validateNotNull('Archived', $value); - $this->_validateInt('Archived', $value); - - if ($this->data['archived'] === $value) { - return; - } - - $this->data['archived'] = $value; - - $this->_setModified('archived'); - } - - /** - * Set the value of GroupId / group_id. - * - * Must not be null. - * @param $value int - */ - public function setGroupId($value) - { - $this->_validateNotNull('GroupId', $value); - $this->_validateInt('GroupId', $value); - - if ($this->data['group_id'] === $value) { - return; - } - - $this->data['group_id'] = $value; - - $this->_setModified('group_id'); - } - - /** - * Get the ProjectGroup model for this Project by Id. - * - * @uses \PHPCI\Store\ProjectGroupStore::getById() - * @uses \PHPCI\Model\ProjectGroup - * @return \PHPCI\Model\ProjectGroup - */ - public function getGroup() - { - $key = $this->getGroupId(); - - if (empty($key)) { - return null; - } - - $cacheKey = 'Cache.ProjectGroup.' . $key; - $rtn = $this->cache->get($cacheKey, null); - - if (empty($rtn)) { - $rtn = Factory::getStore('ProjectGroup', 'PHPCI')->getById($key); - $this->cache->set($cacheKey, $rtn); - } - - return $rtn; - } - - /** - * Set Group - Accepts an ID, an array representing a ProjectGroup or a ProjectGroup model. - * - * @param $value mixed - */ - public function setGroup($value) - { - // Is this an instance of ProjectGroup? - if ($value instanceof \PHPCI\Model\ProjectGroup) { - return $this->setGroupObject($value); - } - - // Is this an array representing a ProjectGroup item? - if (is_array($value) && !empty($value['id'])) { - return $this->setGroupId($value['id']); - } - - // Is this a scalar value representing the ID of this foreign key? - return $this->setGroupId($value); - } - - /** - * Set Group - Accepts a ProjectGroup model. - * - * @param $value \PHPCI\Model\ProjectGroup - */ - public function setGroupObject(\PHPCI\Model\ProjectGroup $value) - { - return $this->setGroupId($value->getId()); - } - /** * Get Build models by ProjectId for this Project. * diff --git a/PHPCI/Model/Base/ProjectGroupBase.php b/PHPCI/Model/Base/ProjectGroupBase.php deleted file mode 100644 index 3b5eed69..00000000 --- a/PHPCI/Model/Base/ProjectGroupBase.php +++ /dev/null @@ -1,168 +0,0 @@ - null, - 'title' => null, - ); - - /** - * @var array - */ - protected $getters = array( - // Direct property getters: - 'id' => 'getId', - 'title' => 'getTitle', - - // Foreign key getters: - ); - - /** - * @var array - */ - protected $setters = array( - // Direct property setters: - 'id' => 'setId', - 'title' => 'setTitle', - - // Foreign key setters: - ); - - /** - * @var array - */ - public $columns = array( - 'id' => array( - 'type' => 'int', - 'length' => 11, - 'primary_key' => true, - 'auto_increment' => true, - 'default' => null, - ), - 'title' => array( - 'type' => 'varchar', - 'length' => 100, - 'default' => null, - ), - ); - - /** - * @var array - */ - public $indexes = array( - 'PRIMARY' => array('unique' => true, 'columns' => 'id'), - ); - - /** - * @var array - */ - public $foreignKeys = array( - ); - - /** - * Get the value of Id / id. - * - * @return int - */ - public function getId() - { - $rtn = $this->data['id']; - - return $rtn; - } - - /** - * Get the value of Title / title. - * - * @return string - */ - public function getTitle() - { - $rtn = $this->data['title']; - - return $rtn; - } - - /** - * Set the value of Id / id. - * - * Must not be null. - * @param $value int - */ - public function setId($value) - { - $this->_validateNotNull('Id', $value); - $this->_validateInt('Id', $value); - - if ($this->data['id'] === $value) { - return; - } - - $this->data['id'] = $value; - - $this->_setModified('id'); - } - - /** - * Set the value of Title / title. - * - * Must not be null. - * @param $value string - */ - public function setTitle($value) - { - $this->_validateNotNull('Title', $value); - $this->_validateString('Title', $value); - - if ($this->data['title'] === $value) { - return; - } - - $this->data['title'] = $value; - - $this->_setModified('title'); - } - - /** - * Get Project models by GroupId for this ProjectGroup. - * - * @uses \PHPCI\Store\ProjectStore::getByGroupId() - * @uses \PHPCI\Model\Project - * @return \PHPCI\Model\Project[] - */ - public function getGroupProjects() - { - return Factory::getStore('Project', 'PHPCI')->getByGroupId($this->getId()); - } -} diff --git a/PHPCI/Model/Base/UserBase.php b/PHPCI/Model/Base/UserBase.php index 4de48537..e9be15a0 100644 --- a/PHPCI/Model/Base/UserBase.php +++ b/PHPCI/Model/Base/UserBase.php @@ -106,8 +106,6 @@ class UserBase extends Model public $indexes = array( 'PRIMARY' => array('unique' => true, 'columns' => 'id'), 'idx_email' => array('unique' => true, 'columns' => 'email'), - 'email' => array('unique' => true, 'columns' => 'email'), - 'name' => array('columns' => 'name'), ); /** diff --git a/PHPCI/Model/Build.php b/PHPCI/Model/Build.php index a8bfd683..3d07778a 100644 --- a/PHPCI/Model/Build.php +++ b/PHPCI/Model/Build.php @@ -28,7 +28,7 @@ class Build extends BuildBase const STATUS_SUCCESS = 2; const STATUS_FAILED = 3; - public $currentBuildPath; + public $currentBuildPath = null; /** * Get link to commit from another source (i.e. Github) @@ -99,21 +99,16 @@ class Build extends BuildBase { $build_config = null; + // Try phpci.yml first: + if (is_file($buildPath . '/phpci.yml')) { + $build_config = file_get_contents($buildPath . '/phpci.yml'); + } + // Try getting the project build config from the database: if (empty($build_config)) { $build_config = $this->getProject()->getBuildConfig(); } - // Try .phpci.yml - if (is_file($buildPath . '/.phpci.yml')) { - $build_config = file_get_contents($buildPath . '/.phpci.yml'); - } - - // Try phpci.yml first: - if (empty($build_config) && is_file($buildPath . '/phpci.yml')) { - $build_config = file_get_contents($buildPath . '/phpci.yml'); - } - // Fall back to zero config plugins: if (empty($build_config)) { $build_config = $this->getZeroConfigPlugins($builder); @@ -213,89 +208,13 @@ class Build extends BuildBase /** * Allows specific build types (e.g. Github) to report violations back to their respective services. * @param Builder $builder - * @param $plugin + * @param $file + * @param $line * @param $message - * @param int $severity - * @param null $file - * @param null $lineStart - * @param null $lineEnd - * @return BuildError + * @return mixed */ - public function reportError( - Builder $builder, - $plugin, - $message, - $severity = BuildError::SEVERITY_NORMAL, - $file = null, - $lineStart = null, - $lineEnd = null - ) { - unset($builder); - - $error = new BuildError(); - $error->setBuild($this); - $error->setCreatedDate(new \DateTime()); - $error->setPlugin($plugin); - $error->setMessage($message); - $error->setSeverity($severity); - $error->setFile($file); - $error->setLineStart($lineStart); - $error->setLineEnd($lineEnd); - - return Factory::getStore('BuildError')->save($error); - } - - /** - * Return the path to run this build into. - * - * @return string|null - */ - public function getBuildPath() + public function reportError(Builder $builder, $file, $line, $message) { - if (!$this->getId()) { - return null; - } - - if (empty($this->currentBuildPath)) { - $buildDirectory = $this->getId() . '_' . substr(md5(microtime(true)), 0, 5); - $this->currentBuildPath = PHPCI_BUILD_ROOT_DIR . $buildDirectory . DIRECTORY_SEPARATOR; - } - - return $this->currentBuildPath; - } - - /** - * Removes the build directory. - */ - public function removeBuildDirectory() - { - $buildPath = $this->getBuildPath(); - - if (!$buildPath || !is_dir($buildPath)) { - return; - } - - exec(sprintf(IS_WIN ? 'rmdir /S /Q "%s"' : 'rm -Rf "%s"', $buildPath)); - } - - /** - * Get the number of seconds a build has been running for. - * @return int - */ - public function getDuration() - { - $start = $this->getStarted(); - - if (empty($start)) { - return 0; - } - - $end = $this->getFinished(); - - if (empty($end)) { - $end = new \DateTime(); - } - - return $end->getTimestamp() - $start->getTimestamp(); + return array($builder, $file, $line, $message); } } diff --git a/PHPCI/Model/Build/GithubBuild.php b/PHPCI/Model/Build/GithubBuild.php index a9a18913..7c8f3f6f 100644 --- a/PHPCI/Model/Build/GithubBuild.php +++ b/PHPCI/Model/Build/GithubBuild.php @@ -45,52 +45,39 @@ class GithubBuild extends RemoteGitBuild { $token = \b8\Config::getInstance()->get('phpci.github.token'); - if (empty($token) || empty($this->data['id'])) { + if (empty($token)) { return; } $project = $this->getProject(); - if (empty($project)) { - return; - } - $url = 'https://api.github.com/repos/'.$project->getReference().'/statuses/'.$this->getCommitId(); $http = new \b8\HttpClient(); - switch ($this->getStatus()) { + switch($this->getStatus()) + { case 0: case 1: $status = 'pending'; - $description = 'PHPCI build running.'; break; case 2: $status = 'success'; - $description = 'PHPCI build passed.'; break; case 3: $status = 'failure'; - $description = 'PHPCI build failed.'; break; default: $status = 'error'; - $description = 'PHPCI build failed to complete.'; break; } $phpciUrl = \b8\Config::getInstance()->get('phpci.url'); - - $params = array( - 'state' => $status, - 'target_url' => $phpciUrl . '/build/view/' . $this->getId(), - 'description' => $description, - 'context' => 'PHPCI', - ); - + $params = array( 'state' => $status, + 'target_url' => $phpciUrl . '/build/view/' . $this->getId()); $headers = array( 'Authorization: token ' . $token, 'Content-Type: application/x-www-form-urlencoded' - ); + ); $http->setHeaders($headers); $http->request('POST', $url, json_encode($params)); @@ -118,14 +105,10 @@ class GithubBuild extends RemoteGitBuild { $rtn = parent::getCommitMessage($this->data['commit_message']); - $project = $this->getProject(); - - if (!is_null($project)) { - $reference = $project->getReference(); - $commitLink = '#$1'; - $rtn = preg_replace('/\#([0-9]+)/', $commitLink, $rtn); - $rtn = preg_replace('/\@([a-zA-Z0-9_]+)/', '@$1', $rtn); - } + $reference = $this->getProject()->getReference(); + $commitLink = '#$1'; + $rtn = preg_replace('/\#([0-9]+)/', $commitLink, $rtn); + $rtn = preg_replace('/\@([a-zA-Z0-9_]+)/', '@$1', $rtn); return $rtn; } @@ -142,7 +125,7 @@ class GithubBuild extends RemoteGitBuild if ($this->getExtra('build_type') == 'pull_request') { $matches = array(); - preg_match('/[\/:]([a-zA-Z0-9_\-]+\/[a-zA-Z0-9_\-]+)/', $this->getExtra('remote_url'), $matches); + preg_match('/\/([a-zA-Z0-9_\-]+\/[a-zA-Z0-9_\-]+)/', $this->getExtra('remote_url'), $matches); $reference = $matches[1]; $branch = $this->getExtra('remote_branch'); @@ -151,7 +134,7 @@ class GithubBuild extends RemoteGitBuild $link = 'https://github.com/' . $reference . '/'; $link .= 'blob/' . $branch . '/'; $link .= '{FILE}'; - $link .= '#L{LINE}-L{LINE_END}'; + $link .= '#L{LINE}'; return $link; } @@ -190,16 +173,9 @@ class GithubBuild extends RemoteGitBuild /** * @inheritDoc */ - public function reportError( - Builder $builder, - $plugin, - $message, - $severity = BuildError::SEVERITY_NORMAL, - $file = null, - $lineStart = null, - $lineEnd = null - ) { - $diffLineNumber = $this->getDiffLineNumber($builder, $file, $lineStart); + public function reportError(Builder $builder, $file, $line, $message) + { + $diffLineNumber = $this->getDiffLineNumber($builder, $file, $line); if (!is_null($diffLineNumber)) { $helper = new Github(); @@ -214,8 +190,6 @@ class GithubBuild extends RemoteGitBuild $helper->createCommitComment($repo, $commit, $file, $diffLineNumber, $message); } } - - return parent::reportError($builder, $plugin, $message, $severity, $file, $lineStart, $lineEnd); } /** @@ -227,8 +201,6 @@ class GithubBuild extends RemoteGitBuild */ protected function getDiffLineNumber(Builder $builder, $file, $line) { - $line = (integer)$line; - $builder->logExecOutput(false); $prNumber = $this->getExtra('pull_request_number'); @@ -237,9 +209,7 @@ class GithubBuild extends RemoteGitBuild if (!empty($prNumber)) { $builder->executeCommand('cd %s && git diff origin/%s "%s"', $path, $this->getBranch(), $file); } else { - $commitId = $this->getCommitId(); - $compare = $commitId == 'Manual' ? 'HEAD' : $commitId; - $builder->executeCommand('cd %s && git diff %s^^ "%s"', $path, $compare, $file); + $builder->executeCommand('cd %s && git diff %s^! "%s"', $path, $this->getCommitId(), $file); } $builder->logExecOutput(true); @@ -249,6 +219,6 @@ class GithubBuild extends RemoteGitBuild $helper = new Diff(); $lines = $helper->getLinePositions($diff); - return isset($lines[$line]) ? $lines[$line] : null; + return $lines[$line]; } } diff --git a/PHPCI/Model/Build/GitlabBuild.php b/PHPCI/Model/Build/GitlabBuild.php index a1e0562c..086bc046 100644 --- a/PHPCI/Model/Build/GitlabBuild.php +++ b/PHPCI/Model/Build/GitlabBuild.php @@ -47,7 +47,7 @@ class GitlabBuild extends RemoteGitBuild 'http://%s/%s/blob/%s/{FILE}#L{LINE}', $this->getProject()->getAccessInformation("domain"), $this->getProject()->getReference(), - $this->getCommitId() + $this->getBranch() ); } diff --git a/PHPCI/Model/Build/LocalBuild.php b/PHPCI/Model/Build/LocalBuild.php index 5131abe1..b94ede4e 100644 --- a/PHPCI/Model/Build/LocalBuild.php +++ b/PHPCI/Model/Build/LocalBuild.php @@ -35,14 +35,12 @@ class LocalBuild extends Build return $this->handleConfig($builder, $buildPath) !== false; } - $configHandled = $this->handleConfig($builder, $reference); + $buildSettings = $this->handleConfig($builder, $reference); - if ($configHandled === false) { + if ($buildSettings === false) { return false; } - $buildSettings = $builder->getConfig('build_settings'); - if (isset($buildSettings['prefer_symlink']) && $buildSettings['prefer_symlink'] === true) { return $this->handleSymlink($builder, $reference, $buildPath); } else { diff --git a/PHPCI/Model/Build/MercurialBuild.php b/PHPCI/Model/Build/MercurialBuild.php index 0f38940b..500b5372 100644 --- a/PHPCI/Model/Build/MercurialBuild.php +++ b/PHPCI/Model/Build/MercurialBuild.php @@ -13,87 +13,36 @@ use PHPCI\Model\Build; use PHPCI\Builder; /** - * Mercurial Build Model - * @author Pavel Gopanenko - * @package PHPCI - * @subpackage Core - */ +* Mercurial Build Model +* @author Pavel Gopanenko +* @package PHPCI +* @subpackage Core +*/ class MercurialBuild extends Build { /** - * Get the URL to be used to clone this remote repository. - */ + * Get the URL to be used to clone this remote repository. + */ protected function getCloneUrl() { return $this->getProject()->getReference(); } /** - * Create a working copy by cloning, copying, or similar. - */ + * Create a working copy by cloning, copying, or similar. + */ public function createWorkingCopy(Builder $builder, $buildPath) { - $key = trim($this->getProject()->getSshPublicKey()); - - if (!empty($key) && strpos($this->getProject()->getReference(), 'ssh') > -1) { - $success = $this->cloneBySsh($builder, $buildPath); - } else { - $success = $this->cloneByHttp($builder, $buildPath); - } - - if (!$success) { - $builder->logFailure('Failed to clone remote git repository.'); - return false; - } + $this->cloneByHttp($builder, $buildPath); return $this->handleConfig($builder, $buildPath); } /** - * Use a HTTP-based Mercurial clone. - */ + * Use an mercurial clone. + */ protected function cloneByHttp(Builder $builder, $cloneTo) { return $builder->executeCommand('hg clone %s "%s" -r %s', $this->getCloneUrl(), $cloneTo, $this->getBranch()); } - - /** - * Use an SSH-based Mercurial clone. - */ - protected function cloneBySsh(Builder $builder, $cloneTo) - { - $keyFile = $this->writeSshKey(); - - // Do the git clone: - $cmd = 'hg clone --ssh "ssh -i '.$keyFile.'" %s "%s"'; - $success = $builder->executeCommand($cmd, $this->getCloneUrl(), $cloneTo); - - if ($success) { - $success = $this->postCloneSetup($builder, $cloneTo); - } - - // Remove the key file: - unlink($keyFile); - return $success; - } - - /** - * Handle post-clone tasks (switching branch, etc.) - * @param Builder $builder - * @param $cloneTo - * @return bool - */ - protected function postCloneSetup(Builder $builder, $cloneTo) - { - $success = true; - $commit = $this->getCommitId(); - - // Allow switching to a specific branch: - if (!empty($commit) && $commit != 'Manual') { - $cmd = 'cd "%s" && hg checkout %s'; - $success = $builder->executeCommand($cmd, $cloneTo, $this->getBranch()); - } - - return $success; - } } diff --git a/PHPCI/Model/Build/RemoteGitBuild.php b/PHPCI/Model/Build/RemoteGitBuild.php index faaccfb5..80718011 100644 --- a/PHPCI/Model/Build/RemoteGitBuild.php +++ b/PHPCI/Model/Build/RemoteGitBuild.php @@ -54,7 +54,7 @@ class RemoteGitBuild extends Build */ protected function cloneByHttp(Builder $builder, $cloneTo) { - $cmd = 'git clone --recursive '; + $cmd = 'git clone '; $depth = $builder->getConfig('clone_depth'); @@ -84,7 +84,7 @@ class RemoteGitBuild extends Build } // Do the git clone: - $cmd = 'git clone --recursive '; + $cmd = 'git clone '; $depth = $builder->getConfig('clone_depth'); @@ -124,16 +124,16 @@ class RemoteGitBuild extends Build $success = true; $commit = $this->getCommitId(); - $chdir = IS_WIN ? 'cd /d "%s"' : 'cd "%s"'; - if (!empty($commit) && $commit != 'Manual') { - $cmd = $chdir . ' && git checkout %s --quiet'; - $success = $builder->executeCommand($cmd, $cloneTo, $commit); - } + $cmd = 'cd "%s"'; - // Always update the commit hash with the actual HEAD hash - if ($builder->executeCommand($chdir . ' && git rev-parse HEAD', $cloneTo)) { - $this->setCommitId(trim($builder->getLastOutput())); + if (IS_WIN) { + $cmd = 'cd /d "%s"'; + } + + $cmd .= ' && git checkout %s --quiet'; + + $success = $builder->executeCommand($cmd, $cloneTo, $this->getCommitId()); } return $success; diff --git a/PHPCI/Model/BuildError.php b/PHPCI/Model/BuildError.php deleted file mode 100644 index 8d005e26..00000000 --- a/PHPCI/Model/BuildError.php +++ /dev/null @@ -1,63 +0,0 @@ -getSeverity()) { - case self::SEVERITY_CRITICAL: - return 'critical'; - - case self::SEVERITY_HIGH: - return 'high'; - - case self::SEVERITY_NORMAL: - return 'normal'; - - case self::SEVERITY_LOW: - return 'low'; - } - } - - /** - * Get the class to apply to HTML elements representing this error. - * @return string - */ - public function getSeverityClass() - { - switch ($this->getSeverity()) { - case self::SEVERITY_CRITICAL: - return 'danger'; - - case self::SEVERITY_HIGH: - return 'warning'; - - case self::SEVERITY_NORMAL: - return 'info'; - - case self::SEVERITY_LOW: - return 'default'; - } - } -} diff --git a/PHPCI/Model/Project.php b/PHPCI/Model/Project.php index 4b5268b2..4a8b3c69 100644 --- a/PHPCI/Model/Project.php +++ b/PHPCI/Model/Project.php @@ -50,29 +50,6 @@ class Project extends ProjectBase return null; } - /** - * Return the previous build from a specific branch, for this project. - * @param string $branch - * @return mixed|null - */ - public function getPreviousBuild($branch = 'master') - { - $criteria = array('branch' => $branch, 'project_id' => $this->getId()); - - $order = array('id' => 'DESC'); - $builds = Store\Factory::getStore('Build')->getWhere($criteria, 1, 1, array(), $order); - - if (is_array($builds['items']) && count($builds['items'])) { - $previous = array_shift($builds['items']); - - if (isset($previous) && $previous instanceof Build) { - return $previous; - } - } - - return null; - } - /** * Store this project's access_information data * @param string|array $value @@ -96,7 +73,7 @@ class Project extends ProjectBase $info = $this->data['access_information']; // Handle old-format (serialized) access information first: - if (!empty($info) && !in_array(substr($info, 0, 1), array('{', '['))) { + if (!empty($info) && substr($info, 0, 1) != '{') { $data = unserialize($info); } else { $data = json_decode($info, true); diff --git a/PHPCI/Model/ProjectGroup.php b/PHPCI/Model/ProjectGroup.php deleted file mode 100644 index f85e6339..00000000 --- a/PHPCI/Model/ProjectGroup.php +++ /dev/null @@ -1,18 +0,0 @@ - $lineParts[1] ); - $this->build->reportError( - $this->phpci, - 'behat', - 'Behat scenario failed.', - BuildError::SEVERITY_HIGH, - $lineParts[0], - $lineParts[1] - ); + $this->build->reportError($this->phpci, $lineParts[0], $lineParts[1], 'Behat scenario failed.'); } } diff --git a/PHPCI/Plugin/Campfire.php b/PHPCI/Plugin/Campfire.php index 59ab9128..325e6e40 100644 --- a/PHPCI/Plugin/Campfire.php +++ b/PHPCI/Plugin/Campfire.php @@ -38,19 +38,19 @@ class Campfire implements \PHPCI\Plugin */ public function __construct(Builder $phpci, Build $build, array $options = array()) { - $this->phpci = $phpci; - $this->build = $build; - $this->message = $options['message']; + $this->phpci = $phpci; + $this->build = $build; + + $this->message = $options['message']; $this->userAgent = "PHPCI/1.0 (+http://www.phptesting.org/)"; - $this->cookie = "phpcicookie"; + $this->cookie = "phpcicookie"; $buildSettings = $phpci->getConfig('build_settings'); - if (isset($buildSettings['campfire'])) { - $campfire = $buildSettings['campfire']; - $this->url = $campfire['url']; + $campfire = $buildSettings['campfire']; + $this->url = $campfire['url']; $this->authToken = $campfire['authToken']; - $this->roomId = $campfire['roomId']; + $this->roomId = $campfire['roomId']; } else { throw new \Exception(Lang::get('no_campfire_settings')); } @@ -63,7 +63,7 @@ class Campfire implements \PHPCI\Plugin */ public function execute() { - $url = PHPCI_URL . "build/view/" . $this->build->getId(); + $url = PHPCI_URL."build/view/".$this->build->getId(); $message = str_replace("%buildurl%", $url, $this->message); $this->joinRoom($this->roomId); $status = $this->speak($message, $this->roomId); @@ -101,7 +101,6 @@ class Campfire implements \PHPCI\Plugin public function speak($message, $roomId, $isPaste = false) { $page = '/room/'.$roomId.'/speak.json'; - if ($isPaste) { $type = 'PasteMessage'; } else { @@ -144,12 +143,10 @@ class Campfire implements \PHPCI\Plugin // We tend to get one space with an otherwise blank response $output = trim($output); - if (strlen($output)) { /* Responses are JSON. Decode it to a data structure */ return json_decode($output); } - // Simple 200 OK response (such as for joining a room) return true; } diff --git a/PHPCI/Plugin/CleanBuild.php b/PHPCI/Plugin/CleanBuild.php index 684e8e7a..2d33aee4 100644 --- a/PHPCI/Plugin/CleanBuild.php +++ b/PHPCI/Plugin/CleanBuild.php @@ -39,9 +39,9 @@ class CleanBuild implements \PHPCI\Plugin */ public function __construct(Builder $phpci, Build $build, array $options = array()) { - $this->phpci = $phpci; - $this->build = $build; - $this->remove = isset($options['remove']) && is_array($options['remove']) ? $options['remove'] : array(); + $this->phpci = $phpci; + $this->build = $build; + $this->remove = isset($options['remove']) && is_array($options['remove']) ? $options['remove'] : array(); } /** @@ -57,7 +57,7 @@ class CleanBuild implements \PHPCI\Plugin $this->phpci->executeCommand($cmd, $this->phpci->buildPath . 'composer.lock'); $success = true; - + foreach ($this->remove as $file) { $ok = $this->phpci->executeCommand($cmd, $this->phpci->buildPath . $file); diff --git a/PHPCI/Plugin/Codeception.php b/PHPCI/Plugin/Codeception.php index c28e3a48..7d7fd81e 100644 --- a/PHPCI/Plugin/Codeception.php +++ b/PHPCI/Plugin/Codeception.php @@ -9,72 +9,50 @@ namespace PHPCI\Plugin; +use PHPCI; use PHPCI\Builder; use PHPCI\Helper\Lang; use PHPCI\Model\Build; -use PHPCI\Plugin\Util\TestResultParsers\Codeception as Parser; -use Psr\Log\LogLevel; +use PHPCI\Plugin\Util\TapParser; /** - * Codeception Plugin - Enables full acceptance, unit, and functional testing. + * Codeception Plugin - Enables full acceptance, unit, and functional testing + * * @author Don Gilbert * @author Igor Timoshenko - * @author Adam Cooper * @package PHPCI * @subpackage Plugins */ -class Codeception implements \PHPCI\Plugin, \PHPCI\ZeroConfigPlugin +class Codeception implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin { - /** @var string */ + /** + * @var string + */ protected $args = ''; - /** @var Builder */ - protected $phpci; - - /** @var Build */ + /** + * @var Build + */ protected $build; /** - * @var string $ymlConfigFile The path of a yml config for Codeception + * @var Builder */ - protected $ymlConfigFile; + protected $phpci; /** - * @var string $path The path to the codeception tests folder. + * @var string|string[] The path (or array of paths) of an yml config for Codeception */ - protected $path; + protected $configFile; /** - * @param $stage - * @param Builder $builder - * @param Build $build - * @return bool + * @var string The path where the reports and logs are stored */ - public static function canExecute($stage, Builder $builder, Build $build) - { - return $stage == 'test' && !is_null(self::findConfigFile($builder->buildPath)); - } - - /** - * Try and find the codeception YML config file. - * @param $buildPath - * @return null|string - */ - public static function findConfigFile($buildPath) - { - if (file_exists($buildPath . 'codeception.yml')) { - return 'codeception.yml'; - } - - if (file_exists($buildPath . 'codeception.dist.yml')) { - return 'codeception.dist.yml'; - } - - return null; - } + protected $logPath = 'tests/_output'; /** * Set up the plugin, configure options, etc. + * * @param Builder $phpci * @param Build $build * @param array $options @@ -83,81 +61,110 @@ class Codeception implements \PHPCI\Plugin, \PHPCI\ZeroConfigPlugin { $this->phpci = $phpci; $this->build = $build; - $this->path = 'tests' . DIRECTORY_SEPARATOR . '_output' . DIRECTORY_SEPARATOR; - if (empty($options['config'])) { - $this->ymlConfigFile = self::findConfigFile($this->phpci->buildPath); - } else { - $this->ymlConfigFile = $options['config']; + if (isset($options['config'])) { + $this->configFile = $options['config']; } + if (isset($options['args'])) { $this->args = (string) $options['args']; } - if (isset($options['path'])) { - $this->path = $options['path']; + + if (isset($options['log_path'])) { + $this->logPath = $options['log_path']; } } /** - * Runs Codeception tests + * {@inheritDoc} */ public function execute() { - if (empty($this->ymlConfigFile)) { - throw new \Exception("No configuration file found"); - } + $success = true; - // Run any config files first. This can be either a single value or an array. - return $this->runConfigFile($this->ymlConfigFile); - } - - /** - * Run tests from a Codeception config file. - * @param $configPath - * @return bool|mixed - * @throws \Exception - */ - protected function runConfigFile($configPath) - { $this->phpci->logExecOutput(false); - $codecept = $this->phpci->findBinary('codecept'); - - if (!$codecept) { - $this->phpci->logFailure(Lang::get('could_not_find', 'codecept')); - - return false; + // Run any config files first. This can be either a single value or an array + if ($this->configFile !== null) { + $success &= $this->runConfigFile($this->configFile); } - $cmd = 'cd "%s" && ' . $codecept . ' run -c "%s" --xml ' . $this->args; + $tapString = file_get_contents( + $this->phpci->buildPath . $this->logPath . DIRECTORY_SEPARATOR . 'report.tap.log' + ); - if (IS_WIN) { - $cmd = 'cd /d "%s" && ' . $codecept . ' run -c "%s" --xml ' . $this->args; + try { + $tapParser = new TapParser($tapString); + $output = $tapParser->parse(); + } catch (\Exception $ex) { + $this->phpci->logFailure($tapString); + + throw $ex; } - $configPath = $this->phpci->buildPath . $configPath; - $success = $this->phpci->executeCommand($cmd, $this->phpci->buildPath, $configPath); + $failures = $tapParser->getTotalFailures(); - $this->phpci->log( - 'Codeception XML path: '. $this->phpci->buildPath . $this->path . 'report.xml', - Loglevel::DEBUG - ); - - $xml = file_get_contents($this->phpci->buildPath . $this->path . 'report.xml', false); - $parser = new Parser($this->phpci, $xml); - $output = $parser->parse(); - - $meta = array( - 'tests' => $parser->getTotalTests(), - 'timetaken' => $parser->getTotalTimeTaken(), - 'failures' => $parser->getTotalFailures() - ); - - $this->build->storeMeta('codeception-meta', $meta); + $this->build->storeMeta('codeception-errors', $failures); $this->build->storeMeta('codeception-data', $output); - $this->build->storeMeta('codeception-errors', $parser->getTotalFailures()); + $this->phpci->logExecOutput(true); return $success; } + + /** + * {@inheritDoc} + */ + public static function canExecute($stage, Builder $builder, Build $build) + { + return $stage === 'test'; + } + + /** + * Run tests from a Codeception config file + * + * @param string $configPath + * @return bool|mixed + */ + protected function runConfigFile($configPath) + { + if (is_array($configPath)) { + return $this->recurseArg($configPath, array($this, 'runConfigFile')); + } else { + $codecept = $this->phpci->findBinary('codecept'); + + if (!$codecept) { + $this->phpci->logFailure(Lang::get('could_not_find', 'codecept')); + + return false; + } + + $cmd = 'cd "%s" && ' . $codecept . ' run -c "%s" --tap ' . $this->args; + + if (IS_WIN) { + $cmd = 'cd /d "%s" && ' . $codecept . ' run -c "%s" --tap ' . $this->args; + } + + $configPath = $this->phpci->buildPath . $configPath; + $success = $this->phpci->executeCommand($cmd, $this->phpci->buildPath, $configPath); + + return $success; + } + } + + /** + * @param array $array + * @param \Callback $callable + * @return bool|mixed + */ + protected function recurseArg(array $array, $callable) + { + $success = true; + + foreach ($array as $subItem) { + $success &= call_user_func($callable, $subItem); + } + + return $success; + } } diff --git a/PHPCI/Plugin/Composer.php b/PHPCI/Plugin/Composer.php index 7bd86ac3..3930f3d6 100644 --- a/PHPCI/Plugin/Composer.php +++ b/PHPCI/Plugin/Composer.php @@ -27,7 +27,6 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin protected $preferDist; protected $phpci; protected $build; - protected $nodev; /** * Check if this plugin can be executed. @@ -38,7 +37,7 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin */ public static function canExecute($stage, Builder $builder, Build $build) { - $path = $builder->buildPath . DIRECTORY_SEPARATOR . 'composer.json'; + $path = $builder->buildPath . '/composer.json'; if (file_exists($path) && $stage == 'setup') { return true; @@ -55,17 +54,15 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin */ public function __construct(Builder $phpci, Build $build, array $options = array()) { - $path = $phpci->buildPath; - $this->phpci = $phpci; - $this->build = $build; - $this->directory = $path; - $this->action = 'install'; + $path = $phpci->buildPath; + $this->phpci = $phpci; + $this->build = $build; + $this->directory = $path; + $this->action = 'install'; $this->preferDist = false; - $this->preferSource = false; - $this->nodev = false; if (array_key_exists('directory', $options)) { - $this->directory = $path . DIRECTORY_SEPARATOR . $options['directory']; + $this->directory = $path . '/' . $options['directory']; } if (array_key_exists('action', $options)) { @@ -75,15 +72,6 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin if (array_key_exists('prefer_dist', $options)) { $this->preferDist = (bool)$options['prefer_dist']; } - - if (array_key_exists('prefer_source', $options)) { - $this->preferDist = false; - $this->preferSource = (bool)$options['prefer_source']; - } - - if (array_key_exists('no_dev', $options)) { - $this->nodev = (bool)$options['no_dev']; - } } /** @@ -93,6 +81,11 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin { $composerLocation = $this->phpci->findBinary(array('composer', 'composer.phar')); + if (!$composerLocation) { + $this->phpci->logFailure(Lang::get('could_not_find', 'composer')); + return false; + } + $cmd = ''; if (IS_WIN) { @@ -103,17 +96,10 @@ class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin if ($this->preferDist) { $this->phpci->log('Using --prefer-dist flag'); - $cmd .= ' --prefer-dist'; - } - - if ($this->preferSource) { + $cmd .= '--prefer-dist'; + } else { $this->phpci->log('Using --prefer-source flag'); - $cmd .= ' --prefer-source'; - } - - if ($this->nodev) { - $this->phpci->log('Using --no-dev flag'); - $cmd .= ' --no-dev'; + $cmd .= '--prefer-source'; } $cmd .= ' --working-dir="%s" %s'; diff --git a/PHPCI/Plugin/CopyBuild.php b/PHPCI/Plugin/CopyBuild.php index f9646cac..7f447291 100644 --- a/PHPCI/Plugin/CopyBuild.php +++ b/PHPCI/Plugin/CopyBuild.php @@ -35,12 +35,12 @@ class CopyBuild implements \PHPCI\Plugin */ public function __construct(Builder $phpci, Build $build, array $options = array()) { - $path = $phpci->buildPath; - $this->phpci = $phpci; - $this->build = $build; - $this->directory = isset($options['directory']) ? $options['directory'] : $path; - $this->wipe = isset($options['wipe']) ? (bool)$options['wipe'] : false; - $this->ignore = isset($options['respect_ignore']) ? (bool)$options['respect_ignore'] : false; + $path = $phpci->buildPath; + $this->phpci = $phpci; + $this->build = $build; + $this->directory = isset($options['directory']) ? $options['directory'] : $path; + $this->wipe = isset($options['wipe']) ? (bool)$options['wipe'] : false; + $this->ignore = isset($options['respect_ignore']) ? (bool)$options['respect_ignore'] : false; } /** diff --git a/PHPCI/Plugin/Deployer.php b/PHPCI/Plugin/Deployer.php deleted file mode 100644 index 9c56a340..00000000 --- a/PHPCI/Plugin/Deployer.php +++ /dev/null @@ -1,73 +0,0 @@ - -* @package PHPCI -* @subpackage Plugins -*/ -class Deployer implements \PHPCI\Plugin -{ - protected $webhookUrl; - protected $reason; - protected $updateOnly; - - /** - * Set up the plugin, configure options, etc. - * @param Builder $phpci - * @param Build $build - * @param array $options - */ - public function __construct(Builder $phpci, Build $build, array $options = array()) - { - $this->phpci = $phpci; - $this->build = $build; - $this->reason = 'PHPCI Build #%BUILD% - %COMMIT_MESSAGE%'; - - if (isset($options['webhook_url'])) { - $this->webhookUrl = $options['webhook_url']; - } - - if (isset($options['reason'])) { - $this->reason = $options['reason']; - } - - $this->updateOnly = isset($options['update_only']) ? (bool) $options['update_only'] : true; - } - - /** - * Copies files from the root of the build directory into the target folder - */ - public function execute() - { - if (empty($this->webhookUrl)) { - $this->phpci->logFailure('You must specify a webhook URL.'); - return false; - } - - $http = new HttpClient(); - - $response = $http->post($this->webhookUrl, array( - 'reason' => $this->phpci->interpolate($this->reason), - 'source' => 'PHPCI', - 'url' => $this->phpci->interpolate('%BUILD_URI%'), - 'branch' => $this->phpci->interpolate('%BRANCH%'), - 'update_only' => $this->updateOnly - )); - - return $response['success']; - } -} diff --git a/PHPCI/Plugin/Email.php b/PHPCI/Plugin/Email.php index 17e235e2..9e361d91 100644 --- a/PHPCI/Plugin/Email.php +++ b/PHPCI/Plugin/Email.php @@ -9,13 +9,11 @@ namespace PHPCI\Plugin; -use Exception; use b8\View; use PHPCI\Builder; use PHPCI\Helper\Lang; use PHPCI\Model\Build; use PHPCI\Helper\Email as EmailHelper; -use Psr\Log\LogLevel; /** * Email Plugin - Provides simple email capability to PHPCI. @@ -52,9 +50,9 @@ class Email implements \PHPCI\Plugin Build $build, array $options = array() ) { - $this->phpci = $phpci; - $this->build = $build; - $this->options = $options; + $this->phpci = $phpci; + $this->build = $build; + $this->options = $options; } /** @@ -72,25 +70,12 @@ class Email implements \PHPCI\Plugin $buildStatus = $this->build->isSuccessful() ? "Passing Build" : "Failing Build"; $projectName = $this->build->getProject()->getTitle(); + $mailTemplate = $this->build->isSuccessful() ? 'Email/success' : 'Email/failed'; - try { - $view = $this->getMailTemplate(); - } catch (Exception $e) { - $this->phpci->log( - sprintf('Unknown mail template "%s", falling back to default.', $this->options['template']), - LogLevel::WARNING - ); - $view = $this->getDefaultMailTemplate(); - } - + $view = new View($mailTemplate); $view->build = $this->build; $view->project = $this->build->getProject(); - - $layout = new View('Email/layout'); - $layout->build = $this->build; - $layout->project = $this->build->getProject(); - $layout->content = $view->render(); - $body = $layout->render(); + $body = $view->render(); $sendFailures = $this->sendSeparateEmails( $addresses, @@ -112,7 +97,7 @@ class Email implements \PHPCI\Plugin * @param string $body Email body * @return array Array of failed addresses */ - protected function sendEmail($toAddress, $ccList, $subject, $body) + public function sendEmail($toAddress, $ccList, $subject, $body) { $email = new EmailHelper(); @@ -134,7 +119,7 @@ class Email implements \PHPCI\Plugin * Send an email to a list of specified subjects. * * @param array $toAddresses - * List of destination addresses for message. + * List of destinatary of message. * @param string $subject * Mail subject * @param string $body @@ -174,16 +159,15 @@ class Email implements \PHPCI\Plugin } } - if (empty($addresses) && isset($this->options['default_mailto_address'])) { + if (isset($this->options['default_mailto_address'])) { $addresses[] = $this->options['default_mailto_address']; + return $addresses; } - return array_unique($addresses); } /** * Get the list of email addresses to CC. - * * @return array */ protected function getCcAddresses() @@ -198,30 +182,4 @@ class Email implements \PHPCI\Plugin return $ccAddresses; } - - /** - * Get the mail template used to sent the mail. - * - * @return View - */ - protected function getMailTemplate() - { - if (isset($this->options['template'])) { - return new View('Email/' . $this->options['template']); - } - - return $this->getDefaultMailTemplate(); - } - - /** - * Get the default mail template. - * - * @return View - */ - protected function getDefaultMailTemplate() - { - $template = $this->build->isSuccessful() ? 'short' : 'long'; - - return new View('Email/' . $template); - } } diff --git a/PHPCI/Plugin/Env.php b/PHPCI/Plugin/Env.php index b89bf67d..4e4b6563 100644 --- a/PHPCI/Plugin/Env.php +++ b/PHPCI/Plugin/Env.php @@ -52,7 +52,7 @@ class Env implements \PHPCI\Plugin // This allows the standard syntax: "FOO: bar" $env_var = "$key=$value"; } - + if (!putenv($this->phpci->interpolate($env_var))) { $success = false; $this->phpci->logFailure(Lang::get('unable_to_set_env')); diff --git a/PHPCI/Plugin/FlowdockNotify.php b/PHPCI/Plugin/FlowdockNotify.php deleted file mode 100644 index 8ac9f2ab..00000000 --- a/PHPCI/Plugin/FlowdockNotify.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @package PHPCI - * @subpackage Plugins - */ -class FlowdockNotify implements \PHPCI\Plugin -{ - private $api_key; - private $email; - const MESSAGE_DEFAULT = 'Build %BUILD% has finished for commit %SHORT_COMMIT% - (%COMMIT_EMAIL%)> on branch %BRANCH%'; - - /** - * Set up the plugin, configure options, etc. - * @param Builder $phpci - * @param Build $build - * @param array $options - * @throws \Exception - */ - public function __construct(Builder $phpci, Build $build, array $options = array()) - { - $this->phpci = $phpci; - $this->build = $build; - if (!is_array($options) || !isset($options['api_key'])) { - throw new \Exception('Please define the api_key for Flowdock Notify plugin!'); - } - $this->api_key = trim($options['api_key']); - $this->message = isset($options['message']) ? $options['message'] : self::MESSAGE_DEFAULT; - $this->email = isset($options['email']) ? $options['email'] : 'PHPCI'; - } - - /** - * Run the Flowdock plugin. - * @return bool - * @throws \Exception - */ - public function execute() - { - - $message = $this->phpci->interpolate($this->message); - $successfulBuild = $this->build->isSuccessful() ? 'Success' : 'Failed'; - $push = new Push($this->api_key); - $flowMessage = TeamInboxMessage::create() - ->setSource("PHPCI") - ->setFromAddress($this->email) - ->setFromName($this->build->getProject()->getTitle()) - ->setSubject($successfulBuild) - ->setTags(['#ci']) - ->setLink($this->build->getBranchLink()) - ->setContent($message); - - if (!$push->sendTeamInboxMessage($flowMessage, array('connect_timeout' => 5000, 'timeout' => 5000))) { - throw new \Exception(sprintf('Flowdock Failed: %s', $flowMessage->getResponseErrors())); - } - return true; - } -} diff --git a/PHPCI/Plugin/Grunt.php b/PHPCI/Plugin/Grunt.php index 4d62ffd8..1ad0ceec 100644 --- a/PHPCI/Plugin/Grunt.php +++ b/PHPCI/Plugin/Grunt.php @@ -52,7 +52,7 @@ class Grunt implements \PHPCI\Plugin // Handle options: if (isset($options['directory'])) { - $this->directory = $path . DIRECTORY_SEPARATOR . $options['directory']; + $this->directory = $path . '/' . $options['directory']; } if (isset($options['task'])) { diff --git a/PHPCI/Plugin/Gulp.php b/PHPCI/Plugin/Gulp.php index b6c6cab4..97ad9246 100644 --- a/PHPCI/Plugin/Gulp.php +++ b/PHPCI/Plugin/Gulp.php @@ -52,7 +52,7 @@ class Gulp implements \PHPCI\Plugin // Handle options: if (isset($options['directory'])) { - $this->directory = $path . DIRECTORY_SEPARATOR . $options['directory']; + $this->directory = $path . '/' . $options['directory']; } if (isset($options['task'])) { diff --git a/PHPCI/Plugin/Irc.php b/PHPCI/Plugin/Irc.php index a7610a8c..7fe06753 100644 --- a/PHPCI/Plugin/Irc.php +++ b/PHPCI/Plugin/Irc.php @@ -77,56 +77,19 @@ class Irc implements \PHPCI\Plugin } $sock = fsockopen($this->server, $this->port); - stream_set_timeout($sock, 1); + fputs($sock, 'USER ' . $this->nick . ' phptesting.org ' . $this->nick . ' :' . $this->nick . "\r\n"); + fputs($sock, 'NICK ' . $this->nick . "\r\n"); + fputs($sock, 'JOIN ' . $this->room . "\r\n"); + fputs($sock, 'PRIVMSG ' . $this->room . ' :' . $msg . "\r\n"); - $connectCommands = array( - 'USER ' . $this->nick . ' 0 * :' . $this->nick, - 'NICK ' . $this->nick, - ); - $this->executeIrcCommands($sock, $connectCommands); - $this->executeIrcCommand($sock, 'JOIN ' . $this->room); - $this->executeIrcCommand($sock, 'PRIVMSG ' . $this->room . ' :' . $msg); + while (fgets($sock)) { + // We don't need to do anything, + // but the IRC server doesn't appear to post the message + // unless we wait for responses. + } fclose($sock); return true; } - - /** - * @param resource $socket - * @param array $commands - * @return bool - */ - private function executeIrcCommands($socket, array $commands) - { - foreach ($commands as $command) { - fputs($socket, $command . "\n"); - } - - $pingBack = false; - - // almost all servers expect pingback! - while ($response = fgets($socket)) { - $matches = array(); - if (preg_match('/^PING \\:([A-Z0-9]+)/', $response, $matches)) { - $pingBack = $matches[1]; - } - } - - if ($pingBack) { - $command = 'PONG :' . $pingBack . "\n"; - fputs($socket, $command); - } - } - - /** - * - * @param resource $socket - * @param string $command - * @return bool - */ - private function executeIrcCommand($socket, $command) - { - return $this->executeIrcCommands($socket, array($command)); - } } diff --git a/PHPCI/Plugin/Lint.php b/PHPCI/Plugin/Lint.php index a7ddc55c..90436d70 100644 --- a/PHPCI/Plugin/Lint.php +++ b/PHPCI/Plugin/Lint.php @@ -41,9 +41,9 @@ class Lint implements PHPCI\Plugin */ public function __construct(Builder $phpci, Build $build, array $options = array()) { - $this->phpci = $phpci; + $this->phpci = $phpci; $this->build = $build; - $this->directories = array(''); + $this->directories = array(''); $this->ignore = $phpci->ignore; if (!empty($options['directory'])) { @@ -93,7 +93,7 @@ class Lint implements PHPCI\Plugin if ($item->isFile() && $item->getExtension() == 'php' && !$this->lintFile($php, $itemPath)) { $success = false; - } elseif ($item->isDir() && $this->recursive && !$this->lintDirectory($php, $itemPath . DIRECTORY_SEPARATOR)) { + } elseif ($item->isDir() && $this->recursive && !$this->lintDirectory($php, $itemPath . '/')) { $success = false; } diff --git a/PHPCI/Plugin/Mysql.php b/PHPCI/Plugin/Mysql.php index fdb521ef..5c36a09f 100644 --- a/PHPCI/Plugin/Mysql.php +++ b/PHPCI/Plugin/Mysql.php @@ -166,11 +166,10 @@ class Mysql implements \PHPCI\Plugin $args = array( ':import_file' => escapeshellarg($import_file), ':decomp_cmd' => $decomp_cmd, - ':host' => escapeshellarg($this->host), ':user' => escapeshellarg($this->user), ':pass' => escapeshellarg($this->pass), ':database' => ($database === null)? '': escapeshellarg($database), ); - return strtr('cat :import_file :decomp_cmd | mysql -h:host -u:user -p:pass :database', $args); + return strtr('cat :import_file :decomp_cmd | mysql -u:user -p:pass :database', $args); } } diff --git a/PHPCI/Plugin/PackageBuild.php b/PHPCI/Plugin/PackageBuild.php index fb116640..8e40c71f 100644 --- a/PHPCI/Plugin/PackageBuild.php +++ b/PHPCI/Plugin/PackageBuild.php @@ -33,12 +33,12 @@ class PackageBuild implements \PHPCI\Plugin */ public function __construct(Builder $phpci, Build $build, array $options = array()) { - $path = $phpci->buildPath; - $this->build = $build; - $this->phpci = $phpci; - $this->directory = isset($options['directory']) ? $options['directory'] : $path; - $this->filename = isset($options['filename']) ? $options['filename'] : 'build'; - $this->format = isset($options['format']) ? $options['format'] : 'zip'; + $path = $phpci->buildPath; + $this->build = $build; + $this->phpci = $phpci; + $this->directory = isset($options['directory']) ? $options['directory'] : $path; + $this->filename = isset($options['filename']) ? $options['filename'] : 'build'; + $this->format = isset($options['format']) ? $options['format'] : 'zip'; } /** @@ -46,7 +46,7 @@ class PackageBuild implements \PHPCI\Plugin */ public function execute() { - $path = $this->phpci->buildPath; + $path = $this->phpci->buildPath; $build = $this->build; if ($this->directory == $path) { @@ -69,7 +69,8 @@ class PackageBuild implements \PHPCI\Plugin } foreach ($this->format as $format) { - switch ($format) { + switch($format) + { case 'tar': $cmd = 'tar cfz "%s/%s.tar.gz" ./*'; break; diff --git a/PHPCI/Plugin/Pdepend.php b/PHPCI/Plugin/Pdepend.php index faef406d..d1039554 100644 --- a/PHPCI/Plugin/Pdepend.php +++ b/PHPCI/Plugin/Pdepend.php @@ -73,19 +73,21 @@ class Pdepend implements \PHPCI\Plugin */ public function execute() { - if (!file_exists($this->location)) { - mkdir($this->location); - } if (!is_writable($this->location)) { - throw new \Exception(sprintf('The location %s is not writable or does not exist.', $this->location)); + throw new \Exception(sprintf('The location %s is not writable.', $this->location)); } $pdepend = $this->phpci->findBinary('pdepend'); + if (!$pdepend) { + $this->phpci->logFailure(Lang::get('could_not_find', 'pdepend')); + return false; + } + $cmd = $pdepend . ' --summary-xml="%s" --jdepend-chart="%s" --overview-pyramid="%s" %s "%s"'; $this->removeBuildArtifacts(); - + // If we need to ignore directories if (count($this->phpci->ignore)) { $ignore = ' --ignore=' . implode(',', $this->phpci->ignore); diff --git a/PHPCI/Plugin/Pgsql.php b/PHPCI/Plugin/Pgsql.php index 60057464..9d0f924d 100644 --- a/PHPCI/Plugin/Pgsql.php +++ b/PHPCI/Plugin/Pgsql.php @@ -73,9 +73,9 @@ class Pgsql implements \PHPCI\Plugin } /** - * Connects to PgSQL and runs a specified set of queries. - * @return boolean - */ + * Connects to PgSQL and runs a specified set of queries. + * @return boolean + */ public function execute() { try { diff --git a/PHPCI/Plugin/Phar.php b/PHPCI/Plugin/Phar.php index c734bb6c..f04580e7 100644 --- a/PHPCI/Plugin/Phar.php +++ b/PHPCI/Plugin/Phar.php @@ -213,7 +213,7 @@ class Phar implements \PHPCI\Plugin $content = ''; $filename = $this->getStub(); if ($filename) { - $content = file_get_contents($this->getPHPCI()->buildPath . DIRECTORY_SEPARATOR . $this->getStub()); + $content = file_get_contents($this->getPHPCI()->buildPath . '/' . $this->getStub()); } return $content; } @@ -227,8 +227,8 @@ class Phar implements \PHPCI\Plugin $success = false; try { - $file = $this->getDirectory() . DIRECTORY_SEPARATOR . $this->getFilename(); - $phar = new PHPPhar($file, 0, $this->getFilename()); + + $phar = new PHPPhar($this->getDirectory() . '/' . $this->getFilename(), 0, $this->getFilename()); $phar->buildFromDirectory($this->getPHPCI()->buildPath, $this->getRegExp()); $stub = $this->getStubContent(); @@ -237,6 +237,7 @@ class Phar implements \PHPCI\Plugin } $success = true; + } catch (Exception $e) { $this->getPHPCI()->log(Lang::get('phar_internal_error')); $this->getPHPCI()->log($e->getMessage()); diff --git a/PHPCI/Plugin/Phing.php b/PHPCI/Plugin/Phing.php index e322b72e..ae86968b 100644 --- a/PHPCI/Plugin/Phing.php +++ b/PHPCI/Plugin/Phing.php @@ -47,7 +47,7 @@ class Phing implements \PHPCI\Plugin * Set working directory */ if (isset($options['directory'])) { - $directory = $phpci->buildPath . DIRECTORY_SEPARATOR . $options['directory']; + $directory = $phpci->buildPath . '/' . $options['directory']; } else { $directory = $phpci->buildPath; } @@ -81,6 +81,11 @@ class Phing implements \PHPCI\Plugin { $phingExecutable = $this->phpci->findBinary('phing'); + if (!$phingExecutable) { + $this->phpci->logFailure(Lang::get('could_not_find', 'phing')); + return false; + } + $cmd[] = $phingExecutable . ' -f ' . $this->getBuildFilePath(); if ($this->getPropertyFile()) { @@ -208,12 +213,8 @@ class Phing implements \PHPCI\Plugin */ public function propertiesToString() { - /** - * fix the problem when execute phing out of the build dir - * @ticket 748 - */ - if (!isset($this->properties['project.basedir'])) { - $this->properties['project.basedir'] = $this->getDirectory(); + if (empty($this->properties)) { + return ''; } $propertiesString = array(); @@ -255,7 +256,7 @@ class Phing implements \PHPCI\Plugin */ public function setPropertyFile($propertyFile) { - if (!file_exists($this->getDirectory() . DIRECTORY_SEPARATOR . $propertyFile)) { + if (!file_exists($this->getDirectory() . '/' . $propertyFile)) { throw new \Exception(Lang::get('property_file_missing')); } diff --git a/PHPCI/Plugin/PhpCodeSniffer.php b/PHPCI/Plugin/PhpCodeSniffer.php index 6f4ed4e0..df276eac 100644 --- a/PHPCI/Plugin/PhpCodeSniffer.php +++ b/PHPCI/Plugin/PhpCodeSniffer.php @@ -12,7 +12,6 @@ namespace PHPCI\Plugin; use PHPCI; use PHPCI\Builder; use PHPCI\Model\Build; -use PHPCI\Model\BuildError; /** * PHP Code Sniffer Plugin - Allows PHP Code Sniffer testing. @@ -150,6 +149,11 @@ class PhpCodeSniffer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin $phpcs = $this->phpci->findBinary('phpcs'); + if (!$phpcs) { + $this->phpci->logFailure(PHPCI\Helper\Lang::get('could_not_find', 'phpcs')); + return false; + } + $this->phpci->logExecOutput(false); $cmd = $phpcs . ' --report=json %s %s %s %s %s "%s"'; @@ -164,13 +168,14 @@ class PhpCodeSniffer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin ); $output = $this->phpci->getLastOutput(); - list($errors, $warnings) = $this->processReport($output); + list($errors, $warnings, $data) = $this->processReport($output); $this->phpci->logExecOutput(true); $success = true; $this->build->storeMeta('phpcs-warnings', $warnings); $this->build->storeMeta('phpcs-errors', $errors); + $this->build->storeMeta('phpcs-data', $data); if ($this->allowed_warnings != -1 && $warnings > $this->allowed_warnings) { $success = false; @@ -226,21 +231,23 @@ class PhpCodeSniffer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin $errors = $data['totals']['errors']; $warnings = $data['totals']['warnings']; + $rtn = array(); + foreach ($data['files'] as $fileName => $file) { $fileName = str_replace($this->phpci->buildPath, '', $fileName); foreach ($file['messages'] as $message) { - $this->build->reportError( - $this->phpci, - 'php_code_sniffer', - 'PHPCS: ' . $message['message'], - $message['type'] == 'ERROR' ? BuildError::SEVERITY_HIGH : BuildError::SEVERITY_LOW, - $fileName, - $message['line'] + $this->build->reportError($this->phpci, $fileName, $message['line'], 'PHPCS: ' . $message['message']); + + $rtn[] = array( + 'file' => $fileName, + 'line' => $message['line'], + 'type' => $message['type'], + 'message' => $message['message'], ); } } - return array($errors, $warnings); + return array($errors, $warnings, $rtn); } } diff --git a/PHPCI/Plugin/PhpCpd.php b/PHPCI/Plugin/PhpCpd.php old mode 100755 new mode 100644 index aa076d2d..c663db5a --- a/PHPCI/Plugin/PhpCpd.php +++ b/PHPCI/Plugin/PhpCpd.php @@ -12,7 +12,6 @@ namespace PHPCI\Plugin; use PHPCI\Builder; use PHPCI\Helper\Lang; use PHPCI\Model\Build; -use PHPCI\Model\BuildError; /** * PHP Copy / Paste Detector - Allows PHP Copy / Paste Detector testing. @@ -29,7 +28,7 @@ class PhpCpd implements \PHPCI\Plugin /** * @var string, based on the assumption the root may not hold the code to be - * tested, extends the base path + * tested, exteds the base path */ protected $path; @@ -50,12 +49,17 @@ class PhpCpd implements \PHPCI\Plugin $this->build = $build; $this->path = $phpci->buildPath; + $this->standard = 'PSR1'; $this->ignore = $phpci->ignore; if (!empty($options['path'])) { $this->path = $phpci->buildPath . $options['path']; } + if (!empty($options['standard'])) { + $this->standard = $options['standard']; + } + if (!empty($options['ignore'])) { $this->ignore = $options['ignore']; } @@ -70,9 +74,9 @@ class PhpCpd implements \PHPCI\Plugin if (count($this->ignore)) { $map = function ($item) { // remove the trailing slash - $item = rtrim($item, DIRECTORY_SEPARATOR); + $item = (substr($item, -1) == '/' ? substr($item, 0, -1) : $item); - if (is_file(rtrim($this->path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $item)) { + if (is_file($this->path . '/' . $item)) { return ' --names-exclude ' . $item; } else { return ' --exclude ' . $item; @@ -86,15 +90,21 @@ class PhpCpd implements \PHPCI\Plugin $phpcpd = $this->phpci->findBinary('phpcpd'); + if (!$phpcpd) { + $this->phpci->logFailure(Lang::get('could_not_find', 'phpcpd')); + return false; + } + $tmpfilename = tempnam('/tmp', 'phpcpd'); $cmd = $phpcpd . ' --log-pmd "%s" %s "%s"'; $success = $this->phpci->executeCommand($cmd, $tmpfilename, $ignore, $this->path); print $this->phpci->getLastOutput(); - - $errorCount = $this->processReport(file_get_contents($tmpfilename)); + + list($errorCount, $data) = $this->processReport(file_get_contents($tmpfilename)); $this->build->storeMeta('phpcpd-warnings', $errorCount); + $this->build->storeMeta('phpcpd-data', $data); unlink($tmpfilename); @@ -117,11 +127,20 @@ class PhpCpd implements \PHPCI\Plugin } $warnings = 0; + $data = array(); + foreach ($xml->duplication as $duplication) { foreach ($duplication->file as $file) { $fileName = (string)$file['path']; $fileName = str_replace($this->phpci->buildPath, '', $fileName); + $data[] = array( + 'file' => $fileName, + 'line_start' => (int) $file['line'], + 'line_end' => (int) $file['line'] + (int) $duplication['lines'], + 'code' => (string) $duplication->codefragment + ); + $message = <<build->reportError( - $this->phpci, - 'php_cpd', - $message, - BuildError::SEVERITY_NORMAL, - $fileName, - $file['line'], - (int) $file['line'] + (int) $duplication['lines'] - ); + $this->build->reportError($this->phpci, $fileName, $file['line'], $message); + } $warnings++; } - return $warnings; + return array($warnings, $data); } } diff --git a/PHPCI/Plugin/PhpCsFixer.php b/PHPCI/Plugin/PhpCsFixer.php index 9aa0d33f..1374bc71 100644 --- a/PHPCI/Plugin/PhpCsFixer.php +++ b/PHPCI/Plugin/PhpCsFixer.php @@ -14,7 +14,7 @@ use PHPCI\Helper\Lang; use PHPCI\Model\Build; /** -* PHP CS Fixer - Works with the PHP Coding Standards Fixer for testing coding standards. +* PHP CS Fixer - Works with the PHP CS Fixer for testing coding standards. * @author Gabriel Baker * @package PHPCI * @subpackage Plugins @@ -32,10 +32,10 @@ class PhpCsFixer implements \PHPCI\Plugin protected $build; protected $workingDir = ''; - protected $level = ' --level=psr2'; - protected $verbose = ''; - protected $diff = ''; - protected $levels = array('psr0', 'psr1', 'psr2', 'symfony'); + protected $level = ' --level=all'; + protected $verbose = ''; + protected $diff = ''; + protected $levels = array('psr0', 'psr1', 'psr2', 'all'); /** * Standard Constructor @@ -69,6 +69,11 @@ class PhpCsFixer implements \PHPCI\Plugin $phpcsfixer = $this->phpci->findBinary('php-cs-fixer'); + if (!$phpcsfixer) { + $this->phpci->logFailure(Lang::get('could_not_find', 'php-cs-fixer')); + return false; + } + $cmd = $phpcsfixer . ' fix . %s %s %s'; $success = $this->phpci->executeCommand($cmd, $this->verbose, $this->diff, $this->level); diff --git a/PHPCI/Plugin/PhpDocblockChecker.php b/PHPCI/Plugin/PhpDocblockChecker.php index 2396497c..9f71afef 100644 --- a/PHPCI/Plugin/PhpDocblockChecker.php +++ b/PHPCI/Plugin/PhpDocblockChecker.php @@ -104,6 +104,11 @@ class PhpDocblockChecker implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin // Check that the binary exists: $checker = $this->phpci->findBinary('phpdoccheck'); + if (!$checker) { + $this->phpci->logFailure(PHPCI\Helper\Lang::get('could_not_find', 'phpdoccheck')); + return false; + } + // Build ignore string: $ignore = ''; if (count($this->ignore)) { @@ -143,6 +148,7 @@ class PhpDocblockChecker implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin $success = true; $this->build->storeMeta('phpdoccheck-warnings', $errors); + $this->build->storeMeta('phpdoccheck-data', $output); $this->reportErrors($output); if ($this->allowed_warnings != -1 && $errors > $this->allowed_warnings) { @@ -159,22 +165,13 @@ class PhpDocblockChecker implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin protected function reportErrors($output) { foreach ($output as $error) { - $message = 'Class ' . $error['class'] . ' is missing a docblock.'; - $severity = PHPCI\Model\BuildError::SEVERITY_LOW; + $message = 'Class ' . $error['class'] . ' does not have a Docblock comment.'; if ($error['type'] == 'method') { - $message = $error['class'] . '::' . $error['method'] . ' is missing a docblock.'; - $severity = PHPCI\Model\BuildError::SEVERITY_NORMAL; + $message = 'Method ' . $error['class'] . '::' . $error['method'] . ' does not have a Docblock comment.'; } - $this->build->reportError( - $this->phpci, - 'php_docblock_checker', - $message, - $severity, - $error['file'], - $error['line'] - ); + $this->build->reportError($this->phpci, $error['file'], $error['line'], $message); } } } diff --git a/PHPCI/Plugin/PhpLoc.php b/PHPCI/Plugin/PhpLoc.php index c8dedb91..65398e05 100644 --- a/PHPCI/Plugin/PhpLoc.php +++ b/PHPCI/Plugin/PhpLoc.php @@ -69,20 +69,24 @@ class PhpLoc implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin public function execute() { $ignore = ''; - if (count($this->phpci->ignore)) { - $map = function ($item) { - return ' --exclude ' . rtrim($item, DIRECTORY_SEPARATOR); + $map = function ($item) { + return ' --exclude ' . (substr($item, -1) == '/' ? substr($item, 0, -1) : $item); }; - $ignore = array_map($map, $this->phpci->ignore); + $ignore = implode('', $ignore); } $phploc = $this->phpci->findBinary('phploc'); + if (!$phploc) { + $this->phpci->logFailure(PHPCI\Helper\Lang::get('could_not_find', 'phploc')); + return false; + } + $success = $this->phpci->executeCommand($phploc . ' %s "%s"', $ignore, $this->directory); - $output = $this->phpci->getLastOutput(); + $output = $this->phpci->getLastOutput(); if (preg_match_all('/\((LOC|CLOC|NCLOC|LLOC)\)\s+([0-9]+)/', $output, $matches)) { $data = array(); diff --git a/PHPCI/Plugin/PhpMessDetector.php b/PHPCI/Plugin/PhpMessDetector.php index ec92bc61..21c171cb 100644 --- a/PHPCI/Plugin/PhpMessDetector.php +++ b/PHPCI/Plugin/PhpMessDetector.php @@ -38,7 +38,7 @@ class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin /** * @var string, based on the assumption the root may not hold the code to be - * tested, extends the base path only if the provided path is relative. Absolute + * tested, exteds the base path only if the provided path is relative. Absolute * paths are used verbatim */ protected $path; @@ -50,7 +50,7 @@ class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin /** * Array of PHPMD rules. Can be one of the builtins (codesize, unusedcode, naming, design, controversial) - * or a filename (detected by checking for a / in it), either absolute or relative to the project root. + * or a filenname (detected by checking for a / in it), either absolute or relative to the project root. * @var array */ protected $rules; @@ -121,10 +121,16 @@ class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin $phpmdBinaryPath = $this->phpci->findBinary('phpmd'); + if (!$phpmdBinaryPath) { + $this->phpci->logFailure(PHPCI\Helper\Lang::get('could_not_find', 'phpmd')); + return false; + } + $this->executePhpMd($phpmdBinaryPath); - $errorCount = $this->processReport(trim($this->phpci->getLastOutput())); + list($errorCount, $data) = $this->processReport(trim($this->phpci->getLastOutput())); $this->build->storeMeta('phpmd-warnings', $errorCount); + $this->build->storeMeta('phpmd-data', $data); return $this->wasLastExecSuccessful($errorCount); } @@ -157,6 +163,7 @@ class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin } $warnings = 0; + $data = array(); foreach ($xml->file as $file) { $fileName = (string)$file['name']; @@ -164,20 +171,22 @@ class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin foreach ($file->violation as $violation) { $warnings++; - - $this->build->reportError( - $this->phpci, - 'php_mess_detector', - (string)$violation, - PHPCI\Model\BuildError::SEVERITY_HIGH, - $fileName, - (int)$violation['beginline'], - (int)$violation['endline'] + $warning = array( + 'file' => $fileName, + 'line_start' => (int)$violation['beginline'], + 'line_end' => (int)$violation['endline'], + 'rule' => (string)$violation['rule'], + 'ruleset' => (string)$violation['ruleset'], + 'priority' => (int)$violation['priority'], + 'message' => (string)$violation, ); + + $this->build->reportError($this->phpci, $fileName, (int)$violation['beginline'], (string)$violation); + $data[] = $warning; } } - return $warnings; + return array($warnings, $data); } /** diff --git a/PHPCI/Plugin/PhpParallelLint.php b/PHPCI/Plugin/PhpParallelLint.php index febed528..fdaeaf65 100644 --- a/PHPCI/Plugin/PhpParallelLint.php +++ b/PHPCI/Plugin/PhpParallelLint.php @@ -55,10 +55,10 @@ class PhpParallelLint implements \PHPCI\Plugin */ public function __construct(Builder $phpci, Build $build, array $options = array()) { - $this->phpci = $phpci; - $this->build = $build; - $this->directory = $phpci->buildPath; - $this->ignore = $this->phpci->ignore; + $this->phpci = $phpci; + $this->build = $build; + $this->directory = $phpci->buildPath; + $this->ignore = $this->phpci->ignore; if (isset($options['directory'])) { $this->directory = $phpci->buildPath.$options['directory']; @@ -78,6 +78,11 @@ class PhpParallelLint implements \PHPCI\Plugin $phplint = $this->phpci->findBinary('parallel-lint'); + if (!$phplint) { + $this->phpci->logFailure(Lang::get('could_not_find', 'parallel-lint')); + return false; + } + $cmd = $phplint . ' %s "%s"'; $success = $this->phpci->executeCommand( $cmd, diff --git a/PHPCI/Plugin/PhpSpec.php b/PHPCI/Plugin/PhpSpec.php index e468a718..681a5a6c 100644 --- a/PHPCI/Plugin/PhpSpec.php +++ b/PHPCI/Plugin/PhpSpec.php @@ -59,6 +59,11 @@ class PhpSpec implements PHPCI\Plugin $phpspec = $this->phpci->findBinary(array('phpspec', 'phpspec.php')); + if (!$phpspec) { + $this->phpci->logFailure(PHPCI\Helper\Lang::get('could_not_find', 'phpspec')); + return false; + } + $success = $this->phpci->executeCommand($phpspec . ' --format=junit --no-code-generation run'); $output = $this->phpci->getLastOutput(); diff --git a/PHPCI/Plugin/PhpTalLint.php b/PHPCI/Plugin/PhpTalLint.php index 8513ec36..146b0479 100644 --- a/PHPCI/Plugin/PhpTalLint.php +++ b/PHPCI/Plugin/PhpTalLint.php @@ -155,7 +155,7 @@ class PhpTalLint implements PHPCI\Plugin if (!$this->lintFile($itemPath)) { $success = false; } - } elseif ($item->isDir() && $this->recursive && !$this->lintDirectory($itemPath . DIRECTORY_SEPARATOR)) { + } elseif ($item->isDir() && $this->recursive && !$this->lintDirectory($itemPath . '/')) { $success = false; } @@ -202,9 +202,7 @@ class PhpTalLint implements PHPCI\Plugin list($suffixes, $tales) = $this->getFlags(); - $lint = dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR; - $lint .= 'vendor' . DIRECTORY_SEPARATOR . 'phptal' . DIRECTORY_SEPARATOR . 'phptal' . DIRECTORY_SEPARATOR; - $lint .= 'tools' . DIRECTORY_SEPARATOR . 'phptal_lint.php'; + $lint = dirname(__FILE__) . '/../../vendor/phptal/phptal/tools/phptal_lint.php'; $cmd = '/usr/bin/env php ' . $lint . ' %s %s "%s"'; $this->phpci->executeCommand($cmd, $suffixes, $tales, $this->phpci->buildPath . $path); @@ -212,6 +210,7 @@ class PhpTalLint implements PHPCI\Plugin $output = $this->phpci->getLastOutput(); if (preg_match('/Found (.+?) (error|warning)/i', $output, $matches)) { + $rows = explode(PHP_EOL, $output); unset($rows[0]); @@ -224,7 +223,7 @@ class PhpTalLint implements PHPCI\Plugin $row = str_replace('(use -i to include your custom modifier functions)', '', $row); $message = str_replace($name . ': ', '', $row); - + $parts = explode(' (line ', $message); $message = trim($parts[0]); diff --git a/PHPCI/Plugin/PhpUnit.php b/PHPCI/Plugin/PhpUnit.php index f716f079..3ea1ae8d 100644 --- a/PHPCI/Plugin/PhpUnit.php +++ b/PHPCI/Plugin/PhpUnit.php @@ -76,8 +76,8 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin return 'phpunit.xml'; } - if (file_exists($buildPath . 'tests' . DIRECTORY_SEPARATOR . 'phpunit.xml')) { - return 'tests' . DIRECTORY_SEPARATOR . 'phpunit.xml'; + if (file_exists($buildPath . 'tests/phpunit.xml')) { + return 'tests/phpunit.xml'; } if (file_exists($buildPath . 'phpunit.xml.dist')) { @@ -85,7 +85,7 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin } if (file_exists($buildPath . 'tests/phpunit.xml.dist')) { - return 'tests' . DIRECTORY_SEPARATOR . 'phpunit.xml.dist'; + return 'tests/phpunit.xml.dist'; } return null; @@ -133,7 +133,7 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin } if (isset($options['coverage'])) { - $this->coverage = ' --coverage-html ' . $this->phpci->interpolate($options['coverage']) . ' '; + $this->coverage = " --coverage-html {$options['coverage']} "; } } @@ -162,7 +162,6 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin } $tapString = $this->phpci->getLastOutput(); - $tapString = mb_convert_encoding($tapString, "UTF-8", "ISO-8859-1"); try { $tapParser = new TapParser($tapString); @@ -194,11 +193,18 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin } else { if ($this->runFrom) { $curdir = getcwd(); - chdir($this->phpci->buildPath . DIRECTORY_SEPARATOR . $this->runFrom); + chdir($this->phpci->buildPath.'/'.$this->runFrom); } + $phpunit = $this->phpci->findBinary('phpunit'); + if (!$phpunit) { + $this->phpci->logFailure(PHPCI\Helper\Lang::get('could_not_find', 'phpunit')); + return false; + } + + $cmd = $phpunit . ' --tap %s -c "%s" ' . $this->coverage . $this->path; $success = $this->phpci->executeCommand($cmd, $this->args, $this->phpci->buildPath . $configPath); @@ -225,6 +231,11 @@ class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin $phpunit = $this->phpci->findBinary('phpunit'); + if (!$phpunit) { + $this->phpci->logFailure(PHPCI\Helper\Lang::get('could_not_find', 'phpunit')); + return false; + } + $cmd = $phpunit . ' --tap %s "%s"'; $success = $this->phpci->executeCommand($cmd, $this->args, $this->phpci->buildPath . $directory); chdir($curdir); diff --git a/PHPCI/Plugin/SlackNotify.php b/PHPCI/Plugin/SlackNotify.php index 0e8d1cad..65a190fd 100644 --- a/PHPCI/Plugin/SlackNotify.php +++ b/PHPCI/Plugin/SlackNotify.php @@ -24,7 +24,6 @@ class SlackNotify implements \PHPCI\Plugin private $username; private $message; private $icon; - private $show_status; /** * Set up the plugin, configure options, etc. @@ -61,12 +60,6 @@ class SlackNotify implements \PHPCI\Plugin $this->username = 'PHPCI'; } - if (isset($options['show_status'])) { - $this->show_status = (bool) $options['show_status']; - } else { - $this->show_status = true; - } - if (isset($options['icon'])) { $this->icon = $options['icon']; } @@ -81,7 +74,31 @@ class SlackNotify implements \PHPCI\Plugin */ public function execute() { - $body = $this->phpci->interpolate($this->message); + $message = $this->phpci->interpolate($this->message); + + $successfulBuild = $this->build->isSuccessful(); + + if ($successfulBuild) { + $status = 'Success'; + $color = 'good'; + } else { + $status = 'Failed'; + $color = 'danger'; + } + + // Build up the attachment data + $attachment = new \Maknz\Slack\Attachment(array( + 'fallback' => $message, + 'pretext' => $message, + 'color' => $color, + 'fields' => array( + new \Maknz\Slack\AttachmentField(array( + 'title' => 'Status', + 'value' => $status, + 'short' => false + )) + ) + )); $client = new \Maknz\Slack\Client($this->webHook); @@ -99,39 +116,12 @@ class SlackNotify implements \PHPCI\Plugin $message->setIcon($this->icon); } - // Include an attachment which shows the status and hide the message - if ($this->show_status) { - $successfulBuild = $this->build->isSuccessful(); + $message->attach($attachment); - if ($successfulBuild) { - $status = 'Success'; - $color = 'good'; - } else { - $status = 'Failed'; - $color = 'danger'; - } + $success = true; - // Build up the attachment data - $attachment = new \Maknz\Slack\Attachment(array( - 'fallback' => $body, - 'pretext' => $body, - 'color' => $color, - 'fields' => array( - new \Maknz\Slack\AttachmentField(array( - 'title' => 'Status', - 'value' => $status, - 'short' => false - )) - ) - )); + $message->send(''); - $message->attach($attachment); - - $body = ''; - } - - $message->send($body); - - return true; + return $success; } } diff --git a/PHPCI/Plugin/TechnicalDebt.php b/PHPCI/Plugin/TechnicalDebt.php index 6d4711b5..afe6c920 100755 --- a/PHPCI/Plugin/TechnicalDebt.php +++ b/PHPCI/Plugin/TechnicalDebt.php @@ -42,6 +42,11 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin */ protected $allowed_errors; + /** + * @var int + */ + protected $allowed_warnings; + /** * @var string, based on the assumption the root may not hold the code to be * tested, extends the base path @@ -89,6 +94,7 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin $this->directory = $phpci->buildPath; $this->path = ''; $this->ignore = $this->phpci->ignore; + $this->allowed_warnings = 0; $this->allowed_errors = 0; $this->searches = array('TODO', 'FIXME', 'TO DO', 'FIX ME'); @@ -97,10 +103,9 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin } if (isset($options['zero_config']) && $options['zero_config']) { + $this->allowed_warnings = -1; $this->allowed_errors = -1; } - - $this->setOptions($options); } /** @@ -109,7 +114,7 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin */ protected function setOptions($options) { - foreach (array('directory', 'path', 'ignore', 'allowed_errors') as $key) { + foreach (array('directory', 'path', 'ignore', 'allowed_warnings', 'allowed_errors') as $key) { if (array_key_exists($key, $options)) { $this->{$key} = $options[$key]; } @@ -124,11 +129,12 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin $success = true; $this->phpci->logExecOutput(false); - $errorCount = $this->getErrorList(); + list($errorCount, $data) = $this->getErrorList(); $this->phpci->log("Found $errorCount instances of " . implode(', ', $this->searches)); $this->build->storeMeta('technical_debt-warnings', $errorCount); + $this->build->storeMeta('technical_debt-data', $data); if ($this->allowed_errors != -1 && $errorCount > $this->allowed_errors) { $success = false; @@ -146,11 +152,10 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin { $dirIterator = new \RecursiveDirectoryIterator($this->directory); $iterator = new \RecursiveIteratorIterator($dirIterator, \RecursiveIteratorIterator::SELF_FIRST); - $files = array(); + $files = []; $ignores = $this->ignore; $ignores[] = 'phpci.yml'; - $ignores[] = '.phpci.yml'; foreach ($iterator as $file) { $filePath = $file->getRealPath(); @@ -163,7 +168,7 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin } // Ignore hidden files, else .git, .sass_cache, etc. all get looped over - if (stripos($filePath, DIRECTORY_SEPARATOR . '.') !== false) { + if (stripos($filePath, '/.') !== false) { $skipFile = true; } @@ -174,6 +179,7 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin $files = array_filter(array_unique($files)); $errorCount = 0; + $data = array(); foreach ($files as $file) { foreach ($this->searches as $search) { @@ -187,21 +193,19 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin $content = trim($allLines[$lineNumber - 1]); $errorCount++; + $this->phpci->log("Found $search on line $lineNumber of $file:\n$content"); $fileName = str_replace($this->directory, '', $file); - - $this->build->reportError( - $this->phpci, - 'technical_debt', - $content, - PHPCI\Model\BuildError::SEVERITY_LOW, - $fileName, - $lineNumber + $data[] = array( + 'file' => $fileName, + 'line' => $lineNumber, + 'message' => $content ); + + $this->build->reportError($this->phpci, $fileName, $lineNumber, $content); + } } } - - return $errorCount; } } diff --git a/PHPCI/Plugin/Util/Executor.php b/PHPCI/Plugin/Util/Executor.php index bdd06b7e..9482c81f 100644 --- a/PHPCI/Plugin/Util/Executor.php +++ b/PHPCI/Plugin/Util/Executor.php @@ -2,12 +2,8 @@ namespace PHPCI\Plugin\Util; -use b8\Store\Factory as StoreFactory; -use Exception; use PHPCI\Helper\Lang; -use PHPCI\Logging\BuildLogger; -use PHPCI\Model\Build; -use PHPCI\Store\BuildStore; +use \PHPCI\Logging\BuildLogger; /** * Plugin Executor - Runs the configured plugins for a given build stage. @@ -25,20 +21,14 @@ class Executor */ protected $pluginFactory; - /** - * @var BuildStore - */ - protected $store; - /** * @param Factory $pluginFactory * @param BuildLogger $logger */ - public function __construct(Factory $pluginFactory, BuildLogger $logger, BuildStore $store = null) + public function __construct(Factory $pluginFactory, BuildLogger $logger) { $this->pluginFactory = $pluginFactory; $this->logger = $logger; - $this->store = $store ?: StoreFactory::getStore('Build'); } /** @@ -50,114 +40,32 @@ class Executor public function executePlugins(&$config, $stage) { $success = true; - $pluginsToExecute = array(); - - // If we have global plugins to execute for this stage, add them to the list to be executed: - if (array_key_exists($stage, $config) && is_array($config[$stage])) { - $pluginsToExecute[] = $config[$stage]; + // Ignore any stages for which we don't have plugins set: + if (!array_key_exists($stage, $config) || !is_array($config[$stage])) { + return $success; } - $pluginsToExecute = $this->getBranchSpecificPlugins($config, $stage, $pluginsToExecute); - - foreach ($pluginsToExecute as $pluginSet) { - if (!$this->doExecutePlugins($pluginSet, $stage)) { - $success = false; - } - } - - return $success; - } - - /** - * Check the config for any plugins specific to the branch we're currently building. - * @param $config - * @param $stage - * @param $pluginsToExecute - * @return array - */ - protected function getBranchSpecificPlugins(&$config, $stage, $pluginsToExecute) - { - /** @var \PHPCI\Model\Build $build */ - $build = $this->pluginFactory->getResourceFor('PHPCI\Model\Build'); - $branch = $build->getBranch(); - - // If we don't have any branch-specific plugins: - if (!isset($config['branch-' . $branch][$stage]) || !is_array($config['branch-' . $branch][$stage])) { - return $pluginsToExecute; - } - - // If we have branch-specific plugins to execute, add them to the list to be executed: - $branchConfig = $config['branch-' . $branch]; - $plugins = $branchConfig[$stage]; - - $runOption = 'after'; - - if (!empty($branchConfig['run-option'])) { - $runOption = $branchConfig['run-option']; - } - - switch ($runOption) { - // Replace standard plugin set for this stage with just the branch-specific ones: - case 'replace': - $pluginsToExecute = array(); - $pluginsToExecute[] = $plugins; - break; - - // Run branch-specific plugins before standard plugins: - case 'before': - array_unshift($pluginsToExecute, $plugins); - break; - - // Run branch-specific plugins after standard plugins: - case 'after': - array_push($pluginsToExecute, $plugins); - break; - - default: - array_push($pluginsToExecute, $plugins); - break; - } - - return $pluginsToExecute; - } - - /** - * Execute the list of plugins found for a given testing stage. - * @param $plugins - * @param $stage - * @return bool - * @throws \Exception - */ - protected function doExecutePlugins(&$plugins, $stage) - { - $success = true; - - foreach ($plugins as $plugin => $options) { + foreach ($config[$stage] as $plugin => $options) { $this->logger->log(Lang::get('running_plugin', $plugin)); - $this->setPluginStatus($stage, $plugin, Build::STATUS_RUNNING); - - // Try and execute it + // Try and execute it: if ($this->executePlugin($plugin, $options)) { - // Execution was successful - $this->logger->logSuccess(Lang::get('plugin_success')); - $this->setPluginStatus($stage, $plugin, Build::STATUS_SUCCESS); - } else { - // Execution failed - $this->logger->logFailure(Lang::get('plugin_failed')); - $this->setPluginStatus($stage, $plugin, Build::STATUS_FAILED); - if ($stage === 'setup') { - // If we're in the "setup" stage, execution should not continue after - // a plugin has failed: - throw new Exception('Plugin failed: ' . $plugin); - } elseif ($stage === 'test') { - // If we're in the "test" stage and the plugin is not allowed to fail, - // then mark the build as failed: - if (empty($options['allow_failures'])) { - $success = false; - } + // Execution was successful: + $this->logger->logSuccess(Lang::get('plugin_success')); + + } elseif ($stage == 'setup') { + // If we're in the "setup" stage, execution should not continue after + // a plugin has failed: + throw new \Exception('Plugin failed: ' . $plugin); + } else { + // If we're in the "test" stage and the plugin is not allowed to fail, + // then mark the build as failed: + if ($stage == 'test' && (!isset($options['allow_failures']) || !$options['allow_failures'])) { + $success = false; } + + $this->logger->logFailure(Lang::get('plugin_failed')); } } @@ -185,62 +93,20 @@ class Executor return false; } + $rtn = true; + + // Try running it: try { - // Build and run it $obj = $this->pluginFactory->buildPlugin($class, $options); - return $obj->execute(); + + if (!$obj->execute()) { + $rtn = false; + } } catch (\Exception $ex) { $this->logger->logFailure(Lang::get('exception') . $ex->getMessage(), $ex); - return false; - } - } - - /** - * Change the status of a plugin for a given stage. - * - * @param string $stage The builder stage. - * @param string $plugin The plugin name. - * @param int $status The new status. - */ - protected function setPluginStatus($stage, $plugin, $status) - { - $summary = $this->getBuildSummary(); - - if (!isset($summary[$stage][$plugin])) { - $summary[$stage][$plugin] = array(); + $rtn = false; } - $summary[$stage][$plugin]['status'] = $status; - - if ($status === Build::STATUS_RUNNING) { - $summary[$stage][$plugin]['started'] = time(); - } elseif ($status >= Build::STATUS_SUCCESS) { - $summary[$stage][$plugin]['ended'] = time(); - } - - $this->setBuildSummary($summary); - } - - /** - * Fetch the summary data of the current build. - * - * @return array - */ - private function getBuildSummary() - { - $build = $this->pluginFactory->getResourceFor('PHPCI\Model\Build'); - $metas = $this->store->getMeta('plugin-summary', $build->getProjectId(), $build->getId()); - return isset($metas[0]['meta_value']) ? $metas[0]['meta_value'] : array(); - } - - /** - * Sets the summary data of the current build. - * - * @param array summary - */ - private function setBuildSummary($summary) - { - $build = $this->pluginFactory->getResourceFor('PHPCI\Model\Build'); - $this->store->setMeta($build->getProjectId(), $build->getId(), 'plugin-summary', json_encode($summary)); + return $rtn; } } diff --git a/PHPCI/Plugin/Util/Factory.php b/PHPCI/Plugin/Util/Factory.php index b6d11e5e..8127bcd2 100644 --- a/PHPCI/Plugin/Util/Factory.php +++ b/PHPCI/Plugin/Util/Factory.php @@ -8,8 +8,8 @@ namespace PHPCI\Plugin\Util; */ class Factory { - const TYPE_ARRAY = "array"; - const TYPE_CALLABLE = "callable"; + const TYPE_ARRAY = "array"; + const TYPE_CALLABLE = "callable"; const INTERFACE_PHPCI_PLUGIN = '\PHPCI\Plugin'; private $currentPluginOptions; @@ -150,11 +150,11 @@ class Factory } /** - * @param string $type - * @param string $name - * @return mixed + * @param null $type + * @param null $name + * @return null */ - public function getResourceFor($type = null, $name = null) + private function getResourceFor($type = null, $name = null) { $fullId = $this->getInternalID($type, $name); if (isset($this->container[$fullId])) { @@ -185,7 +185,7 @@ class Factory return $class->getName(); } elseif ($param->isArray()) { return self::TYPE_ARRAY; - } elseif (is_callable($param)) { + } elseif ($param->isCallable()) { return self::TYPE_CALLABLE; } else { return null; diff --git a/PHPCI/Plugin/Util/FilesPluginInformation.php b/PHPCI/Plugin/Util/FilesPluginInformation.php index 35587283..2593ae22 100644 --- a/PHPCI/Plugin/Util/FilesPluginInformation.php +++ b/PHPCI/Plugin/Util/FilesPluginInformation.php @@ -56,7 +56,6 @@ class FilesPluginInformation implements InstalledPluginInformation if ($this->pluginInfo === null) { $this->loadPluginInfo(); } - return $this->pluginInfo; } @@ -70,7 +69,7 @@ class FilesPluginInformation implements InstalledPluginInformation { return array_map( function (\stdClass $plugin) { - return $plugin->class; + return $plugin->class; }, $this->getInstalledPlugins() ); @@ -84,7 +83,7 @@ class FilesPluginInformation implements InstalledPluginInformation $this->pluginInfo = array(); foreach ($this->files as $fileInfo) { if ($fileInfo instanceof \SplFileInfo) { - if ($fileInfo->isFile() && $fileInfo->getExtension() == 'php') { + if ($fileInfo->isFile() && $fileInfo->getExtension()=='php') { $this->addPluginFromFile($fileInfo); } } @@ -100,11 +99,11 @@ class FilesPluginInformation implements InstalledPluginInformation $class = $this->getFullClassFromFile($fileInfo); if (!is_null($class)) { - $newPlugin = new \stdClass(); - $newPlugin->class = $class; + $newPlugin = new \stdClass(); + $newPlugin->class = $class; $newPlugin->source = "core"; - $parts = explode('\\', $newPlugin->class); - $newPlugin->name = end($parts); + $parts = explode('\\', $newPlugin->class); + $newPlugin->name = end($parts); $this->pluginInfo[] = $newPlugin; } @@ -124,11 +123,11 @@ class FilesPluginInformation implements InstalledPluginInformation if (isset($matches[1])) { $className = $matches[1]; - + $matches = array(); preg_match('#namespace +([A-Za-z\\\\]+);#i', $contents, $matches); $namespace = $matches[1]; - + return $namespace . '\\' . $className; } else { return null; diff --git a/PHPCI/Plugin/Util/PluginInformationCollection.php b/PHPCI/Plugin/Util/PluginInformationCollection.php index 906935e5..16341733 100644 --- a/PHPCI/Plugin/Util/PluginInformationCollection.php +++ b/PHPCI/Plugin/Util/PluginInformationCollection.php @@ -32,11 +32,9 @@ class PluginInformationCollection implements InstalledPluginInformation public function getInstalledPlugins() { $arr = array(); - foreach ($this->pluginInformations as $single) { $arr = array_merge($arr, $single->getInstalledPlugins()); } - return $arr; } @@ -49,11 +47,9 @@ class PluginInformationCollection implements InstalledPluginInformation public function getPluginClasses() { $arr = array(); - foreach ($this->pluginInformations as $single) { $arr = array_merge($arr, $single->getPluginClasses()); } - return $arr; } } diff --git a/PHPCI/Plugin/Util/TapParser.php b/PHPCI/Plugin/Util/TapParser.php index 86981566..57b92b55 100644 --- a/PHPCI/Plugin/Util/TapParser.php +++ b/PHPCI/Plugin/Util/TapParser.php @@ -2,9 +2,7 @@ namespace PHPCI\Plugin\Util; -use Exception; use PHPCI\Helper\Lang; -use Symfony\Component\Yaml\Yaml; /** * Processes TAP format strings into usable test result data. @@ -12,42 +10,18 @@ use Symfony\Component\Yaml\Yaml; */ class TapParser { - const TEST_COUNTS_PATTERN = '/^\d+\.\.(\d+)/'; - const TEST_LINE_PATTERN = '/^(ok|not ok)(?:\s+\d+)?(?:\s+\-)?\s*(.*?)(?:\s*#\s*(skip|todo)\s*(.*))?\s*$/i'; - const TEST_YAML_START = '/^(\s*)---/'; - const TEST_DIAGNOSTIC = '/^#/'; - const TEST_COVERAGE = '/^Generating/'; + const TEST_COUNTS_PATTERN = '/([0-9]+)\.\.([0-9]+)/'; + const TEST_LINE_PATTERN = '/(ok|not ok)\s+[0-9]+\s+\-\s+([^\n]+)::([^\n]+)/'; + const TEST_MESSAGE_PATTERN = '/message\:\s+\'([^\']+)\'/'; + const TEST_COVERAGE_PATTERN = '/Generating code coverage report/'; + const TEST_SKIP_PATTERN = '/ok\s+[0-9]+\s+\-\s+#\s+SKIP/'; /** * @var string */ protected $tapString; - - /** - * @var int - */ protected $failures = 0; - /** - * @var array - */ - protected $lines; - - /** - * @var integer - */ - protected $lineNumber; - - /** - * @var integer - */ - protected $testCount; - - /** - * @var array - */ - protected $results; - /** * Create a new TAP parser for a given string. * @param string $tapString The TAP format string to be parsed. @@ -64,215 +38,81 @@ class TapParser { // Split up the TAP string into an array of lines, then // trim all of the lines so there's no leading or trailing whitespace. - $this->lines = array_map('rtrim', explode("\n", $this->tapString)); - $this->lineNumber = 0; + $lines = explode("\n", $this->tapString); + $lines = array_map(function ($line) { + return trim($line); + }, $lines); - $this->testCount = false; - $this->results = array(); + // Check TAP version: + $versionLine = array_shift($lines); - $header = $this->findTapLog(); - - $line = $this->nextLine(); - if ($line === $header) { - throw new Exception("Duplicated TAP log, please check the configuration."); + if ($versionLine != 'TAP version 13') { + throw new \Exception(Lang::get('tap_version')); } - while ($line !== false && ($this->testCount === false || count($this->results) < $this->testCount)) { - $this->parseLine($line); - $line = $this->nextLine(); - } - - if (false !== $this->testCount && count($this->results) !== $this->testCount) { - throw new Exception(Lang::get('tap_error')); - } - - return $this->results; - } - - /** Looks for the start of the TAP log in the string. - * - * @return string The TAP header line. - * - * @throws Exception if no TAP log is found or versions mismatch. - */ - protected function findTapLog() - { - // Look for the beginning of the TAP output - do { - $header = $this->nextLine(); - } while ($header !== false && substr($header, 0, 12) !== 'TAP version '); - - // - if ($header === false) { - throw new Exception('No TAP log found, please check the configuration.'); - } elseif ($header !== 'TAP version 13') { - throw new Exception(Lang::get('tap_version')); - } - - return $header; - } - - /** Fetch the next line. - * - * @return string|false The next line or false if the end has been reached. - */ - protected function nextLine() - { - if ($this->lineNumber < count($this->lines)) { - return $this->lines[$this->lineNumber++]; - } - return false; - } - - /** - * @param string $line - * - * @return boolean - */ - protected function testLine($line) - { - if (preg_match(self::TEST_LINE_PATTERN, $line, $matches)) { - $this->results[] = $this->processTestLine( - $matches[1], - isset($matches[2]) ? $matches[2] : '', - isset($matches[3]) ? $matches[3] : null, - isset($matches[4]) ? $matches[4] : null - ); - - return true; - } - - return false; - } - - /** - * @param string $line - * - * @return boolean - */ - protected function yamlLine($line) - { - if (preg_match(self::TEST_YAML_START, $line, $matches)) { - $diagnostic = $this->processYamlBlock($matches[1]); - $test = array_pop($this->results); - if (isset($test['message'], $diagnostic['message'])) { - $test['message'] .= PHP_EOL . $diagnostic['message']; - unset($diagnostic['message']); + if (isset($lines[count($lines) - 1]) && preg_match(self::TEST_COVERAGE_PATTERN, $lines[count($lines) - 1])) { + array_pop($lines); + if ($lines[count($lines) - 1] == "") { + array_pop($lines); } - $this->results[] = array_replace($test, $diagnostic); - - return true; } - return false; - } - - /** Parse a single line. - * - * @param string $line - * - * @throws Exception - */ - protected function parseLine($line) - { - if (preg_match(self::TEST_DIAGNOSTIC, $line) || preg_match(self::TEST_COVERAGE, $line) || !$line) { - return; + $matches = array(); + $totalTests = 0; + if (preg_match(self::TEST_COUNTS_PATTERN, $lines[0], $matches)) { + array_shift($lines); + $totalTests = (int) $matches[2]; } - if (preg_match(self::TEST_COUNTS_PATTERN, $line, $matches)) { - $this->testCount = intval($matches[1]); - - return; + if (isset($lines[count($lines) - 1]) && + preg_match(self::TEST_COUNTS_PATTERN, $lines[count($lines) - 1], $matches)) { + array_pop($lines); + $totalTests = (int) $matches[2]; } - if ($this->testLine($line)) { - return; + $rtn = $this->processTestLines($lines); + + if ($totalTests != count($rtn)) { + throw new \Exception(Lang::get('tap_error')); } - if ($this->yamlLine($line)) { - return; - } - - throw new Exception(sprintf('Incorrect TAP data, line %d: %s', $this->lineNumber, $line)); + return $rtn; } /** - * Process an individual test line. - * - * @param string $result - * @param string $message - * @param string $directive - * @param string $reason - * + * Process the individual test lines within a TAP string. + * @param $lines * @return array */ - protected function processTestLine($result, $message, $directive, $reason) + protected function processTestLines($lines) { - $test = array( - 'pass' => true, - 'message' => $message, - 'severity' => 'success', - ); + $rtn = array(); - if ($result !== 'ok') { - $test['pass'] = false; - $test['severity'] = substr($message, 0, 6) === 'Error:' ? 'error' : 'fail'; - $this->failures++; - } + foreach ($lines as $line) { + $matches = array(); - if ($directive) { - $test = $this->processDirective($test, $directive, $reason); - } + if (preg_match(self::TEST_LINE_PATTERN, $line, $matches)) { + $ok = ($matches[1] == 'ok' ? true : false); - return $test; - } + if (!$ok) { + $this->failures++; + } - /** Process an indented Yaml block. - * - * @param string $indent The block indentation to ignore. - * - * @return array The processed Yaml content. - */ - protected function processYamlBlock($indent) - { - $startLine = $this->lineNumber + 1; - $endLine = $indent . '...'; - $yamlLines = array(); + $item = array( + 'pass' => $ok, + 'suite' => $matches[2], + 'test' => $matches[3], + ); - do { - $line = $this->nextLine(); - - if ($line === false) { - throw new Exception(Lang::get('tap_error_endless_yaml', $startLine)); - } elseif ($line === $endLine) { - break; + $rtn[] = $item; + } elseif (preg_match(self::TEST_SKIP_PATTERN, $line, $matches)) { + $rtn[] = array('message' => 'SKIP'); + } elseif (preg_match(self::TEST_MESSAGE_PATTERN, $line, $matches)) { + $rtn[count($rtn) - 1]['message'] = $matches[1]; } - - $yamlLines[] = substr($line, strlen($indent)); - } while (true); - - return Yaml::parse(join("\n", $yamlLines)); - } - - /** Process a TAP directive - * - * @param array $test - * @param string $directive - * @param string $reason - * @return array - */ - protected function processDirective($test, $directive, $reason) - { - $test['severity'] = strtolower($directive) === 'skip' ? 'skipped' : 'todo'; - - if (!empty($reason)) { - if (!empty($test['message'])) { - $test['message'] .= ', '.$test['severity'].': '; - } - $test['message'] .= $reason; } - return $test; + return $rtn; } /** diff --git a/PHPCI/Plugin/Util/TestResultParsers/Codeception.php b/PHPCI/Plugin/Util/TestResultParsers/Codeception.php deleted file mode 100644 index 24af62e4..00000000 --- a/PHPCI/Plugin/Util/TestResultParsers/Codeception.php +++ /dev/null @@ -1,114 +0,0 @@ - - * @package PHPCI\Plugin\Util\TestResultParsers - */ -class Codeception implements ParserInterface -{ - protected $phpci; - protected $resultsXml; - - protected $results; - - protected $totalTests; - protected $totalTimeTaken; - protected $totalFailures; - protected $totalErrors; - - /** - * @param Builder $phpci - * @param $resultsXml - */ - public function __construct(Builder $phpci, $resultsXml) - { - $this->phpci = $phpci; - $this->resultsXml = $resultsXml; - $this->totalTests = 0; - } - - /** - * @return array An array of key/value pairs for storage in the plugins result metadata - */ - public function parse() - { - $rtn = array(); - - $this->results = new \SimpleXMLElement($this->resultsXml); - - // calculate total results - foreach ($this->results->testsuite as $testsuite) { - $this->totalTests += (int) $testsuite['tests']; - $this->totalTimeTaken += (float) $testsuite['time']; - $this->totalFailures += (int) $testsuite['failures']; - $this->totalErrors += (int) $testsuite['errors']; - - foreach ($testsuite->testcase as $testcase) { - $testresult = array( - 'suite' => (string) $testsuite['name'], - 'file' => str_replace($this->phpci->buildPath, '/', (string) $testcase['file']), - 'name' => (string) $testcase['name'], - 'feature' => (string) $testcase['feature'], - 'assertions' => (int) $testcase['assertions'], - 'time' => (float) $testcase['time'] - ); - - if (isset($testcase['class'])) { - $testresult['class'] = (string) $testcase['class']; - } - - // PHPUnit testcases does not have feature field. Use class::method instead - if (!$testresult['feature']) { - $testresult['feature'] = sprintf('%s::%s', $testresult['class'], $testresult['name']); - } - - if (isset($testcase->failure) || isset($testcase->error)) { - $testresult['pass'] = false; - $testresult['message'] = (string)$testcase->failure . (string)$testcase->error; - } else { - $testresult['pass'] = true; - } - - $rtn[] = $testresult; - } - } - - return $rtn; - } - - /** - * Get the total number of tests performed. - * - * @return int - */ - public function getTotalTests() - { - return $this->totalTests; - } - - /** - * The time take to complete all tests - * - * @return mixed - */ - public function getTotalTimeTaken() - { - return $this->totalTimeTaken; - } - - /** - * A count of the test failures - * - * @return mixed - */ - public function getTotalFailures() - { - return $this->totalFailures + $this->totalErrors; - } -} diff --git a/PHPCI/Plugin/Util/TestResultParsers/ParserInterface.php b/PHPCI/Plugin/Util/TestResultParsers/ParserInterface.php deleted file mode 100644 index d0c77cb7..00000000 --- a/PHPCI/Plugin/Util/TestResultParsers/ParserInterface.php +++ /dev/null @@ -1,16 +0,0 @@ -buildPath; $this->phpci = $phpci; $this->build = $build; - $this->directory = isset($options['directory']) ? $this->phpci->interpolate($options['directory']) : $path; + $this->directory = isset($options['directory']) ? $options['directory'] : $path; } /** @@ -61,8 +61,8 @@ class Wipe implements \PHPCI\Plugin if (IS_WIN) { $cmd = 'rmdir /S /Q "%s"'; } - return $this->phpci->executeCommand($cmd, $this->directory); + $success = $this->phpci->executeCommand($cmd, $this->directory); } - return true; + return $success; } } diff --git a/PHPCI/Plugin/Xmpp.php b/PHPCI/Plugin/Xmpp.php index ccfc4399..8614e208 100644 --- a/PHPCI/Plugin/Xmpp.php +++ b/PHPCI/Plugin/Xmpp.php @@ -132,9 +132,8 @@ class XMPP implements \PHPCI\Plugin */ public function findConfigFile() { - if (file_exists($this->phpci->buildPath . DIRECTORY_SEPARATOR . '.sendxmpprc')) { - if (md5(file_get_contents($this->phpci->buildPath . DIRECTORY_SEPARATOR . '.sendxmpprc')) - !== md5($this->getConfigFormat())) { + if (file_exists('.sendxmpprc')) { + if (md5(file_get_contents('.sendxmpprc')) !== md5($this->getConfigFormat())) { return null; } @@ -149,7 +148,12 @@ class XMPP implements \PHPCI\Plugin */ public function execute() { - $sendxmpp = $this->phpci->findBinary('sendxmpp'); + $sendxmpp = $this->phpci->findBinary('/usr/bin/sendxmpp'); + + if (!$sendxmpp) { + $this->phpci->logFailure('Could not find sendxmpp.'); + return false; + } /* * Without recipients we can't send notification @@ -161,10 +165,9 @@ class XMPP implements \PHPCI\Plugin /* * Try to build conf file */ - $config_file = $this->phpci->buildPath . DIRECTORY_SEPARATOR . '.sendxmpprc'; if (is_null($this->findConfigFile())) { - file_put_contents($config_file, $this->getConfigFormat()); - chmod($config_file, 0600); + file_put_contents('.sendxmpprc', $this->getConfigFormat()); + chmod('.sendxmpprc', 0600); } /* @@ -175,7 +178,7 @@ class XMPP implements \PHPCI\Plugin $tls = ' -t'; } - $message_file = $this->phpci->buildPath . DIRECTORY_SEPARATOR . uniqid('xmppmessage'); + $message_file = uniqid('xmppmessage'); if ($this->buildMessage($message_file) === false) { return false; } @@ -183,10 +186,10 @@ class XMPP implements \PHPCI\Plugin /* * Send XMPP notification for all recipients */ - $cmd = $sendxmpp . "%s -f %s -m %s %s"; + $cmd = $sendxmpp . "%s -f .sendxmpprc -m %s %s"; $recipients = implode(' ', $this->recipients); - $success = $this->phpci->executeCommand($cmd, $tls, $config_file, $message_file, $recipients); + $success = $this->phpci->executeCommand($cmd, $tls, $message_file, $recipients); print $this->phpci->getLastOutput(); diff --git a/PHPCI/ProcessControl/Factory.php b/PHPCI/ProcessControl/Factory.php deleted file mode 100644 index 7622fd49..00000000 --- a/PHPCI/ProcessControl/Factory.php +++ /dev/null @@ -1,63 +0,0 @@ - - */ -class Factory -{ - /** - * ProcessControl singleton. - * - * @var ProcessControlInterface - */ - protected static $instance = null; - - /** - * Returns the ProcessControl singleton. - * - * @return ProcessControlInterface - */ - public static function getInstance() - { - if (static::$instance === null) { - static::$instance = static::createProcessControl(); - } - return static::$instance; - } - - /** - * Create a ProcessControl depending on available extensions and the underlying OS. - * - * Check PosixProcessControl, WindowsProcessControl and UnixProcessControl, in that order. - * - * @return ProcessControlInterface - * - * @internal - */ - public static function createProcessControl() - { - switch (true) { - case PosixProcessControl::isAvailable(): - return new PosixProcessControl(); - - case WindowsProcessControl::isAvailable(): - return new WindowsProcessControl(); - - case UnixProcessControl::isAvailable(): - return new UnixProcessControl(); - } - - throw new \Exception("No ProcessControl implementation available."); - } -} diff --git a/PHPCI/ProcessControl/PosixProcessControl.php b/PHPCI/ProcessControl/PosixProcessControl.php deleted file mode 100644 index bac55ee2..00000000 --- a/PHPCI/ProcessControl/PosixProcessControl.php +++ /dev/null @@ -1,52 +0,0 @@ - - */ -class PosixProcessControl implements ProcessControlInterface -{ - /** - * - * @param int $pid - * @return bool - */ - public function isRunning($pid) - { - // Signal "0" is not sent to the process, but posix_kill checks the process anyway; - return posix_kill($pid, 0); - } - - /** - * Sends a TERMINATE or KILL signal to the process using posix_kill. - * - * @param int $pid - * @param bool $forcefully Whether to send TERMINATE (false) or KILL (true). - */ - public function kill($pid, $forcefully = false) - { - posix_kill($pid, $forcefully ? 9 : 15); - } - - /** - * Check whether this posix_kill is available. - * - * @return bool - * - * @internal - */ - public static function isAvailable() - { - return function_exists('posix_kill'); - } -} diff --git a/PHPCI/ProcessControl/ProcessControlInterface.php b/PHPCI/ProcessControl/ProcessControlInterface.php deleted file mode 100644 index 709e0bee..00000000 --- a/PHPCI/ProcessControl/ProcessControlInterface.php +++ /dev/null @@ -1,33 +0,0 @@ - - */ -interface ProcessControlInterface -{ - /** Checks if a process exists. - * - * @param int $pid The process identifier. - * - * @return boolean true is the process is running, else false. - */ - public function isRunning($pid); - - /** Terminate a running process. - * - * @param int $pid The process identifier. - * @param bool $forcefully Whether to gently (false) or forcefully (true) terminate the process. - */ - public function kill($pid, $forcefully = false); -} diff --git a/PHPCI/ProcessControl/UnixProcessControl.php b/PHPCI/ProcessControl/UnixProcessControl.php deleted file mode 100644 index 8b638073..00000000 --- a/PHPCI/ProcessControl/UnixProcessControl.php +++ /dev/null @@ -1,54 +0,0 @@ - - */ -class UnixProcessControl implements ProcessControlInterface -{ - /** - * Check process using the "ps" command. - * - * @param int $pid - * @return boolean - */ - public function isRunning($pid) - { - $output = $exitCode = null; - exec(sprintf("ps %d", $pid), $output, $exitCode); - return $exitCode === 0; - } - - /** - * Sends a signal using the "kill" command. - * - * @param int $pid - * @param bool $forcefully - */ - public function kill($pid, $forcefully = false) - { - exec(sprintf("kill -%d %d", $forcefully ? 9 : 15, $pid)); - } - - /** - * Check whether the commands "ps" and "kill" are available. - * - * @return bool - * - * @internal - */ - public static function isAvailable() - { - return DIRECTORY_SEPARATOR === '/' && exec("which ps") && exec("which kill"); - } -} diff --git a/PHPCI/ProcessControl/WindowsProcessControl.php b/PHPCI/ProcessControl/WindowsProcessControl.php deleted file mode 100644 index e750d321..00000000 --- a/PHPCI/ProcessControl/WindowsProcessControl.php +++ /dev/null @@ -1,54 +0,0 @@ - - */ -class WindowsProcessControl implements ProcessControlInterface -{ - /** - * Check if the process is running using the "tasklist" command. - * - * @param type $pid - * @return bool - */ - public function isRunning($pid) - { - $lastLine = exec(sprintf('tasklist /fi "PID eq %d" /nh /fo csv 2>nul:', $pid)); - $record = str_getcsv($lastLine); - return isset($record[1]) && intval($record[1]) === $pid; - } - - /** - * Terminate the process using the "taskkill" command. - * - * @param type $pid - * @param bool $forcefully - */ - public function kill($pid, $forcefully = false) - { - exec(sprintf("taskkill /t /pid %d %s 2>nul:", $pid, $forcefully ? '/f' : '')); - } - - /** - * Check whether the commands "tasklist" and "taskkill" are available. - * - * @return bool - * - * @internal - */ - public static function isAvailable() - { - return DIRECTORY_SEPARATOR === '\\' && exec("where tasklist") && exec("where taskkill"); - } -} diff --git a/PHPCI/Service/BuildService.php b/PHPCI/Service/BuildService.php index a120a64e..ca2336c8 100644 --- a/PHPCI/Service/BuildService.php +++ b/PHPCI/Service/BuildService.php @@ -9,11 +9,6 @@ namespace PHPCI\Service; -use b8\Config; -use Pheanstalk\Pheanstalk; -use Pheanstalk\PheanstalkInterface; -use PHPCI\BuildFactory; -use PHPCI\Helper\Lang; use PHPCI\Model\Build; use PHPCI\Model\Project; use PHPCI\Store\BuildStore; @@ -30,11 +25,6 @@ class BuildService */ protected $buildStore; - /** - * @var bool - */ - public $queueError = false; - /** * @param BuildStore $buildStore */ @@ -69,7 +59,6 @@ class BuildService $build->setCommitId($commitId); } else { $build->setCommitId('Manual'); - $build->setCommitMessage(Lang::get('manual_build')); } if (!is_null($branch)) { @@ -90,17 +79,7 @@ class BuildService $build->setExtra(json_encode($extra)); } - $build = $this->buildStore->save($build); - - $buildId = $build->getId(); - - if (!empty($buildId)) { - $build = BuildFactory::getBuild($build); - $build->sendStatusPostback(); - $this->addBuildToQueue($build); - } - - return $build; + return $this->buildStore->save($build); } /** @@ -123,17 +102,7 @@ class BuildService $build->setCreated(new \DateTime()); $build->setStatus(0); - $build = $this->buildStore->save($build); - - $buildId = $build->getId(); - - if (!empty($buildId)) { - $build = BuildFactory::getBuild($build); - $build->sendStatusPostback(); - $this->addBuildToQueue($build); - } - - return $build; + return $this->buildStore->save($build); } /** @@ -143,47 +112,6 @@ class BuildService */ public function deleteBuild(Build $build) { - $build->removeBuildDirectory(); return $this->buildStore->delete($build); } - - /** - * Takes a build and puts it into the queue to be run (if using a queue) - * @param Build $build - */ - public function addBuildToQueue(Build $build) - { - $buildId = $build->getId(); - - if (empty($buildId)) { - return; - } - - $config = Config::getInstance(); - $settings = $config->get('phpci.worker', []); - - if (!empty($settings['host']) && !empty($settings['queue'])) { - try { - $jobData = array( - 'type' => 'phpci.build', - 'build_id' => $build->getId(), - ); - - if ($config->get('using_custom_file')) { - $jobData['config'] = $config->getArray(); - } - - $pheanstalk = new Pheanstalk($settings['host']); - $pheanstalk->useTube($settings['queue']); - $pheanstalk->put( - json_encode($jobData), - PheanstalkInterface::DEFAULT_PRIORITY, - PheanstalkInterface::DEFAULT_DELAY, - $config->get('phpci.worker.job_timeout', 600) - ); - } catch (\Exception $ex) { - $this->queueError = true; - } - } - } } diff --git a/PHPCI/Service/BuildStatusService.php b/PHPCI/Service/BuildStatusService.php deleted file mode 100644 index b4f3c009..00000000 --- a/PHPCI/Service/BuildStatusService.php +++ /dev/null @@ -1,222 +0,0 @@ -project = $project; - $this->branch = $branch; - $this->build = $build; - if ($this->build) { - $this->loadParentBuild($isParent); - } - if (defined('PHPCI_URL')) { - $this->setUrl(PHPCI_URL); - } - } - - /** - * @param $url - */ - public function setUrl($url) - { - $this->url = $url; - } - - /** - * @return Build - */ - public function getBuild() - { - return $this->build; - } - - /** - * @param bool $isParent - * @throws \Exception - */ - protected function loadParentBuild($isParent = true) - { - if ($isParent === false && !$this->isFinished()) { - $lastFinishedBuild = $this->project->getLatestBuild($this->branch, $this->finishedStatusIds); - - if ($lastFinishedBuild) { - $this->prevService = new BuildStatusService( - $this->branch, - $this->project, - $lastFinishedBuild, - true - ); - } - } - } - - /** - * @return string - */ - public function getActivity() - { - if (in_array($this->build->getStatus(), $this->finishedStatusIds)) { - return 'Sleeping'; - } elseif ($this->build->getStatus() == Build::STATUS_NEW) { - return 'Pending'; - } elseif ($this->build->getStatus() == Build::STATUS_RUNNING) { - return 'Building'; - } - return 'Unknown'; - } - - /** - * @return string - */ - public function getName() - { - return $this->project->getTitle() . ' / ' . $this->branch; - } - - /** - * @return bool - */ - public function isFinished() - { - if (in_array($this->build->getStatus(), $this->finishedStatusIds)) { - return true; - } - return false; - } - - /** - * @return null|Build - */ - public function getFinishedBuildInfo() - { - if ($this->isFinished()) { - return $this->build; - } elseif ($this->prevService) { - return $this->prevService->getBuild(); - } - return null; - } - - /** - * @return int|string - */ - public function getLastBuildLabel() - { - if ($buildInfo = $this->getFinishedBuildInfo()) { - return $buildInfo->getId(); - } - return ''; - } - - /** - * @return string - */ - public function getLastBuildTime() - { - $dateFormat = 'Y-m-d\\TH:i:sO'; - if ($buildInfo = $this->getFinishedBuildInfo()) { - return ($buildInfo->getFinished()) ? $buildInfo->getFinished()->format($dateFormat) : ''; - } - return ''; - } - - /** - * @param Build $build - * @return string - */ - public function getBuildStatus(Build $build) - { - switch ($build->getStatus()) { - case Build::STATUS_SUCCESS: - return 'Success'; - case Build::STATUS_FAILED: - return 'Failure'; - } - return 'Unknown'; - } - - /** - * @return string - */ - public function getLastBuildStatus() - { - if ($build = $this->getFinishedBuildInfo()) { - return $this->getBuildStatus($build); - } - return ''; - } - - /** - * @return string - */ - public function getBuildUrl() - { - return $this->url . 'build/view/' . $this->build->getId(); - } - - /** - * @return array - */ - public function toArray() - { - if (!$this->build) { - return array(); - } - return array( - 'name' => $this->getName(), - 'activity' => $this->getActivity(), - 'lastBuildLabel' => $this->getLastBuildLabel(), - 'lastBuildStatus' => $this->getLastBuildStatus(), - 'lastBuildTime' => $this->getLastBuildTime(), - 'webUrl' => $this->getBuildUrl(), - ); - } -} diff --git a/PHPCI/Service/ProjectService.php b/PHPCI/Service/ProjectService.php index 8b07b0a9..22e940ac 100644 --- a/PHPCI/Service/ProjectService.php +++ b/PHPCI/Service/ProjectService.php @@ -81,18 +81,10 @@ class ProjectService $project->setAllowPublicStatus((int)$options['allow_public_status']); } - if (array_key_exists('archived', $options)) { - $project->setArchived((bool)$options['archived']); - } - if (array_key_exists('branch', $options)) { $project->setBranch($options['branch']); } - if (array_key_exists('group', $options)) { - $project->setGroup($options['group']); - } - // Allow certain project types to set access information: $this->processAccessInformation($project); diff --git a/PHPCI/Store/Base/BuildErrorStoreBase.php b/PHPCI/Store/Base/BuildErrorStoreBase.php deleted file mode 100644 index 627b9d54..00000000 --- a/PHPCI/Store/Base/BuildErrorStoreBase.php +++ /dev/null @@ -1,85 +0,0 @@ -getById($value, $useConnection); - } - - /** - * Get a single BuildError by Id. - * @return null|BuildError - */ - public function getById($value, $useConnection = 'read') - { - if (is_null($value)) { - throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); - } - - $query = 'SELECT * FROM `build_error` WHERE `id` = :id LIMIT 1'; - $stmt = Database::getConnection($useConnection)->prepare($query); - $stmt->bindValue(':id', $value); - - if ($stmt->execute()) { - if ($data = $stmt->fetch(\PDO::FETCH_ASSOC)) { - return new BuildError($data); - } - } - - return null; - } - - /** - * Get multiple BuildError by BuildId. - * @return array - */ - public function getByBuildId($value, $limit = 1000, $useConnection = 'read') - { - if (is_null($value)) { - throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); - } - - - $query = 'SELECT * FROM `build_error` WHERE `build_id` = :build_id LIMIT :limit'; - $stmt = Database::getConnection($useConnection)->prepare($query); - $stmt->bindValue(':build_id', $value); - $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); - - if ($stmt->execute()) { - $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); - - $map = function ($item) { - return new BuildError($item); - }; - $rtn = array_map($map, $res); - - $count = count($rtn); - - return array('items' => $rtn, 'count' => $count); - } else { - return array('items' => array(), 'count' => 0); - } - } -} diff --git a/PHPCI/Store/Base/BuildMetaStoreBase.php b/PHPCI/Store/Base/BuildMetaStoreBase.php index 52665d79..7a3d4159 100644 --- a/PHPCI/Store/Base/BuildMetaStoreBase.php +++ b/PHPCI/Store/Base/BuildMetaStoreBase.php @@ -21,7 +21,10 @@ class BuildMetaStoreBase extends Store protected $primaryKey = 'id'; /** - * Get a BuildMeta by primary key (Id) + * Returns a BuildMeta model by primary key. + * @param mixed $value + * @param string $useConnection + * @return \@appNamespace\Model\BuildMeta|null */ public function getByPrimaryKey($value, $useConnection = 'read') { @@ -29,8 +32,11 @@ class BuildMetaStoreBase extends Store } /** - * Get a single BuildMeta by Id. - * @return null|BuildMeta + * Returns a BuildMeta model by Id. + * @param mixed $value + * @param string $useConnection + * @throws HttpException + * @return \@appNamespace\Model\BuildMeta|null */ public function getById($value, $useConnection = 'read') { @@ -52,7 +58,11 @@ class BuildMetaStoreBase extends Store } /** - * Get multiple BuildMeta by ProjectId. + * Returns an array of BuildMeta models by ProjectId. + * @param mixed $value + * @param int $limit + * @param string $useConnection + * @throws HttpException * @return array */ public function getByProjectId($value, $limit = 1000, $useConnection = 'read') @@ -84,7 +94,11 @@ class BuildMetaStoreBase extends Store } /** - * Get multiple BuildMeta by BuildId. + * Returns an array of BuildMeta models by BuildId. + * @param mixed $value + * @param int $limit + * @param string $useConnection + * @throws HttpException * @return array */ public function getByBuildId($value, $limit = 1000, $useConnection = 'read') diff --git a/PHPCI/Store/Base/BuildStoreBase.php b/PHPCI/Store/Base/BuildStoreBase.php index b8b49cb7..0560d72b 100644 --- a/PHPCI/Store/Base/BuildStoreBase.php +++ b/PHPCI/Store/Base/BuildStoreBase.php @@ -21,7 +21,10 @@ class BuildStoreBase extends Store protected $primaryKey = 'id'; /** - * Get a Build by primary key (Id) + * Returns a Build model by primary key. + * @param mixed $value + * @param string $useConnection + * @return \@appNamespace\Model\Build|null */ public function getByPrimaryKey($value, $useConnection = 'read') { @@ -29,8 +32,11 @@ class BuildStoreBase extends Store } /** - * Get a single Build by Id. - * @return null|Build + * Returns a Build model by Id. + * @param mixed $value + * @param string $useConnection + * @throws HttpException + * @return \@appNamespace\Model\Build|null */ public function getById($value, $useConnection = 'read') { @@ -52,7 +58,11 @@ class BuildStoreBase extends Store } /** - * Get multiple Build by ProjectId. + * Returns an array of Build models by ProjectId. + * @param mixed $value + * @param int $limit + * @param string $useConnection + * @throws HttpException * @return array */ public function getByProjectId($value, $limit = 1000, $useConnection = 'read') @@ -84,7 +94,11 @@ class BuildStoreBase extends Store } /** - * Get multiple Build by Status. + * Returns an array of Build models by Status. + * @param mixed $value + * @param int $limit + * @param string $useConnection + * @throws HttpException * @return array */ public function getByStatus($value, $limit = 1000, $useConnection = 'read') diff --git a/PHPCI/Store/Base/ProjectGroupStoreBase.php b/PHPCI/Store/Base/ProjectGroupStoreBase.php deleted file mode 100644 index c7cd8772..00000000 --- a/PHPCI/Store/Base/ProjectGroupStoreBase.php +++ /dev/null @@ -1,53 +0,0 @@ -getById($value, $useConnection); - } - - /** - * Get a single ProjectGroup by Id. - * @return null|ProjectGroup - */ - public function getById($value, $useConnection = 'read') - { - if (is_null($value)) { - throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); - } - - $query = 'SELECT * FROM `project_group` WHERE `id` = :id LIMIT 1'; - $stmt = Database::getConnection($useConnection)->prepare($query); - $stmt->bindValue(':id', $value); - - if ($stmt->execute()) { - if ($data = $stmt->fetch(\PDO::FETCH_ASSOC)) { - return new ProjectGroup($data); - } - } - - return null; - } -} diff --git a/PHPCI/Store/Base/ProjectStoreBase.php b/PHPCI/Store/Base/ProjectStoreBase.php index 1e2bf65b..562afba2 100644 --- a/PHPCI/Store/Base/ProjectStoreBase.php +++ b/PHPCI/Store/Base/ProjectStoreBase.php @@ -21,7 +21,10 @@ class ProjectStoreBase extends Store protected $primaryKey = 'id'; /** - * Get a Project by primary key (Id) + * Returns a Project model by primary key. + * @param mixed $value + * @param string $useConnection + * @return \@appNamespace\Model\Project|null */ public function getByPrimaryKey($value, $useConnection = 'read') { @@ -29,8 +32,11 @@ class ProjectStoreBase extends Store } /** - * Get a single Project by Id. - * @return null|Project + * Returns a Project model by Id. + * @param mixed $value + * @param string $useConnection + * @throws HttpException + * @return \@appNamespace\Model\Project|null */ public function getById($value, $useConnection = 'read') { @@ -52,7 +58,11 @@ class ProjectStoreBase extends Store } /** - * Get multiple Project by Title. + * Returns an array of Project models by Title. + * @param mixed $value + * @param int $limit + * @param string $useConnection + * @throws HttpException * @return array */ public function getByTitle($value, $limit = 1000, $useConnection = 'read') @@ -82,36 +92,4 @@ class ProjectStoreBase extends Store return array('items' => array(), 'count' => 0); } } - - /** - * Get multiple Project by GroupId. - * @return array - */ - public function getByGroupId($value, $limit = 1000, $useConnection = 'read') - { - if (is_null($value)) { - throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); - } - - - $query = 'SELECT * FROM `project` WHERE `group_id` = :group_id LIMIT :limit'; - $stmt = Database::getConnection($useConnection)->prepare($query); - $stmt->bindValue(':group_id', $value); - $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); - - if ($stmt->execute()) { - $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); - - $map = function ($item) { - return new Project($item); - }; - $rtn = array_map($map, $res); - - $count = count($rtn); - - return array('items' => $rtn, 'count' => $count); - } else { - return array('items' => array(), 'count' => 0); - } - } } diff --git a/PHPCI/Store/Base/UserStoreBase.php b/PHPCI/Store/Base/UserStoreBase.php index 105ccd3e..d91271d0 100644 --- a/PHPCI/Store/Base/UserStoreBase.php +++ b/PHPCI/Store/Base/UserStoreBase.php @@ -21,7 +21,10 @@ class UserStoreBase extends Store protected $primaryKey = 'id'; /** - * Get a User by primary key (Id) + * Returns a User model by primary key. + * @param mixed $value + * @param string $useConnection + * @return \@appNamespace\Model\User|null */ public function getByPrimaryKey($value, $useConnection = 'read') { @@ -29,8 +32,11 @@ class UserStoreBase extends Store } /** - * Get a single User by Id. - * @return null|User + * Returns a User model by Id. + * @param mixed $value + * @param string $useConnection + * @throws HttpException + * @return \@appNamespace\Model\User|null */ public function getById($value, $useConnection = 'read') { @@ -52,8 +58,11 @@ class UserStoreBase extends Store } /** - * Get a single User by Email. - * @return null|User + * Returns a User model by Email. + * @param mixed $value + * @param string $useConnection + * @throws HttpException + * @return \@appNamespace\Model\User|null */ public function getByEmail($value, $useConnection = 'read') { @@ -73,36 +82,4 @@ class UserStoreBase extends Store return null; } - - /** - * Get multiple User by Name. - * @return array - */ - public function getByName($value, $limit = 1000, $useConnection = 'read') - { - if (is_null($value)) { - throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); - } - - - $query = 'SELECT * FROM `user` WHERE `name` = :name LIMIT :limit'; - $stmt = Database::getConnection($useConnection)->prepare($query); - $stmt->bindValue(':name', $value); - $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); - - if ($stmt->execute()) { - $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); - - $map = function ($item) { - return new User($item); - }; - $rtn = array_map($map, $res); - - $count = count($rtn); - - return array('items' => $rtn, 'count' => $count); - } else { - return array('items' => array(), 'count' => 0); - } - } } diff --git a/PHPCI/Store/BuildErrorStore.php b/PHPCI/Store/BuildErrorStore.php deleted file mode 100644 index c2d32468..00000000 --- a/PHPCI/Store/BuildErrorStore.php +++ /dev/null @@ -1,80 +0,0 @@ - :since'; - } - - $query .= ' LIMIT 15000'; - - $stmt = Database::getConnection('read')->prepare($query); - - $stmt->bindValue(':build', $buildId, \PDO::PARAM_INT); - - if (!is_null($since)) { - $stmt->bindValue(':since', $since); - } - - if ($stmt->execute()) { - $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); - - $map = function ($item) { - return new BuildError($item); - }; - $rtn = array_map($map, $res); - - return $rtn; - } else { - return array(); - } - } - - /** - * Gets the total number of errors for a given build. - * @param $buildId - * @param string $since date string - * @return array - */ - public function getErrorTotalForBuild($buildId) - { - $query = 'SELECT COUNT(*) AS total FROM build_error - WHERE build_id = :build'; - - $stmt = Database::getConnection('read')->prepare($query); - - $stmt->bindValue(':build', $buildId, \PDO::PARAM_INT); - - if ($stmt->execute()) { - $res = $stmt->fetch(\PDO::FETCH_ASSOC); - return $res['total']; - } else { - return array(); - } - } -} diff --git a/PHPCI/Store/BuildMetaStore.php b/PHPCI/Store/BuildMetaStore.php index f932bc11..9800dcad 100644 --- a/PHPCI/Store/BuildMetaStore.php +++ b/PHPCI/Store/BuildMetaStore.php @@ -10,8 +10,6 @@ namespace PHPCI\Store; use PHPCI\Store\Base\BuildMetaStoreBase; -use b8\Database; -use PHPCI\Model\BuildMeta; /** * BuildMeta Store @@ -19,33 +17,5 @@ use PHPCI\Model\BuildMeta; */ class BuildMetaStore extends BuildMetaStoreBase { - /** - * Only used by an upgrade migration to move errors from build_meta to build_error - * @param $start - * @param $limit - * @return array - */ - public function getErrorsForUpgrade($limit) - { - $query = 'SELECT * FROM build_meta - WHERE meta_key IN (\'phpmd-data\', \'phpcs-data\', \'phpdoccheck-data\') - ORDER BY id ASC LIMIT :limit'; - - $stmt = Database::getConnection('read')->prepare($query); - - $stmt->bindValue(':limit', $limit, \PDO::PARAM_INT); - - if ($stmt->execute()) { - $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); - - $map = function ($item) { - return new BuildMeta($item); - }; - $rtn = array_map($map, $res); - - return $rtn; - } else { - return array(); - } - } + // This class has been left blank so that you can modify it - changes in this file will not be overwritten. } diff --git a/PHPCI/Store/BuildStore.php b/PHPCI/Store/BuildStore.php index d6feb084..3a4c0ddc 100644 --- a/PHPCI/Store/BuildStore.php +++ b/PHPCI/Store/BuildStore.php @@ -107,27 +107,6 @@ class BuildStore extends BuildStoreBase } } - /** - * Returns all registered branches for project - * - * @param $projectId - * @return array - * @throws \Exception - */ - public function getBuildBranches($projectId) - { - $query = 'SELECT DISTINCT `branch` FROM `build` WHERE `project_id` = :project_id'; - $stmt = Database::getConnection('read')->prepare($query); - $stmt->bindValue(':project_id', $projectId); - - if ($stmt->execute()) { - $res = $stmt->fetchAll(\PDO::FETCH_COLUMN); - return $res; - } else { - return array(); - } - } - /** * Return build metadata by key, project and optionally build id. * @param $key @@ -165,10 +144,7 @@ class BuildStore extends BuildStoreBase $stmt->bindValue(':projectId', (int)$projectId, \PDO::PARAM_INT); $stmt->bindValue(':buildId', (int)$buildId, \PDO::PARAM_INT); $stmt->bindValue(':numResults', (int)$numResults, \PDO::PARAM_INT); - - if (!is_null($branch)) { - $stmt->bindValue(':branch', $branch, \PDO::PARAM_STR); - } + $stmt->bindValue(':branch', $branch, \PDO::PARAM_STR); if ($stmt->execute()) { $rtn = $stmt->fetchAll(\PDO::FETCH_ASSOC); @@ -184,6 +160,7 @@ class BuildStore extends BuildStoreBase } else { return $rtn; } + } else { return null; } diff --git a/PHPCI/Store/ProjectGroupStore.php b/PHPCI/Store/ProjectGroupStore.php deleted file mode 100644 index fa254e3e..00000000 --- a/PHPCI/Store/ProjectGroupStore.php +++ /dev/null @@ -1,18 +0,0 @@ - $rtn, 'count' => $count); - } else { - return array('items' => array(), 'count' => 0); - } - } - - /** - * Get multiple Project by GroupId. - * @param int $value - * @param int $limit - * @param string $useConnection - * @return array - * @throws \Exception - */ - public function getByGroupId($value, $limit = 1000, $useConnection = 'read') - { - if (is_null($value)) { - throw new \Exception('Value passed to ' . __FUNCTION__ . ' cannot be null.'); - } - - $query = 'SELECT * FROM `project` WHERE `group_id` = :group_id ORDER BY title LIMIT :limit'; - $stmt = Database::getConnection($useConnection)->prepare($query); - $stmt->bindValue(':group_id', $value); - $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); - - if ($stmt->execute()) { - $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); - - $map = function ($item) { - return new Project($item); - }; - $rtn = array_map($map, $res); - - $count = count($rtn); - return array('items' => $rtn, 'count' => $count); } else { return array('items' => array(), 'count' => 0); diff --git a/PHPCI/View/Build/errors.phtml b/PHPCI/View/Build/errors.phtml deleted file mode 100644 index 04ab9c25..00000000 --- a/PHPCI/View/Build/errors.phtml +++ /dev/null @@ -1,37 +0,0 @@ -getFileLinkTemplate(); - -/** @var \PHPCI\Model\BuildError $error */ -foreach ($errors as $error): - - $link = str_replace('{FILE}', $error->getFile(), $linkTemplate); - $link = str_replace('{LINE}', $error->getLineStart(), $link); - $link = str_replace('{LINE_END}', $error->getLineEnd(), $link); -?> - - - - - getSeverityString()); ?> - - - getPlugin()); ?> - getFile(); ?> - - - getLineStart() == $error->getLineEnd() || !$error->getLineEnd()) { - print $error->getLineStart(); - } else { - print $error->getLineStart() . ' - ' . $error->getLineEnd(); - } - ?> - - - getMessage(); ?> - - - - \ No newline at end of file diff --git a/PHPCI/View/Build/view.phtml b/PHPCI/View/Build/view.phtml index 61fafd33..1fcb57d8 100644 --- a/PHPCI/View/Build/view.phtml +++ b/PHPCI/View/Build/view.phtml @@ -1,161 +1,36 @@ +
-
-
-
-
-

- Build Details -

-
- -
- - - - - - - - - - - - - - - -
Project - - - getProject()->getTitle(); ?> - -
Branch - - getBranch(); ?> - -
Duration - -
-
-
+
+

+ getCommitterEmail()); ?> + +

-
-
-
-

- Commit Details -

-
+
+ -
- - - - - +
+ getCommitMessage()): ?> +
+ getCommitMessage(); ?> +
+ -
- - - + getBranch()); ?> - - - -
Commit - - getCommitId(), 0, 7); ?> - -
Committer - getCommitterEmail(); ?> -
- getCommitMessage(); ?> -
-
+ getCommitId() != 'Manual'): ?> +
getCommitId()); ?> +
- -
-
-
-

- Timing -

-
- -
- - - - - - - - - - - - - - - -
Created -
Started -
Finished - -
-
-
-
-
-