Skip to content

Instantly share code, notes, and snippets.

@jdecool
Last active August 29, 2015 14:11
Show Gist options
  • Save jdecool/8cd1e23d5d3a6d3d5e2e to your computer and use it in GitHub Desktop.
Save jdecool/8cd1e23d5d3a6d3d5e2e to your computer and use it in GitHub Desktop.
behat-installer.sh
#!/usr/bin/env php
<?php
// Crapy script to install and configure Behat in my PHP project
// Usage : curl -sS http://url/to/file | sh
$dockerRepo = 'https://github.com/jdecool/dockerfiles.git';
$dependencies = [
'behat/behat' => '~3.0',
'behat/mink' => '~1.6',
'behat/mink-extension' => '~2.0',
'behat/symfony2-extension' => '~2.0',
'behat/mink-selenium2-driver' => '~1.2',
"behat/mink-goutte-driver" => "~1.1",
];
process($argv, $dependencies);
/**
* process the installer
*/
function process($argv, $packageToInstall) {
// check for composer file
$composerFile = sprintf('%s/composer.json', __DIR__);
if (!file_exists(__DIR__.'/composer.json')) {
die('No composer file detected.');
}
updateComposerFile($packageToInstall);
updateComposerDependencies($packageToInstall);
initBehat();
foreach ($argv as $key => $val) {
if (0 === strpos($val, '--docker-container')) {
if (18 === strlen($val) && isset($argv[$key+1])) {
$containers = trim($argv[$key+1]);
} else {
$containers = trim(substr($val, 19));
}
installDockerContainers($containers);
}
if (0 === strpos($val, '--behat-behatch')) {
installBehatchContexts();
}
// ** No compatible with Behat 3 **
// if (0 === strpos($val, '--behat-commons')) {
// installBehatCommonsContexts();
// }
}
}
/**
* update composer file for behat
*/
function updateComposerFile($packageToInstall) {
$deps = getComposerDeps();
foreach ($packageToInstall as $name => $version) {
addDependency($deps, $name, $version);
}
setComposerDeps($deps);
}
/**
* add BehatCH contexts
*/
function installBehatchContexts() {
$deps = getComposerDeps();
addDependency($deps, 'behatch/contexts', '~2.1');
setComposerDeps($deps);
}
/**
* install composer deps
*/
function updateComposerDependencies($packageToInstall) {
copy('http://getcomposer.org/composer.phar', __DIR__.'/composer.phar');
$cmd = 'php composer.phar update';
foreach (array_keys($packageToInstall) as $name) {
$cmd .= ' '.$name;
}
shell_exec($cmd);
unlink(__DIR__.'/composer.phar');
}
/**
* behat initialization + Composer autoload
*/
function initBehat() {
shell_exec('bin/behat --init');
behatAutolodingUpdate();
behatFeatureContextUpdate();
behatConfigurationFile();
}
/**
* update Composer autoloading with Behat configuration
*/
function behatAutolodingUpdate() {
$deps = getComposerDeps();
if (is_string($deps['autoload']['psr-0'][''])) {
$deps['autoload']['psr-0'][''] = [$deps['autoload']['psr-0']['']];
}
if (is_array($deps['autoload']['psr-0'][''])) {
$isConfigured = false;
foreach ($deps['autoload']['psr-0'][''] as $dir) {
if ('features/bootstrap/' === $dir) {
$isConfigured = true;
}
}
if (false === $isConfigured) {
$deps['autoload']['psr-0'][''][] = 'features/bootstrap/';
}
}
setComposerDeps($deps);
}
/**
* FeatureContext with MinkContext
*/
function behatFeatureContextUpdate() {
$template = <<<PHP
<?php
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\MinkExtension\Context\RawMinkContext;
/**
* Defines application features from the specific context.
*/
class FeatureContext extends RawMinkContext implements Context, SnippetAcceptingContext
{
/**
* Initializes context.
*
* Every scenario gets its own context instance.
* You can also pass arbitrary arguments to the
* context constructor through behat.yml.
*/
public function __construct()
{
}
/**
* Set browser resolution
*
* @BeforeScenario
*/
public function resizeBrowser()
{
$this->getSession()->resizeWindow(1024, 800, 'current');
}
}
PHP;
file_put_contents(__DIR__.'/features/bootstrap/FeatureContext.php', $template);
}
/**
* behat.yml template
*/
function behatConfigurationFile() {
$template = <<<YML
default:
extensions:
Behat\Symfony2Extension: ~
Behat\MinkExtension:
base_url: 'http://localhost:8000'
sessions:
default:
selenium2:
wd_host: http://localhost:8643/wd/hub
suites:
default:
contexts:
- FeatureContext
- Behat\MinkExtension\Context\MinkContext
YML;
file_put_contents(__DIR__.'/behat.yml', $template);
}
/**
* add composer dependency if not exists
*/
function addDependency(&$deps, $name, $version) {
if (false === searchDependency($deps, $name)) {
$deps['require-dev'][$name] = $version;
}
}
/**
* search for composer dependency in file
*/
function searchDependency($deps, $name) {
if (isset($deps['require'])) {
foreach ($deps['require'] as $dependency => $version) {
if ($dependency == $name) {
return true;
}
}
}
if (isset($deps['required-dev'])) {
foreach ($deps['require-dev'] as $dependency => $version) {
if ($dependency == $name) {
return true;
}
}
}
return false;
}
/**
* install docker container into project
*/
function installDockerContainers($containers) {
$cmd = sprintf('cd /tmp; rm -Rf /tmp/dockerfiles; git clone %s > /dev/null', $GLOBALS['dockerRepo']);
shell_exec($cmd);
$dirs = (!empty($containers)) ? explode(',', $containers) : [];
foreach (['apache', 'mysql', 'phantomjs', 'behat'] as $c) {
$dirs[] = $c;
}
foreach ($dirs as $d) {
$containerPath = sprintf('/tmp/dockerfiles/%s', $d);
if (is_dir($containerPath)) {
$dest = sprintf('%s/scripts/docker/%s', __DIR__, $d);
mkdir($dest, 0777, true);
recurse_copy($containerPath, $dest);
}
}
}
/**
* retrieve array describe composer.json file
*/
function getComposerDeps() {
$content = file_get_contents(getComposerFilePath());
return json_decode($content, true);
}
/**
* write composer.json file from array
*/
function setComposerDeps($deps) {
file_put_contents(getComposerFilePath(), json_encode($deps, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
}
/**
* composer.json file path
*/
function getComposerFilePath() {
return sprintf('%s/composer.json', __DIR__);
}
// VENDORS
function recurse_copy($src, $dst) {
$dir = opendir($src);
@mkdir($dst);
while(false !== ($file = readdir($dir))) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
recurse_copy($src . '/' . $file,$dst . '/' . $file);
}
else {
copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
closedir($dir);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment