This commit is contained in:
Steve Kamerman 2013-05-16 13:40:22 -04:00
commit 6ad3c0894e
24 changed files with 191 additions and 9 deletions

View file

@ -20,6 +20,10 @@ use PHPCI\Model\Build\BitbucketBuild;
*/
class BuildFactory
{
/**
* Takes a generic build and returns a type-specific build model.
* @return PHPCI\Model\Build\LocalBuild|PHPCI\Model\Build\GithubBuild|PHPCI\Model\Build\BitbucketBuild
*/
public static function getBuild(Build $base)
{
switch($base->getProject()->getType())

View file

@ -30,6 +30,9 @@ class GenerateCommand extends Command
->setDescription('Generate models and stores from the database.');
}
/**
* Generates Model and Store classes by reading database meta data.
*/
protected function execute()
{
$gen = new \b8\Database\CodeGenerator(\b8\Database::getConnection(), 'PHPCI', PHPCI_DIR . '/PHPCI/');

View file

@ -32,16 +32,21 @@ class InstallCommand extends Command
->setDescription('Install PHPCI.');
}
/**
* Installs PHPCI - Can be run more than once as long as you ^C instead of entering an email address.
*/
protected function execute()
{
// Gather initial data from the user:
$dbHost = $this->ask('Enter your MySQL host: ');
$dbName = $this->ask('Enter the database name PHPCI should use: ');
$dbUser = $this->ask('Enter your MySQL username: ');
$dbPass = $this->ask('Enter your MySQL password: ', true);
$ciUrl = $this->ask('Your PHPCI URL (without trailing slash): ', true);
$ciUrl = $this->ask('Your PHPCI URL (without trailing slash): ');
$ghId = $this->ask('(Optional) Github Application ID: ', true);
$ghSecret = $this->ask('(Optional) Github Application Secret: ', true);
// Create the database if it doesn't exist:
$cmd = 'mysql -u' . $dbUser . (!empty($dbPass) ? ' -p' . $dbPass : '') . ' -h' . $dbHost .
' -e "CREATE DATABASE IF NOT EXISTS ' . $dbName . '"';
@ -61,21 +66,28 @@ b8\Database::setReadServers(array('{$dbHost}'));
\$registry->set('install_url', '{$ciUrl}');
";
// Has the user entered Github app details? If so add those to config:
if (!empty($ghId) && !empty($ghSecret)) {
$str .= PHP_EOL .
"\$registry->set('github_app', array('id' => '{$ghId}', 'secret' => '{$ghSecret}'));" .
PHP_EOL;
}
// Write the config file and then re-bootstrap:
file_put_contents(PHPCI_DIR . 'config.php', $str);
require(PHPCI_DIR . 'bootstrap.php');
// Update the database:
$gen = new \b8\Database\Generator(\b8\Database::getConnection(), 'PHPCI', './PHPCI/Model/Base/');
$gen->generate();
$adminEmail = $this->ask('Enter your email address: ');
// Try to create a user account:
$adminEmail = $this->ask('Enter your email address (leave blank if updating): ', true);
if (empty($adminEmail)) {
return;
}
$adminPass = $this->ask('Enter your desired admin password: ');
$adminName = $this->ask('Enter your name: ');

View file

@ -33,6 +33,9 @@ class RunCommand extends Command
->setDescription('Run all pending PHPCI builds.');
}
/**
* Pulls all pending builds from the database and runs them.
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->output = $output;
@ -53,6 +56,10 @@ class RunCommand extends Command
}
}
/**
* Called when log entries are made in Builder / the plugins.
* @see \PHPCI\Builder::log()
*/
public function logCallback($log)
{
$this->output->writeln($log);

View file

@ -26,6 +26,9 @@ class BitbucketController extends b8\Controller
$this->_buildStore = Store\Factory::getStore('Build');
}
/**
* Called by Bitbucket POST service.
*/
public function webhook($project)
{
$payload = json_decode($this->getParam('payload'), true);

View file

@ -26,6 +26,9 @@ class BuildController extends b8\Controller
$this->_buildStore = b8\Store\Factory::getStore('Build');
}
/**
* View a specific build.
*/
public function view($buildId)
{
$build = $this->_buildStore->getById($buildId);
@ -37,11 +40,17 @@ class BuildController extends b8\Controller
return $view->render();
}
/**
* AJAX call to get build data:
*/
public function data($buildId)
{
die($this->getBuildData($buildId));
}
/**
* Get build data from database and json encode it:
*/
protected function getBuildData($buildId)
{
$build = $this->_buildStore->getById($buildId);
@ -57,6 +66,9 @@ class BuildController extends b8\Controller
return json_encode($data);
}
/**
* Create a build using an existing build as a template:
*/
public function rebuild($buildId)
{
$copy = $this->_buildStore->getById($buildId);
@ -73,6 +85,9 @@ class BuildController extends b8\Controller
header('Location: /build/view/' . $build->getId());
}
/**
* Delete a build.
*/
public function delete($buildId)
{
if (!Registry::getInstance()->get('user')->getIsAdmin()) {
@ -85,6 +100,9 @@ class BuildController extends b8\Controller
header('Location: /project/view/' . $build->getProjectId());
}
/**
* Parse log for unix colours and replace with HTML.
*/
protected function cleanLog($log)
{
$log = str_replace('[0;32m', '<span style="color: green">', $log);

View file

@ -26,6 +26,9 @@ class GithubController extends b8\Controller
$this->_buildStore = Store\Factory::getStore('Build');
}
/**
* Called by Github Webhooks:
*/
public function webhook($project)
{
$payload = json_decode($this->getParam('payload'), true);

View file

@ -25,6 +25,9 @@ class IndexController extends b8\Controller
$this->_projectStore = b8\Store\Factory::getStore('Project');
}
/**
* Display PHPCI dashboard:
*/
public function index()
{
$projects = $this->_projectStore->getWhere(array(), 50, 0, array(), array('title' => 'ASC'));
@ -35,11 +38,17 @@ class IndexController extends b8\Controller
return $view->render();
}
/**
* AJAX get latest builds table (HTML)
*/
public function latest()
{
die($this->getLatestBuildsHtml());
}
/**
* Get latest builds and render as a table.
*/
protected function getLatestBuildsHtml()
{
$builds = $this->_buildStore->getWhere(array(), 10, 0, array(), array('id' => 'DESC'));

View file

@ -29,6 +29,9 @@ class ProjectController extends b8\Controller
$this->_projectStore = b8\Store\Factory::getStore('Project');
}
/**
* View a specific project.
*/
public function view($projectId)
{
$project = $this->_projectStore->getById($projectId);
@ -44,6 +47,9 @@ class ProjectController extends b8\Controller
return $view->render();
}
/**
* Create a new pending build for a project.
*/
public function build($projectId)
{
$build = new Build();
@ -58,6 +64,9 @@ class ProjectController extends b8\Controller
header('Location: /build/view/' . $build->getId());
}
/**
* Delete a project.
*/
public function delete($projectId)
{
if (!Registry::getInstance()->get('user')->getIsAdmin()) {
@ -70,12 +79,18 @@ class ProjectController extends b8\Controller
header('Location: /');
}
/**
* AJAX get latest builds.
*/
public function builds($projectId)
{
$builds = $this->getLatestBuildsHtml($projectId);
die($builds[0]);
}
/**
* Render latest builds for project as HTML table.
*/
protected function getLatestBuildsHtml($projectId, $start = 0)
{
$criteria = array('project_id' => $projectId);
@ -87,6 +102,9 @@ class ProjectController extends b8\Controller
return array($view->render(), $builds['count']);
}
/**
* Add a new project. Handles both the form, and processing.
*/
public function add()
{
if (!Registry::getInstance()->get('user')->getIsAdmin()) {
@ -150,6 +168,9 @@ class ProjectController extends b8\Controller
die;
}
/**
* Handles log in with Github
*/
protected function handleGithubResponse()
{
$github = \b8\Registry::getInstance()->get('github_app');
@ -170,6 +191,9 @@ class ProjectController extends b8\Controller
}
}
/**
* Edit a project. Handles both the form and processing.
*/
public function edit($projectId)
{
if (!Registry::getInstance()->get('user')->getIsAdmin()) {
@ -208,6 +232,9 @@ class ProjectController extends b8\Controller
die;
}
/**
* Create add / edit project form.
*/
protected function projectForm($values, $type = 'add')
{
$form = new Form();
@ -289,6 +316,9 @@ class ProjectController extends b8\Controller
return $form;
}
/**
* Get an array of repositories from Github's API.
*/
protected function getGithubRepositories()
{
$http = new \b8\HttpClient();

View file

@ -24,6 +24,9 @@ class SessionController extends b8\Controller
$this->_userStore = b8\Store\Factory::getStore('User');
}
/**
* Handles user login (form and processing)
*/
public function login()
{
if (b8\Registry::getInstance()->get('requestMethod') == 'POST') {
@ -62,6 +65,9 @@ class SessionController extends b8\Controller
die($view->render());
}
/**
* Handles user logout.
*/
public function logout()
{
unset($_SESSION['user_id']);

View file

@ -27,6 +27,9 @@ class UserController extends b8\Controller
$this->_userStore = b8\Store\Factory::getStore('User');
}
/**
* View user list.
*/
public function index()
{
$users = $this->_userStore->getWhere(array(), 1000, 0, array(), array('email' => 'ASC'));
@ -36,6 +39,9 @@ class UserController extends b8\Controller
return $view->render();
}
/**
* Add a user - handles both form and processing.
*/
public function add()
{
if (!Registry::getInstance()->get('user')->getIsAdmin()) {
@ -74,6 +80,9 @@ class UserController extends b8\Controller
die;
}
/**
* Edit a user - handles both form and processing.
*/
public function edit($userId)
{
if (!Registry::getInstance()->get('user')->getIsAdmin()) {
@ -115,6 +124,9 @@ class UserController extends b8\Controller
die;
}
/**
* Create user add / edit form.
*/
protected function userForm($values, $type = 'add')
{
$form = new Form();
@ -155,6 +167,9 @@ class UserController extends b8\Controller
return $form;
}
/**
* Delete a user.
*/
public function delete($userId)
{
if (!Registry::getInstance()->get('user')->getIsAdmin()) {

View file

@ -21,21 +21,33 @@ use PHPCI\Builder;
*/
class Build extends BuildBase
{
/**
* Get link to commit from another source (i.e. Github)
*/
public function getCommitLink()
{
return '#';
}
/**
* Get link to branch from another source (i.e. Github)
*/
public function getBranchLink()
{
return '#';
}
/**
* Send status updates to any relevant third parties (i.e. Github)
*/
public function sendStatusPostback()
{
return;
}
/**
* Create a working copy by cloning, copying, or similar.
*/
public function createWorkingCopy(Builder $builder, $buildPath)
{
}

View file

@ -20,16 +20,25 @@ use PHPCI\Model\Build\RemoteGitBuild;
*/
class BitbucketBuild extends RemoteGitBuild
{
/**
* Get link to commit from another source (i.e. Github)
*/
public function getCommitLink()
{
return 'https://bitbucket.org/' . $this->getProject()->getReference() . '/commits/' . $this->getCommitId();
}
/**
* Get link to branch from another source (i.e. Github)
*/
public function getBranchLink()
{
return 'https://bitbucket.org/' . $this->getProject()->getReference() . '/src/?at=' . $this->getBranch();
}
/**
* Get the URL to be used to clone this remote repository.
*/
protected function getCloneUrl()
{
$key = trim($this->getProject()->getGitKey());

View file

@ -19,16 +19,25 @@ use PHPCI\Model\Build\RemoteGitBuild;
*/
class GithubBuild extends RemoteGitBuild
{
/**
* Get link to commit from another source (i.e. Github)
*/
public function getCommitLink()
{
return 'https://github.com/' . $this->getProject()->getReference() . '/commit/' . $this->getCommitId();
}
/**
* Get link to branch from another source (i.e. Github)
*/
public function getBranchLink()
{
return 'https://github.com/' . $this->getProject()->getReference() . '/tree/' . $this->getBranch();
}
/**
* Send status updates to any relevant third parties (i.e. Github)
*/
public function sendStatusPostback()
{
$project = $this->getProject();
@ -70,6 +79,9 @@ class GithubBuild extends RemoteGitBuild
$http->request('POST', $url, json_encode($params));
}
/**
* Get the URL to be used to clone this remote repository.
*/
protected function getCloneUrl()
{
$key = trim($this->getProject()->getGitKey());

View file

@ -21,6 +21,9 @@ use Symfony\Component\Yaml\Parser as YamlParser;
*/
class LocalBuild extends Build
{
/**
* Create a working copy by cloning, copying, or similar.
*/
public function createWorkingCopy(Builder $builder, $buildPath)
{
$reference = $this->getProject()->getReference();

View file

@ -21,8 +21,14 @@ use Symfony\Component\Yaml\Parser as YamlParser;
*/
abstract class RemoteGitBuild extends Build
{
/**
* Get the URL to be used to clone this remote repository.
*/
abstract protected function getCloneUrl();
/**
* Create a working copy by cloning, copying, or similar.
*/
public function createWorkingCopy(Builder $builder, $buildPath)
{
$yamlParser = new YamlParser();
@ -51,11 +57,17 @@ abstract class RemoteGitBuild extends Build
return true;
}
/**
* Use an HTTP-based git clone.
*/
protected function cloneByHttp(Builder $builder, $to)
{
return $builder->executeCommand('git clone -b %s %s "%s"', $this->getBranch(), $this->getCloneUrl(), $to);
}
/**
* Use an SSH-based git clone.
*/
protected function cloneBySsh(Builder $builder, $to)
{
// Copy the project's keyfile to disk:

View file

@ -29,6 +29,9 @@ class Composer implements \PHPCI\Plugin
$this->action = isset($options['action']) ? $options['action'] : 'update';
}
/**
* Executes Composer and runs a specified command (e.g. install / update)
*/
public function execute()
{
$cmd = PHPCI_DIR . 'composer.phar --prefer-dist --working-dir="%s" %s';

View file

@ -46,6 +46,9 @@ class Mysql implements \PHPCI\Plugin
}
}
/**
* Connects to MySQL and runs a specified set of queries.
*/
public function execute()
{
try {

View file

@ -41,6 +41,9 @@ class Pgsql implements \PHPCI\Plugin
}
}
/**
* Connects to PgSQL and runs a specified set of queries.
*/
public function execute()
{
try {

View file

@ -28,10 +28,13 @@ class PhpCodeSniffer implements \PHPCI\Plugin
$this->standard = isset($options['standard']) ? $options['standard'] : 'PSR2';
}
/**
* Runs PHP Code Sniffer in a specified directory, to a specified standard.
*/
public function execute()
{
$ignore = '';
if (count($this->phpci->ignore)) {
$ignore = ' --ignore=' . implode(',', $this->phpci->ignore);
}

View file

@ -28,6 +28,9 @@ class PhpCpd implements \PHPCI\Plugin
$this->standard = isset($options['standard']) ? $options['standard'] : 'PSR2';
}
/**
* Runs PHP Copy/Paste Detector in a specified directory.
*/
public function execute()
{
$ignore = '';

View file

@ -24,6 +24,9 @@ class PhpMessDetector implements \PHPCI\Plugin
$this->phpci = $phpci;
}
/**
* Runs PHP Mess Detector in a specified directory.
*/
public function execute()
{
$ignore = '';

View file

@ -24,6 +24,9 @@ class PhpSpec implements \PHPCI\Plugin
$this->phpci = $phpci;
}
/**
* Runs PHP Spec tests.
*/
public function execute()
{
$curdir = getcwd();

View file

@ -39,23 +39,26 @@ class PhpUnit implements \PHPCI\Plugin
{
$this->phpci = $phpci;
if(isset($options['directory'])) {
if (isset($options['directory'])) {
$this->directory = $options['directory'];
}
if(isset($options['config'])) {
if (isset($options['config'])) {
$this->xmlConfigFile = $options['config'];
}
if(isset($options['run_from'])) {
if (isset($options['run_from'])) {
$this->runFrom = $options['run_from'];
}
if(isset($options['args'])) {
if (isset($options['args'])) {
$this->args = $options['args'];
}
}
/**
* Runs PHP Unit tests in a specified directory, optionally using specified config file(s).
*/
public function execute()
{
$success = true;