From 1bc2117c69e1d833688113a650038c89a5ff05cb Mon Sep 17 00:00:00 2001 From: meadsteve Date: Fri, 13 Dec 2013 15:57:56 +0000 Subject: [PATCH 01/74] extracted build logging logic from the Builder class. --- PHPCI/BuildLogger.php | 31 ------ PHPCI/Builder.php | 115 ++++++++------------- PHPCI/Helper/CommandExecutor.php | 4 +- PHPCI/Logging/BuildLogger.php | 96 +++++++++++++++++ Tests/PHPCI/Helper/CommandExecutorTest.php | 2 +- 5 files changed, 141 insertions(+), 107 deletions(-) delete mode 100644 PHPCI/BuildLogger.php create mode 100644 PHPCI/Logging/BuildLogger.php diff --git a/PHPCI/BuildLogger.php b/PHPCI/BuildLogger.php deleted file mode 100644 index ccb6288a..00000000 --- a/PHPCI/BuildLogger.php +++ /dev/null @@ -1,31 +0,0 @@ - */ -class Builder implements LoggerAwareInterface, BuildLogger +class Builder implements LoggerAwareInterface { /** * @var string @@ -102,21 +103,32 @@ class Builder implements LoggerAwareInterface, BuildLogger */ protected $commandExecutor; + /** + * @var Logging\BuildLogger + */ + protected $buildLogger; + /** * Set up the builder. * @param \PHPCI\Model\Build $build * @param LoggerInterface $logger */ - public function __construct(Build $build, $logger = null) + public function __construct(Build $build, LoggerInterface $logger = null) { - if ($logger) { - $this->setLogger($logger); - } $this->build = $build; $this->store = Store\Factory::getStore('Build'); + + $this->buildLogger = new BuildLogger($logger, $build); + $this->pluginExecutor = new Plugin\Util\Executor($this->buildPluginFactory($build), $this); - $this->commandExecutor = new CommandExecutor($this, PHPCI_DIR, $this->quiet, $this->verbose); + $this->commandExecutor = new CommandExecutor( + $this->buildLogger, + PHPCI_DIR, + $this->quiet, + $this->verbose + ); + } /** @@ -195,15 +207,15 @@ class Builder implements LoggerAwareInterface, BuildLogger if ($this->success) { $this->pluginExecutor->executePlugins($this->config, 'success'); - $this->logSuccess('BUILD SUCCESSFUL!'); + $this->buildLogger->logSuccess('BUILD SUCCESSFUL!'); } else { $this->pluginExecutor->executePlugins($this->config, 'failure'); - $this->logFailure("BUILD FAILURE"); + $this->buildLogger->logFailure("BUILD FAILURE"); } // Clean up: - $this->log('Removing build.'); + $this->buildLogger->log('Removing build.'); shell_exec(sprintf('rm -Rf "%s"', $this->buildPath)); // Update the build in the database, ping any external services, etc. @@ -238,63 +250,6 @@ class Builder implements LoggerAwareInterface, BuildLogger return $this->commandExecutor->findBinary($binary); } - /** - * Add an entry to the build log. - * @param string|string[] $message - * @param string $level - * @param mixed[] $context - */ - public function log($message, $level = LogLevel::INFO, $context = array()) - { - // Skip if no logger has been loaded. - if (!$this->logger) { - return; - } - - if (!is_array($message)) { - $message = array($message); - } - - // The build is added to the context so the logger can use - // details from it if required. - $context['build'] = $this->build; - - foreach ($message as $item) { - $this->logger->log($level, $item, $context); - } - } - - /** - * Add a success-coloured message to the log. - * @param string - */ - public function logSuccess($message) - { - $this->log("\033[0;32m" . $message . "\033[0m"); - } - - /** - * Add a failure-coloured message to the log. - * @param string $message - * @param \Exception $exception The exception that caused the error. - */ - public function logFailure($message, \Exception $exception = null) - { - $context = array(); - - // The psr3 log interface stipulates that exceptions should be passed - // as the exception key in the context array. - if ($exception) { - $context['exception'] = $exception; - } - - $this->log( - "\033[0;31m" . $message . "\033[0m", - LogLevel::ERROR, - $context - ); - } - /** * Replace every occurance of the interpolation vars in the given string * Example: "This is build %PHPCI_BUILD%" => "This is build 182" @@ -369,7 +324,7 @@ class Builder implements LoggerAwareInterface, BuildLogger $this->ignore = $this->config['build_settings']['ignore']; } - $this->logSuccess('Working copy created: ' . $this->buildPath); + $this->buildLogger->logSuccess('Working copy created: ' . $this->buildPath); return true; } @@ -381,17 +336,31 @@ class Builder implements LoggerAwareInterface, BuildLogger */ public function setLogger(LoggerInterface $logger) { - $this->logger = $logger; + $this->buildLogger->setLogger($logger); + } + + public function log($message, $level = LogLevel::INFO, $context = array()) + { + $this->buildLogger->log($message, $level, $context); + } + + /** + * Add a success-coloured message to the log. + * @param string + */ + public function logSuccess($message) + { + $this->buildLogger->logSuccess($message); } /** - * returns the logger attached to this builder. - * - * @return LoggerInterface + * Add a failure-coloured message to the log. + * @param string $message + * @param \Exception $exception The exception that caused the error. */ - public function getLogger() + public function logFailure($message, \Exception $exception = null) { - return $this->logger; + $this->buildLogger->logFailure($message, $exception); } private function buildPluginFactory(Build $build) diff --git a/PHPCI/Helper/CommandExecutor.php b/PHPCI/Helper/CommandExecutor.php index 43813924..60061404 100644 --- a/PHPCI/Helper/CommandExecutor.php +++ b/PHPCI/Helper/CommandExecutor.php @@ -3,12 +3,12 @@ namespace PHPCI\Helper; -use PHPCI\BuildLogger; +use \PHPCI\Logging\BuildLogger; class CommandExecutor { /** - * @var \PHPCI\BuildLogger + * @var \PHPCI\Logging\BuildLogger */ protected $logger; diff --git a/PHPCI/Logging/BuildLogger.php b/PHPCI/Logging/BuildLogger.php new file mode 100644 index 00000000..f3f5ebce --- /dev/null +++ b/PHPCI/Logging/BuildLogger.php @@ -0,0 +1,96 @@ +logger = $logger; + $this->build = $build; + } + + /** + * Add an entry to the build log. + * @param string|string[] $message + * @param string $level + * @param mixed[] $context + */ + public function log($message, $level = LogLevel::INFO, $context = array()) + { + // Skip if no logger has been loaded. + if (!$this->logger) { + return; + } + + if (!is_array($message)) { + $message = array($message); + } + + // The build is added to the context so the logger can use + // details from it if required. + $context['build'] = $this->build; + + foreach ($message as $item) { + $this->logger->log($level, $item, $context); + } + } + + /** + * Add a success-coloured message to the log. + * @param string + */ + public function logSuccess($message) + { + $this->log("\033[0;32m" . $message . "\033[0m"); + } + + /** + * Add a failure-coloured message to the log. + * @param string $message + * @param \Exception $exception The exception that caused the error. + */ + public function logFailure($message, \Exception $exception = null) + { + $context = array(); + + // The psr3 log interface stipulates that exceptions should be passed + // as the exception key in the context array. + if ($exception) { + $context['exception'] = $exception; + } + + $this->log( + "\033[0;31m" . $message . "\033[0m", + LogLevel::ERROR, + $context + ); + } + + /** + * Sets a logger instance on the object + * + * @param LoggerInterface $logger + * @return null + */ + public function setLogger(LoggerInterface $logger) + { + $this->logger = $logger; + } +} \ No newline at end of file diff --git a/Tests/PHPCI/Helper/CommandExecutorTest.php b/Tests/PHPCI/Helper/CommandExecutorTest.php index 008443e9..f394c9f9 100644 --- a/Tests/PHPCI/Helper/CommandExecutorTest.php +++ b/Tests/PHPCI/Helper/CommandExecutorTest.php @@ -15,7 +15,7 @@ class CommandExecutorTest extends ProphecyTestCase protected function setUp() { parent::setUp(); - $mockBuildLogger = $this->prophesize('\PHPCI\BuildLogger'); + $mockBuildLogger = $this->prophesize('\PHPCI\Logging\BuildLogger'); $this->testedExecutor = new CommandExecutor($mockBuildLogger->reveal(), __DIR__ . "/"); } From f05ffb308132909e32c04daaeb8e0994ece17668 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Fri, 13 Dec 2013 16:07:11 +0000 Subject: [PATCH 02/74] update executor test --- Tests/PHPCI/Plugin/Util/ExecutorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/PHPCI/Plugin/Util/ExecutorTest.php b/Tests/PHPCI/Plugin/Util/ExecutorTest.php index ec640e95..01267217 100644 --- a/Tests/PHPCI/Plugin/Util/ExecutorTest.php +++ b/Tests/PHPCI/Plugin/Util/ExecutorTest.php @@ -22,7 +22,7 @@ class ExecutorTest extends ProphecyTestCase protected function setUp() { parent::setUp(); - $this->mockBuildLogger = $this->prophesize('\PHPCI\BuildLogger'); + $this->mockBuildLogger = $this->prophesize('\PHPCI\Logging\BuildLogger'); $this->mockFactory = $this->prophesize('\PHPCI\Plugin\Util\Factory'); $this->testedExecutor = new Executor($this->mockFactory->reveal(), $this->mockBuildLogger->reveal()); } From 356a2293a1bb0e6985a3c3379595f1f4d6bf7632 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Fri, 13 Dec 2013 16:10:54 +0000 Subject: [PATCH 03/74] move logging related classes to appropriate namespace. --- PHPCI/Command/RunCommand.php | 6 +++--- PHPCI/{Helper => Logging}/BuildDBLogHandler.php | 2 +- PHPCI/{Helper => Logging}/LoggedBuildContextTidier.php | 2 +- PHPCI/{Helper => Logging}/LoggerConfig.php | 2 +- PHPCI/{Helper => Logging}/OutputLogHandler.php | 2 +- PHPCI/Plugin/Util/Executor.php | 4 ++-- Tests/PHPCI/Helper/CommandExecutorTest.php | 2 +- Tests/PHPCI/Helper/LoggerConfigTest.php | 2 +- console | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) rename PHPCI/{Helper => Logging}/BuildDBLogHandler.php (96%) rename PHPCI/{Helper => Logging}/LoggedBuildContextTidier.php (96%) rename PHPCI/{Helper => Logging}/LoggerConfig.php (98%) rename PHPCI/{Helper => Logging}/OutputLogHandler.php (95%) diff --git a/PHPCI/Command/RunCommand.php b/PHPCI/Command/RunCommand.php index d635b8a2..d95455ce 100644 --- a/PHPCI/Command/RunCommand.php +++ b/PHPCI/Command/RunCommand.php @@ -10,9 +10,9 @@ namespace PHPCI\Command; use Monolog\Logger; -use PHPCI\Helper\BuildDBLogHandler; -use PHPCI\Helper\LoggedBuildContextTidier; -use PHPCI\Helper\OutputLogHandler; +use PHPCI\Logging\BuildDBLogHandler; +use PHPCI\Logging\LoggedBuildContextTidier; +use PHPCI\Logging\OutputLogHandler; use Psr\Log\LoggerAwareInterface; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; diff --git a/PHPCI/Helper/BuildDBLogHandler.php b/PHPCI/Logging/BuildDBLogHandler.php similarity index 96% rename from PHPCI/Helper/BuildDBLogHandler.php rename to PHPCI/Logging/BuildDBLogHandler.php index 6ae34379..60cf48d3 100644 --- a/PHPCI/Helper/BuildDBLogHandler.php +++ b/PHPCI/Logging/BuildDBLogHandler.php @@ -1,6 +1,6 @@ pluginFactory = $pluginFactory; $this->logger = $logger; diff --git a/Tests/PHPCI/Helper/CommandExecutorTest.php b/Tests/PHPCI/Helper/CommandExecutorTest.php index f394c9f9..047f4258 100644 --- a/Tests/PHPCI/Helper/CommandExecutorTest.php +++ b/Tests/PHPCI/Helper/CommandExecutorTest.php @@ -15,7 +15,7 @@ class CommandExecutorTest extends ProphecyTestCase protected function setUp() { parent::setUp(); - $mockBuildLogger = $this->prophesize('\PHPCI\Logging\BuildLogger'); + $mockBuildLogger = $this->prophesize('PHPCI\Logging\BuildLogger'); $this->testedExecutor = new CommandExecutor($mockBuildLogger->reveal(), __DIR__ . "/"); } diff --git a/Tests/PHPCI/Helper/LoggerConfigTest.php b/Tests/PHPCI/Helper/LoggerConfigTest.php index 95ea3d62..e19fb736 100644 --- a/Tests/PHPCI/Helper/LoggerConfigTest.php +++ b/Tests/PHPCI/Helper/LoggerConfigTest.php @@ -1,6 +1,6 @@ Date: Sat, 14 Dec 2013 10:41:21 +0000 Subject: [PATCH 04/74] move logging test --- Tests/PHPCI/{Helper => Logging}/LoggerConfigTest.php | 2 ++ 1 file changed, 2 insertions(+) rename Tests/PHPCI/{Helper => Logging}/LoggerConfigTest.php (98%) diff --git a/Tests/PHPCI/Helper/LoggerConfigTest.php b/Tests/PHPCI/Logging/LoggerConfigTest.php similarity index 98% rename from Tests/PHPCI/Helper/LoggerConfigTest.php rename to Tests/PHPCI/Logging/LoggerConfigTest.php index e19fb736..699f9384 100644 --- a/Tests/PHPCI/Helper/LoggerConfigTest.php +++ b/Tests/PHPCI/Logging/LoggerConfigTest.php @@ -1,5 +1,7 @@ Date: Sat, 14 Dec 2013 11:07:04 +0000 Subject: [PATCH 05/74] add tests for BuildLogger --- Tests/PHPCI/Logging/BuildLoggerTest.php | 107 ++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 Tests/PHPCI/Logging/BuildLoggerTest.php diff --git a/Tests/PHPCI/Logging/BuildLoggerTest.php b/Tests/PHPCI/Logging/BuildLoggerTest.php new file mode 100644 index 00000000..ed0e7341 --- /dev/null +++ b/Tests/PHPCI/Logging/BuildLoggerTest.php @@ -0,0 +1,107 @@ +mockLogger = $this->prophesize('\Psr\Log\LoggerInterface'); + $this->mockBuild = $this->prophesize('\PHPCI\Model\Build'); + + $this->testedBuildLogger = new BuildLogger( + $this->mockLogger->reveal(), + $this->mockBuild->reveal() + ); + } + + public function testLog_CallsWrappedLogger() + { + $level = LogLevel::NOTICE; + $message = "Testing"; + $contextIn = array(); + + $this->mockLogger->log($level, $message, Argument::type('array')) + ->shouldBeCalledTimes(1); + + $this->testedBuildLogger->log($message, $level, $contextIn); + } + + public function testLog_CallsWrappedLoggerForEachMessage() + { + $level = LogLevel::NOTICE; + $message = array("One", "Two", "Three"); + $contextIn = array(); + + $this->mockLogger->log($level, "One", Argument::type('array')) + ->shouldBeCalledTimes(1); + + $this->mockLogger->log($level, "Two", Argument::type('array')) + ->shouldBeCalledTimes(1); + + $this->mockLogger->log($level, "Three", Argument::type('array')) + ->shouldBeCalledTimes(1); + + $this->testedBuildLogger->log($message, $level, $contextIn); + } + + public function testLog_AddsBuildToContext() + { + $level = LogLevel::NOTICE; + $message = "Testing"; + $contextIn = array(); + + $expectedContext = array( + 'build' => $this->mockBuild->reveal() + ); + + $this->mockLogger->log($level, $message, $expectedContext) + ->shouldBeCalledTimes(1); + + $this->testedBuildLogger->log($message, $level, $contextIn); + } + + public function testLogFailure_LogsAsErrorLevel() + { + $message = "Testing"; + $expectedLevel = LogLevel::ERROR; + + $this->mockLogger->log($expectedLevel, + Argument::type('string'), + Argument::type('array')) + ->shouldBeCalledTimes(1); + + $this->testedBuildLogger->logFailure($message); + } + + public function testLogFailure_AddsExceptionContext() + { + $message = "Testing"; + + $exception = new \Exception("Expected Exception"); + + + $this->mockLogger->log(Argument::type('string'), + Argument::type('string'), + Argument::withEntry('exception', $exception)) + ->shouldBeCalledTimes(1); + + $this->testedBuildLogger->logFailure($message, $exception); + } +} + \ No newline at end of file From 30bd11f0dde248e8b9ca3c2f84c5c75726ecad77 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Tue, 17 Dec 2013 15:03:48 +0000 Subject: [PATCH 06/74] fix testing namespace --- Tests/PHPCI/Logging/LoggerConfigTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/PHPCI/Logging/LoggerConfigTest.php b/Tests/PHPCI/Logging/LoggerConfigTest.php index 699f9384..a8954c82 100644 --- a/Tests/PHPCI/Logging/LoggerConfigTest.php +++ b/Tests/PHPCI/Logging/LoggerConfigTest.php @@ -4,7 +4,7 @@ namespace PHPCI\Plugin\Tests\Helper; use \PHPCI\Logging\LoggerConfig; -class LoggerConfigTest extends PHPUnit_Framework_TestCase +class LoggerConfigTest extends \PHPUnit_Framework_TestCase { public function testGetFor_ReturnsPSRLogger() { From 0c12f0b98d9a7ebbf505e7335f02bdd02fea80c2 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Tue, 17 Dec 2013 15:05:08 +0000 Subject: [PATCH 07/74] fix monolog name spacing in tests. --- Tests/PHPCI/Logging/LoggerConfigTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Tests/PHPCI/Logging/LoggerConfigTest.php b/Tests/PHPCI/Logging/LoggerConfigTest.php index a8954c82..68f28f3a 100644 --- a/Tests/PHPCI/Logging/LoggerConfigTest.php +++ b/Tests/PHPCI/Logging/LoggerConfigTest.php @@ -22,7 +22,7 @@ class LoggerConfigTest extends \PHPUnit_Framework_TestCase public function testGetFor_AttachesAlwaysPresentHandlers() { - $expectedHandler = new Monolog\Handler\NullHandler(); + $expectedHandler = new \Monolog\Handler\NullHandler(); $config = new LoggerConfig(array( LoggerConfig::KEY_AlwaysLoaded => function() use ($expectedHandler) { return array($expectedHandler); @@ -38,7 +38,7 @@ class LoggerConfigTest extends \PHPUnit_Framework_TestCase public function testGetFor_AttachesSpecificHandlers() { - $expectedHandler = new Monolog\Handler\NullHandler(); + $expectedHandler = new \Monolog\Handler\NullHandler(); $config = new LoggerConfig(array( "Specific" => function() use ($expectedHandler) { return array($expectedHandler); @@ -54,8 +54,8 @@ class LoggerConfigTest extends \PHPUnit_Framework_TestCase public function testGetFor_IgnoresAlternativeHandlers() { - $expectedHandler = new Monolog\Handler\NullHandler(); - $alternativeHandler = new Monolog\Handler\NullHandler(); + $expectedHandler = new \Monolog\Handler\NullHandler(); + $alternativeHandler = new \Monolog\Handler\NullHandler(); $config = new LoggerConfig(array( "Specific" => function() use ($expectedHandler) { From 248579f67dd67eb4d2ce525f98bb4584ac60365a Mon Sep 17 00:00:00 2001 From: meadsteve Date: Tue, 17 Dec 2013 15:14:26 +0000 Subject: [PATCH 08/74] add getProjectTitle() to buildBase as shorthand for getProject()->getTitle() --- PHPCI/Model/Base/BuildBase.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/PHPCI/Model/Base/BuildBase.php b/PHPCI/Model/Base/BuildBase.php index 52a549d5..de423590 100644 --- a/PHPCI/Model/Base/BuildBase.php +++ b/PHPCI/Model/Base/BuildBase.php @@ -550,6 +550,17 @@ class BuildBase extends Model return $rtn; } + /** + * Get the value of the project's Title / title. + * + * @return string + */ + public function getProjectTitle() + { + return $this->getProject()->getTitle(); + } + + /** * Set Project - Accepts an ID, an array representing a Project or a Project model. * From f0d224ce3c8b15ff3e3ccbcdb34c06a4bc7e6829 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Tue, 17 Dec 2013 15:23:17 +0000 Subject: [PATCH 09/74] copy code from Builder to create BuildInterpolator. --- PHPCI/Helper/BuildInterpolator.php | 61 ++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 PHPCI/Helper/BuildInterpolator.php diff --git a/PHPCI/Helper/BuildInterpolator.php b/PHPCI/Helper/BuildInterpolator.php new file mode 100644 index 00000000..d4609793 --- /dev/null +++ b/PHPCI/Helper/BuildInterpolator.php @@ -0,0 +1,61 @@ + value pairs that will be used for + * interpolation and environment variables + * @var mixed[] + * @see setupInterpolationVars() + */ + protected $interpolation_vars = array(); + + /** + * Sets the variables that will be used for interpolation. + * @param Build $build + * @param string $buildPath + * @param string $phpCiUrl + */ + public function setupInterpolationVars(Build $build, $buildPath, $phpCiUrl) + { + $this->interpolation_vars = array(); + $this->interpolation_vars['%PHPCI%'] = 1; + $this->interpolation_vars['%COMMIT%'] = $build->getCommitId(); + $this->interpolation_vars['%PROJECT%'] = $build->getProjectId(); + $this->interpolation_vars['%BUILD%'] = $build->getId(); + $this->interpolation_vars['%PROJECT_TITLE%'] = $build->getProjectTitle(); + $this->interpolation_vars['%BUILD_PATH%'] = $buildPath; + $this->interpolation_vars['%BUILD_URI%'] = $phpCiUrl . "build/view/" . $build->getId(); + $this->interpolation_vars['%PHPCI_COMMIT%'] = $this->interpolation_vars['%COMMIT%']; + $this->interpolation_vars['%PHPCI_PROJECT%'] = $this->interpolation_vars['%PROJECT%']; + $this->interpolation_vars['%PHPCI_BUILD%'] = $this->interpolation_vars['%BUILD%']; + $this->interpolation_vars['%PHPCI_PROJECT_TITLE%'] = $this->interpolation_vars['%PROJECT_TITLE%']; + $this->interpolation_vars['%PHPCI_BUILD_PATH%'] = $this->interpolation_vars['%BUILD_PATH%']; + $this->interpolation_vars['%PHPCI_BUILD_URI%'] = $this->interpolation_vars['%BUILD_URI%']; + + putenv('PHPCI=1'); + putenv('PHPCI_COMMIT=' . $this->interpolation_vars['%COMMIT%']); + putenv('PHPCI_PROJECT=' . $this->interpolation_vars['%PROJECT%']); + putenv('PHPCI_BUILD=' . $this->interpolation_vars['%BUILD%']); + putenv('PHPCI_PROJECT_TITLE=' . $this->interpolation_vars['%PROJECT_TITLE%']); + putenv('PHPCI_BUILD_PATH=' . $this->interpolation_vars['%BUILD_PATH%']); + putenv('PHPCI_BUILD_URI=' . $this->interpolation_vars['%BUILD_URI%']); + } + + /** + * Replace every occurrence of the interpolation vars in the given string + * Example: "This is build %PHPCI_BUILD%" => "This is build 182" + * @param string $input + * @return string + */ + public function interpolate($input) + { + $keys = array_keys($this->interpolation_vars); + $values = array_values($this->interpolation_vars); + return str_replace($keys, $values, $input); + } +} \ No newline at end of file From 1b2f19c81f48c7f059fe8e41cd2dac7bccceead5 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Tue, 17 Dec 2013 15:24:13 +0000 Subject: [PATCH 10/74] remove interopolation code from builder and make use of BuildInterpolator object. --- PHPCI/Builder.php | 56 ++++++++++------------------------------------- 1 file changed, 12 insertions(+), 44 deletions(-) diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index d47ec3ee..dcf59f8e 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -9,6 +9,7 @@ namespace PHPCI; +use PHPCI\Helper\BuildInterpolator; use PHPCI\Helper\CommandExecutor; use PHPCI\Helper\MailerFactory; use PHPCI\Logging\BuildLogger; @@ -76,12 +77,9 @@ class Builder implements LoggerAwareInterface protected $lastOutput; /** - * An array of key => value pairs that will be used for - * interpolation and environment variables - * @var array - * @see setInterpolationVars() + * @var BuildInterpolator */ - protected $interpolation_vars = array(); + protected $interpolator; /** * @var \PHPCI\Store\BuildStore @@ -129,6 +127,8 @@ class Builder implements LoggerAwareInterface $this->verbose ); + $this->interpolator = new BuildInterpolator(); + } /** @@ -251,50 +251,14 @@ class Builder implements LoggerAwareInterface } /** - * Replace every occurance of the interpolation vars in the given string + * Replace every occurrence of the interpolation vars in the given string * Example: "This is build %PHPCI_BUILD%" => "This is build 182" * @param string $input * @return string */ public function interpolate($input) { - $keys = array_keys($this->interpolation_vars); - $values = array_values($this->interpolation_vars); - return str_replace($keys, $values, $input); - } - - /** - * Sets the variables that will be used for interpolation. This must be run - * from setupBuild() because prior to that, we don't know the buildPath - */ - protected function setInterpolationVars() - { - $this->interpolation_vars = array(); - $this->interpolation_vars['%PHPCI%'] = 1; - $this->interpolation_vars['%COMMIT%'] = $this->build->getCommitId(); - $this->interpolation_vars['%PROJECT%'] = $this->build->getProjectId(); - $this->interpolation_vars['%BUILD%'] = $this->build->getId(); - $this->interpolation_vars['%PROJECT_TITLE%'] = $this->getBuildProjectTitle( - ); - $this->interpolation_vars['%BUILD_PATH%'] = $this->buildPath; - $this->interpolation_vars['%BUILD_URI%'] = PHPCI_URL . "build/view/" . $this->build->getId( - ); - $this->interpolation_vars['%PHPCI_COMMIT%'] = $this->interpolation_vars['%COMMIT%']; - $this->interpolation_vars['%PHPCI_PROJECT%'] = $this->interpolation_vars['%PROJECT%']; - $this->interpolation_vars['%PHPCI_BUILD%'] = $this->interpolation_vars['%BUILD%']; - $this->interpolation_vars['%PHPCI_PROJECT_TITLE%'] = $this->interpolation_vars['%PROJECT_TITLE%']; - $this->interpolation_vars['%PHPCI_BUILD_PATH%'] = $this->interpolation_vars['%BUILD_PATH%']; - $this->interpolation_vars['%PHPCI_BUILD_URI%'] = $this->interpolation_vars['%BUILD_URI%']; - - putenv('PHPCI=1'); - putenv('PHPCI_COMMIT=' . $this->interpolation_vars['%COMMIT%']); - putenv('PHPCI_PROJECT=' . $this->interpolation_vars['%PROJECT%']); - putenv('PHPCI_BUILD=' . $this->interpolation_vars['%BUILD%']); - putenv( - 'PHPCI_PROJECT_TITLE=' . $this->interpolation_vars['%PROJECT_TITLE%'] - ); - putenv('PHPCI_BUILD_PATH=' . $this->interpolation_vars['%BUILD_PATH%']); - putenv('PHPCI_BUILD_URI=' . $this->interpolation_vars['%BUILD_URI%']); + return $this->interpolator->interpolate($input); } /** @@ -307,7 +271,11 @@ class Builder implements LoggerAwareInterface $this->ciDir = dirname(__FILE__) . '/../'; $this->buildPath = $this->ciDir . 'build/' . $buildId . '/'; - $this->setInterpolationVars(); + $this->interpolator->setupInterpolationVars( + $this->build, + $this->buildPath, + PHPCI_URL + ); // Create a working copy of the project: if (!$this->build->createWorkingCopy($this, $this->buildPath)) { From e32635c4747bc696f1a53aef7c33345003a0c031 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Tue, 17 Dec 2013 15:35:18 +0000 Subject: [PATCH 11/74] add very basic tests for BuildInterpolator --- Tests/PHPCI/Helper/BuildInterpolatorTest.php | 49 ++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Tests/PHPCI/Helper/BuildInterpolatorTest.php diff --git a/Tests/PHPCI/Helper/BuildInterpolatorTest.php b/Tests/PHPCI/Helper/BuildInterpolatorTest.php new file mode 100644 index 00000000..c45e1b8c --- /dev/null +++ b/Tests/PHPCI/Helper/BuildInterpolatorTest.php @@ -0,0 +1,49 @@ +testedInterpolator = new BuildInterpolator(); + } + + public function testInterpolate_LeavesStringsUnchangedByDefault() + { + $string = "Hello World"; + $expectedOutput = "Hello World"; + + $actualOutput = $this->testedInterpolator->interpolate($string); + + $this->assertEquals($expectedOutput, $actualOutput); + } + + public function testInterpolate_LeavesStringsUnchangedWhenBuildIsSet() + { + $build = $this->prophesize('PHPCI\\Model\\Build')->reveal(); + + $string = "Hello World"; + $expectedOutput = "Hello World"; + + $this->testedInterpolator->setupInterpolationVars( + $build, + "/buildpath/", + "phpci.com" + ); + + $actualOutput = $this->testedInterpolator->interpolate($string); + + $this->assertEquals($expectedOutput, $actualOutput); + } +} + \ No newline at end of file From cfb0db5b81a778aba8f6f323c2103cb3bcb0f325 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Tue, 17 Dec 2013 15:44:49 +0000 Subject: [PATCH 12/74] fixing builder so that PluginExecutor receives BuildLogger instance --- PHPCI/Builder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index dcf59f8e..738f7bf3 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -118,7 +118,7 @@ class Builder implements LoggerAwareInterface $this->buildLogger = new BuildLogger($logger, $build); - $this->pluginExecutor = new Plugin\Util\Executor($this->buildPluginFactory($build), $this); + $this->pluginExecutor = new Plugin\Util\Executor($this->buildPluginFactory($build), $this->buildLogger); $this->commandExecutor = new CommandExecutor( $this->buildLogger, From 71588cd8e1e53d55553efeb79e1049d3ae742519 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Sun, 29 Dec 2013 17:34:41 +0000 Subject: [PATCH 13/74] add LoadedPluginInformation class to process composer's installed.json file and pull out information about phpci plugins. --- PHPCI/Plugin/Util/LoadedPluginInformation.php | 147 ++++++++++++++++++ .../Util/LoadedPluginInformationTest.php | 51 ++++++ 2 files changed, 198 insertions(+) create mode 100644 PHPCI/Plugin/Util/LoadedPluginInformation.php create mode 100644 Tests/PHPCI/Plugin/Util/LoadedPluginInformationTest.php diff --git a/PHPCI/Plugin/Util/LoadedPluginInformation.php b/PHPCI/Plugin/Util/LoadedPluginInformation.php new file mode 100644 index 00000000..89107129 --- /dev/null +++ b/PHPCI/Plugin/Util/LoadedPluginInformation.php @@ -0,0 +1,147 @@ +composerPackages = $composerPackages; + } + + /** + * Returns an array of objects. Each one represents an available plugin + * and will have the following properties: + * name - The friendly name of the plugin (may be an empty string) + * class - The class of the plugin (will include namespace) + * @return \stdClass[] + */ + public function getInstalledPlugins() + { + $this->loadPluginInfo(); + return $this->pluginInfo; + } + + /** + * Returns an array of all the class names of plugins that have been + * loaded. + * + * @return string[] + */ + public function getPluginClasses() + { + return array_map( + function($plugin) { + return $plugin->class; + }, + $this->getInstalledPlugins() + ); + } + + protected function loadPluginInfo() + { + if ($this->pluginInfo !== null) { + return; + } + $this->pluginInfo = array(); + foreach($this->composerPackages as $package) { + $this->addPluginsFromPackage($package); + } + } + + /** + * @param \stdClass $package + */ + protected function addPluginsFromPackage($package) + { + if (isset($package->extra->phpci)) { + $phpciData = $package->extra->phpci; + + if (isset($phpciData->pluginNamespace)) { + $rootNamespace = $phpciData->pluginNamespace; + } + else { + $rootNamespace = ""; + } + + if (is_array($phpciData->suppliedPlugins)) { + $this->addPlugins( + $phpciData->suppliedPlugins, + $package->name, + $rootNamespace + ); + } + } + } + + /** + * @param \stdClass[] $plugins + * @param string $sourcePackageName + * @param string $rootNamespace + */ + protected function addPlugins( + array $plugins, + $sourcePackageName, + $rootNamespace = "") + { + foreach($plugins as $plugin) { + if (!isset($plugin->class)) { + continue; + } + $this->addPlugin($plugin, $sourcePackageName, $rootNamespace); + } + } + + /** + * @param \stdClass $plugin + * @param string $sourcePackageName + * @param string $rootNamespace + */ + protected function addPlugin( + $plugin, + $sourcePackageName, + $rootNamespace = "") + { + $newPlugin = clone $plugin; + + $newPlugin->class = $rootNamespace . $newPlugin->class; + + if (!isset($newPlugin->name)) { + $newPlugin->name = ""; + } + + $newPlugin->source = $sourcePackageName; + + $this->pluginInfo[] = $newPlugin; + } +} \ No newline at end of file diff --git a/Tests/PHPCI/Plugin/Util/LoadedPluginInformationTest.php b/Tests/PHPCI/Plugin/Util/LoadedPluginInformationTest.php new file mode 100644 index 00000000..a5c6c02f --- /dev/null +++ b/Tests/PHPCI/Plugin/Util/LoadedPluginInformationTest.php @@ -0,0 +1,51 @@ +testedInformation = LoadedPluginInformation::buildFromYaml($file); + } + + protected function phpciSetup() + { + $this->setUpFromFile( + __DIR__ . "/../../../../vendor/composer/installed.json" + ); + } + + public function testBuildFromYaml_ReturnsInstance() + { + $this->phpciSetup(); + $this->assertInstanceOf( + '\PHPCI\Plugin\Util\LoadedPluginInformation', + $this->testedInformation + ); + } + + public function testGetInstalledPlugins_ReturnsStdClassArray() + { + $this->phpciSetup(); + $plugins = $this->testedInformation->getInstalledPlugins(); + $this->assertInternalType("array", $plugins); + $this->assertContainsOnly("stdClass", $plugins); + } + + public function testGetPluginClasses_ReturnsStringArray() + { + $this->phpciSetup(); + $classes = $this->testedInformation->getPluginClasses(); + $this->assertInternalType("array", $classes); + $this->assertContainsOnly("string", $classes); + } +} + \ No newline at end of file From 4b9207e05f5826fe64b8f60a56211ad281d2c5fc Mon Sep 17 00:00:00 2001 From: meadsteve Date: Sun, 29 Dec 2013 17:35:33 +0000 Subject: [PATCH 14/74] update plugin controller to display plugin information as well as composer package information. --- PHPCI/Controller/PluginController.php | 10 ++++++-- PHPCI/View/Plugin/index.phtml | 37 ++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/PHPCI/Controller/PluginController.php b/PHPCI/Controller/PluginController.php index 56d01f3e..c0654a7d 100644 --- a/PHPCI/Controller/PluginController.php +++ b/PHPCI/Controller/PluginController.php @@ -11,6 +11,7 @@ namespace PHPCI\Controller; use b8; use PHPCI\Model\Build; +use PHPCI\Plugin\Util\LoadedPluginInformation; /** * Plugin Controller - Provides support for installing Composer packages. @@ -59,8 +60,13 @@ class PluginController extends \PHPCI\Controller $this->view->required = $this->required; $json = $this->getComposerJson(); - $this->view->installed = $json['require']; - $this->view->suggested = $json['suggest']; + $this->view->installedPackages = $json['require']; + $this->view->suggestedPackages = $json['suggest']; + + $pluginInfo = LoadedPluginInformation::buildFromYaml( + PHPCI_DIR . "vendor/composer/installed.json" + ); + $this->view->plugins = $pluginInfo->getInstalledPlugins(); return $this->view->render(); } diff --git a/PHPCI/View/Plugin/index.phtml b/PHPCI/View/Plugin/index.phtml index f9170032..d2731f2f 100644 --- a/PHPCI/View/Plugin/index.phtml +++ b/PHPCI/View/Plugin/index.phtml @@ -1,4 +1,4 @@ -

Plugins

+

Packages and Provided Plugins

PHPCI cannot automatically install/remove plugins for you, as either the shell_exec() function is disabled or PHPCI could not find Composer. PHPCI will update composer.json for you, but you will need to run Composer manually to make the changes.

@@ -21,7 +21,30 @@
-

Installed Plugins

+

Available Plugins

+ + + + + + + + + + + + + + + + + + +
NameClassProvided by Package
name; ?>class; ?>source; ?>
+
+ +
+

Installed Packages

@@ -32,7 +55,7 @@ - $version): ?> + $version): ?> @@ -48,7 +71,7 @@
-

