Files
icehrm/lib/composer/vendor/consolidation/robo/RoboFile.php
2017-09-03 20:39:22 +02:00

378 lines
12 KiB
PHP

<?php
use Symfony\Component\Finder\Finder;
use Robo\Result;
use Robo\Collection\CollectionBuilder;
class RoboFile extends \Robo\Tasks
{
/**
* Run the Robo unit tests.
*/
public function test(array $args, $options =
[
'coverage-html' => false,
'coverage' => false
])
{
$taskCodecept = $this->taskCodecept()
->args($args);
if ($options['coverage']) {
$taskCodecept->coverageXml('../../build/logs/clover.xml');
}
if ($options['coverage-html']) {
$taskCodecept->coverageHtml('../../build/logs/coverage');
}
return $taskCodecept->run();
}
/**
* Code sniffer.
*
* Run the PHP Codesniffer on a file or directory.
*
* @param string $file
* A file or directory to analyze.
* @option $autofix Whether to run the automatic fixer or not.
* @option $strict Show warnings as well as errors.
* Default is to show only errors.
*/
public function sniff(
$file = 'src/',
$options = [
'autofix' => false,
'strict' => false,
]
) {
$strict = $options['strict'] ? '' : '-n';
$result = $this->taskExec("./vendor/bin/phpcs --standard=PSR2 {$strict} {$file}")->run();
if (!$result->wasSuccessful()) {
if (!$options['autofix']) {
$options['autofix'] = $this->confirm('Would you like to run phpcbf to fix the reported errors?');
}
if ($options['autofix']) {
$result = $this->taskExec("./vendor/bin/phpcbf --standard=PSR2 {$file}")->run();
}
}
return $result;
}
/**
* Generate a new Robo task that wraps an existing utility class.
*
* @param $className The name of the existing utility class to wrap.
* @param $wrapperClassName The name of the wrapper class to create. Optional.
* @usage generate:task 'Symfony\Component\Filesystem\Filesystem' FilesystemStack
*/
public function generateTask($className, $wrapperClassName = "")
{
return $this->taskGenTask($className, $wrapperClassName)->run();
}
/**
* Release Robo.
*/
public function release($opts = ['beta' => false])
{
$this->yell("Releasing Robo");
$stable = true;
if ($opts['beta']) {
$stable = false;
$this->say('non-stable release');
}
$this->docs();
$this->taskGitStack()
->add('-A')
->commit("auto-update")
->pull()
->push()
->run();
if ($stable) $this->pharPublish();
$this->publish();
$this->taskGitStack()
->tag(\Robo\Robo::VERSION)
->push('origin master --tags')
->run();
if ($stable) $this->versionBump();
}
/**
* Update changelog.
*
* Add an entry to the Robo CHANGELOG.md file.
*
* @param string $addition The text to add to the change log.
*/
public function changed($addition)
{
return $this->taskChangelog()
->version(\Robo\Robo::VERSION)
->change($addition)
->run();
}
/**
* Update the version of Robo.
*
* @param string $version The new verison for Robo.
* Defaults to the next minor (bugfix) version after the current relelase.
*/
public function versionBump($version = '')
{
if (empty($version)) {
$versionParts = explode('.', \Robo\Robo::VERSION);
$versionParts[count($versionParts)-1]++;
$version = implode('.', $versionParts);
}
return $this->taskReplaceInFile(__DIR__.'/src/Robo.php')
->from("VERSION = '".\Robo\Robo::VERSION."'")
->to("VERSION = '".$version."'")
->run();
}
/**
* Generate the Robo documentation files.
*/
public function docs()
{
$collection = $this->collectionBuilder();
$collection->progressMessage('Generate documentation from source code.');
$files = Finder::create()->files()->name('*.php')->in('src/Task');
$docs = [];
foreach ($files as $file) {
if ($file->getFileName() == 'loadTasks.php') {
continue;
}
if ($file->getFileName() == 'loadShortcuts.php') {
continue;
}
$ns = $file->getRelativePath();
if (!$ns) {
continue;
}
$class = basename(substr($file, 0, -4));
class_exists($class = "Robo\\Task\\$ns\\$class");
$docs[$ns][] = $class;
}
ksort($docs);
foreach ($docs as $ns => $tasks) {
$taskGenerator = $collection->taskGenDoc("docs/tasks/$ns.md");
$taskGenerator->filterClasses(function (\ReflectionClass $r) {
return !($r->isAbstract() || $r->isTrait()) && $r->implementsInterface('Robo\Contract\TaskInterface');
})->prepend("# $ns Tasks");
sort($tasks);
foreach ($tasks as $class) {
$taskGenerator->docClass($class);
}
$taskGenerator->filterMethods(
function (\ReflectionMethod $m) {
if ($m->isConstructor() || $m->isDestructor() || $m->isStatic()) {
return false;
}
$undocumentedMethods =
[
'',
'run',
'__call',
'inflect',
'injectDependencies',
'getCommand',
'getPrinted',
'getConfig',
'setConfig',
'logger',
'setLogger',
'setProgressIndicator',
'progressIndicatorSteps',
'setBuilder',
'getBuilder',
'collectionBuilder',
];
return !in_array($m->name, $undocumentedMethods) && $m->isPublic(); // methods are not documented
}
)->processClassSignature(
function ($c) {
return "## " . preg_replace('~Task$~', '', $c->getShortName()) . "\n";
}
)->processClassDocBlock(
function (\ReflectionClass $c, $doc) {
$doc = preg_replace('~@method .*?(.*?)\)~', '* `$1)` ', $doc);
$doc = str_replace('\\'.$c->name, '', $doc);
return $doc;
}
)->processMethodSignature(
function (\ReflectionMethod $m, $text) {
return str_replace('#### *public* ', '* `', $text) . '`';
}
)->processMethodDocBlock(
function (\ReflectionMethod $m, $text) {
return $text ? ' ' . trim(strtok($text, "\n"), "\n") : '';
}
);
}
$collection->progressMessage('Documentation generation complete.');
return $collection->run();
}
/**
* Publish Robo.
*
* Builds a site in gh-pages branch. Uses mkdocs
*/
public function publish()
{
$current_branch = exec('git rev-parse --abbrev-ref HEAD');
return $this->collectionBuilder()
->taskGitStack()
->checkout('site')
->merge('master')
->completion($this->taskGitStack()->checkout($current_branch))
->taskFilesystemStack()
->copy('CHANGELOG.md', 'docs/changelog.md')
->completion($this->taskFilesystemStack()->remove('docs/changelog.md'))
->taskExec('mkdocs gh-deploy')
->run();
}
/**
* Build the Robo phar executable.
*/
public function pharBuild()
{
// Create a collection builder to hold the temporary
// directory until the pack phar task runs.
$collection = $this->collectionBuilder();
$workDir = $collection->tmpDir();
$roboBuildDir = "$workDir/robo";
// Before we run `composer install`, we will remove the dev
// dependencies that we only use in the unit tests. Any dev dependency
// that is in the 'suggested' section is used by a core task;
// we will include all of those in the phar.
$devProjectsToRemove = $this->devDependenciesToRemoveFromPhar();
// We need to create our work dir and run `composer install`
// before we prepare the pack phar task, so create a separate
// collection builder to do this step in.
$prepTasks = $this->collectionBuilder();
$preparationResult = $prepTasks
->taskFilesystemStack()
->mkdir($workDir)
->taskRsync()
->fromPath(
[
__DIR__ . '/composer.json',
__DIR__ . '/scripts',
__DIR__ . '/src',
__DIR__ . '/data'
]
)
->toPath($roboBuildDir)
->recursive()
->progress()
->stats()
->taskComposerRemove()
->dir($roboBuildDir)
->dev()
->noUpdate()
->args($devProjectsToRemove)
->taskComposerInstall()
->dir($roboBuildDir)
->printed(false)
->run();
// Exit if the preparation step failed
if (!$preparationResult->wasSuccessful()) {
return $preparationResult;
}
// Decide which files we're going to pack
$files = Finder::create()->ignoreVCS(true)
->files()
->name('*.php')
->name('*.exe') // for 1symfony/console/Resources/bin/hiddeninput.exe
->name('GeneratedWrapper.tmpl')
->path('src')
->path('vendor')
->notPath('docs')
->notPath('/vendor\/.*\/[Tt]est/')
->in(is_dir($roboBuildDir) ? $roboBuildDir : __DIR__);
// Build the phar
return $collection
->taskPackPhar('robo.phar')
->addFiles($files)
->addFile('robo', 'robo')
->executable('robo')
->taskFilesystemStack()
->chmod('robo.phar', 0777)
->run();
}
/**
* The phar:build command removes the project requirements from the
* 'require-dev' section that are not in the 'suggest' section.
*
* @return array
*/
protected function devDependenciesToRemoveFromPhar()
{
$composerInfo = (array) json_decode(file_get_contents(__DIR__ . '/composer.json'));
$devDependencies = array_keys((array)$composerInfo['require-dev']);
$suggestedProjects = array_keys((array)$composerInfo['suggest']);
return array_diff($devDependencies, $suggestedProjects);
}
/**
* Install Robo phar.
*
* Installs the Robo phar executable in /usr/bin. Uses 'sudo'.
*/
public function pharInstall()
{
return $this->taskExec('sudo cp')
->arg('robo.phar')
->arg('/usr/bin/robo')
->run();
}
/**
* Publish Robo phar.
*
* Commits the phar executable to Robo's GitHub pages site.
*/
public function pharPublish()
{
$this->pharBuild();
$this->collectionBuilder()
->taskFilesystemStack()
->rename('robo.phar', 'robo-release.phar')
->taskGitStack()
->checkout('site')
->pull('origin site')
->taskFilesystemStack()
->remove('robotheme/robo.phar')
->rename('robo-release.phar', 'robotheme/robo.phar')
->taskGitStack()
->add('robotheme/robo.phar')
->commit('Update robo.phar to ' . \Robo\Robo::VERSION)
->push('origin site')
->checkout('master')
->run();
}
}