Compare commits
182 commits
plugin-cle
...
master
Author | SHA1 | Date | |
---|---|---|---|
64b0f60368 | |||
42ca1c6527 | |||
4d0911f2a9 | |||
3cdaef8fa9 | |||
db93f55427 | |||
49db1a26ba | |||
77e9710d09 | |||
7027055711 | |||
21ba39e6ff | |||
6418fde928 | |||
21d5f4954f | |||
1f035463e4 | |||
5ead42a7c2 | |||
1e13538c28 | |||
424f1c5c4b | |||
dc9aa195d1 | |||
1e2cbcaf3d | |||
e567088a00 | |||
ffa593f1a3 | |||
cc6d0f2964 | |||
e6b02b6019 | |||
81eadcf3f5 | |||
f200bd0411 | |||
fe9289eda5 | |||
66ffea12f0 | |||
3c8ed45c46 | |||
2ddda7711e | |||
42bea5f876 | |||
d3af89a0c5 | |||
9af9e0ec35 | |||
7f43f94cc0 | |||
949bfc5376 | |||
992cf767a6 | |||
6eeddc9dc6 | |||
6eb180ed5f | |||
148e4414fb | |||
b24b01ec65 | |||
04c67dc1dd | |||
4b8d25c0f7 | |||
9ea6f299c1 | |||
7b345cbc49 | |||
c95e226496 | |||
7bfba0ee30 | |||
551bae312f | |||
d8be38ace0 | |||
1d9c610a25 | |||
943c8124ac | |||
f33f0a4512 | |||
dd1d3b3d6a | |||
66cf713ebc | |||
8fed994921 | |||
cb346f6808 | |||
78690f32c2 | |||
f904cab599 | |||
19a7ab995c | |||
38b024833f | |||
7c03c77870 | |||
7f823b37cf | |||
d49cecf40a | |||
9c7a1c7907 | |||
82ffbfea5c | |||
0f84cc6334 | |||
914067c15a | |||
8f3cdd0fb7 | |||
9c2cdbe3d1 | |||
a821072d27 | |||
8f8009c30c | |||
2f34c47656 | |||
3f71695013 | |||
94b79860c5 | |||
4a5b1afb47 | |||
8e0122f6a0 | |||
2d667d477d | |||
d2ab7b300d | |||
6e5ede8073 | |||
6aea2bdb88 | |||
3aeef0650d | |||
5216270416 | |||
ad27ca9037 | |||
1385379f1a | |||
10720656f9 | |||
0fbae60f52 | |||
3d21ad24e9 | |||
d8cbe68705 | |||
6591ada85b | |||
bee77a25c8 | |||
351b24c91d | |||
c49821adf1 | |||
ed35dee322 | |||
156c635af5 | |||
a504789bd4 | |||
dc6e4ed6b4 | |||
c9f6946189 | |||
21b59ab4d4 | |||
c474a5c73a | |||
8845fe63d9 | |||
c9541d630b | |||
97216b0f41 | |||
725ce70ae9 | |||
edcff1030d | |||
fbc3da59dd | |||
f747371c6d | |||
07b92fecf3 | |||
e61ce203a3 | |||
a008358056 | |||
68249d2f5d | |||
4375c524a9 | |||
af90b94a3c | |||
2f859be369 | |||
370eebd227 | |||
ada9e33204 | |||
4e0325e887 | |||
e871df80c2 | |||
a7473eb250 | |||
7ad1d317cd | |||
31165a6bfa | |||
74d313862c | |||
e186874eba | |||
cf415a7c78 | |||
2380d2e472 | |||
69cd4789be | |||
6f0945fb97 | |||
857990b776 | |||
3f8bb1acc4 | |||
801a4f7309 | |||
06e3235960 | |||
de6eb62367 | |||
7e2fee9504 | |||
668ee67617 | |||
de1c058f83 | |||
90b4de453e | |||
5062a58ba1 | |||
9dd6edc24a | |||
11445304d6 | |||
771bee0aa3 | |||
2858ce506a | |||
ea1157066e | |||
b2ed9f102b | |||
183d7d9e50 | |||
06204ef171 | |||
647c0eb09c | |||
6c33417839 | |||
c0b2ed0df0 | |||
fa979f6a02 | |||
9ee27bad37 | |||
b0482b191d | |||
58a97e5a97 | |||
b171a10759 | |||
aaf93ddd7d | |||
dc6e63a7e7 | |||
f55b336900 | |||
92ee90998a | |||
8a3d7605d5 | |||
d2c512d94b | |||
9efd8e06dc | |||
d698b11673 | |||
2672908225 | |||
3a6008db53 | |||
9ace15a55f | |||
3784cc8ea9 | |||
d34818f029 | |||
1eb5248319 | |||
3734d3bc9a | |||
b7d9af1e72 | |||
5c6dd81a9a | |||
7ff080971e | |||
ad29ba4cfd | |||
8549ba30cf | |||
4edefee761 | |||
15b6917f68 | |||
853107027b | |||
3f02e63c92 | |||
c20ee0533b | |||
1c864cebed | |||
0887bd4bc4 | |||
8bf1d09afd | |||
5cd29ca7fc | |||
21bf104587 | |||
5133d85b99 | |||
fdaaa1ede4 | |||
52b2f87df2 | |||
70f0d2516f |
41
.github/CONTRIBUTING.md
vendored
Normal file
41
.github/CONTRIBUTING.md
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
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: <Your Feature>". 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.
|
28
.github/ISSUE_TEMPLATE.md
vendored
Normal file
28
.github/ISSUE_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
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).
|
23
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
23
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
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:
|
||||
|
||||
|
||||
|
38
.phpci.yml
Normal file
38
.phpci.yml
Normal file
|
@ -0,0 +1,38 @@
|
|||
build_settings:
|
||||
verbose: false
|
||||
ignore:
|
||||
- "vendor"
|
||||
- "Tests"
|
||||
- "PHPCI/Command" # PHPMD complains about un-used parameters, but they are required.
|
||||
- "public/install.php" # PHPCS really doesn't like PHP mixed with HTML (and so it shouldn't)
|
||||
- "PHPCI/Migrations" # Ignore the migrations directory, as both PHPMD and PHPCS can't cope with them.
|
||||
- "PHPCI/Model/Base" # These files are auto-generated, and sometimes hit PHPMD complexity thresholds.
|
||||
- "PHPCI/Languages" # PHPCS fails on character counts for non-Latin languages
|
||||
- "public/assets" # If there are any PHP files in here, we didn't write them.
|
||||
|
||||
setup:
|
||||
composer:
|
||||
action: "install"
|
||||
|
||||
test:
|
||||
php_parallel_lint:
|
||||
ignore:
|
||||
# Only ignore vendor
|
||||
- vendor/
|
||||
php_mess_detector:
|
||||
allowed_warnings: 0
|
||||
rules:
|
||||
- phpmd.xml
|
||||
php_code_sniffer:
|
||||
standard: phpcs.xml
|
||||
allowed_warnings: 0
|
||||
allowed_errors: 0
|
||||
php_loc:
|
||||
php_unit:
|
||||
php_docblock_checker:
|
||||
allowed_warnings: 0
|
||||
|
||||
broken:
|
||||
email:
|
||||
committer: true
|
||||
cc: ["php-ci@googlegroups.com"]
|
|
@ -135,15 +135,18 @@ class Application extends b8\Application
|
|||
*/
|
||||
protected function setLayoutVariables(View &$layout)
|
||||
{
|
||||
/** @var \PHPCI\Store\ProjectStore $projectStore */
|
||||
$projectStore = b8\Store\Factory::getStore('Project');
|
||||
$layout->projects = $projectStore->getWhere(
|
||||
array('archived' => (int)isset($_GET['archived'])),
|
||||
50,
|
||||
0,
|
||||
array(),
|
||||
array('title' => 'ASC')
|
||||
);
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,38 +36,44 @@ class BuildFactory
|
|||
|
||||
/**
|
||||
* Takes a generic build and returns a type-specific build model.
|
||||
* @param Build $base The build from which to get a more specific build type.
|
||||
* @param Build $build The build from which to get a more specific build type.
|
||||
* @return Build
|
||||
*/
|
||||
public static function getBuild(Build $base)
|
||||
public static function getBuild(Build $build)
|
||||
{
|
||||
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;
|
||||
$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());
|
||||
}
|
||||
|
||||
$type = '\\PHPCI\\Model\\Build\\' . $type;
|
||||
|
||||
return new $type($base->getDataArray());
|
||||
return $build;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -188,6 +188,14 @@ 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();
|
||||
|
@ -205,19 +213,30 @@ 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'));
|
||||
}
|
||||
} 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');
|
||||
}
|
||||
|
||||
|
||||
|
@ -285,8 +304,7 @@ class Builder implements LoggerAwareInterface
|
|||
*/
|
||||
protected function setupBuild()
|
||||
{
|
||||
$this->buildPath = $this->build->getBuildPath() . '/';
|
||||
$this->build->currentBuildPath = $this->buildPath;
|
||||
$this->buildPath = $this->build->getBuildPath();
|
||||
|
||||
$this->interpolator->setupInterpolationVars(
|
||||
$this->build,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
|
@ -10,28 +11,48 @@
|
|||
namespace PHPCI\Command;
|
||||
|
||||
use Monolog\Logger;
|
||||
use PHPCI\ProcessControl\Factory;
|
||||
use PHPCI\ProcessControl\ProcessControlInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Daemon that loops and call the run-command.
|
||||
* @author Gabriel Baker <gabriel.baker@autonomicpilot.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Console
|
||||
*/
|
||||
* Daemon that loops and call the run-command.
|
||||
* @author Gabriel Baker <gabriel.baker@autonomicpilot.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Console
|
||||
*/
|
||||
class DaemonCommand extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \Monolog\Logger
|
||||
* @var Logger
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
public function __construct(Logger $logger, $name = null)
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $pidFilePath;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $logFilePath;
|
||||
|
||||
/**
|
||||
* @var ProcessControlInterface
|
||||
*/
|
||||
protected $processControl;
|
||||
|
||||
public function __construct(Logger $logger, ProcessControlInterface $processControl = null, $name = null)
|
||||
{
|
||||
parent::__construct($name);
|
||||
$this->logger = $logger;
|
||||
$this->processControl = $processControl ?: Factory::getInstance();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
|
@ -40,17 +61,30 @@ class DaemonCommand extends Command
|
|||
->setName('phpci:daemon')
|
||||
->setDescription('Initiates the daemon to run commands.')
|
||||
->addArgument(
|
||||
'state',
|
||||
InputArgument::REQUIRED,
|
||||
'start|stop|status'
|
||||
);
|
||||
'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'))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
|
@ -61,64 +95,108 @@ class DaemonCommand extends Command
|
|||
$this->stopDaemon();
|
||||
break;
|
||||
case 'status':
|
||||
$this->statusDaemon();
|
||||
$this->statusDaemon($output);
|
||||
break;
|
||||
default:
|
||||
echo "Not a valid choice, please use start stop or status";
|
||||
$this->output->writeln("<error>Not a valid choice, please use start, stop or status</error>");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function startDaemon()
|
||||
{
|
||||
|
||||
if (file_exists(PHPCI_DIR.'/daemon/daemon.pid')) {
|
||||
echo "Already started\n";
|
||||
$this->logger->warning("Daemon already started");
|
||||
$pid = $this->getRunningPid();
|
||||
if ($pid) {
|
||||
$this->logger->notice("Daemon already started", array('pid' => $pid));
|
||||
return "alreadystarted";
|
||||
}
|
||||
|
||||
$logfile = PHPCI_DIR."/daemon/daemon.log";
|
||||
$this->logger->info("Trying to start the daemon");
|
||||
|
||||
$cmd = "nohup %s/daemonise phpci:daemonise > %s 2>&1 &";
|
||||
$command = sprintf($cmd, PHPCI_DIR, $logfile);
|
||||
$this->logger->info("Daemon started");
|
||||
exec($command);
|
||||
$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";
|
||||
}
|
||||
|
||||
protected function stopDaemon()
|
||||
{
|
||||
|
||||
if (!file_exists(PHPCI_DIR.'/daemon/daemon.pid')) {
|
||||
echo "Not started\n";
|
||||
$this->logger->warning("Can't stop daemon as not started");
|
||||
$pid = $this->getRunningPid();
|
||||
if (!$pid) {
|
||||
$this->logger->notice("Cannot stop the daemon as it is not started");
|
||||
return "notstarted";
|
||||
}
|
||||
|
||||
$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');
|
||||
}
|
||||
$this->logger->info("Trying to terminate the daemon", array('pid' => $pid));
|
||||
$this->processControl->kill($pid);
|
||||
|
||||
protected function statusDaemon()
|
||||
{
|
||||
|
||||
if (!file_exists(PHPCI_DIR.'/daemon/daemon.pid')) {
|
||||
echo "Not running\n";
|
||||
return "notrunning";
|
||||
for ($i = 0; ($pid = $this->getRunningPid()) && $i < 5; $i++) {
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
$pid = trim(file_get_contents(PHPCI_DIR.'/daemon/daemon.pid'));
|
||||
$pidcheck = sprintf("/proc/%s", $pid);
|
||||
if (is_dir($pidcheck)) {
|
||||
echo "Running\n";
|
||||
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");
|
||||
}
|
||||
|
||||
protected function statusDaemon(OutputInterface $output)
|
||||
{
|
||||
$pid = $this->getRunningPid();
|
||||
if ($pid) {
|
||||
$output->writeln(sprintf('The daemon is running, PID: %d', $pid));
|
||||
return "running";
|
||||
}
|
||||
|
||||
unlink(PHPCI_DIR.'/daemon/daemon.pid');
|
||||
echo "Not running\n";
|
||||
$output->writeln('The daemon is not running');
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,10 +16,12 @@ 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.
|
||||
|
@ -46,6 +48,9 @@ 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'));
|
||||
}
|
||||
|
||||
|
@ -229,10 +234,45 @@ 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('<error>Skipping beanstalkd configuration.</error>');
|
||||
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.
|
||||
*
|
||||
|
|
|
@ -75,7 +75,8 @@ class RebuildCommand extends Command
|
|||
$store = Factory::getStore('Build');
|
||||
$service = new BuildService($store);
|
||||
|
||||
$lastBuild = array_shift($store->getLatestBuilds(null, 1));
|
||||
$builds = $store->getLatestBuilds(null, 1);
|
||||
$lastBuild = array_shift($builds);
|
||||
$service->createDuplicateBuild($lastBuild);
|
||||
|
||||
$runner->run(new ArgvInput(array()), $output);
|
||||
|
|
85
PHPCI/Command/RebuildQueueCommand.php
Normal file
85
PHPCI/Command/RebuildQueueCommand.php
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2015, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link https://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\Command;
|
||||
|
||||
use b8\Config;
|
||||
use b8\Store\Factory;
|
||||
use Monolog\Logger;
|
||||
use PHPCI\BuildFactory;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\Logging\OutputLogHandler;
|
||||
use PHPCI\Service\BuildService;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
|
||||
/**
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
}
|
87
PHPCI/Command/WorkerCommand.php
Normal file
87
PHPCI/Command/WorkerCommand.php
Normal file
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2015, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link https://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\Command;
|
||||
|
||||
use b8\Config;
|
||||
use Monolog\Logger;
|
||||
use PHPCI\Logging\OutputLogHandler;
|
||||
use PHPCI\Worker\BuildWorker;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Worker Command - Starts the BuildWorker, which pulls jobs from beanstalkd
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @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('<comment>Debug mode enabled.</comment>');
|
||||
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();
|
||||
}
|
||||
}
|
|
@ -63,24 +63,42 @@ class BuildController extends \PHPCI\Controller
|
|||
|
||||
$this->view->plugins = $this->getUiPlugins();
|
||||
$this->view->build = $build;
|
||||
$this->view->data = json_encode($this->getBuildData($build));
|
||||
$this->view->data = $this->getBuildData($build);
|
||||
|
||||
$this->layout->title = Lang::get('build_n', $buildId);
|
||||
$this->layout->subtitle = $build->getProjectTitle();
|
||||
|
||||
$nav = array(
|
||||
'title' => Lang::get('build_n', $buildId),
|
||||
'icon' => 'cog',
|
||||
'links' => array(
|
||||
'build/rebuild/' . $build->getId() => Lang::get('rebuild_now'),
|
||||
),
|
||||
);
|
||||
switch ($build->getStatus()) {
|
||||
case 0:
|
||||
$this->layout->skin = 'blue';
|
||||
break;
|
||||
|
||||
if ($this->currentUserIsAdmin()) {
|
||||
$nav['links']['build/delete/' . $build->getId()] = Lang::get('delete_build');
|
||||
case 1:
|
||||
$this->layout->skin = 'yellow';
|
||||
break;
|
||||
|
||||
case 2:
|
||||
$this->layout->skin = 'green';
|
||||
break;
|
||||
|
||||
case 3:
|
||||
$this->layout->skin = 'red';
|
||||
break;
|
||||
}
|
||||
|
||||
$this->layout->nav = $nav;
|
||||
$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 = "<a class=\"btn btn-default\" href=\"{$rebuildLink}\">{$rebuild}</a> ";
|
||||
|
||||
if ($this->currentUserIsAdmin()) {
|
||||
$actions .= " <a class=\"btn btn-danger\" href=\"{$deleteLink}\">{$delete}</a>";
|
||||
}
|
||||
|
||||
$this->layout->actions = $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -144,7 +162,7 @@ class BuildController extends \PHPCI\Controller
|
|||
/**
|
||||
* Get build data from database and json encode it:
|
||||
*/
|
||||
protected function getBuildData($build)
|
||||
protected function getBuildData(Build $build)
|
||||
{
|
||||
$data = array();
|
||||
$data['status'] = (int)$build->getStatus();
|
||||
|
@ -152,6 +170,19 @@ 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;
|
||||
}
|
||||
|
@ -169,6 +200,10 @@ 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;
|
||||
|
|
|
@ -15,6 +15,7 @@ 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.
|
||||
|
@ -24,10 +25,9 @@ use PHPCI\Model\Build;
|
|||
*/
|
||||
class BuildStatusController extends \PHPCI\Controller
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Store\ProjectStore
|
||||
*/
|
||||
/* @var \PHPCI\Store\ProjectStore */
|
||||
protected $projectStore;
|
||||
/* @var \PHPCI\Store\BuildStore */
|
||||
protected $buildStore;
|
||||
|
||||
/**
|
||||
|
@ -70,11 +70,69 @@ 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('<Projects/>');
|
||||
|
||||
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('<projects/>');
|
||||
}
|
||||
|
||||
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)) {
|
||||
|
@ -84,7 +142,13 @@ class BuildStatusController extends \PHPCI\Controller
|
|||
}
|
||||
|
||||
$color = ($status == 'passing') ? 'green' : 'red';
|
||||
$image = file_get_contents('http://img.shields.io/badge/build-' . $status . '-' . $color . '.svg');
|
||||
$image = file_get_contents(sprintf(
|
||||
'http://img.shields.io/badge/%s-%s-%s.svg?style=%s',
|
||||
$label,
|
||||
$status,
|
||||
$color,
|
||||
$style
|
||||
));
|
||||
|
||||
$this->response->disableLayout();
|
||||
$this->response->setHeader('Content-Type', 'image/svg+xml');
|
||||
|
|
120
PHPCI/Controller/GroupController.php
Normal file
120
PHPCI/Controller/GroupController.php
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2015, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link https://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\Controller;
|
||||
|
||||
use b8;
|
||||
use b8\Form;
|
||||
use b8\Store;
|
||||
use PHPCI\Controller;
|
||||
use PHPCI\Model\ProjectGroup;
|
||||
|
||||
/**
|
||||
* Project Controller - Allows users to create, edit and view projects.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @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;
|
||||
}
|
||||
}
|
|
@ -23,15 +23,20 @@ use PHPCI\Model\Build;
|
|||
class HomeController extends \PHPCI\Controller
|
||||
{
|
||||
/**
|
||||
* @var \b8\Store\BuildStore
|
||||
* @var \PHPCI\Store\BuildStore
|
||||
*/
|
||||
protected $buildStore;
|
||||
|
||||
/**
|
||||
* @var \b8\Store\ProjectStore
|
||||
* @var \PHPCI\Store\ProjectStore
|
||||
*/
|
||||
protected $projectStore;
|
||||
|
||||
/**
|
||||
* @var \PHPCI\Store\ProjectGroupStore
|
||||
*/
|
||||
protected $groupStore;
|
||||
|
||||
/**
|
||||
* Initialise the controller, set up stores and services.
|
||||
*/
|
||||
|
@ -39,6 +44,7 @@ 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');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,15 +53,6 @@ class HomeController extends \PHPCI\Controller
|
|||
public function index()
|
||||
{
|
||||
$this->layout->title = Lang::get('dashboard');
|
||||
|
||||
$projects = $this->projectStore->getWhere(
|
||||
array('archived' => (int)isset($_GET['archived'])),
|
||||
50,
|
||||
0,
|
||||
array(),
|
||||
array('title' => 'ASC')
|
||||
);
|
||||
|
||||
$builds = $this->buildStore->getLatestBuilds(null, 10);
|
||||
|
||||
foreach ($builds as &$build) {
|
||||
|
@ -63,8 +60,7 @@ class HomeController extends \PHPCI\Controller
|
|||
}
|
||||
|
||||
$this->view->builds = $builds;
|
||||
$this->view->projects = $projects['items'];
|
||||
$this->view->summary = $this->getSummaryHtml($projects);
|
||||
$this->view->groups = $this->getGroupInfo();
|
||||
|
||||
return $this->view->render();
|
||||
}
|
||||
|
@ -102,7 +98,7 @@ class HomeController extends \PHPCI\Controller
|
|||
$failures = array();
|
||||
$counts = array();
|
||||
|
||||
foreach ($projects['items'] as $project) {
|
||||
foreach ($projects as $project) {
|
||||
$summaryBuilds[$project->getId()] = $this->buildStore->getLatestBuilds($project->getId());
|
||||
|
||||
$count = $this->buildStore->getWhere(
|
||||
|
@ -122,7 +118,7 @@ class HomeController extends \PHPCI\Controller
|
|||
}
|
||||
|
||||
$summaryView = new b8\View('SummaryTable');
|
||||
$summaryView->projects = $projects['items'];
|
||||
$summaryView->projects = $projects;
|
||||
$summaryView->builds = $summaryBuilds;
|
||||
$summaryView->successful = $successes;
|
||||
$summaryView->failed = $failures;
|
||||
|
@ -147,4 +143,24 @@ 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,24 +23,6 @@ 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
|
||||
|
@ -49,12 +31,8 @@ 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(
|
||||
|
@ -71,49 +49,6 @@ 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
|
||||
|
@ -123,83 +58,4 @@ 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,6 +116,10 @@ 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;
|
||||
|
@ -220,6 +224,7 @@ 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);
|
||||
|
@ -284,6 +289,7 @@ class ProjectController extends PHPCI\Controller
|
|||
'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);
|
||||
|
@ -352,6 +358,20 @@ 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);
|
||||
|
|
|
@ -44,12 +44,12 @@ class SessionController extends \PHPCI\Controller
|
|||
|
||||
if ($this->request->getMethod() == 'POST') {
|
||||
$token = $this->getParam('token');
|
||||
if ($token === null || $token !== $_SESSION['login_token']) {
|
||||
if (!isset($token, $_SESSION['login_token']) || $token !== $_SESSION['login_token']) {
|
||||
$isLoginFailure = true;
|
||||
} else {
|
||||
unset($_SESSION['login_token']);
|
||||
|
||||
$user = $this->userStore->getByLoginOrEmail($this->getParam('email'));
|
||||
$user = $this->userStore->getByEmail($this->getParam('email'));
|
||||
|
||||
if ($user && password_verify($this->getParam('password', ''), $user->getHash())) {
|
||||
session_regenerate_id(true);
|
||||
|
@ -68,7 +68,7 @@ class SessionController extends \PHPCI\Controller
|
|||
$form->setAction(PHPCI_URL.'session/login');
|
||||
|
||||
$email = new b8\Form\Element\Email('email');
|
||||
$email->setLabel(Lang::get('login'));
|
||||
$email->setLabel(Lang::get('email_address'));
|
||||
$email->setRequired(true);
|
||||
$email->setContainerClass('form-group');
|
||||
$email->setClass('form-control');
|
||||
|
|
|
@ -444,7 +444,7 @@ class SettingsController extends Controller
|
|||
$field->setClass('form-control');
|
||||
$field->setContainerClass('form-group');
|
||||
$field->setOptions(Lang::getLanguageOptions());
|
||||
$field->setValue('en');
|
||||
$field->setValue(Lang::getLanguage());
|
||||
$form->addField($field);
|
||||
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@ use PHPCI\Store\ProjectStore;
|
|||
* @author Guillaume Perréal <adirelle@gmail.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Web
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
|
||||
*/
|
||||
class WebhookController extends \b8\Controller
|
||||
{
|
||||
|
@ -80,11 +82,64 @@ class WebhookController extends \b8\Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Called by Bitbucket POST service.
|
||||
* 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();
|
||||
|
@ -170,7 +225,7 @@ class WebhookController extends \b8\Controller
|
|||
protected function githubCommitRequest(Project $project, array $payload)
|
||||
{
|
||||
// Github sends a payload when you close a pull request with a
|
||||
// non-existant commit. We don't want this.
|
||||
// non-existent commit. We don't want this.
|
||||
if (array_key_exists('after', $payload) && $payload['after'] === '0000000000000000000000000000000000000000') {
|
||||
return array('status' => 'ignored');
|
||||
}
|
||||
|
@ -364,10 +419,6 @@ class WebhookController extends \b8\Controller
|
|||
|
||||
// If not, create a new build job for it:
|
||||
$build = $this->buildService->createBuild($project, $commitId, $branch, $committer, $commitMessage, $extra);
|
||||
$build = BuildFactory::getBuild($build);
|
||||
|
||||
// Send a status postback if the build type provides one:
|
||||
$build->sendStatusPostback();
|
||||
|
||||
return array('status' => 'ok', 'buildID' => $build->getID());
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ final class AnsiConverter
|
|||
static private $converter = null;
|
||||
|
||||
/**
|
||||
* Initialize the singletion.
|
||||
* Initialize the singleton.
|
||||
*
|
||||
* @return AnsiToHtmlConverter
|
||||
*/
|
||||
|
@ -35,7 +35,7 @@ final class AnsiConverter
|
|||
}
|
||||
|
||||
/**
|
||||
* Convert a text containing ANSI colr sequences into HTML code.
|
||||
* Convert a text containing ANSI color sequences into HTML code.
|
||||
*
|
||||
* @param string $text The text to convert
|
||||
*
|
||||
|
@ -47,7 +47,7 @@ final class AnsiConverter
|
|||
}
|
||||
|
||||
/**
|
||||
* Do not instanciate this class.
|
||||
* Do not instantiate this class.
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
|
|
|
@ -76,6 +76,7 @@ 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);
|
||||
|
@ -89,7 +90,6 @@ abstract class BaseCommandExecutor implements CommandExecutor
|
|||
);
|
||||
|
||||
$pipes = array();
|
||||
|
||||
$process = proc_open($command, $descriptorSpec, $pipes, $this->buildPath, null);
|
||||
|
||||
if (is_resource($process)) {
|
||||
|
|
|
@ -38,6 +38,7 @@ 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();
|
||||
|
@ -49,6 +50,7 @@ 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%'];
|
||||
|
@ -61,6 +63,7 @@ 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%']);
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace PHPCI\Helper;
|
|||
use b8\Config;
|
||||
|
||||
/**
|
||||
* Login Is Disabled Helper - Checks if login is disalbed in the view
|
||||
* Login Is Disabled Helper - Checks if login is disabled in the view
|
||||
* @author Stephen Ball <phpci@stephen.rebelinblue.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Web
|
||||
|
|
|
@ -71,7 +71,7 @@ class MailerFactory
|
|||
} else {
|
||||
// Check defaults
|
||||
|
||||
switch($configName) {
|
||||
switch ($configName) {
|
||||
case 'smtp_address':
|
||||
return "localhost";
|
||||
case 'default_mailto_address':
|
||||
|
|
|
@ -114,6 +114,7 @@ i din foretrukne hosting-platform.',
|
|||
'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://',
|
||||
|
@ -203,7 +204,7 @@ Services</a> sektionen under dit Bitbucket-repository.',
|
|||
'build_finished' => 'Build Afsluttet',
|
||||
'test_message' => 'Message',
|
||||
'test_no_message' => 'No message',
|
||||
'test_success' => 'Succesfull: %d',
|
||||
'test_success' => 'Successful: %d',
|
||||
'test_fail' => 'Failures: %d',
|
||||
'test_skipped' => 'Skipped: %d',
|
||||
'test_error' => 'Errors: %d',
|
||||
|
|
|
@ -39,7 +39,7 @@ 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 / Email Address',
|
||||
'login' => 'Login / Emailadresse',
|
||||
'password' => 'Passwort',
|
||||
'log_in' => 'Einloggen',
|
||||
|
||||
|
@ -102,6 +102,7 @@ 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:',
|
||||
|
@ -114,7 +115,8 @@ 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' => 'Archived',
|
||||
'archived' => 'Archiviert',
|
||||
'archived_menu' => 'Archiviert',
|
||||
'save_project' => 'Projekt speichern',
|
||||
|
||||
'error_mercurial' => 'Mercurial Repository-URL muss mit http://, oder https:// beginnen',
|
||||
|
@ -128,7 +130,7 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab
|
|||
'all_branches' => 'Alle Branches',
|
||||
'builds' => 'Builds',
|
||||
'id' => 'ID',
|
||||
'date' => 'Date',
|
||||
'date' => 'Datum',
|
||||
'project' => 'Projekt',
|
||||
'commit' => 'Commit',
|
||||
'branch' => 'Branch',
|
||||
|
@ -149,6 +151,9 @@ 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 <a href="https://bitbucket.org/%s/admin/services">Services</a>-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',
|
||||
|
@ -183,6 +188,14 @@ 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' => '<strong>%1$d</strong> Tests in <strong>%2$f</strong> Sekunden ausgeführt.
|
||||
<strong>%3$d</strong> Fehler.',
|
||||
|
||||
'file' => 'Datei',
|
||||
'line' => 'Zeile',
|
||||
|
@ -199,14 +212,14 @@ generiert. Um es zu verwenden, fügen Sie einfach den folgenden Public Key im Ab
|
|||
'build_created' => 'Build erstellt',
|
||||
'build_started' => 'Build gestartet',
|
||||
'build_finished' => 'Build abgeschlossen',
|
||||
'test_message' => 'Message',
|
||||
'test_no_message' => 'No message',
|
||||
'test_success' => 'Succesfull: %d',
|
||||
'test_fail' => 'Failures: %d',
|
||||
'test_skipped' => 'Skipped: %d',
|
||||
'test_error' => 'Errors: %d',
|
||||
'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)',
|
||||
'test_total' => '%d Test(s)',
|
||||
|
||||
// Users
|
||||
'name' => 'Name',
|
||||
|
@ -282,6 +295,19 @@ 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',
|
||||
|
@ -390,5 +416,18 @@ 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.'
|
||||
'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',
|
||||
);
|
||||
|
|
|
@ -115,6 +115,7 @@ PHPCI',
|
|||
'default_branch' => 'Προκαθορισμένο όνομα διακλάδωσης',
|
||||
'allow_public_status' => 'Ενεργοποίηση της σελίδας δημόσιας κατάστασης και την εικόνα για το έργο αυτό;',
|
||||
'archived' => 'Archived',
|
||||
'archived_menu' => 'Archived',
|
||||
'save_project' => 'Αποθήκευση έργου',
|
||||
|
||||
'error_mercurial' => 'Ο σύνδεσμος URL του ευμετάβλητου αποθετηρίου πρέπει να ξεκινάει με http:// ή https://',
|
||||
|
@ -204,7 +205,7 @@ Services</a> του Bitbucket αποθετηρίου σας.',
|
|||
'build_finished' => 'Η κατασκευή ολοκληρώθηκε',
|
||||
'test_message' => 'Message',
|
||||
'test_no_message' => 'No message',
|
||||
'test_success' => 'Succesfull: %d',
|
||||
'test_success' => 'Successful: %d',
|
||||
'test_fail' => 'Failures: %d',
|
||||
'test_skipped' => 'Skipped: %d',
|
||||
'test_error' => 'Errors: %d',
|
||||
|
|
|
@ -116,6 +116,7 @@ PHPCI',
|
|||
'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://',
|
||||
|
@ -153,6 +154,9 @@ PHPCI',
|
|||
Services</a> 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',
|
||||
|
@ -213,7 +217,7 @@ PHPCI',
|
|||
'build_finished' => 'Build Finished',
|
||||
'test_message' => 'Message',
|
||||
'test_no_message' => 'No message',
|
||||
'test_success' => 'Succesfull: %d',
|
||||
'test_success' => 'Successful: %d',
|
||||
'test_fail' => 'Failures: %d',
|
||||
'test_skipped' => 'Skipped: %d',
|
||||
'test_error' => 'Errors: %d',
|
||||
|
@ -295,6 +299,19 @@ 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',
|
||||
|
@ -355,6 +372,9 @@ PHPCI',
|
|||
'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.',
|
||||
|
@ -403,5 +423,22 @@ 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.'
|
||||
'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',
|
||||
|
||||
);
|
||||
|
|
|
@ -115,6 +115,7 @@ PHPCI',
|
|||
'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://',
|
||||
|
|
|
@ -115,6 +115,7 @@ PHPCI',
|
|||
'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://',
|
||||
|
@ -286,6 +287,17 @@ 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',
|
||||
|
|
|
@ -113,8 +113,9 @@ 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?',
|
||||
'save_project' => 'Salva il 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://',
|
||||
'error_remote' => 'L\'URL del repository deve iniziare con git://, http:// o https://',
|
||||
|
@ -206,7 +207,7 @@ PHPCI',
|
|||
'build_finished' => 'Build Terminata',
|
||||
'test_message' => 'Message',
|
||||
'test_no_message' => 'No message',
|
||||
'test_success' => 'Succesfull: %d',
|
||||
'test_success' => 'Successful: %d',
|
||||
'test_fail' => 'Failures: %d',
|
||||
'test_skipped' => 'Skipped: %d',
|
||||
'test_error' => 'Errors: %d',
|
||||
|
|
|
@ -115,6 +115,7 @@ van je gekozen source code hosting platform',
|
|||
'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://',
|
||||
|
@ -204,7 +205,7 @@ Services</a> sectie van je Bitbucket repository toegevoegd worden.',
|
|||
'build_finished' => 'Build beëindigd',
|
||||
'test_message' => 'Message',
|
||||
'test_no_message' => 'No message',
|
||||
'test_success' => 'Succesfull: %d',
|
||||
'test_success' => 'Successful: %d',
|
||||
'test_fail' => 'Failures: %d',
|
||||
'test_skipped' => 'Skipped: %d',
|
||||
'test_error' => 'Errors: %d',
|
||||
|
|
|
@ -116,6 +116,7 @@ od wybranego kodu źródłowego platformy hostingowej.',
|
|||
'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://',
|
||||
|
@ -129,7 +130,7 @@ od wybranego kodu źródłowego platformy hostingowej.',
|
|||
'all_branches' => 'Wszystkie Gałęzie',
|
||||
'builds' => 'Budowania',
|
||||
'id' => 'ID',
|
||||
'date' => 'Date',
|
||||
'date' => 'Data',
|
||||
'project' => 'Projekt',
|
||||
'commit' => 'Commit',
|
||||
'branch' => 'Gałąź',
|
||||
|
@ -205,14 +206,14 @@ Services</a> repozytoria Bitbucket.',
|
|||
'build_created' => 'Budowanie Stworzone',
|
||||
'build_started' => 'Budowanie Rozpoczęte',
|
||||
'build_finished' => 'Budowanie Zakończone',
|
||||
'test_message' => 'Message',
|
||||
'test_no_message' => 'No message',
|
||||
'test_success' => 'Succesfull: %d',
|
||||
'test_fail' => 'Failures: %d',
|
||||
'test_skipped' => 'Skipped: %d',
|
||||
'test_error' => 'Errors: %d',
|
||||
'test_todo' => 'Todos: %d',
|
||||
'test_total' => '%d test(s)',
|
||||
'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',
|
||||
|
@ -343,10 +344,10 @@ Przejrzyj powyższą listę błędów przed kontynuowaniem.',
|
|||
'incorrect_format' => 'Niepoprawny 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',
|
||||
'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',
|
||||
|
|
|
@ -42,7 +42,6 @@ PHPCI',
|
|||
'password' => 'Пароль',
|
||||
'log_in' => 'Войти',
|
||||
|
||||
|
||||
// Top Nav
|
||||
'toggle_navigation' => 'Скрыть/показать панель навигации',
|
||||
'n_builds_pending' => '%d сборок ожидает',
|
||||
|
@ -108,12 +107,13 @@ PHPCI',
|
|||
'repo_name' => 'Репозиторий / Внешний URL / Локальный путь',
|
||||
'project_title' => 'Название проекта',
|
||||
'project_private_key' => 'Приватный ключ для доступа к репозиторию
|
||||
(оставьте поле пустым для локального использования и/или анонимного доступа)',
|
||||
(оставьте поле пустым для локального использования и/или анонимного доступа)',
|
||||
'build_config' => 'Конфигурация сборки проекта для PHPCI
|
||||
(если вы не добавили файл phpci.yml в репозиторий вашего проекта)',
|
||||
(если вы не добавили файл phpci.yml в репозиторий вашего проекта)',
|
||||
'default_branch' => 'Ветка по умолчанию',
|
||||
'allow_public_status' => 'Разрешить публичный статус и изображение (статуса) для проекта',
|
||||
'archived' => 'Запакован',
|
||||
'archived' => 'Архивный',
|
||||
'archived_menu' => 'Архив',
|
||||
'save_project' => 'Сохранить проект',
|
||||
|
||||
'error_mercurial' => 'URL репозитория Mercurial должен начинаться с http:// или https://',
|
||||
|
@ -139,13 +139,13 @@ PHPCI',
|
|||
|
||||
'webhooks' => 'Webhooks',
|
||||
'webhooks_help_github' => 'Чтобы Автоматически собирать этот проект при публикации новых коммитов, добавьте URL ниже в качестве нового хука в разделе настроек <a href="https://github.com/%s/settings/hooks">Webhooks
|
||||
and Services</a> вашего GitHub репозитория.',
|
||||
and Services</a> вашего GitHub репозитория.',
|
||||
|
||||
'webhooks_help_gitlab' => 'Чтобы Автоматически собирать этот проект при публикации новых коммитов, добавьте URL ниже в качестве "WebHook URL"
|
||||
в разделе "Web Hooks" вашего GitLab репозитория.',
|
||||
|
||||
'webhooks_help_bitbucket' => 'Чтобы Автоматически собирать этот проект при публикации новых коммитов, добавьте URL ниже как "POST" сервис в разделе <a href="https://bitbucket.org/%s/admin/services">
|
||||
Services</a> вашего Bitbucket репозитория.',
|
||||
Services</a> вашего Bitbucket репозитория.',
|
||||
|
||||
// View Build
|
||||
'build_x_not_found' => 'Сборки с ID %d не существует.',
|
||||
|
@ -185,6 +185,11 @@ PHPCI',
|
|||
'technical_debt' => 'Технические долги',
|
||||
'behat' => 'Behat',
|
||||
|
||||
'codeception_feature' => 'Свойство',
|
||||
'codeception_suite' => 'Набор',
|
||||
'codeception_time' => 'Время',
|
||||
'codeception_synopsis' => 'Тестов выполнено: <strong>%1$d</strong> (за <strong>%2$f</strong> сек.). Провалов: <strong>%3$d</strong>.',
|
||||
|
||||
'file' => 'Файл',
|
||||
'line' => 'Строка',
|
||||
'class' => 'Класс',
|
||||
|
@ -202,12 +207,12 @@ PHPCI',
|
|||
'build_finished' => 'Сборка окончена',
|
||||
'test_message' => 'Message',
|
||||
'test_no_message' => 'No message',
|
||||
'test_success' => 'Succesfull: %d',
|
||||
'test_fail' => 'Failures: %d',
|
||||
'test_skipped' => 'Skipped: %d',
|
||||
'test_error' => 'Errors: %d',
|
||||
'test_todo' => 'Todos: %d',
|
||||
'test_total' => '%d test(s)',
|
||||
'test_success' => 'Успешно: %d',
|
||||
'test_fail' => 'Провалено: %d',
|
||||
'test_skipped' => 'Пропущено: %d',
|
||||
'test_error' => 'Ошибок: %d',
|
||||
'test_todo' => 'Todo: %d',
|
||||
'test_total' => 'Тестов: %d',
|
||||
|
||||
// Users
|
||||
'name' => 'Имя',
|
||||
|
@ -282,6 +287,19 @@ 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' => 'Хост базы данных',
|
||||
|
|
|
@ -113,7 +113,8 @@ PHPCI',
|
|||
(якщо ви не додали файл phpci.yml до репозиторію вашого проекту)',
|
||||
'default_branch' => 'Назва гілки за замовчуванням',
|
||||
'allow_public_status' => 'Увімкнути публічну сторінку статусу та зображення для цього проекта?',
|
||||
'archived' => 'Archived',
|
||||
'archived' => 'Архівний',
|
||||
'archived_menu' => 'Архів',
|
||||
'save_project' => 'Зберегти проект',
|
||||
|
||||
'error_mercurial' => 'URL репозиторію Mercurial повинен починатись із http:// або https://',
|
||||
|
@ -204,7 +205,7 @@ PHPCI',
|
|||
'build_finished' => 'Збірка завершена',
|
||||
'test_message' => 'Message',
|
||||
'test_no_message' => 'No message',
|
||||
'test_success' => 'Succesfull: %d',
|
||||
'test_success' => 'Successful: %d',
|
||||
'test_fail' => 'Failures: %d',
|
||||
'test_skipped' => 'Skipped: %d',
|
||||
'test_error' => 'Errors: %d',
|
||||
|
|
|
@ -67,7 +67,7 @@ class BuildLogger implements LoggerAwareInterface
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Add a success-coloured message to the log.
|
||||
* @param string
|
||||
*/
|
||||
|
@ -98,6 +98,17 @@ 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
|
||||
*
|
||||
|
|
|
@ -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, 'default' => ''));
|
||||
$build->changeColumn('log', 'text', array('null' => true));
|
||||
$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));
|
||||
|
|
|
@ -14,7 +14,6 @@ class FixColumnTypes extends AbstractMigration
|
|||
$build = $this->table('build');
|
||||
$build->changeColumn('log', 'text', array(
|
||||
'null' => true,
|
||||
'default' => '',
|
||||
'limit' => MysqlAdapter::TEXT_MEDIUM,
|
||||
));
|
||||
|
||||
|
|
29
PHPCI/Migrations/20151008140800_add_project_groups.php
Normal file
29
PHPCI/Migrations/20151008140800_add_project_groups.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
|
||||
class AddProjectGroups extends AbstractMigration
|
||||
{
|
||||
public function change()
|
||||
{
|
||||
$table = $this->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();
|
||||
}
|
||||
}
|
40
PHPCI/Migrations/20151009100610_remove_unique_name_index.php
Normal file
40
PHPCI/Migrations/20151009100610_remove_unique_name_index.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
|
||||
class RemoveUniqueNameIndex extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* Change Method.
|
||||
*
|
||||
* Write your reversible migrations using this method.
|
||||
*
|
||||
* More information on writing migrations is available here:
|
||||
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
|
||||
*
|
||||
* The following commands can be used in this method and Phinx will
|
||||
* automatically reverse them when rolling back:
|
||||
*
|
||||
* createTable
|
||||
* renameTable
|
||||
* addColumn
|
||||
* renameColumn
|
||||
* addIndex
|
||||
* addForeignKey
|
||||
*
|
||||
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||
* with the Table class.
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
$user = $this->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();
|
||||
}
|
||||
}
|
24
PHPCI/Migrations/20151014091859_errors_table.php
Normal file
24
PHPCI/Migrations/20151014091859_errors_table.php
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
use Phinx\Db\Adapter\MysqlAdapter;
|
||||
|
||||
class ErrorsTable extends AbstractMigration
|
||||
{
|
||||
public function change()
|
||||
{
|
||||
$table = $this->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();
|
||||
|
||||
}
|
||||
}
|
183
PHPCI/Migrations/20151015124825_convert_errors.php
Normal file
183
PHPCI/Migrations/20151015124825_convert_errors.php
Normal file
|
@ -0,0 +1,183 @@
|
|||
<?php
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
use PHPCI\Model\BuildMeta;
|
||||
use PHPCI\Model\BuildError;
|
||||
|
||||
class ConvertErrors extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Store\BuildMetaStore
|
||||
*/
|
||||
protected $metaStore;
|
||||
|
||||
/**
|
||||
* @var \PHPCI\Store\BuildErrorStore
|
||||
*/
|
||||
protected $errorStore;
|
||||
|
||||
public function change()
|
||||
{
|
||||
$count = 100;
|
||||
|
||||
$this->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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
18
PHPCI/Migrations/20160623100223_project_table_defaults.php
Normal file
18
PHPCI/Migrations/20160623100223_project_table_defaults.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
use Phinx\Db\Adapter\MysqlAdapter;
|
||||
|
||||
class ProjectTableDefaults extends AbstractMigration
|
||||
{
|
||||
public function change()
|
||||
{
|
||||
$this->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();
|
||||
}
|
||||
}
|
|
@ -118,7 +118,7 @@ class BuildBase extends Model
|
|||
'default' => null,
|
||||
),
|
||||
'log' => array(
|
||||
'type' => 'text',
|
||||
'type' => 'mediumtext',
|
||||
'nullable' => true,
|
||||
'default' => null,
|
||||
),
|
||||
|
@ -621,6 +621,18 @@ 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.
|
||||
*
|
||||
|
|
503
PHPCI/Model/Base/BuildErrorBase.php
Normal file
503
PHPCI/Model/Base/BuildErrorBase.php
Normal file
|
@ -0,0 +1,503 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* BuildError base model for table: build_error
|
||||
*/
|
||||
|
||||
namespace PHPCI\Model\Base;
|
||||
|
||||
use PHPCI\Model;
|
||||
use b8\Store\Factory;
|
||||
|
||||
/**
|
||||
* BuildError Base Model
|
||||
*/
|
||||
class BuildErrorBase extends Model
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $sleepable = array();
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tableName = 'build_error';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $modelName = 'BuildError';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $data = array(
|
||||
'id' => 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());
|
||||
}
|
||||
}
|
|
@ -99,7 +99,7 @@ class BuildMetaBase extends Model
|
|||
'default' => null,
|
||||
),
|
||||
'meta_value' => array(
|
||||
'type' => 'text',
|
||||
'type' => 'mediumtext',
|
||||
'default' => null,
|
||||
),
|
||||
);
|
||||
|
|
|
@ -45,6 +45,7 @@ class ProjectBase extends Model
|
|||
'ssh_public_key' => null,
|
||||
'allow_public_status' => null,
|
||||
'archived' => null,
|
||||
'group_id' => null,
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -64,8 +65,10 @@ class ProjectBase extends Model
|
|||
'ssh_public_key' => 'getSshPublicKey',
|
||||
'allow_public_status' => 'getAllowPublicStatus',
|
||||
'archived' => 'getArchived',
|
||||
'group_id' => 'getGroupId',
|
||||
|
||||
// Foreign key getters:
|
||||
'Group' => 'getGroup',
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -85,8 +88,10 @@ class ProjectBase extends Model
|
|||
'ssh_public_key' => 'setSshPublicKey',
|
||||
'allow_public_status' => 'setAllowPublicStatus',
|
||||
'archived' => 'setArchived',
|
||||
'group_id' => 'setGroupId',
|
||||
|
||||
// Foreign key setters:
|
||||
'Group' => 'setGroup',
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -153,10 +158,14 @@ class ProjectBase extends Model
|
|||
),
|
||||
'archived' => array(
|
||||
'type' => 'tinyint',
|
||||
'length' => 4,
|
||||
'nullable' => true,
|
||||
'length' => 1,
|
||||
'default' => null,
|
||||
),
|
||||
'group_id' => array(
|
||||
'type' => 'int',
|
||||
'length' => 11,
|
||||
'default' => 1,
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -165,12 +174,20 @@ 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'
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -317,6 +334,18 @@ class ProjectBase extends Model
|
|||
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.
|
||||
*
|
||||
|
@ -530,10 +559,12 @@ class ProjectBase extends Model
|
|||
/**
|
||||
* 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) {
|
||||
|
@ -545,6 +576,83 @@ class ProjectBase extends Model
|
|||
$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.
|
||||
*
|
||||
|
|
168
PHPCI/Model/Base/ProjectGroupBase.php
Normal file
168
PHPCI/Model/Base/ProjectGroupBase.php
Normal file
|
@ -0,0 +1,168 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* ProjectGroup base model for table: project_group
|
||||
*/
|
||||
|
||||
namespace PHPCI\Model\Base;
|
||||
|
||||
use PHPCI\Model;
|
||||
use b8\Store\Factory;
|
||||
|
||||
/**
|
||||
* ProjectGroup Base Model
|
||||
*/
|
||||
class ProjectGroupBase extends Model
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $sleepable = array();
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tableName = 'project_group';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $modelName = 'ProjectGroup';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $data = array(
|
||||
'id' => 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());
|
||||
}
|
||||
}
|
|
@ -106,6 +106,8 @@ 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'),
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,7 +28,7 @@ class Build extends BuildBase
|
|||
const STATUS_SUCCESS = 2;
|
||||
const STATUS_FAILED = 3;
|
||||
|
||||
public $currentBuildPath = null;
|
||||
public $currentBuildPath;
|
||||
|
||||
/**
|
||||
* Get link to commit from another source (i.e. Github)
|
||||
|
@ -99,16 +99,21 @@ 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);
|
||||
|
@ -208,14 +213,36 @@ class Build extends BuildBase
|
|||
/**
|
||||
* Allows specific build types (e.g. Github) to report violations back to their respective services.
|
||||
* @param Builder $builder
|
||||
* @param $file
|
||||
* @param $line
|
||||
* @param $plugin
|
||||
* @param $message
|
||||
* @return mixed
|
||||
* @param int $severity
|
||||
* @param null $file
|
||||
* @param null $lineStart
|
||||
* @param null $lineEnd
|
||||
* @return BuildError
|
||||
*/
|
||||
public function reportError(Builder $builder, $file, $line, $message)
|
||||
{
|
||||
return array($builder, $file, $line, $message);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -228,7 +255,13 @@ class Build extends BuildBase
|
|||
if (!$this->getId()) {
|
||||
return null;
|
||||
}
|
||||
return PHPCI_BUILD_ROOT_DIR . $this->getId();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -244,4 +277,25 @@ class Build extends BuildBase
|
|||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,39 +45,52 @@ class GithubBuild extends RemoteGitBuild
|
|||
{
|
||||
$token = \b8\Config::getInstance()->get('phpci.github.token');
|
||||
|
||||
if (empty($token)) {
|
||||
if (empty($token) || empty($this->data['id'])) {
|
||||
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());
|
||||
|
||||
$params = array(
|
||||
'state' => $status,
|
||||
'target_url' => $phpciUrl . '/build/view/' . $this->getId(),
|
||||
'description' => $description,
|
||||
'context' => 'PHPCI',
|
||||
);
|
||||
|
||||
$headers = array(
|
||||
'Authorization: token ' . $token,
|
||||
'Content-Type: application/x-www-form-urlencoded'
|
||||
);
|
||||
);
|
||||
|
||||
$http->setHeaders($headers);
|
||||
$http->request('POST', $url, json_encode($params));
|
||||
|
@ -105,10 +118,14 @@ class GithubBuild extends RemoteGitBuild
|
|||
{
|
||||
$rtn = parent::getCommitMessage($this->data['commit_message']);
|
||||
|
||||
$reference = $this->getProject()->getReference();
|
||||
$commitLink = '<a target="_blank" href="https://github.com/' . $reference . '/issues/$1">#$1</a>';
|
||||
$rtn = preg_replace('/\#([0-9]+)/', $commitLink, $rtn);
|
||||
$rtn = preg_replace('/\@([a-zA-Z0-9_]+)/', '<a target="_blank" href="https://github.com/$1">@$1</a>', $rtn);
|
||||
$project = $this->getProject();
|
||||
|
||||
if (!is_null($project)) {
|
||||
$reference = $project->getReference();
|
||||
$commitLink = '<a target="_blank" href="https://github.com/' . $reference . '/issues/$1">#$1</a>';
|
||||
$rtn = preg_replace('/\#([0-9]+)/', $commitLink, $rtn);
|
||||
$rtn = preg_replace('/\@([a-zA-Z0-9_]+)/', '<a target="_blank" href="https://github.com/$1">@$1</a>', $rtn);
|
||||
}
|
||||
|
||||
return $rtn;
|
||||
}
|
||||
|
@ -134,7 +151,7 @@ class GithubBuild extends RemoteGitBuild
|
|||
$link = 'https://github.com/' . $reference . '/';
|
||||
$link .= 'blob/' . $branch . '/';
|
||||
$link .= '{FILE}';
|
||||
$link .= '#L{LINE}';
|
||||
$link .= '#L{LINE}-L{LINE_END}';
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
@ -173,9 +190,16 @@ class GithubBuild extends RemoteGitBuild
|
|||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function reportError(Builder $builder, $file, $line, $message)
|
||||
{
|
||||
$diffLineNumber = $this->getDiffLineNumber($builder, $file, $line);
|
||||
public function reportError(
|
||||
Builder $builder,
|
||||
$plugin,
|
||||
$message,
|
||||
$severity = BuildError::SEVERITY_NORMAL,
|
||||
$file = null,
|
||||
$lineStart = null,
|
||||
$lineEnd = null
|
||||
) {
|
||||
$diffLineNumber = $this->getDiffLineNumber($builder, $file, $lineStart);
|
||||
|
||||
if (!is_null($diffLineNumber)) {
|
||||
$helper = new Github();
|
||||
|
@ -190,6 +214,8 @@ class GithubBuild extends RemoteGitBuild
|
|||
$helper->createCommitComment($repo, $commit, $file, $diffLineNumber, $message);
|
||||
}
|
||||
}
|
||||
|
||||
return parent::reportError($builder, $plugin, $message, $severity, $file, $lineStart, $lineEnd);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -201,6 +227,8 @@ class GithubBuild extends RemoteGitBuild
|
|||
*/
|
||||
protected function getDiffLineNumber(Builder $builder, $file, $line)
|
||||
{
|
||||
$line = (integer)$line;
|
||||
|
||||
$builder->logExecOutput(false);
|
||||
|
||||
$prNumber = $this->getExtra('pull_request_number');
|
||||
|
@ -221,6 +249,6 @@ class GithubBuild extends RemoteGitBuild
|
|||
$helper = new Diff();
|
||||
$lines = $helper->getLinePositions($diff);
|
||||
|
||||
return $lines[$line];
|
||||
return isset($lines[$line]) ? $lines[$line] : null;
|
||||
}
|
||||
}
|
||||
|
|
63
PHPCI/Model/BuildError.php
Normal file
63
PHPCI/Model/BuildError.php
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* BuildError model for table: build_error
|
||||
*/
|
||||
|
||||
namespace PHPCI\Model;
|
||||
|
||||
use PHPCI\Model\Base\BuildErrorBase;
|
||||
|
||||
/**
|
||||
* BuildError Model
|
||||
* @uses PHPCI\Model\Base\BuildErrorBase
|
||||
*/
|
||||
class BuildError extends BuildErrorBase
|
||||
{
|
||||
const SEVERITY_CRITICAL = 0;
|
||||
const SEVERITY_HIGH = 1;
|
||||
const SEVERITY_NORMAL = 2;
|
||||
const SEVERITY_LOW = 3;
|
||||
|
||||
/**
|
||||
* Get the language string key for this error's severity level.
|
||||
* @return string
|
||||
*/
|
||||
public function getSeverityString()
|
||||
{
|
||||
switch ($this->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';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -50,6 +50,29 @@ 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
|
||||
|
@ -73,7 +96,7 @@ class Project extends ProjectBase
|
|||
$info = $this->data['access_information'];
|
||||
|
||||
// Handle old-format (serialized) access information first:
|
||||
if (!empty($info) && substr($info, 0, 1) != '{') {
|
||||
if (!empty($info) && !in_array(substr($info, 0, 1), array('{', '['))) {
|
||||
$data = unserialize($info);
|
||||
} else {
|
||||
$data = json_decode($info, true);
|
||||
|
|
18
PHPCI/Model/ProjectGroup.php
Normal file
18
PHPCI/Model/ProjectGroup.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* ProjectGroup model for table: project_group
|
||||
*/
|
||||
|
||||
namespace PHPCI\Model;
|
||||
|
||||
use PHPCI\Model\Base\ProjectGroupBase;
|
||||
|
||||
/**
|
||||
* ProjectGroup Model
|
||||
* @uses PHPCI\Model\Base\ProjectGroupBase
|
||||
*/
|
||||
class ProjectGroup extends ProjectGroupBase
|
||||
{
|
||||
// This class has been left blank so that you can modify it - changes in this file will not be overwritten.
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -10,13 +10,10 @@
|
|||
namespace PHPCI;
|
||||
|
||||
/**
|
||||
* PHPCI Plugin Interface - Used by all build plugins.
|
||||
*
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @deprecated 1.8 Only for backward compatibility
|
||||
* @see PluginInterface
|
||||
*/
|
||||
interface Plugin extends PluginInterface
|
||||
* PHPCI Plugin Interface - Used by all build plugins.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
*/
|
||||
interface Plugin
|
||||
{
|
||||
|
||||
public function execute();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,20 +12,12 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI\Builder;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* Atoum plugin
|
||||
*
|
||||
* Runs Atoum tests within a project.
|
||||
*
|
||||
* @author Sanpi <sanpi@homecomputing.fr>
|
||||
* @author André Cianfarani <acianfa@gmail.com>
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
* Atoum plugin, runs Atoum tests within a project.
|
||||
* @package PHPCI\Plugin
|
||||
*/
|
||||
class Atoum implements PluginInterface
|
||||
class Atoum implements \PHPCI\Plugin
|
||||
{
|
||||
private $args;
|
||||
private $config;
|
||||
|
@ -33,7 +25,6 @@ class Atoum implements PluginInterface
|
|||
|
||||
/**
|
||||
* Set up the plugin, configure options, etc.
|
||||
*
|
||||
* @param Builder $phpci
|
||||
* @param Build $build
|
||||
* @param array $options
|
||||
|
@ -63,7 +54,8 @@ class Atoum implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Run the Atoum plugin.
|
||||
* @return bool
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
|
@ -92,7 +84,7 @@ class Atoum implements PluginInterface
|
|||
$status = false;
|
||||
$this->phpci->log(Lang::get('no_tests_performed'));
|
||||
}
|
||||
|
||||
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,16 +12,15 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI\Builder;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
use PHPCI\Model\BuildError;
|
||||
|
||||
/**
|
||||
* Behat BDD Plugin
|
||||
*
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Behat implements PluginInterface
|
||||
class Behat implements \PHPCI\Plugin
|
||||
{
|
||||
protected $phpci;
|
||||
protected $build;
|
||||
|
@ -57,7 +56,7 @@ class Behat implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Runs Behat tests.
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
|
@ -121,7 +120,14 @@ class Behat implements PluginInterface
|
|||
'line' => $lineParts[1]
|
||||
);
|
||||
|
||||
$this->build->reportError($this->phpci, $lineParts[0], $lineParts[1], 'Behat scenario failed.');
|
||||
$this->build->reportError(
|
||||
$this->phpci,
|
||||
'behat',
|
||||
'Behat scenario failed.',
|
||||
BuildError::SEVERITY_HIGH,
|
||||
$lineParts[0],
|
||||
$lineParts[1]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,18 +12,15 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI\Builder;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* Campfire Plugin
|
||||
*
|
||||
* Allows Campfire API actions, strongly based on icecube (http://labs.mimmin.com/icecube)
|
||||
*
|
||||
* Campfire Plugin - Allows Campfire API actions.
|
||||
* strongly based on icecube (http://labs.mimmin.com/icecube)
|
||||
* @author André Cianfarani <acianfa@gmail.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Campfire implements PluginInterface
|
||||
class Campfire implements \PHPCI\Plugin
|
||||
{
|
||||
private $url;
|
||||
private $authToken;
|
||||
|
@ -34,7 +31,6 @@ class Campfire implements PluginInterface
|
|||
|
||||
/**
|
||||
* Set up the plugin, configure options, etc.
|
||||
*
|
||||
* @param Builder $phpci
|
||||
* @param Build $build
|
||||
* @param array $options
|
||||
|
@ -42,19 +38,19 @@ class Campfire implements PluginInterface
|
|||
*/
|
||||
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'));
|
||||
}
|
||||
|
@ -62,11 +58,12 @@ class Campfire implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Run the Campfire plugin.
|
||||
* @return bool|mixed
|
||||
*/
|
||||
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);
|
||||
|
@ -104,6 +101,7 @@ class Campfire implements PluginInterface
|
|||
public function speak($message, $roomId, $isPaste = false)
|
||||
{
|
||||
$page = '/room/'.$roomId.'/speak.json';
|
||||
|
||||
if ($isPaste) {
|
||||
$type = 'PasteMessage';
|
||||
} else {
|
||||
|
@ -146,10 +144,12 @@ class Campfire implements PluginInterface
|
|||
|
||||
// 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;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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,19 +11,15 @@ namespace PHPCI\Plugin;
|
|||
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* Clean build Plugin
|
||||
*
|
||||
* Removes Composer related files and allows PHPCI users to clean up their build
|
||||
* directory. Useful as a precursor to copy_build.
|
||||
*
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class CleanBuild implements PluginInterface
|
||||
* Clean build removes Composer related files and allows PHPCI users to clean up their build directory.
|
||||
* Useful as a precursor to copy_build.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class CleanBuild implements \PHPCI\Plugin
|
||||
{
|
||||
protected $remove;
|
||||
protected $phpci;
|
||||
|
@ -43,14 +39,14 @@ class CleanBuild implements PluginInterface
|
|||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
*/
|
||||
* Executes Composer and runs a specified command (e.g. install / update)
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$cmd = 'rm -Rf "%s"';
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -14,21 +14,16 @@ use PHPCI\Helper\Lang;
|
|||
use PHPCI\Model\Build;
|
||||
use PHPCI\Plugin\Util\TestResultParsers\Codeception as Parser;
|
||||
use Psr\Log\LogLevel;
|
||||
use PHPCI\PluginInterface;
|
||||
use PHPCI\PluginZeroConfigInterface;
|
||||
|
||||
/**
|
||||
* Codeception Plugin
|
||||
*
|
||||
* Enables full acceptance, unit, and functional testing.
|
||||
*
|
||||
* Codeception Plugin - Enables full acceptance, unit, and functional testing.
|
||||
* @author Don Gilbert <don@dongilbert.net>
|
||||
* @author Igor Timoshenko <contact@igortimoshenko.com>
|
||||
* @author Adam Cooper <adam@networkpie.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Codeception implements PluginInterface, PluginZeroConfigInterface
|
||||
class Codeception implements \PHPCI\Plugin, \PHPCI\ZeroConfigPlugin
|
||||
{
|
||||
/** @var string */
|
||||
protected $args = '';
|
||||
|
@ -50,22 +45,19 @@ class Codeception implements PluginInterface, PluginZeroConfigInterface
|
|||
protected $path;
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* @param $stage
|
||||
* @param Builder $builder
|
||||
* @param Build $build
|
||||
* @return bool
|
||||
*/
|
||||
public static function canExecute($stage, Builder $builder, Build $build)
|
||||
{
|
||||
if ($stage == 'test' && !is_null(self::findConfigFile($builder->buildPath))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
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)
|
||||
|
@ -83,7 +75,6 @@ class Codeception implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
/**
|
||||
* Set up the plugin, configure options, etc.
|
||||
*
|
||||
* @param Builder $phpci
|
||||
* @param Build $build
|
||||
* @param array $options
|
||||
|
@ -92,12 +83,11 @@ class Codeception implements PluginInterface, PluginZeroConfigInterface
|
|||
{
|
||||
$this->phpci = $phpci;
|
||||
$this->build = $build;
|
||||
$this->path = 'tests/';
|
||||
$this->path = 'tests' . DIRECTORY_SEPARATOR . '_output' . DIRECTORY_SEPARATOR;
|
||||
|
||||
if (empty($options['config'])) {
|
||||
$this->ymlConfigFile = self::findConfigFile($this->phpci->buildPath);
|
||||
}
|
||||
if (isset($options['config'])) {
|
||||
} else {
|
||||
$this->ymlConfigFile = $options['config'];
|
||||
}
|
||||
if (isset($options['args'])) {
|
||||
|
@ -109,82 +99,65 @@ class Codeception implements PluginInterface, PluginZeroConfigInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Runs Codeception tests
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
if (empty($this->ymlConfigFile)) {
|
||||
$this->phpci->logFailure('No configuration file found');
|
||||
return false;
|
||||
throw new \Exception("No configuration file found");
|
||||
}
|
||||
|
||||
$success = true;
|
||||
|
||||
// Run any config files first. This can be either a single value or an array.
|
||||
$success &= $this->runConfigFile($this->ymlConfigFile);
|
||||
|
||||
return $success;
|
||||
return $this->runConfigFile($this->ymlConfigFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run tests from a Codeception config file.
|
||||
*
|
||||
* @param $configPath
|
||||
*
|
||||
* @return bool|mixed
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function runConfigFile($configPath)
|
||||
{
|
||||
if (is_array($configPath)) {
|
||||
return $this->recurseArg($configPath, array($this, 'runConfigFile'));
|
||||
} else {
|
||||
$this->phpci->logExecOutput(false);
|
||||
$this->phpci->logExecOutput(false);
|
||||
|
||||
$codecept = $this->phpci->findBinary('codecept');
|
||||
$codecept = $this->phpci->findBinary('codecept');
|
||||
|
||||
if (!$codecept) {
|
||||
$this->phpci->logFailure(Lang::get('could_not_find', 'codecept'));
|
||||
if (!$codecept) {
|
||||
$this->phpci->logFailure(Lang::get('could_not_find', 'codecept'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$cmd = 'cd "%s" && ' . $codecept . ' run -c "%s" --xml ' . $this->args;
|
||||
if (IS_WIN) {
|
||||
$cmd = 'cd /d "%s" && ' . $codecept . ' run -c "%s" --xml ' . $this->args;
|
||||
}
|
||||
|
||||
$configPath = $this->phpci->buildPath . $configPath;
|
||||
$success = $this->phpci->executeCommand($cmd, $this->phpci->buildPath, $configPath);
|
||||
|
||||
|
||||
$this->phpci->log(
|
||||
'Codeception XML path: '. $this->phpci->buildPath . $this->path . '_output/report.xml',
|
||||
Loglevel::DEBUG
|
||||
);
|
||||
$xml = file_get_contents($this->phpci->buildPath . $this->path . '_output/report.xml', false);
|
||||
|
||||
try {
|
||||
$parser = new Parser($this->phpci, $xml);
|
||||
$output = $parser->parse();
|
||||
} catch (\Exception $ex) {
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
$meta = array(
|
||||
'tests' => $parser->getTotalTests(),
|
||||
'timetaken' => $parser->getTotalTimeTaken(),
|
||||
'failures' => $parser->getTotalFailures()
|
||||
);
|
||||
|
||||
$this->build->storeMeta('codeception-meta', $meta);
|
||||
$this->build->storeMeta('codeception-data', $output);
|
||||
$this->build->storeMeta('codeception-errors', $parser->getTotalFailures());
|
||||
|
||||
$this->phpci->logExecOutput(true);
|
||||
|
||||
return $success;
|
||||
return false;
|
||||
}
|
||||
|
||||
$cmd = 'cd "%s" && ' . $codecept . ' run -c "%s" --xml ' . $this->args;
|
||||
|
||||
if (IS_WIN) {
|
||||
$cmd = 'cd /d "%s" && ' . $codecept . ' run -c "%s" --xml ' . $this->args;
|
||||
}
|
||||
|
||||
$configPath = $this->phpci->buildPath . $configPath;
|
||||
$success = $this->phpci->executeCommand($cmd, $this->phpci->buildPath, $configPath);
|
||||
|
||||
$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-data', $output);
|
||||
$this->build->storeMeta('codeception-errors', $parser->getTotalFailures());
|
||||
$this->phpci->logExecOutput(true);
|
||||
|
||||
return $success;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -13,32 +13,32 @@ use PHPCI;
|
|||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\PluginInterface;
|
||||
use PHPCI\PluginZeroConfigInterface;
|
||||
|
||||
/**
|
||||
* Composer Plugin
|
||||
*
|
||||
* Provides access to Composer functionality.
|
||||
*
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Composer implements PluginInterface, PluginZeroConfigInterface
|
||||
* Composer Plugin - Provides access to Composer functionality.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Composer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
|
||||
{
|
||||
protected $directory;
|
||||
protected $action;
|
||||
protected $preferDist;
|
||||
protected $phpci;
|
||||
protected $build;
|
||||
protected $nodev;
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Check if this plugin can be executed.
|
||||
* @param $stage
|
||||
* @param Builder $builder
|
||||
* @param Build $build
|
||||
* @return bool
|
||||
*/
|
||||
public static function canExecute($stage, Builder $builder, Build $build)
|
||||
{
|
||||
$path = $builder->buildPath . '/composer.json';
|
||||
$path = $builder->buildPath . DIRECTORY_SEPARATOR . 'composer.json';
|
||||
|
||||
if (file_exists($path) && $stage == 'setup') {
|
||||
return true;
|
||||
|
@ -49,22 +49,23 @@ class Composer implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
/**
|
||||
* 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())
|
||||
{
|
||||
$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 . '/' . $options['directory'];
|
||||
$this->directory = $path . DIRECTORY_SEPARATOR . $options['directory'];
|
||||
}
|
||||
|
||||
if (array_key_exists('action', $options)) {
|
||||
|
@ -74,11 +75,20 @@ class Composer implements PluginInterface, PluginZeroConfigInterface
|
|||
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'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
*/
|
||||
* Executes Composer and runs a specified command (e.g. install / update)
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$composerLocation = $this->phpci->findBinary(array('composer', 'composer.phar'));
|
||||
|
@ -93,10 +103,17 @@ class Composer implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
if ($this->preferDist) {
|
||||
$this->phpci->log('Using --prefer-dist flag');
|
||||
$cmd .= '--prefer-dist';
|
||||
} else {
|
||||
$cmd .= ' --prefer-dist';
|
||||
}
|
||||
|
||||
if ($this->preferSource) {
|
||||
$this->phpci->log('Using --prefer-source flag');
|
||||
$cmd .= '--prefer-source';
|
||||
$cmd .= ' --prefer-source';
|
||||
}
|
||||
|
||||
if ($this->nodev) {
|
||||
$this->phpci->log('Using --no-dev flag');
|
||||
$cmd .= ' --no-dev';
|
||||
}
|
||||
|
||||
$cmd .= ' --working-dir="%s" %s';
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,18 +12,14 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* Copy Build Plugin
|
||||
*
|
||||
* Copies the entire build to another directory.
|
||||
*
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class CopyBuild implements PluginInterface
|
||||
* Copy Build Plugin - Copies the entire build to another directory.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class CopyBuild implements \PHPCI\Plugin
|
||||
{
|
||||
protected $directory;
|
||||
protected $ignore;
|
||||
|
@ -33,24 +29,23 @@ class CopyBuild implements PluginInterface
|
|||
|
||||
/**
|
||||
* 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())
|
||||
{
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
*/
|
||||
* Copies files from the root of the build directory into the target folder
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$build = $this->phpci->buildPath;
|
||||
|
@ -75,7 +70,6 @@ class CopyBuild implements PluginInterface
|
|||
|
||||
/**
|
||||
* Wipe the destination directory if it already exists.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function wipeExistingDirectory()
|
||||
|
|
73
PHPCI/Plugin/Deployer.php
Normal file
73
PHPCI/Plugin/Deployer.php
Normal file
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2015, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link https://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\Plugin;
|
||||
|
||||
use b8\HttpClient;
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
|
||||
/**
|
||||
* Integrates PHPCI with Deployer: https://github.com/rebelinblue/deployer
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @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'];
|
||||
}
|
||||
}
|
|
@ -2,30 +2,28 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
||||
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 PHPCI\PluginInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* Email Plugin
|
||||
*
|
||||
* Provides simple email capability to PHPCI.
|
||||
*
|
||||
* @author Steve Brazier <meadsteve@gmail.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Email implements PluginInterface
|
||||
* Email Plugin - Provides simple email capability to PHPCI.
|
||||
* @author Steve Brazier <meadsteve@gmail.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Email implements \PHPCI\Plugin
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Builder
|
||||
|
@ -44,7 +42,6 @@ class Email implements PluginInterface
|
|||
|
||||
/**
|
||||
* Set up the plugin, configure options, etc.
|
||||
*
|
||||
* @param Builder $phpci
|
||||
* @param Build $build
|
||||
* @param \Swift_Mailer $mailer
|
||||
|
@ -55,13 +52,13 @@ class Email implements PluginInterface
|
|||
Build $build,
|
||||
array $options = array()
|
||||
) {
|
||||
$this->phpci = $phpci;
|
||||
$this->build = $build;
|
||||
$this->options = $options;
|
||||
$this->phpci = $phpci;
|
||||
$this->build = $build;
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Send a notification mail.
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
|
@ -75,12 +72,25 @@ class Email implements PluginInterface
|
|||
|
||||
$buildStatus = $this->build->isSuccessful() ? "Passing Build" : "Failing Build";
|
||||
$projectName = $this->build->getProject()->getTitle();
|
||||
$mailTemplate = $this->build->isSuccessful() ? 'Email/success' : 'Email/failed';
|
||||
|
||||
$view = new View($mailTemplate);
|
||||
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->build = $this->build;
|
||||
$view->project = $this->build->getProject();
|
||||
$body = $view->render();
|
||||
|
||||
$layout = new View('Email/layout');
|
||||
$layout->build = $this->build;
|
||||
$layout->project = $this->build->getProject();
|
||||
$layout->content = $view->render();
|
||||
$body = $layout->render();
|
||||
|
||||
$sendFailures = $this->sendSeparateEmails(
|
||||
$addresses,
|
||||
|
@ -96,16 +106,13 @@ class Email implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* Send a mail using the specified information.
|
||||
*
|
||||
* @param string $toAddress Single address to send to
|
||||
* @param string[] $ccList List of user to CC
|
||||
* @param string $subject Email subject
|
||||
* @param string $body Email body
|
||||
*
|
||||
* @return array Array of failed addresses
|
||||
* @param string $toAddress Single address to send to
|
||||
* @param string[] $ccList
|
||||
* @param string $subject Email subject
|
||||
* @param string $body Email body
|
||||
* @return array Array of failed addresses
|
||||
*/
|
||||
public function sendEmail($toAddress, $ccList, $subject, $body)
|
||||
protected function sendEmail($toAddress, $ccList, $subject, $body)
|
||||
{
|
||||
$email = new EmailHelper();
|
||||
|
||||
|
@ -126,11 +133,14 @@ class Email implements PluginInterface
|
|||
/**
|
||||
* Send an email to a list of specified subjects.
|
||||
*
|
||||
* @param array $toAddresses List of destinatary of message.
|
||||
* @param string $subject Mail subject
|
||||
* @param string $body Mail body
|
||||
* @param array $toAddresses
|
||||
* List of destination addresses for message.
|
||||
* @param string $subject
|
||||
* Mail subject
|
||||
* @param string $body
|
||||
* Mail body
|
||||
*
|
||||
* @return int number of failed messages
|
||||
* @return int number of failed messages
|
||||
*/
|
||||
public function sendSeparateEmails(array $toAddresses, $subject, $body)
|
||||
{
|
||||
|
@ -147,7 +157,6 @@ class Email implements PluginInterface
|
|||
|
||||
/**
|
||||
* Get the list of email addresses to send to.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getEmailAddresses()
|
||||
|
@ -189,4 +198,30 @@ class Email implements PluginInterface
|
|||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,16 +12,14 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI\Builder;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* Environment variable plugin
|
||||
*
|
||||
* @author Steve Kamerman <stevekamerman@gmail.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Env implements PluginInterface
|
||||
* Environment variable plugin
|
||||
* @author Steve Kamerman <stevekamerman@gmail.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Env implements \PHPCI\Plugin
|
||||
{
|
||||
protected $phpci;
|
||||
protected $build;
|
||||
|
@ -29,7 +27,6 @@ class Env implements PluginInterface
|
|||
|
||||
/**
|
||||
* Set up the plugin, configure options, etc.
|
||||
*
|
||||
* @param Builder $phpci
|
||||
* @param Build $build
|
||||
* @param array $options
|
||||
|
@ -42,8 +39,8 @@ class Env implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
*/
|
||||
* Adds the specified environment variables to the builder environment
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$success = true;
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2015, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link https://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\Plugin\Exception;
|
||||
|
||||
use PHPCI\Plugin\Exception\PluginException;
|
||||
|
||||
class PluginBinaryNotFoundException extends PluginException
|
||||
{
|
||||
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2015, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link https://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\Plugin\Exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
class PluginException extends Exception
|
||||
{
|
||||
|
||||
}
|
73
PHPCI/Plugin/FlowdockNotify.php
Normal file
73
PHPCI/Plugin/FlowdockNotify.php
Normal file
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
* @copyright Copyright 2014, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link https://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\Plugin;
|
||||
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use Mremi\Flowdock\Api\Push\Push;
|
||||
use Mremi\Flowdock\Api\Push\TeamInboxMessage;
|
||||
|
||||
/**
|
||||
* Flowdock Plugin
|
||||
* @author Petr Cervenka <petr@nanosolutions.io>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class FlowdockNotify implements \PHPCI\Plugin
|
||||
{
|
||||
private $api_key;
|
||||
private $email;
|
||||
const MESSAGE_DEFAULT = 'Build %BUILD% has finished for commit <a href="%COMMIT_URI%">%SHORT_COMMIT%</a>
|
||||
(%COMMIT_EMAIL%)> on branch <a href="%BRANCH_URI%">%BRANCH%</a>';
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,16 +12,14 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI\Builder;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* Git plugin.
|
||||
*
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Git implements PluginInterface
|
||||
class Git implements \PHPCI\Plugin
|
||||
{
|
||||
protected $phpci;
|
||||
protected $build;
|
||||
|
@ -29,7 +27,6 @@ class Git implements PluginInterface
|
|||
|
||||
/**
|
||||
* Set up the plugin, configure options, etc.
|
||||
*
|
||||
* @param Builder $phpci
|
||||
* @param Build $build
|
||||
* @param array $options
|
||||
|
@ -42,7 +39,8 @@ class Git implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Run the Git plugin.
|
||||
* @return bool
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
|
@ -72,10 +70,8 @@ class Git implements PluginInterface
|
|||
|
||||
/**
|
||||
* Determine which action to run, and run it.
|
||||
*
|
||||
* @param $action
|
||||
* @param array $options
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function runAction($action, array $options = array())
|
||||
|
@ -100,7 +96,6 @@ class Git implements PluginInterface
|
|||
|
||||
/**
|
||||
* Handle a merge action.
|
||||
*
|
||||
* @param $options
|
||||
* @return bool
|
||||
*/
|
||||
|
@ -115,7 +110,6 @@ class Git implements PluginInterface
|
|||
|
||||
/**
|
||||
* Handle a tag action.
|
||||
*
|
||||
* @param $options
|
||||
* @return bool
|
||||
*/
|
||||
|
@ -138,7 +132,6 @@ class Git implements PluginInterface
|
|||
|
||||
/**
|
||||
* Handle a pull action.
|
||||
*
|
||||
* @param $options
|
||||
* @return bool
|
||||
*/
|
||||
|
@ -160,7 +153,6 @@ class Git implements PluginInterface
|
|||
|
||||
/**
|
||||
* Handle a push action.
|
||||
*
|
||||
* @param $options
|
||||
* @return bool
|
||||
*/
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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,18 +11,14 @@ namespace PHPCI\Plugin;
|
|||
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* Grunt Plugin
|
||||
*
|
||||
* Provides access to grunt functionality.
|
||||
*
|
||||
* @author Tobias Tom <t.tom@succont.de>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Grunt implements PluginInterface
|
||||
* Grunt Plugin - Provides access to grunt functionality.
|
||||
* @author Tobias Tom <t.tom@succont.de>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Grunt implements \PHPCI\Plugin
|
||||
{
|
||||
protected $directory;
|
||||
protected $task;
|
||||
|
@ -56,7 +52,7 @@ class Grunt implements PluginInterface
|
|||
|
||||
// Handle options:
|
||||
if (isset($options['directory'])) {
|
||||
$this->directory = $path . '/' . $options['directory'];
|
||||
$this->directory = $path . DIRECTORY_SEPARATOR . $options['directory'];
|
||||
}
|
||||
|
||||
if (isset($options['task'])) {
|
||||
|
@ -73,8 +69,8 @@ class Grunt implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
*/
|
||||
* Executes grunt and runs a specified command (e.g. install / update)
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
// if npm does not work, we cannot use grunt, so we return false
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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,18 +11,14 @@ namespace PHPCI\Plugin;
|
|||
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* Gulp Plugin
|
||||
*
|
||||
* Provides access to gulp functionality.
|
||||
*
|
||||
* @author Dirk Heilig <dirk@heilig-online.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Gulp implements PluginInterface
|
||||
* Gulp Plugin - Provides access to gulp functionality.
|
||||
* @author Dirk Heilig <dirk@heilig-online.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Gulp implements \PHPCI\Plugin
|
||||
{
|
||||
protected $directory;
|
||||
protected $task;
|
||||
|
@ -56,7 +52,7 @@ class Gulp implements PluginInterface
|
|||
|
||||
// Handle options:
|
||||
if (isset($options['directory'])) {
|
||||
$this->directory = $path . '/' . $options['directory'];
|
||||
$this->directory = $path . DIRECTORY_SEPARATOR . $options['directory'];
|
||||
}
|
||||
|
||||
if (isset($options['task'])) {
|
||||
|
@ -73,8 +69,8 @@ class Gulp implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
*/
|
||||
* Executes gulp and runs a specified command (e.g. install / update)
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
// if npm does not work, we cannot use gulp, so we return false
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,18 +12,14 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI\Builder;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* Hipchat Plugin.
|
||||
*
|
||||
* Send build notification in HipChat.
|
||||
*
|
||||
* Hipchat Plugin
|
||||
* @author James Inman <james@jamesinman.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class HipchatNotify implements PluginInterface
|
||||
class HipchatNotify implements \PHPCI\Plugin
|
||||
{
|
||||
protected $authToken;
|
||||
protected $color;
|
||||
|
@ -31,11 +27,9 @@ class HipchatNotify implements PluginInterface
|
|||
|
||||
/**
|
||||
* 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())
|
||||
|
@ -74,7 +68,8 @@ class HipchatNotify implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Run the HipChat plugin.
|
||||
* @return bool
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,18 +12,14 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI\Builder;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* IRC Plugin
|
||||
*
|
||||
* Sends a notification to an IRC channel.
|
||||
*
|
||||
* IRC Plugin - Sends a notification to an IRC channel
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Irc implements PluginInterface
|
||||
class Irc implements \PHPCI\Plugin
|
||||
{
|
||||
protected $phpci;
|
||||
protected $build;
|
||||
|
@ -65,7 +61,8 @@ class Irc implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Run IRC plugin.
|
||||
* @return bool
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
|
@ -96,11 +93,8 @@ class Irc implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* Execute a list of IRC commands.
|
||||
*
|
||||
* @param resource $socket
|
||||
* @param array $commands
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function executeIrcCommands($socket, array $commands)
|
||||
|
@ -126,11 +120,9 @@ class Irc implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* Execute a single IRC command.
|
||||
*
|
||||
* @param resource $socket
|
||||
* @param string $command
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function executeIrcCommand($socket, $command)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,18 +12,14 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI;
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* PHP Lint Plugin
|
||||
*
|
||||
* Provides access to PHP lint functionality.
|
||||
*
|
||||
* PHP Lint Plugin - Provides access to PHP lint functionality.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Lint implements PluginInterface
|
||||
class Lint implements PHPCI\Plugin
|
||||
{
|
||||
protected $directories;
|
||||
protected $recursive = true;
|
||||
|
@ -45,9 +41,9 @@ class Lint implements PluginInterface
|
|||
*/
|
||||
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'])) {
|
||||
|
@ -64,7 +60,7 @@ class Lint implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Executes parallel lint
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
|
@ -86,11 +82,9 @@ class Lint implements PluginInterface
|
|||
|
||||
/**
|
||||
* Lint an item (file or directory) by calling the appropriate method.
|
||||
*
|
||||
* @param $php
|
||||
* @param $item
|
||||
* @param $itemPath
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function lintItem($php, $item, $itemPath)
|
||||
|
@ -99,7 +93,7 @@ class Lint implements PluginInterface
|
|||
|
||||
if ($item->isFile() && $item->getExtension() == 'php' && !$this->lintFile($php, $itemPath)) {
|
||||
$success = false;
|
||||
} elseif ($item->isDir() && $this->recursive && !$this->lintDirectory($php, $itemPath . '/')) {
|
||||
} elseif ($item->isDir() && $this->recursive && !$this->lintDirectory($php, $itemPath . DIRECTORY_SEPARATOR)) {
|
||||
$success = false;
|
||||
}
|
||||
|
||||
|
@ -108,10 +102,8 @@ class Lint implements PluginInterface
|
|||
|
||||
/**
|
||||
* Run php -l against a directory of files.
|
||||
*
|
||||
* @param $php
|
||||
* @param $path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function lintDirectory($php, $path)
|
||||
|
@ -140,10 +132,8 @@ class Lint implements PluginInterface
|
|||
|
||||
/**
|
||||
* Run php -l against a specific file.
|
||||
*
|
||||
* @param $php
|
||||
* @param $path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function lintFile($php, $path)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -13,19 +13,15 @@ use PDO;
|
|||
use PHPCI\Builder;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* MySQL Plugin
|
||||
*
|
||||
* Provides access to a MySQL database.
|
||||
*
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @author Steve Kamerman <stevekamerman@gmail.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Mysql implements PluginInterface
|
||||
* MySQL Plugin - Provides access to a MySQL database.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @author Steve Kamerman <stevekamerman@gmail.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Mysql implements \PHPCI\Plugin
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Builder
|
||||
|
@ -95,8 +91,9 @@ class Mysql implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
*/
|
||||
* Connects to MySQL and runs a specified set of queries.
|
||||
* @return boolean
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
try {
|
||||
|
@ -123,9 +120,7 @@ class Mysql implements PluginInterface
|
|||
|
||||
/**
|
||||
* @param string $query
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function executeFile($query)
|
||||
|
@ -151,10 +146,8 @@ class Mysql implements PluginInterface
|
|||
|
||||
/**
|
||||
* Builds the MySQL import command required to import/execute the specified file
|
||||
*
|
||||
* @param string $import_file Path to file, relative to the build root
|
||||
* @param string $database If specified, this database is selected before execution
|
||||
*
|
||||
* @param string $database If specified, this database is selected before execution
|
||||
* @return string
|
||||
*/
|
||||
protected function getImportCommand($import_file, $database = null)
|
||||
|
@ -173,10 +166,11 @@ class Mysql implements PluginInterface
|
|||
$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 -u:user -p:pass :database', $args);
|
||||
return strtr('cat :import_file :decomp_cmd | mysql -h:host -u:user -p:pass :database', $args);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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,16 +11,14 @@ namespace PHPCI\Plugin;
|
|||
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* Create a ZIP or TAR.GZ archive of the entire build.
|
||||
*
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PackageBuild implements PluginInterface
|
||||
* Create a ZIP or TAR.GZ archive of the entire build.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PackageBuild implements \PHPCI\Plugin
|
||||
{
|
||||
protected $directory;
|
||||
protected $filename;
|
||||
|
@ -29,27 +27,26 @@ class PackageBuild implements PluginInterface
|
|||
|
||||
/**
|
||||
* 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())
|
||||
{
|
||||
$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';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
*/
|
||||
* Executes Composer and runs a specified command (e.g. install / update)
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$path = $this->phpci->buildPath;
|
||||
$path = $this->phpci->buildPath;
|
||||
$build = $this->build;
|
||||
|
||||
if ($this->directory == $path) {
|
||||
|
@ -72,8 +69,7 @@ class PackageBuild implements PluginInterface
|
|||
}
|
||||
|
||||
foreach ($this->format as $format) {
|
||||
switch($format)
|
||||
{
|
||||
switch ($format) {
|
||||
case 'tar':
|
||||
$cmd = 'tar cfz "%s/%s.tar.gz" ./*';
|
||||
break;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,18 +12,14 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI\Builder;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* Pdepend Plugin
|
||||
*
|
||||
* Allows Pdepend report
|
||||
*
|
||||
* Pdepend Plugin - Allows Pdepend report
|
||||
* @author Johan van der Heide <info@japaveh.nl>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Pdepend implements PluginInterface
|
||||
class Pdepend implements \PHPCI\Plugin
|
||||
{
|
||||
protected $args;
|
||||
/**
|
||||
|
@ -54,7 +50,6 @@ class Pdepend implements PluginInterface
|
|||
|
||||
/**
|
||||
* Set up the plugin, configure options, etc.
|
||||
*
|
||||
* @param Builder $phpci
|
||||
* @param Build $build
|
||||
* @param array $options
|
||||
|
@ -74,12 +69,15 @@ class Pdepend implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Runs Pdepend with the given criteria as arguments
|
||||
*/
|
||||
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.', $this->location));
|
||||
throw new \Exception(sprintf('The location %s is not writable or does not exist.', $this->location));
|
||||
}
|
||||
|
||||
$pdepend = $this->phpci->findBinary('pdepend');
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,18 +12,14 @@ namespace PHPCI\Plugin;
|
|||
use PDO;
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* PgSQL Plugin
|
||||
*
|
||||
* Provides access to a PgSQL database.
|
||||
*
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Pgsql implements PluginInterface
|
||||
* PgSQL Plugin - Provides access to a PgSQL database.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Pgsql implements \PHPCI\Plugin
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Builder
|
||||
|
@ -77,7 +73,8 @@ class Pgsql implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Connects to PgSQL and runs a specified set of queries.
|
||||
* @return boolean
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
|
|
|
@ -1,31 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 2015, Block 8 Limited.
|
||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||
* @link https://www.phptesting.org/
|
||||
*/
|
||||
|
||||
namespace PHPCI\Plugin;
|
||||
|
||||
use Exception;
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
use Phar as PHPPhar;
|
||||
|
||||
/**
|
||||
* Phar Plugin
|
||||
*
|
||||
* Plugin to generate php package using phar format.
|
||||
*
|
||||
* @author Wanderson <wandersonwhcr@gmail.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Phar implements PluginInterface
|
||||
class Phar implements \PHPCI\Plugin
|
||||
{
|
||||
/**
|
||||
* PHPCI
|
||||
|
@ -126,7 +111,6 @@ class Phar implements PluginInterface
|
|||
* Directory Setter
|
||||
*
|
||||
* @param string $directory Configuration Value
|
||||
*
|
||||
* @return Phar Fluent Interface
|
||||
*/
|
||||
public function setDirectory($directory)
|
||||
|
@ -152,7 +136,6 @@ class Phar implements PluginInterface
|
|||
* Filename Setter
|
||||
*
|
||||
* @param string $filename Configuration Value
|
||||
*
|
||||
* @return Phar Fluent Interface
|
||||
*/
|
||||
public function setFilename($filename)
|
||||
|
@ -178,7 +161,6 @@ class Phar implements PluginInterface
|
|||
* Regular Expression Setter
|
||||
*
|
||||
* @param string $regexp Configuration Value
|
||||
*
|
||||
* @return Phar Fluent Interface
|
||||
*/
|
||||
public function setRegExp($regexp)
|
||||
|
@ -204,7 +186,6 @@ class Phar implements PluginInterface
|
|||
* Stub Filename Setter
|
||||
*
|
||||
* @param string $stub Configuration Value
|
||||
*
|
||||
* @return Phar Fluent Interface
|
||||
*/
|
||||
public function setStub($stub)
|
||||
|
@ -225,7 +206,6 @@ class Phar implements PluginInterface
|
|||
|
||||
/**
|
||||
* Get stub content for the Phar file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getStubContent()
|
||||
|
@ -233,20 +213,22 @@ class Phar implements PluginInterface
|
|||
$content = '';
|
||||
$filename = $this->getStub();
|
||||
if ($filename) {
|
||||
$content = file_get_contents($this->getPHPCI()->buildPath . '/' . $this->getStub());
|
||||
$content = file_get_contents($this->getPHPCI()->buildPath . DIRECTORY_SEPARATOR . $this->getStub());
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Run the phar plugin.
|
||||
* @return bool
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$success = false;
|
||||
|
||||
try {
|
||||
$phar = new PHPPhar($this->getDirectory() . '/' . $this->getFilename(), 0, $this->getFilename());
|
||||
$file = $this->getDirectory() . DIRECTORY_SEPARATOR . $this->getFilename();
|
||||
$phar = new PHPPhar($file, 0, $this->getFilename());
|
||||
$phar->buildFromDirectory($this->getPHPCI()->buildPath, $this->getRegExp());
|
||||
|
||||
$stub = $this->getStubContent();
|
||||
|
@ -255,7 +237,6 @@ class Phar implements PluginInterface
|
|||
}
|
||||
|
||||
$success = true;
|
||||
|
||||
} catch (Exception $e) {
|
||||
$this->getPHPCI()->log(Lang::get('phar_internal_error'));
|
||||
$this->getPHPCI()->log($e->getMessage());
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,18 +12,15 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI\Builder;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* Phing Plugin
|
||||
*
|
||||
* Provides access to Phing functionality.
|
||||
* Phing Plugin - Provides access to Phing functionality.
|
||||
*
|
||||
* @author Pavel Pavlov <ppavlov@alera.ru>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Phing implements PluginInterface
|
||||
class Phing implements \PHPCI\Plugin
|
||||
{
|
||||
|
||||
private $directory;
|
||||
|
@ -37,7 +34,6 @@ class Phing implements PluginInterface
|
|||
|
||||
/**
|
||||
* Set up the plugin, configure options, etc.
|
||||
*
|
||||
* @param Builder $phpci
|
||||
* @param Build $build
|
||||
* @param array $options
|
||||
|
@ -47,16 +43,20 @@ class Phing implements PluginInterface
|
|||
$this->setPhpci($phpci);
|
||||
$this->build = $build;
|
||||
|
||||
// Set working directory
|
||||
/*
|
||||
* Set working directory
|
||||
*/
|
||||
if (isset($options['directory'])) {
|
||||
$directory = $phpci->buildPath . '/' . $options['directory'];
|
||||
$directory = $phpci->buildPath . DIRECTORY_SEPARATOR . $options['directory'];
|
||||
} else {
|
||||
$directory = $phpci->buildPath;
|
||||
}
|
||||
|
||||
$this->setDirectory($directory);
|
||||
|
||||
// Set name of a non default build file
|
||||
/*
|
||||
* Sen name of a non default build file
|
||||
*/
|
||||
if (isset($options['build_file'])) {
|
||||
$this->setBuildFile($options['build_file']);
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ class Phing implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Executes Phing and runs a specified targets
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
|
@ -97,7 +97,7 @@ class Phing implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @return Builder
|
||||
* @return \PHPCI\Builder
|
||||
*/
|
||||
public function getPhpci()
|
||||
{
|
||||
|
@ -105,7 +105,7 @@ class Phing implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Builder $phpci
|
||||
* @param \PHPCI\Builder $phpci
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
|
@ -142,7 +142,6 @@ class Phing implements PluginInterface
|
|||
|
||||
/**
|
||||
* Converts an array of targets into a string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function targetsToString()
|
||||
|
@ -176,7 +175,6 @@ class Phing implements PluginInterface
|
|||
* @param mixed $buildFile
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function setBuildFile($buildFile)
|
||||
|
@ -190,7 +188,6 @@ class Phing implements PluginInterface
|
|||
|
||||
/**
|
||||
* Get phing build file path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBuildFilePath()
|
||||
|
@ -211,8 +208,10 @@ class Phing implements PluginInterface
|
|||
*/
|
||||
public function propertiesToString()
|
||||
{
|
||||
// Fix the problem when execute phing out of the build dir
|
||||
// @ticket 748
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
@ -252,12 +251,11 @@ class Phing implements PluginInterface
|
|||
* @param string $propertyFile
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function setPropertyFile($propertyFile)
|
||||
{
|
||||
if (!file_exists($this->getDirectory() . '/' . $propertyFile)) {
|
||||
if (!file_exists($this->getDirectory() . DIRECTORY_SEPARATOR . $propertyFile)) {
|
||||
throw new \Exception(Lang::get('property_file_missing'));
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,19 +12,15 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI;
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
use PHPCI\PluginZeroConfigInterface;
|
||||
use PHPCI\Model\BuildError;
|
||||
|
||||
/**
|
||||
* PHP Code Sniffer Plugin
|
||||
*
|
||||
* Allows PHP Code Sniffer testing.
|
||||
*
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpCodeSniffer implements PluginInterface, PluginZeroConfigInterface
|
||||
* PHP Code Sniffer Plugin - Allows PHP Code Sniffer testing.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpCodeSniffer implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Builder
|
||||
|
@ -78,7 +74,11 @@ class PhpCodeSniffer implements PluginInterface, PluginZeroConfigInterface
|
|||
protected $ignore;
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Check if this plugin can be executed.
|
||||
* @param $stage
|
||||
* @param Builder $builder
|
||||
* @param Build $build
|
||||
* @return bool
|
||||
*/
|
||||
public static function canExecute($stage, Builder $builder, Build $build)
|
||||
{
|
||||
|
@ -130,7 +130,6 @@ class PhpCodeSniffer implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
/**
|
||||
* Handle this plugin's options.
|
||||
*
|
||||
* @param $options
|
||||
*/
|
||||
protected function setOptions($options)
|
||||
|
@ -143,8 +142,8 @@ class PhpCodeSniffer implements PluginInterface, PluginZeroConfigInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
*/
|
||||
* Runs PHP Code Sniffer in a specified directory, to a specified standard.
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
list($ignore, $standard, $suffixes) = $this->getFlags();
|
||||
|
@ -165,14 +164,13 @@ class PhpCodeSniffer implements PluginInterface, PluginZeroConfigInterface
|
|||
);
|
||||
|
||||
$output = $this->phpci->getLastOutput();
|
||||
list($errors, $warnings, $data) = $this->processReport($output);
|
||||
list($errors, $warnings) = $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;
|
||||
|
@ -187,7 +185,6 @@ class PhpCodeSniffer implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
/**
|
||||
* Process options and produce an arguments string for PHPCS.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getFlags()
|
||||
|
@ -213,11 +210,8 @@ class PhpCodeSniffer implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
/**
|
||||
* Process the PHPCS output report.
|
||||
*
|
||||
* @param $output
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function processReport($output)
|
||||
|
@ -232,23 +226,21 @@ class PhpCodeSniffer implements PluginInterface, PluginZeroConfigInterface
|
|||
$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, $fileName, $message['line'], 'PHPCS: ' . $message['message']);
|
||||
|
||||
$rtn[] = array(
|
||||
'file' => $fileName,
|
||||
'line' => $message['line'],
|
||||
'type' => $message['type'],
|
||||
'message' => $message['message'],
|
||||
$this->build->reportError(
|
||||
$this->phpci,
|
||||
'php_code_sniffer',
|
||||
'PHPCS: ' . $message['message'],
|
||||
$message['type'] == 'ERROR' ? BuildError::SEVERITY_HIGH : BuildError::SEVERITY_LOW,
|
||||
$fileName,
|
||||
$message['line']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return array($errors, $warnings, $rtn);
|
||||
return array($errors, $warnings);
|
||||
}
|
||||
}
|
||||
|
|
63
PHPCI/Plugin/PhpCpd.php
Normal file → Executable file
63
PHPCI/Plugin/PhpCpd.php
Normal file → Executable file
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,18 +12,15 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI\Builder;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
use PHPCI\Model\BuildError;
|
||||
|
||||
/**
|
||||
* PHP Copy / Paste Detector.
|
||||
*
|
||||
* Allows PHP Copy / Paste Detector testing.
|
||||
*
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpCpd implements PluginInterface
|
||||
* PHP Copy / Paste Detector - Allows PHP Copy / Paste Detector testing.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpCpd implements \PHPCI\Plugin
|
||||
{
|
||||
protected $directory;
|
||||
protected $args;
|
||||
|
@ -32,7 +29,7 @@ class PhpCpd implements PluginInterface
|
|||
|
||||
/**
|
||||
* @var string, based on the assumption the root may not hold the code to be
|
||||
* tested, exteds the base path
|
||||
* tested, extends the base path
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
|
@ -43,7 +40,6 @@ class PhpCpd implements PluginInterface
|
|||
|
||||
/**
|
||||
* Set up the plugin, configure options, etc.
|
||||
*
|
||||
* @param Builder $phpci
|
||||
* @param Build $build
|
||||
* @param array $options
|
||||
|
@ -54,34 +50,29 @@ class PhpCpd implements PluginInterface
|
|||
$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'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
*/
|
||||
* Runs PHP Copy/Paste Detector in a specified directory.
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$ignore = '';
|
||||
if (count($this->ignore)) {
|
||||
$map = function ($item) {
|
||||
// remove the trailing slash
|
||||
$item = (substr($item, -1) == '/' ? substr($item, 0, -1) : $item);
|
||||
$item = rtrim($item, DIRECTORY_SEPARATOR);
|
||||
|
||||
if (is_file($this->path . '/' . $item)) {
|
||||
if (is_file(rtrim($this->path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $item)) {
|
||||
return ' --names-exclude ' . $item;
|
||||
} else {
|
||||
return ' --exclude ' . $item;
|
||||
|
@ -102,9 +93,8 @@ class PhpCpd implements PluginInterface
|
|||
|
||||
print $this->phpci->getLastOutput();
|
||||
|
||||
list($errorCount, $data) = $this->processReport(file_get_contents($tmpfilename));
|
||||
$errorCount = $this->processReport(file_get_contents($tmpfilename));
|
||||
$this->build->storeMeta('phpcpd-warnings', $errorCount);
|
||||
$this->build->storeMeta('phpcpd-data', $data);
|
||||
|
||||
unlink($tmpfilename);
|
||||
|
||||
|
@ -113,11 +103,8 @@ class PhpCpd implements PluginInterface
|
|||
|
||||
/**
|
||||
* Process the PHPCPD XML report.
|
||||
*
|
||||
* @param $xmlString
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function processReport($xmlString)
|
||||
|
@ -130,20 +117,11 @@ class PhpCpd implements PluginInterface
|
|||
}
|
||||
|
||||
$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 = <<<CPD
|
||||
Copy and paste detected:
|
||||
|
||||
|
@ -152,13 +130,20 @@ Copy and paste detected:
|
|||
```
|
||||
CPD;
|
||||
|
||||
$this->build->reportError($this->phpci, $fileName, $file['line'], $message);
|
||||
|
||||
$this->build->reportError(
|
||||
$this->phpci,
|
||||
'php_cpd',
|
||||
$message,
|
||||
BuildError::SEVERITY_NORMAL,
|
||||
$fileName,
|
||||
$file['line'],
|
||||
(int) $file['line'] + (int) $duplication['lines']
|
||||
);
|
||||
}
|
||||
|
||||
$warnings++;
|
||||
}
|
||||
|
||||
return array($warnings, $data);
|
||||
return $warnings;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,18 +12,14 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI\Builder;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* PHP CS Fixer
|
||||
*
|
||||
* Works with the PHP CS Fixer for testing coding standards.
|
||||
*
|
||||
* @author Gabriel Baker <gabriel@autonomicpilot.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpCsFixer implements PluginInterface
|
||||
* PHP CS Fixer - Works with the PHP Coding Standards Fixer for testing coding standards.
|
||||
* @author Gabriel Baker <gabriel@autonomicpilot.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpCsFixer implements \PHPCI\Plugin
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Builder
|
||||
|
@ -36,10 +32,10 @@ class PhpCsFixer implements PluginInterface
|
|||
protected $build;
|
||||
|
||||
protected $workingDir = '';
|
||||
protected $level = ' --level=all';
|
||||
protected $verbose = '';
|
||||
protected $diff = '';
|
||||
protected $levels = array('psr0', 'psr1', 'psr2', 'all');
|
||||
protected $level = ' --level=psr2';
|
||||
protected $verbose = '';
|
||||
protected $diff = '';
|
||||
protected $levels = array('psr0', 'psr1', 'psr2', 'symfony');
|
||||
|
||||
/**
|
||||
* Standard Constructor
|
||||
|
@ -63,7 +59,8 @@ class PhpCsFixer implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Run PHP CS Fixer.
|
||||
* @return bool
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
|
@ -82,7 +79,6 @@ class PhpCsFixer implements PluginInterface
|
|||
|
||||
/**
|
||||
* Build an args string for PHPCS Fixer.
|
||||
*
|
||||
* @param $options
|
||||
*/
|
||||
public function buildArgs($options)
|
||||
|
@ -102,5 +98,6 @@ class PhpCsFixer implements PluginInterface
|
|||
if (isset($options['workingdir']) && $options['workingdir']) {
|
||||
$this->workingdir = $this->phpci->buildPath . $options['workingdir'];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,19 +12,14 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI;
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
use PHPCI\PluginZeroConfigInterface;
|
||||
|
||||
/**
|
||||
* PHP Docblock Checker Plugin
|
||||
*
|
||||
* Checks your PHP files for appropriate uses of Docblocks.
|
||||
*
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpDocblockChecker implements PluginInterface, PluginZeroConfigInterface
|
||||
* PHP Docblock Checker Plugin - Checks your PHP files for appropriate uses of Docblocks
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpDocblockChecker implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Builder
|
||||
|
@ -51,7 +46,11 @@ class PhpDocblockChecker implements PluginInterface, PluginZeroConfigInterface
|
|||
protected $skipMethods = false;
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Check if this plugin can be executed.
|
||||
* @param $stage
|
||||
* @param Builder $builder
|
||||
* @param Build $build
|
||||
* @return bool
|
||||
*/
|
||||
public static function canExecute($stage, Builder $builder, Build $build)
|
||||
{
|
||||
|
@ -64,7 +63,6 @@ class PhpDocblockChecker implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
/**
|
||||
* Set up the plugin, configure options, etc.
|
||||
*
|
||||
* @param Builder $phpci
|
||||
* @param Build $build
|
||||
* @param array $options
|
||||
|
@ -99,7 +97,7 @@ class PhpDocblockChecker implements PluginInterface, PluginZeroConfigInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Runs PHP Mess Detector in a specified directory.
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
|
@ -145,7 +143,6 @@ class PhpDocblockChecker implements PluginInterface, PluginZeroConfigInterface
|
|||
$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) {
|
||||
|
@ -157,19 +154,27 @@ class PhpDocblockChecker implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
/**
|
||||
* Report all of the errors we've encountered line-by-line.
|
||||
*
|
||||
* @param $output
|
||||
*/
|
||||
protected function reportErrors($output)
|
||||
{
|
||||
foreach ($output as $error) {
|
||||
$message = 'Class ' . $error['class'] . ' does not have a Docblock comment.';
|
||||
$message = 'Class ' . $error['class'] . ' is missing a docblock.';
|
||||
$severity = PHPCI\Model\BuildError::SEVERITY_LOW;
|
||||
|
||||
if ($error['type'] == 'method') {
|
||||
$message = 'Method ' . $error['class'] . '::' . $error['method'] . ' does not have a Docblock comment.';
|
||||
$message = $error['class'] . '::' . $error['method'] . ' is missing a docblock.';
|
||||
$severity = PHPCI\Model\BuildError::SEVERITY_NORMAL;
|
||||
}
|
||||
|
||||
$this->build->reportError($this->phpci, $error['file'], $error['line'], $message);
|
||||
$this->build->reportError(
|
||||
$this->phpci,
|
||||
'php_docblock_checker',
|
||||
$message,
|
||||
$severity,
|
||||
$error['file'],
|
||||
$error['line']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,30 +12,30 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI;
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
use PHPCI\PluginZeroConfigInterface;
|
||||
|
||||
/**
|
||||
* PHP Loc - Allows PHP Copy / Lines of Code testing.
|
||||
*
|
||||
* @author Johan van der Heide <info@japaveh.nl>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpLoc implements PluginInterface, PluginZeroConfigInterface
|
||||
class PhpLoc implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $directory;
|
||||
|
||||
/**
|
||||
* @var \PHPCI\Builder
|
||||
*/
|
||||
protected $phpci;
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Check if this plugin can be executed.
|
||||
* @param $stage
|
||||
* @param Builder $builder
|
||||
* @param Build $build
|
||||
* @return bool
|
||||
*/
|
||||
public static function canExecute($stage, Builder $builder, Build $build)
|
||||
{
|
||||
|
@ -48,7 +48,6 @@ class PhpLoc implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
/**
|
||||
* Set up the plugin, configure options, etc.
|
||||
*
|
||||
* @param Builder $phpci
|
||||
* @param Build $build
|
||||
* @param array $options
|
||||
|
@ -65,24 +64,25 @@ class PhpLoc implements PluginInterface, PluginZeroConfigInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Runs PHP Copy/Paste Detector in a specified directory.
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$ignore = '';
|
||||
if (count($this->phpci->ignore)) {
|
||||
$map = function ($item) {
|
||||
return ' --exclude ' . (substr($item, -1) == '/' ? substr($item, 0, -1) : $item);
|
||||
};
|
||||
$ignore = array_map($map, $this->phpci->ignore);
|
||||
|
||||
if (count($this->phpci->ignore)) {
|
||||
$map = function ($item) {
|
||||
return ' --exclude ' . rtrim($item, DIRECTORY_SEPARATOR);
|
||||
};
|
||||
|
||||
$ignore = array_map($map, $this->phpci->ignore);
|
||||
$ignore = implode('', $ignore);
|
||||
}
|
||||
|
||||
$phploc = $this->phpci->findBinary('phploc');
|
||||
|
||||
$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();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,17 +12,14 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI;
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
use PHPCI\PluginZeroConfigInterface;
|
||||
|
||||
/**
|
||||
* PHP Mess Detector Plugin - Allows PHP Mess Detector testing.
|
||||
*
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpMessDetector implements PluginInterface, PluginZeroConfigInterface
|
||||
* PHP Mess Detector Plugin - Allows PHP Mess Detector testing.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpMessDetector implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Builder
|
||||
|
@ -41,7 +38,7 @@ class PhpMessDetector implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
/**
|
||||
* @var string, based on the assumption the root may not hold the code to be
|
||||
* tested, exteds the base path only if the provided path is relative. Absolute
|
||||
* tested, extends the base path only if the provided path is relative. Absolute
|
||||
* paths are used verbatim
|
||||
*/
|
||||
protected $path;
|
||||
|
@ -53,13 +50,17 @@ class PhpMessDetector implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
/**
|
||||
* Array of PHPMD rules. Can be one of the builtins (codesize, unusedcode, naming, design, controversial)
|
||||
* or a filenname (detected by checking for a / in it), either absolute or relative to the project root.
|
||||
* or a filename (detected by checking for a / in it), either absolute or relative to the project root.
|
||||
* @var array
|
||||
*/
|
||||
protected $rules;
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Check if this plugin can be executed.
|
||||
* @param $stage
|
||||
* @param Builder $builder
|
||||
* @param Build $build
|
||||
* @return bool
|
||||
*/
|
||||
public static function canExecute($stage, Builder $builder, Build $build)
|
||||
{
|
||||
|
@ -110,7 +111,7 @@ class PhpMessDetector implements PluginInterface, PluginZeroConfigInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Runs PHP Mess Detector in a specified directory.
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
|
@ -122,16 +123,14 @@ class PhpMessDetector implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
$this->executePhpMd($phpmdBinaryPath);
|
||||
|
||||
list($errorCount, $data) = $this->processReport(trim($this->phpci->getLastOutput()));
|
||||
$errorCount = $this->processReport(trim($this->phpci->getLastOutput()));
|
||||
$this->build->storeMeta('phpmd-warnings', $errorCount);
|
||||
$this->build->storeMeta('phpmd-data', $data);
|
||||
|
||||
return $this->wasLastExecSuccessful($errorCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override a default setting.
|
||||
*
|
||||
* @param $options
|
||||
* @param $key
|
||||
*/
|
||||
|
@ -144,11 +143,8 @@ class PhpMessDetector implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
/**
|
||||
* Process PHPMD's XML output report.
|
||||
*
|
||||
* @param $xmlString
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function processReport($xmlString)
|
||||
|
@ -161,7 +157,6 @@ class PhpMessDetector implements PluginInterface, PluginZeroConfigInterface
|
|||
}
|
||||
|
||||
$warnings = 0;
|
||||
$data = array();
|
||||
|
||||
foreach ($xml->file as $file) {
|
||||
$fileName = (string)$file['name'];
|
||||
|
@ -169,27 +164,24 @@ class PhpMessDetector implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
foreach ($file->violation as $violation) {
|
||||
$warnings++;
|
||||
$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;
|
||||
$this->build->reportError(
|
||||
$this->phpci,
|
||||
'php_mess_detector',
|
||||
(string)$violation,
|
||||
PHPCI\Model\BuildError::SEVERITY_HIGH,
|
||||
$fileName,
|
||||
(int)$violation['beginline'],
|
||||
(int)$violation['endline']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return array($warnings, $data);
|
||||
return $warnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try and process the rules parameter from phpci.yml.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function tryAndProcessRules()
|
||||
|
@ -210,7 +202,6 @@ class PhpMessDetector implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
/**
|
||||
* Execute PHP Mess Detector.
|
||||
*
|
||||
* @param $binaryPath
|
||||
*/
|
||||
protected function executePhpMd($binaryPath)
|
||||
|
@ -247,7 +238,6 @@ class PhpMessDetector implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
/**
|
||||
* Get the path PHPMD should be run against.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getTargetPath()
|
||||
|
@ -264,7 +254,6 @@ class PhpMessDetector implements PluginInterface, PluginZeroConfigInterface
|
|||
* Returns a boolean indicating if the error count can be considered a success.
|
||||
*
|
||||
* @param int $errorCount
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function wasLastExecSuccessful($errorCount)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,16 +12,14 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI\Builder;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* Php Parallel Lint Plugin - Provides access to PHP lint functionality.
|
||||
*
|
||||
* @author Vaclav Makes <vaclav@makes.cz>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpParallelLint implements PluginInterface
|
||||
* Php Parallel Lint Plugin - Provides access to PHP lint functionality.
|
||||
* @author Vaclav Makes <vaclav@makes.cz>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpParallelLint implements \PHPCI\Plugin
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Builder
|
||||
|
@ -57,10 +55,10 @@ class PhpParallelLint implements PluginInterface
|
|||
*/
|
||||
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'];
|
||||
|
@ -72,8 +70,8 @@ class PhpParallelLint implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
*/
|
||||
* Executes parallel lint
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
list($ignore) = $this->getFlags();
|
||||
|
@ -99,7 +97,6 @@ class PhpParallelLint implements PluginInterface
|
|||
|
||||
/**
|
||||
* Produce an argument string for PHP Parallel Lint.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getFlags()
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,24 +12,22 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI;
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* PHP Spec Plugin - Allows PHP Spec testing.
|
||||
*
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpSpec implements PluginInterface
|
||||
* PHP Spec Plugin - Allows PHP Spec testing.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpSpec implements PHPCI\Plugin
|
||||
{
|
||||
/**
|
||||
* @var Builder
|
||||
* @var \PHPCI\Builder
|
||||
*/
|
||||
protected $phpci;
|
||||
|
||||
/**
|
||||
* @var Build
|
||||
* @var \PHPCI\Model\Build
|
||||
*/
|
||||
protected $build;
|
||||
|
||||
|
@ -40,7 +38,6 @@ class PhpSpec implements PluginInterface
|
|||
|
||||
/**
|
||||
* Set up the plugin, configure options, etc.
|
||||
*
|
||||
* @param Builder $phpci
|
||||
* @param Build $build
|
||||
* @param array $options
|
||||
|
@ -53,8 +50,8 @@ class PhpSpec implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
*/
|
||||
* Runs PHP Spec tests.
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$curdir = getcwd();
|
||||
|
@ -146,6 +143,7 @@ class PhpSpec implements PluginInterface
|
|||
|
||||
$this->build->storeMeta('phpspec', $data);
|
||||
|
||||
|
||||
return $success;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,16 +12,14 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI;
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* PHPTAL Lint Plugin - Provides access to PHPTAL lint functionality.
|
||||
*
|
||||
* @author Stephen Ball <phpci@stephen.rebelinblue.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpTalLint implements PluginInterface
|
||||
class PhpTalLint implements PHPCI\Plugin
|
||||
{
|
||||
protected $directories;
|
||||
protected $recursive = true;
|
||||
|
@ -29,12 +27,12 @@ class PhpTalLint implements PluginInterface
|
|||
protected $ignore;
|
||||
|
||||
/**
|
||||
* @var Builder
|
||||
* @var \PHPCI\Builder
|
||||
*/
|
||||
protected $phpci;
|
||||
|
||||
/**
|
||||
* @var Build
|
||||
* @var \PHPCI\Model\Build
|
||||
*/
|
||||
protected $build;
|
||||
|
||||
|
@ -89,7 +87,6 @@ class PhpTalLint implements PluginInterface
|
|||
|
||||
/**
|
||||
* Handle this plugin's options.
|
||||
*
|
||||
* @param $options
|
||||
*/
|
||||
protected function setOptions($options)
|
||||
|
@ -102,7 +99,7 @@ class PhpTalLint implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Executes phptal lint
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
|
@ -146,10 +143,8 @@ class PhpTalLint implements PluginInterface
|
|||
|
||||
/**
|
||||
* Lint an item (file or directory) by calling the appropriate method.
|
||||
*
|
||||
* @param $item
|
||||
* @param $itemPath
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function lintItem($item, $itemPath)
|
||||
|
@ -160,7 +155,7 @@ class PhpTalLint implements PluginInterface
|
|||
if (!$this->lintFile($itemPath)) {
|
||||
$success = false;
|
||||
}
|
||||
} elseif ($item->isDir() && $this->recursive && !$this->lintDirectory($itemPath . '/')) {
|
||||
} elseif ($item->isDir() && $this->recursive && !$this->lintDirectory($itemPath . DIRECTORY_SEPARATOR)) {
|
||||
$success = false;
|
||||
}
|
||||
|
||||
|
@ -169,9 +164,7 @@ class PhpTalLint implements PluginInterface
|
|||
|
||||
/**
|
||||
* Run phptal lint against a directory of files.
|
||||
*
|
||||
* @param $path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function lintDirectory($path)
|
||||
|
@ -200,9 +193,7 @@ class PhpTalLint implements PluginInterface
|
|||
|
||||
/**
|
||||
* Run phptal lint against a specific file.
|
||||
*
|
||||
* @param $path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function lintFile($path)
|
||||
|
@ -211,7 +202,9 @@ class PhpTalLint implements PluginInterface
|
|||
|
||||
list($suffixes, $tales) = $this->getFlags();
|
||||
|
||||
$lint = dirname(__FILE__) . '/../../vendor/phptal/phptal/tools/phptal_lint.php';
|
||||
$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';
|
||||
$cmd = '/usr/bin/env php ' . $lint . ' %s %s "%s"';
|
||||
|
||||
$this->phpci->executeCommand($cmd, $suffixes, $tales, $this->phpci->buildPath . $path);
|
||||
|
@ -253,7 +246,6 @@ class PhpTalLint implements PluginInterface
|
|||
|
||||
/**
|
||||
* Process options and produce an arguments string for PHPTAL Lint.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getFlags()
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -13,17 +13,14 @@ use PHPCI;
|
|||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\Plugin\Util\TapParser;
|
||||
use PHPCI\PluginInterface;
|
||||
use PHPCI\PluginZeroConfigInterface;
|
||||
|
||||
/**
|
||||
* PHP Unit Plugin - Allows PHP Unit testing.
|
||||
*
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpUnit implements PluginInterface, PluginZeroConfigInterface
|
||||
* PHP Unit Plugin - Allows PHP Unit testing.
|
||||
* @author Dan Cryer <dan@block8.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class PhpUnit implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
|
||||
{
|
||||
protected $args;
|
||||
protected $phpci;
|
||||
|
@ -53,7 +50,11 @@ class PhpUnit implements PluginInterface, PluginZeroConfigInterface
|
|||
protected $xmlConfigFile;
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Check if this plugin can be executed.
|
||||
* @param $stage
|
||||
* @param Builder $builder
|
||||
* @param Build $build
|
||||
* @return bool
|
||||
*/
|
||||
public static function canExecute($stage, Builder $builder, Build $build)
|
||||
{
|
||||
|
@ -66,9 +67,7 @@ class PhpUnit implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
/**
|
||||
* Try and find the phpunit XML config file.
|
||||
*
|
||||
* @param $buildPath
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public static function findConfigFile($buildPath)
|
||||
|
@ -77,8 +76,8 @@ class PhpUnit implements PluginInterface, PluginZeroConfigInterface
|
|||
return 'phpunit.xml';
|
||||
}
|
||||
|
||||
if (file_exists($buildPath . 'tests/phpunit.xml')) {
|
||||
return 'tests/phpunit.xml';
|
||||
if (file_exists($buildPath . 'tests' . DIRECTORY_SEPARATOR . 'phpunit.xml')) {
|
||||
return 'tests' . DIRECTORY_SEPARATOR . 'phpunit.xml';
|
||||
}
|
||||
|
||||
if (file_exists($buildPath . 'phpunit.xml.dist')) {
|
||||
|
@ -86,7 +85,7 @@ class PhpUnit implements PluginInterface, PluginZeroConfigInterface
|
|||
}
|
||||
|
||||
if (file_exists($buildPath . 'tests/phpunit.xml.dist')) {
|
||||
return 'tests/phpunit.xml.dist';
|
||||
return 'tests' . DIRECTORY_SEPARATOR . 'phpunit.xml.dist';
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -134,13 +133,13 @@ class PhpUnit implements PluginInterface, PluginZeroConfigInterface
|
|||
}
|
||||
|
||||
if (isset($options['coverage'])) {
|
||||
$this->coverage = " --coverage-html {$options['coverage']} ";
|
||||
$this->coverage = ' --coverage-html ' . $this->phpci->interpolate($options['coverage']) . ' ';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
*/
|
||||
* Runs PHP Unit tests in a specified directory, optionally using specified config file(s).
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
if (empty($this->xmlConfigFile) && empty($this->directory)) {
|
||||
|
@ -185,9 +184,7 @@ class PhpUnit implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
/**
|
||||
* Run the tests defined in a PHPUnit config file.
|
||||
*
|
||||
* @param $configPath
|
||||
*
|
||||
* @return bool|mixed
|
||||
*/
|
||||
protected function runConfigFile($configPath)
|
||||
|
@ -197,7 +194,7 @@ class PhpUnit implements PluginInterface, PluginZeroConfigInterface
|
|||
} else {
|
||||
if ($this->runFrom) {
|
||||
$curdir = getcwd();
|
||||
chdir($this->phpci->buildPath.'/'.$this->runFrom);
|
||||
chdir($this->phpci->buildPath . DIRECTORY_SEPARATOR . $this->runFrom);
|
||||
}
|
||||
|
||||
$phpunit = $this->phpci->findBinary('phpunit');
|
||||
|
@ -215,9 +212,7 @@ class PhpUnit implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
/**
|
||||
* Run the PHPUnit tests in a specific directory or array of directories.
|
||||
*
|
||||
* @param $directory
|
||||
*
|
||||
* @return bool|mixed
|
||||
*/
|
||||
protected function runDir($directory)
|
||||
|
@ -240,7 +235,6 @@ class PhpUnit implements PluginInterface, PluginZeroConfigInterface
|
|||
/**
|
||||
* @param $array
|
||||
* @param $callable
|
||||
*
|
||||
* @return bool|mixed
|
||||
*/
|
||||
protected function recurseArg($array, $callable)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,16 +12,14 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI\Builder;
|
||||
use PHPCI\Helper\Lang;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* Shell Plugin - Allows execute shell commands.
|
||||
*
|
||||
* @author Kinn Coelho Julião <kinncj@gmail.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Shell implements PluginInterface
|
||||
class Shell implements \PHPCI\Plugin
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Builder
|
||||
|
@ -77,7 +75,7 @@ class Shell implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Runs the shell command.
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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,22 +10,21 @@ namespace PHPCI\Plugin;
|
|||
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* Slack Plugin
|
||||
*
|
||||
* @author Stephen Ball <phpci@stephen.rebelinblue.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class SlackNotify implements PluginInterface
|
||||
class SlackNotify implements \PHPCI\Plugin
|
||||
{
|
||||
private $webHook;
|
||||
private $room;
|
||||
private $username;
|
||||
private $message;
|
||||
private $icon;
|
||||
private $show_status;
|
||||
|
||||
/**
|
||||
* Set up the plugin, configure options, etc.
|
||||
|
@ -63,6 +61,12 @@ class SlackNotify implements PluginInterface
|
|||
$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'];
|
||||
}
|
||||
|
@ -72,35 +76,12 @@ class SlackNotify implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Run the Slack plugin.
|
||||
* @return bool
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$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
|
||||
))
|
||||
)
|
||||
));
|
||||
$body = $this->phpci->interpolate($this->message);
|
||||
|
||||
$client = new \Maknz\Slack\Client($this->webHook);
|
||||
|
||||
|
@ -118,12 +99,39 @@ class SlackNotify implements PluginInterface
|
|||
$message->setIcon($this->icon);
|
||||
}
|
||||
|
||||
$message->attach($attachment);
|
||||
// Include an attachment which shows the status and hide the message
|
||||
if ($this->show_status) {
|
||||
$successfulBuild = $this->build->isSuccessful();
|
||||
|
||||
$success = true;
|
||||
if ($successfulBuild) {
|
||||
$status = 'Success';
|
||||
$color = 'good';
|
||||
} else {
|
||||
$status = 'Failed';
|
||||
$color = 'danger';
|
||||
}
|
||||
|
||||
$message->send('');
|
||||
// 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
|
||||
))
|
||||
)
|
||||
));
|
||||
|
||||
return $success;
|
||||
$message->attach($attachment);
|
||||
|
||||
$body = '';
|
||||
}
|
||||
|
||||
$message->send($body);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,16 +12,14 @@ namespace PHPCI\Plugin;
|
|||
use PDO;
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
|
||||
/**
|
||||
* SQLite Plugin — Provides access to a SQLite database.
|
||||
*
|
||||
* @author Corpsee <poisoncorpsee@gmail.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Sqlite implements PluginInterface
|
||||
* SQLite Plugin — Provides access to a SQLite database.
|
||||
* @author Corpsee <poisoncorpsee@gmail.com>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class Sqlite implements \PHPCI\Plugin
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Builder
|
||||
|
@ -62,7 +60,8 @@ class Sqlite implements PluginInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Connects to SQLite and runs a specified set of queries.
|
||||
* @return boolean
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* PHPCI - Continuous Integration for PHP
|
||||
*
|
||||
* @copyright Copyright 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/
|
||||
*/
|
||||
|
@ -12,17 +12,15 @@ namespace PHPCI\Plugin;
|
|||
use PHPCI;
|
||||
use PHPCI\Builder;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\PluginInterface;
|
||||
use PHPCI\PluginZeroConfigInterface;
|
||||
|
||||
/**
|
||||
* Technical Debt Plugin - Checks for existence of "TODO", "FIXME", etc.
|
||||
*
|
||||
* @author James Inman <james@jamesinman.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class TechnicalDebt implements PluginInterface, PluginZeroConfigInterface
|
||||
* Technical Debt Plugin - Checks for existence of "TODO", "FIXME", etc.
|
||||
*
|
||||
* @author James Inman <james@jamesinman.co.uk>
|
||||
* @package PHPCI
|
||||
* @subpackage Plugins
|
||||
*/
|
||||
class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin
|
||||
{
|
||||
/**
|
||||
* @var \PHPCI\Builder
|
||||
|
@ -44,11 +42,6 @@ class TechnicalDebt implements PluginInterface, PluginZeroConfigInterface
|
|||
*/
|
||||
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
|
||||
|
@ -67,7 +60,12 @@ class TechnicalDebt implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
* Check if this plugin can be executed.
|
||||
*
|
||||
* @param $stage
|
||||
* @param Builder $builder
|
||||
* @param Build $build
|
||||
* @return bool
|
||||
*/
|
||||
public static function canExecute($stage, Builder $builder, Build $build)
|
||||
{
|
||||
|
@ -91,7 +89,6 @@ class TechnicalDebt implements PluginInterface, PluginZeroConfigInterface
|
|||
$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');
|
||||
|
||||
|
@ -100,19 +97,19 @@ class TechnicalDebt implements PluginInterface, PluginZeroConfigInterface
|
|||
}
|
||||
|
||||
if (isset($options['zero_config']) && $options['zero_config']) {
|
||||
$this->allowed_warnings = -1;
|
||||
$this->allowed_errors = -1;
|
||||
}
|
||||
|
||||
$this->setOptions($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle this plugin's options.
|
||||
*
|
||||
* @param $options
|
||||
*/
|
||||
protected function setOptions($options)
|
||||
{
|
||||
foreach (array('directory', 'path', 'ignore', 'allowed_warnings', 'allowed_errors') as $key) {
|
||||
foreach (array('directory', 'path', 'ignore', 'allowed_errors') as $key) {
|
||||
if (array_key_exists($key, $options)) {
|
||||
$this->{$key} = $options[$key];
|
||||
}
|
||||
|
@ -120,19 +117,18 @@ class TechnicalDebt implements PluginInterface, PluginZeroConfigInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritDocs}
|
||||
*/
|
||||
* Runs the plugin
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$success = true;
|
||||
$this->phpci->logExecOutput(false);
|
||||
|
||||
list($errorCount, $data) = $this->getErrorList();
|
||||
$errorCount = $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;
|
||||
|
@ -154,6 +150,7 @@ class TechnicalDebt implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
$ignores = $this->ignore;
|
||||
$ignores[] = 'phpci.yml';
|
||||
$ignores[] = '.phpci.yml';
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
$filePath = $file->getRealPath();
|
||||
|
@ -166,7 +163,7 @@ class TechnicalDebt implements PluginInterface, PluginZeroConfigInterface
|
|||
}
|
||||
|
||||
// Ignore hidden files, else .git, .sass_cache, etc. all get looped over
|
||||
if (stripos($filePath, '/.') !== false) {
|
||||
if (stripos($filePath, DIRECTORY_SEPARATOR . '.') !== false) {
|
||||
$skipFile = true;
|
||||
}
|
||||
|
||||
|
@ -177,7 +174,6 @@ class TechnicalDebt implements PluginInterface, PluginZeroConfigInterface
|
|||
|
||||
$files = array_filter(array_unique($files));
|
||||
$errorCount = 0;
|
||||
$data = array();
|
||||
|
||||
foreach ($files as $file) {
|
||||
foreach ($this->searches as $search) {
|
||||
|
@ -191,21 +187,21 @@ class TechnicalDebt implements PluginInterface, PluginZeroConfigInterface
|
|||
$content = trim($allLines[$lineNumber - 1]);
|
||||
|
||||
$errorCount++;
|
||||
$this->phpci->log("Found $search on line $lineNumber of $file:\n$content");
|
||||
|
||||
$fileName = str_replace($this->directory, '', $file);
|
||||
$data[] = array(
|
||||
'file' => $fileName,
|
||||
'line' => $lineNumber,
|
||||
'message' => $content
|
||||
|
||||
$this->build->reportError(
|
||||
$this->phpci,
|
||||
'technical_debt',
|
||||
$content,
|
||||
PHPCI\Model\BuildError::SEVERITY_LOW,
|
||||
$fileName,
|
||||
$lineNumber
|
||||
);
|
||||
|
||||
$this->build->reportError($this->phpci, $fileName, $lineNumber, $content);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array( $errorCount, $data );
|
||||
return $errorCount;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,12 @@
|
|||
|
||||
namespace PHPCI\Plugin\Util;
|
||||
|
||||
use b8\Store\Factory as StoreFactory;
|
||||
use Exception;
|
||||
use PHPCI\Helper\Lang;
|
||||
use \PHPCI\Logging\BuildLogger;
|
||||
use PHPCI\Logging\BuildLogger;
|
||||
use PHPCI\Model\Build;
|
||||
use PHPCI\Store\BuildStore;
|
||||
|
||||
/**
|
||||
* Plugin Executor - Runs the configured plugins for a given build stage.
|
||||
|
@ -21,14 +25,20 @@ class Executor
|
|||
*/
|
||||
protected $pluginFactory;
|
||||
|
||||
/**
|
||||
* @var BuildStore
|
||||
*/
|
||||
protected $store;
|
||||
|
||||
/**
|
||||
* @param Factory $pluginFactory
|
||||
* @param BuildLogger $logger
|
||||
*/
|
||||
public function __construct(Factory $pluginFactory, BuildLogger $logger)
|
||||
public function __construct(Factory $pluginFactory, BuildLogger $logger, BuildStore $store = null)
|
||||
{
|
||||
$this->pluginFactory = $pluginFactory;
|
||||
$this->logger = $logger;
|
||||
$this->store = $store ?: StoreFactory::getStore('Build');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,30 +50,114 @@ class Executor
|
|||
public function executePlugins(&$config, $stage)
|
||||
{
|
||||
$success = true;
|
||||
// Ignore any stages for which we don't have plugins set:
|
||||
if (!array_key_exists($stage, $config) || !is_array($config[$stage])) {
|
||||
return $success;
|
||||
$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];
|
||||
}
|
||||
|
||||
foreach ($config[$stage] as $plugin => $options) {
|
||||
$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) {
|
||||
$this->logger->log(Lang::get('running_plugin', $plugin));
|
||||
|
||||
// Try and execute it:
|
||||
if ($this->executePlugin($plugin, $options)) {
|
||||
// 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->setPluginStatus($stage, $plugin, Build::STATUS_RUNNING);
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,20 +185,62 @@ class Executor
|
|||
return false;
|
||||
}
|
||||
|
||||
$rtn = true;
|
||||
|
||||
// Try running it:
|
||||
try {
|
||||
// Build and run it
|
||||
$obj = $this->pluginFactory->buildPlugin($class, $options);
|
||||
|
||||
if (!$obj->execute()) {
|
||||
$rtn = false;
|
||||
}
|
||||
return $obj->execute();
|
||||
} catch (\Exception $ex) {
|
||||
$this->logger->logFailure(Lang::get('exception') . $ex->getMessage(), $ex);
|
||||
$rtn = false;
|
||||
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();
|
||||
}
|
||||
|
||||
return $rtn;
|
||||
$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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 null $type
|
||||
* @param null $name
|
||||
* @return null
|
||||
* @param string $type
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
private function getResourceFor($type = null, $name = null)
|
||||
public function getResourceFor($type = null, $name = null)
|
||||
{
|
||||
$fullId = $this->getInternalID($type, $name);
|
||||
if (isset($this->container[$fullId])) {
|
||||
|
|
|
@ -56,6 +56,7 @@ class FilesPluginInformation implements InstalledPluginInformation
|
|||
if ($this->pluginInfo === null) {
|
||||
$this->loadPluginInfo();
|
||||
}
|
||||
|
||||
return $this->pluginInfo;
|
||||
}
|
||||
|
||||
|
@ -83,7 +84,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);
|
||||
}
|
||||
}
|
||||
|
@ -99,11 +100,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;
|
||||
}
|
||||
|
@ -123,11 +124,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;
|
||||
|
|
|
@ -32,9 +32,11 @@ class PluginInformationCollection implements InstalledPluginInformation
|
|||
public function getInstalledPlugins()
|
||||
{
|
||||
$arr = array();
|
||||
|
||||
foreach ($this->pluginInformations as $single) {
|
||||
$arr = array_merge($arr, $single->getInstalledPlugins());
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
|
@ -47,9 +49,11 @@ class PluginInformationCollection implements InstalledPluginInformation
|
|||
public function getPluginClasses()
|
||||
{
|
||||
$arr = array();
|
||||
|
||||
foreach ($this->pluginInformations as $single) {
|
||||
$arr = array_merge($arr, $single->getPluginClasses());
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue