diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index 69db31e1..7365f42f 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -10,7 +10,6 @@ namespace PHPCI; use PHPCI\Helper\BuildInterpolator; -use PHPCI\Helper\CommandExecutor; use PHPCI\Helper\MailerFactory; use PHPCI\Logging\BuildLogger; use PHPCI\Model\Build; @@ -118,7 +117,12 @@ class Builder implements LoggerAwareInterface $pluginFactory->addConfigFromFile(PHPCI_DIR . "/pluginconfig.php"); $this->pluginExecutor = new Plugin\Util\Executor($pluginFactory, $this->buildLogger); - $this->commandExecutor = new CommandExecutor( + $executorClass = 'PHPCI\Helper\UnixCommandExecutor'; + if (IS_WIN) { + $executorClass = 'PHPCI\Helper\WindowsCommandExecutor'; + } + + $this->commandExecutor = new $executorClass( $this->buildLogger, PHPCI_DIR, $this->quiet, @@ -126,7 +130,6 @@ class Builder implements LoggerAwareInterface ); $this->interpolator = new BuildInterpolator(); - } /** diff --git a/PHPCI/Helper/BaseCommandExecutor.php b/PHPCI/Helper/BaseCommandExecutor.php new file mode 100644 index 00000000..7dbd7b18 --- /dev/null +++ b/PHPCI/Helper/BaseCommandExecutor.php @@ -0,0 +1,101 @@ +logger = $logger; + $this->quiet = $quiet; + $this->verbose = $verbose; + + $this->lastOutput = array(); + + $this->rootDir = $rootDir; + } + + /** + * Executes shell commands. + * @param array $args + * @return bool Indicates success + */ + public function executeCommand($args = array()) + { + $this->lastOutput = array(); + + $command = call_user_func_array('sprintf', $args); + + if ($this->quiet) { + $this->logger->log('Executing: ' . $command); + } + + $status = 0; + exec($command, $this->lastOutput, $status); + + foreach ($this->lastOutput as &$lastOutput) { + $lastOutput = trim($lastOutput, '"'); + } + + if ($this->logExecOutput && !empty($this->lastOutput) && ($this->verbose|| $status != 0)) { + $this->logger->log($this->lastOutput); + } + + $rtn = false; + + if ($status == 0) { + $rtn = true; + } + + return $rtn; + } + + /** + * Returns the output from the last command run. + */ + public function getLastOutput() + { + return implode(PHP_EOL, $this->lastOutput); + } + + /** + * Find a binary required by a plugin. + * @param string $binary + * @return null|string + */ + abstract public function findBinary($binary); +} diff --git a/PHPCI/Helper/CommandExecutor.php b/PHPCI/Helper/CommandExecutor.php index 438829af..633618bb 100644 --- a/PHPCI/Helper/CommandExecutor.php +++ b/PHPCI/Helper/CommandExecutor.php @@ -2,133 +2,24 @@ namespace PHPCI\Helper; - -use \PHPCI\Logging\BuildLogger; -use Psr\Log\LogLevel; - -class CommandExecutor +interface CommandExecutor { /** - * @var \PHPCI\Logging\BuildLogger - */ - protected $logger; - - /** - * @var bool - */ - protected $quiet; - - /** - * @var bool - */ - protected $verbose; - - protected $lastOutput; - - public $logExecOutput = true; - - - /** - * The path which findBinary will look in. - * @var string - */ - protected $rootDir; - - /** - * @param BuildLogger $logger - * @param $rootDir - * @param bool $quiet - * @param bool $verbose - */ - public function __construct(BuildLogger $logger, $rootDir, &$quiet = false, &$verbose = false) - { - $this->logger = $logger; - $this->quiet = $quiet; - $this->verbose = $verbose; - - $this->lastOutput = array(); - - $this->rootDir = $rootDir; - } - - /** - * Executes shell commands. - * @param array $args + * Executes shell commands. Accepts multiple arguments the first + * is the template and everything else is inserted in. c.f. sprintf * @return bool Indicates success */ - public function executeCommand($args = array()) - { - $this->lastOutput = array(); - - $command = call_user_func_array('sprintf', $args); - - if ($this->quiet) { - $this->logger->log('Executing: ' . $command); - } - - $status = 0; - exec($command, $this->lastOutput, $status); - - foreach ($this->lastOutput as &$lastOutput) { - $lastOutput = trim($lastOutput, '"'); - } - - if ($this->logExecOutput && !empty($this->lastOutput) && ($this->verbose|| $status != 0)) { - $this->logger->log($this->lastOutput); - } - - $rtn = false; - - if ($status == 0) { - $rtn = true; - } - - return $rtn; - } + public function executeCommand(); /** * Returns the output from the last command run. */ - public function getLastOutput() - { - return implode(PHP_EOL, $this->lastOutput); - } + public function getLastOutput(); /** * Find a binary required by a plugin. - * @param $binary + * @param string $binary * @return null|string */ - public function findBinary($binary) - { - if (is_string($binary)) { - $binary = array($binary); - } - - foreach ($binary as $bin) { - $this->logger->log("Looking for binary: " . $bin, LogLevel::DEBUG); - // Check project root directory: - if (is_file($this->rootDir . $bin)) { - $this->logger->log("Found in root: " . $bin, LogLevel::DEBUG); - return $this->rootDir . $bin; - } - - // Check Composer bin dir: - if (is_file($this->rootDir . 'vendor/bin/' . $bin)) { - $this->logger->log("Found in vendor/bin: " . $bin, LogLevel::DEBUG); - return $this->rootDir . 'vendor/bin/' . $bin; - } - - // Use "where" for windows and "which" for other OS - $findCmd = IS_WIN ? 'where' : 'which'; - $findCmdResult = trim(shell_exec($findCmd . ' ' . $bin)); - - if (!empty($findCmdResult)) { - $this->logger->log("Found in " . $findCmdResult, LogLevel::DEBUG); - return $findCmdResult; - } - } - - return null; - } + public function findBinary($binary); } diff --git a/PHPCI/Helper/UnixCommandExecutor.php b/PHPCI/Helper/UnixCommandExecutor.php new file mode 100644 index 00000000..5ab0fbc0 --- /dev/null +++ b/PHPCI/Helper/UnixCommandExecutor.php @@ -0,0 +1,46 @@ +logger->log("Looking for binary: " . $bin, LogLevel::DEBUG); + + if (is_file($this->rootDir . $bin)) { + $this->logger->log("Found in root: " . $bin, LogLevel::DEBUG); + $binaryPath = $this->rootDir . $bin; + break; + } + + if (is_file($this->rootDir . 'vendor/bin/' . $bin)) { + $this->logger->log("Found in vendor/bin: " . $bin, LogLevel::DEBUG); + $binaryPath = $this->rootDir . 'vendor/bin/' . $bin; + break; + } + + $findCmdResult = trim(shell_exec('which ' . $bin)); + if (!empty($findCmdResult)) { + $this->logger->log("Found in " . $findCmdResult, LogLevel::DEBUG); + $binaryPath = $findCmdResult; + break; + } + } + return $binaryPath; + } +} diff --git a/PHPCI/Helper/WindowsCommandExecutor.php b/PHPCI/Helper/WindowsCommandExecutor.php new file mode 100644 index 00000000..83136d2a --- /dev/null +++ b/PHPCI/Helper/WindowsCommandExecutor.php @@ -0,0 +1,46 @@ +logger->log("Looking for binary: " . $bin, LogLevel::DEBUG); + + if (is_file($this->rootDir . $bin)) { + $this->logger->log("Found in root: " . $bin, LogLevel::DEBUG); + $binaryPath = $this->rootDir . $bin; + break; + } + + if (is_file($this->rootDir . 'vendor/bin/' . $bin)) { + $this->logger->log("Found in vendor/bin: " . $bin, LogLevel::DEBUG); + $binaryPath = $this->rootDir . 'vendor/bin/' . $bin; + break; + } + + $findCmdResult = trim(shell_exec('where ' . $bin)); + if (!empty($findCmdResult)) { + $this->logger->log("Found in " . $findCmdResult, LogLevel::DEBUG); + $binaryPath = $findCmdResult; + break; + } + } + return $binaryPath; + } +} diff --git a/PHPCI/Plugin.php b/PHPCI/Plugin.php index 6f915e3b..d4e90ef0 100644 --- a/PHPCI/Plugin.php +++ b/PHPCI/Plugin.php @@ -9,7 +9,6 @@ namespace PHPCI; -use PHPCI\Builder; use PHPCI\Model\Build; /** diff --git a/PHPCI/Plugin/CleanBuild.php b/PHPCI/Plugin/CleanBuild.php index 73a7305f..38c1ccde 100644 --- a/PHPCI/Plugin/CleanBuild.php +++ b/PHPCI/Plugin/CleanBuild.php @@ -38,6 +38,9 @@ class CleanBuild implements \PHPCI\Plugin public function execute() { $cmd = 'rm -Rf "%s"'; + if (IS_WIN) { + $cmd = 'rmdir /S /Q "%s"'; + } $this->phpci->executeCommand($cmd, $this->phpci->buildPath . 'composer.phar'); $this->phpci->executeCommand($cmd, $this->phpci->buildPath . 'composer.lock'); diff --git a/PHPCI/Plugin/CopyBuild.php b/PHPCI/Plugin/CopyBuild.php index 021d5e80..83ed6ebe 100644 --- a/PHPCI/Plugin/CopyBuild.php +++ b/PHPCI/Plugin/CopyBuild.php @@ -46,11 +46,17 @@ class CopyBuild implements \PHPCI\Plugin } $cmd = 'mkdir -p "%s" && cp -R "%s" "%s"'; + if (IS_WIN) { + $cmd = 'mkdir -p "%s" && xcopy /E "%s" "%s"'; + } $success = $this->phpci->executeCommand($cmd, $this->directory, $build, $this->directory); if ($this->ignore) { foreach ($this->phpci->ignore as $file) { $cmd = 'rm -Rf "%s/%s"'; + if (IS_WIN) { + $cmd = 'rmdir /S /Q "%s\%s"'; + } $this->phpci->executeCommand($cmd, $this->directory, $file); } } diff --git a/PHPCI/Plugin/Mysql.php b/PHPCI/Plugin/Mysql.php index c66f77cb..d2a4314e 100755 --- a/PHPCI/Plugin/Mysql.php +++ b/PHPCI/Plugin/Mysql.php @@ -22,24 +22,41 @@ use PHPCI\Model\Build; */ class Mysql implements \PHPCI\Plugin { - /** * @var \PHPCI\Builder */ protected $phpci; + + /** + * @var \PHPCI\Model\Build + */ protected $build; + + /** + * @var array + */ protected $queries = array(); + /** + * @var string + */ protected $host; + + /** + * @var string + */ protected $user; + + /** + * @var string + */ protected $pass; /** - * Database Connection - * @var PDO + * @param Builder $phpci + * @param Build $build + * @param array $options */ - protected $pdo; - public function __construct(Builder $phpci, Build $build, array $options = array()) { $this->phpci = $phpci; @@ -74,19 +91,18 @@ class Mysql implements \PHPCI\Plugin /** * Connects to MySQL and runs a specified set of queries. + * @return boolean */ public function execute() { - $success = true; - try { $opts = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION); - $this->pdo = new PDO('mysql:host=' . $this->host, $this->user, $this->pass, $opts); + $pdo = new PDO('mysql:host=' . $this->host, $this->user, $this->pass, $opts); foreach ($this->queries as $query) { if (!is_array($query)) { // Simple query - $this->pdo->query($this->phpci->interpolate($query)); + $pdo->query($this->phpci->interpolate($query)); } elseif (isset($query['import'])) { // SQL file execution $this->executeFile($query['import']); @@ -98,10 +114,14 @@ class Mysql implements \PHPCI\Plugin $this->phpci->logFailure($ex->getMessage()); return false; } - - return $success; + return true; } + /** + * @param string $query + * @return boolean + * @throws \Exception + */ protected function executeFile($query) { if (!isset($query['file'])) { diff --git a/PHPCI/Plugin/Pgsql.php b/PHPCI/Plugin/Pgsql.php index a05068d2..e4001132 100644 --- a/PHPCI/Plugin/Pgsql.php +++ b/PHPCI/Plugin/Pgsql.php @@ -21,18 +21,45 @@ use PHPCI\Model\Build; */ class Pgsql implements \PHPCI\Plugin { + /** + * @var \PHPCI\Builder + */ protected $phpci; + + /** + * @var \PHPCI\Model\Build + */ protected $build; + + /** + * @var array + */ protected $queries = array(); + /** + * @var string + */ protected $host; + + /** + * @var string + */ protected $user; + + /** + * @var string + */ protected $pass; + /** + * @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->phpci = $phpci; + $this->build = $build; $this->queries = $options; $buildSettings = $phpci->getConfig('build_settings'); @@ -47,6 +74,7 @@ class Pgsql implements \PHPCI\Plugin /** * Connects to PgSQL and runs a specified set of queries. + * @return boolean */ public function execute() { @@ -61,7 +89,6 @@ class Pgsql implements \PHPCI\Plugin $this->phpci->logFailure($ex->getMessage()); return false; } - return true; } } diff --git a/PHPCI/Plugin/Sqlite.php b/PHPCI/Plugin/Sqlite.php new file mode 100644 index 00000000..4753b6e7 --- /dev/null +++ b/PHPCI/Plugin/Sqlite.php @@ -0,0 +1,81 @@ + +* @package PHPCI +* @subpackage Plugins +*/ +class Sqlite implements \PHPCI\Plugin +{ + /** + * @var \PHPCI\Builder + */ + protected $phpci; + + /** + * @var \PHPCI\Model\Build + */ + protected $build; + + /** + * @var array + */ + protected $queries = array(); + + /** + * @var string + */ + protected $path; + + /** + * @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->queries = $options; + $buildSettings = $phpci->getConfig('build_settings'); + + if (isset($buildSettings['sqlite'])) { + $sql = $buildSettings['sqlite']; + $this->path = $sql['path']; + } + } + + /** + * Connects to SQLite and runs a specified set of queries. + * @return boolean + */ + public function execute() + { + try { + $opts = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION); + $pdo = new PDO('sqlite:' . $this->path, $opts); + + foreach ($this->queries as $query) { + $pdo->query($query); + } + } catch (\Exception $ex) { + $this->phpci->logFailure($ex->getMessage()); + return false; + } + return true; + } +} diff --git a/PHPCI/Plugin/Wipe.php b/PHPCI/Plugin/Wipe.php index 7a0c2107..4d55009c 100644 --- a/PHPCI/Plugin/Wipe.php +++ b/PHPCI/Plugin/Wipe.php @@ -52,7 +52,10 @@ class Wipe implements \PHPCI\Plugin return true; } if (is_dir($this->directory)) { - $cmd = 'rm -rf %s*'; + $cmd = 'rm -Rf "%s"'; + if (IS_WIN) { + $cmd = 'rmdir /S /Q "%s"'; + } $success = $this->phpci->executeCommand($cmd, $this->directory); } return $success; diff --git a/Tests/PHPCI/Helper/CommandExecutorTest.php b/Tests/PHPCI/Helper/CommandExecutorTest.php index ae6809d5..8ae045dc 100644 --- a/Tests/PHPCI/Helper/CommandExecutorTest.php +++ b/Tests/PHPCI/Helper/CommandExecutorTest.php @@ -2,13 +2,13 @@ namespace PHPCI\Plugin\Tests\Helper; -use PHPCI\Helper\CommandExecutor; +use PHPCI\Helper\UnixCommandExecutor; use \Prophecy\PhpUnit\ProphecyTestCase; class CommandExecutorTest extends ProphecyTestCase { /** - * @var CommandExecutor + * @var UnixCommandExecutor */ protected $testedExecutor; @@ -16,7 +16,7 @@ class CommandExecutorTest extends ProphecyTestCase { parent::setUp(); $mockBuildLogger = $this->prophesize('PHPCI\Logging\BuildLogger'); - $this->testedExecutor = new CommandExecutor($mockBuildLogger->reveal(), __DIR__ . "/"); + $this->testedExecutor = new UnixCommandExecutor($mockBuildLogger->reveal(), __DIR__ . "/"); } public function testGetLastOutput_ReturnsOutputOfCommand() diff --git a/public/assets/css/phpci.css b/public/assets/css/phpci.css index 7093c2aa..ce98017a 100644 --- a/public/assets/css/phpci.css +++ b/public/assets/css/phpci.css @@ -80,4 +80,8 @@ h1 { position: absolute; right: 25px; width: 200px; +} + +.panel-body { + overflow: auto; } \ No newline at end of file