Suggested Plugins

+

Suggested Packages

@@ -59,8 +82,8 @@ - $version): ?> - + $version): ?> + @@ -76,7 +99,7 @@
-

Search Packagist for More Plugins

+

Search Packagist for More Packages

From df2a8aeac2d23321dba5fe4fe1e8fba533b6330e Mon Sep 17 00:00:00 2001 From: Pavel Pavlov Date: Tue, 31 Dec 2013 04:15:34 +0400 Subject: [PATCH 15/74] Fixes #236 Javascript bug, delete build error --- PHPCI/View/BuildsTable.phtml | 2 +- PHPCI/View/Home/index.phtml | 4 +++- PHPCI/View/User/index.phtml | 2 +- PHPCI/View/layout.phtml | 1 + public/assets/js/init.js | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 public/assets/js/init.js diff --git a/PHPCI/View/BuildsTable.phtml b/PHPCI/View/BuildsTable.phtml index 09cdd09b..d2cdc736 100644 --- a/PHPCI/View/BuildsTable.phtml +++ b/PHPCI/View/BuildsTable.phtml @@ -73,7 +73,7 @@ switch($build->getStatus())
diff --git a/PHPCI/View/Home/index.phtml b/PHPCI/View/Home/index.phtml index 5e48573c..791888ea 100644 --- a/PHPCI/View/Home/index.phtml +++ b/PHPCI/View/Home/index.phtml @@ -60,7 +60,9 @@ +
- - + $version): ?> - - + + @@ -62,11 +62,11 @@ $version): ?> - - + + diff --git a/PHPCI/View/Project/view.phtml b/PHPCI/View/Project/view.phtml index 036f9837..b5957260 100644 --- a/PHPCI/View/Project/view.phtml +++ b/PHPCI/View/Project/view.phtml @@ -5,15 +5,15 @@
Options
@@ -86,14 +86,14 @@ \ No newline at end of file + diff --git a/PHPCI/View/Session/login.phtml b/PHPCI/View/Session/login.phtml index 59027b0e..2314a639 100644 --- a/PHPCI/View/Session/login.phtml +++ b/PHPCI/View/Session/login.phtml @@ -5,9 +5,9 @@ - + - +
#getId(), 6, '0', STR_PAD_LEFT); ?> + #getId(), 6, '0', STR_PAD_LEFT); ?> getProject())) { print htmlspecialchars($build->getProject()->getTitle()); @@ -56,24 +56,24 @@ switch($build->getStatus()) $plugins = array(); } if ( 0 === count($plugins) ) { - ?> $pluginstatus): $subcls = $pluginstatus?'label label-success':'label label-danger'; - ?> Build()->formatPluginName($plugin); ?> + ?> Build()->formatPluginName($plugin); ?>
- View + View User()->getIsAdmin()): ?>
diff --git a/PHPCI/View/Home/index.phtml b/PHPCI/View/Home/index.phtml index 791888ea..44c5af1d 100644 --- a/PHPCI/View/Home/index.phtml +++ b/PHPCI/View/Home/index.phtml @@ -4,14 +4,14 @@
Projects
@@ -60,10 +60,10 @@ \ No newline at end of file + diff --git a/PHPCI/View/Plugin/index.phtml b/PHPCI/View/Plugin/index.phtml index f9170032..134cf260 100644 --- a/PHPCI/View/Plugin/index.phtml +++ b/PHPCI/View/Plugin/index.phtml @@ -9,15 +9,15 @@ -

has been removed.

+

has been removed.

-

has been installed.

+

has been installed.

-

has been added to composer.json and will be installed next time you run composer update.

+

has been added to composer.json and will be installed next time you run composer update.

@@ -34,11 +34,11 @@
- Remove » + Remove »
- +