From fa18d89ddc0db7d0bb466055ef647586d6f8e3f6 Mon Sep 17 00:00:00 2001 From: Dan Cryer Date: Tue, 14 May 2013 19:44:14 +0100 Subject: [PATCH] Adding support for local path based projects. See pull #2 --- PHPCI/Builder.php | 103 ++++++++++++++++++------- PHPCI/Controller/ProjectController.php | 8 +- PHPCI/Plugin/PhpSpec.php | 12 +-- PHPCI/Plugin/PhpUnit.php | 7 +- README.md | 14 ++-- phpci.yml | 8 +- 6 files changed, 104 insertions(+), 48 deletions(-) diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index 1f9d29b1..2f1b870e 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -125,40 +125,81 @@ class Builder $commitId = $this->build->getCommitId(); $url = $this->build->getProject()->getGitUrl(); $key = $this->build->getProject()->getGitKey(); - + $type = $this->build->getProject()->getType(); + $reference = $this->build->getProject()->getReference(); + $reference = substr($reference, -1) == '/' ? substr($reference, 0, -1) : $reference; $buildId = 'project' . $this->build->getProject()->getId() . '-build' . $this->build->getId(); + $yamlParser = new YamlParser(); $this->ciDir = realpath(dirname(__FILE__) . '/../') . '/'; $this->buildPath = $this->ciDir . 'build/' . $buildId . '/'; - mkdir($this->buildPath, 0777, true); + switch ($type) + { + case 'local': + $this->buildPath = $this->ciDir . 'build/' . $buildId; + + if(!is_file($reference . '/phpci.yml')) + { + $this->logFailure('Project does not contain a phpci.yml file.'); + return false; + } - if(!empty($key)) - { - // Do an SSH clone: - $keyFile = $this->ciDir . 'build/' . $buildId . '.key'; - file_put_contents($keyFile, $key); - chmod($keyFile, 0600); - $this->executeCommand('ssh-agent ssh-add '.$keyFile.' && git clone -b ' .$this->build->getBranch() . ' ' .$url.' '.$this->buildPath.' && ssh-agent -k'); - unlink($keyFile); - } - else - { - // Do an HTTP clone: - $this->executeCommand('git clone -b ' .$this->build->getBranch() . ' ' .$url.' '.$this->buildPath); - } - - if(!is_file($this->buildPath . 'phpci.yml')) - { - $this->logFailure('Project does not contain a phpci.yml file.'); - return false; + $yamlFile = file_get_contents($reference . '/phpci.yml'); + $this->config = $yamlParser->parse($yamlFile); + + if(array_key_exists('build_settings', $this->config) + && is_array($this->config['build_settings']) + && array_key_exists('prefer_symlink', $this->config['build_settings']) + && true === $this->config['build_settings']['prefer_symlink']) + { + if(is_link($this->buildPath) && is_file($this->buildPath)) + { + unlink($this->buildPath); + } + + $this->log(sprintf('Symlinking: %s to %s',$reference, $this->buildPath)); + symlink($reference, $this->buildPath); + } + else + { + $this->executeCommand(sprintf("cp -Rf %s %s/", $reference, $this->buildPath)); + } + + $this->buildPath .= '/'; + break; + + case 'github': + case 'bitbucket': + mkdir($this->buildPath, 0777, true); + + if(!empty($key)) + { + // Do an SSH clone: + $keyFile = $this->ciDir . 'build/' . $buildId . '.key'; + file_put_contents($keyFile, $key); + chmod($keyFile, 0600); + $this->executeCommand('ssh-agent ssh-add '.$keyFile.' && git clone -b ' .$this->build->getBranch() . ' ' .$url.' '.$this->buildPath.' && ssh-agent -k'); + unlink($keyFile); + } + else + { + // Do an HTTP clone: + $this->executeCommand('git clone -b ' .$this->build->getBranch() . ' ' .$url.' '.$this->buildPath); + } + + if(!is_file($this->buildPath . 'phpci.yml')) + { + $this->logFailure('Project does not contain a phpci.yml file.'); + return false; + } + + $yamlFile = file_get_contents($this->buildPath . 'phpci.yml'); + $this->config = $yamlParser->parse($yamlFile); + break; } - $yamlParser = new YamlParser(); - $yamlFile = file_get_contents($this->buildPath . 'phpci.yml'); - $this->config = $yamlParser->parse($yamlFile); - - if(!isset($this->config['verbose']) || !$this->config['verbose']) + if(!isset($this->config['build_settings']['verbose']) || !$this->config['build_settings']['verbose']) { $this->verbose = false; } @@ -167,9 +208,9 @@ class Builder $this->verbose = true; } - if(isset($this->config['ignore'])) + if(isset($this->config['build_settings']['ignore'])) { - $this->ignore = $this->config['ignore']; + $this->ignore = $this->config['build_settings']['ignore']; } $this->log('Set up build: ' . $this->buildPath); @@ -185,6 +226,12 @@ class Builder protected function executePlugins($stage) { + // Ignore any stages for which we don't have plugins set: + if(!array_key_exists($stage, $this->config) || !is_array($this->config[$stage])) + { + return; + } + foreach($this->config[$stage] as $plugin => $options) { $this->log(''); diff --git a/PHPCI/Controller/ProjectController.php b/PHPCI/Controller/ProjectController.php index e13ee5d1..fecb424b 100644 --- a/PHPCI/Controller/ProjectController.php +++ b/PHPCI/Controller/ProjectController.php @@ -184,21 +184,21 @@ class ProjectController extends b8\Controller $field = new Form\Element\Select('type'); $field->setRequired(true); - $field->setOptions(array('github' => 'Github', 'bitbucket' => 'Bitbucket')); + $field->setOptions(array('github' => 'Github', 'bitbucket' => 'Bitbucket', 'local' => 'Local Path')); $field->setLabel('Where is your project hosted?'); $field->setClass('span4'); $form->addField($field); $field = new Form\Element\Text('reference'); $field->setRequired(true); - $field->setPattern('[a-zA-Z0-9_\-]+\/[a-zA-Z0-9_\-]+'); - $field->setLabel('Repository Name on Github / Bitbucket (e.g. block8/phpci)'); + $field->setPattern('[a-zA-Z0-9_\-\/]+'); + $field->setLabel('Repository Name / URL (Remote) or Path (Local)'); $field->setClass('span4'); $form->addField($field); $field = new Form\Element\TextArea('key'); $field->setRequired(false); - $field->setLabel('Private key to use to access repository (leave blank to use anonymous HTTP repository access)'); + $field->setLabel('Private key to use to access repository (leave blank for local and/or anonymous remotes)'); $field->setClass('span7'); $field->setRows(6); $form->addField($field); diff --git a/PHPCI/Plugin/PhpSpec.php b/PHPCI/Plugin/PhpSpec.php index 75030161..2bcab4a6 100644 --- a/PHPCI/Plugin/PhpSpec.php +++ b/PHPCI/Plugin/PhpSpec.php @@ -13,11 +13,11 @@ class PhpSpec implements \PHPCI\Plugin public function execute() { - $cwd = getcwd(); - - $command = 'cd ' . $this->phpci->buildPath . ' && '; - $command .= PHPCI_BIN_DIR . 'phpspec'; - $command .= ' && cd ' . $cwd; - return $this->phpci->executeCommand($command); + $curdir = getcwd(); + chdir($this->phpci->buildPath); + $success = $this->phpci->executeCommand(PHPCI_BIN_DIR . 'phpspec'); + chdir($curdir); + + return $success; } } \ No newline at end of file diff --git a/PHPCI/Plugin/PhpUnit.php b/PHPCI/Plugin/PhpUnit.php index d34ee3d5..34817f11 100644 --- a/PHPCI/Plugin/PhpUnit.php +++ b/PHPCI/Plugin/PhpUnit.php @@ -17,6 +17,11 @@ class PhpUnit implements \PHPCI\Plugin public function execute() { - return $this->phpci->executeCommand(PHPCI_BIN_DIR . 'phpunit ' . $this->args . ' ' . $this->phpci->buildPath . $this->directory); + $curdir = getcwd(); + chdir($this->phpci->buildPath); + $success = $this->phpci->executeCommand(PHPCI_BIN_DIR . 'phpunit ' . $this->args . ' ' . $this->phpci->buildPath . $this->directory); + chdir($curdir); + + return $success; } } \ No newline at end of file diff --git a/README.md b/README.md index 082b93a4..7006ef2a 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ PHPCI is a free and open source continuous integration tool specifically designe _**Please be aware that this is a brand new project, in an alpha state, so there will be bugs and missing features.**_ ##What it does: -* Clones your repository from Github or Bitbucket (support for standard Git repositories coming soon.) +* Clones your project from Github, Bitbucket or a local path (support for standard remote Git repositories coming soon.) * Allows you to set up and tear down test databases. * Installs your project's Composer dependencies. * Runs through any combination of the following plugins: @@ -14,6 +14,7 @@ _**Please be aware that this is a brand new project, in an alpha state, so there * PHP Mess Detector * PHP Copy/Paste Detector * PHP Code Sniffer + * PHP Spec * You can mark directories for the plugins to ignore. * You can mark certain plugins as being allowed to fail (but still run.) @@ -67,7 +68,12 @@ Obviously, make sure you change the `/path/to/phpci` to the directory in which y ##Adding support for PHPCI to your projects: Similar to Travis CI, to support PHPCI in your project, you simply need to add a `phpci.yml` file to the root of your repository. The file should look something like this: - setup: + build_settings: + ignore: + - "vendor" + - "tests" + + setup: mysql: - "DROP DATABASE IF EXISTS test;" - "CREATE DATABASE test;" @@ -75,10 +81,6 @@ Similar to Travis CI, to support PHPCI in your project, you simply need to add a composer: action: "install" - ignore: - - "vendor" - - "tests" - test: php_unit: directory: "tests/" diff --git a/phpci.yml b/phpci.yml index 87c592b3..d252d83a 100644 --- a/phpci.yml +++ b/phpci.yml @@ -1,10 +1,12 @@ +build_settings: + verbose: false + ignore: + - "vendor" + setup: composer: action: "install" -ignore: - - "vendor/" - test: php_mess_detector: allow_failures: true \ No newline at end of file