Initial Drupal 11 with DDEV setup
This commit is contained in:
563
vendor/consolidation/robo/src/Task/ApiGen/ApiGen.php
vendored
Normal file
563
vendor/consolidation/robo/src/Task/ApiGen/ApiGen.php
vendored
Normal file
@ -0,0 +1,563 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\ApiGen;
|
||||
|
||||
use Robo\Contract\CommandInterface;
|
||||
use Robo\Exception\TaskException;
|
||||
use Robo\Task\BaseTask;
|
||||
use Traversable;
|
||||
use Robo\Common\ExecOneCommand;
|
||||
|
||||
/**
|
||||
* Executes ApiGen command to generate documentation
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // ApiGen Command
|
||||
* $this->taskApiGen('./vendor/apigen/apigen.phar')
|
||||
* ->config('./apigen.neon')
|
||||
* ->templateConfig('vendor/apigen/apigen/templates/bootstrap/config.neon')
|
||||
* ->wipeout(true)
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class ApiGen extends BaseTask implements CommandInterface
|
||||
{
|
||||
use ExecOneCommand;
|
||||
|
||||
const BOOL_NO = 'no';
|
||||
const BOOL_YES = 'yes';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $command;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $operation = 'generate';
|
||||
|
||||
/**
|
||||
* @param null|string $pathToApiGen
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
public function __construct($pathToApiGen = null)
|
||||
{
|
||||
$this->command = $pathToApiGen;
|
||||
$command_parts = [];
|
||||
preg_match('/((?:.+)?apigen(?:\.phar)?) ?( \w+)? ?(.+)?/', $this->command, $command_parts);
|
||||
if (count($command_parts) === 3) {
|
||||
list(, $this->command, $this->operation) = $command_parts;
|
||||
}
|
||||
if (count($command_parts) === 4) {
|
||||
list(, $this->command, $this->operation, $arg) = $command_parts;
|
||||
$this->arg($arg);
|
||||
}
|
||||
if (!$this->command) {
|
||||
$this->command = $this->findExecutablePhar('apigen');
|
||||
}
|
||||
if (!$this->command) {
|
||||
throw new TaskException(__CLASS__, "No apigen installation found");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass methods parameters as arguments to executable. Argument values
|
||||
* are automatically escaped.
|
||||
*
|
||||
* @param string|string[] $args
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function args($args)
|
||||
{
|
||||
$func_args = func_get_args();
|
||||
if (!is_array($args)) {
|
||||
$args = $func_args;
|
||||
}
|
||||
$args = array_map(function ($arg) {
|
||||
if (preg_match('/^\w+$/', trim($arg)) === 1) {
|
||||
$this->operation = $arg;
|
||||
return null;
|
||||
}
|
||||
return $arg;
|
||||
}, $args);
|
||||
$args = array_filter($args);
|
||||
$this->arguments .= ' ' . implode(' ', array_map('static::escape', $args));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|\Traversable|string $arg
|
||||
* A single object or something traversable.
|
||||
*
|
||||
* @return array|\Traversable
|
||||
* The provided argument if it was already traversable, or the given
|
||||
* argument returned as a one-element array.
|
||||
*/
|
||||
protected static function forceTraversable($arg)
|
||||
{
|
||||
$traversable = $arg;
|
||||
if (!is_array($traversable) && !($traversable instanceof \Traversable)) {
|
||||
$traversable = array($traversable);
|
||||
}
|
||||
return $traversable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $arg
|
||||
* A single argument or an array of multiple string values.
|
||||
*
|
||||
* @return string
|
||||
* A comma-separated string of all of the provided arguments, suitable as
|
||||
* a command-line "list" type argument for ApiGen.
|
||||
*/
|
||||
protected static function asList($arg)
|
||||
{
|
||||
$normalized = is_array($arg) ? $arg : array($arg);
|
||||
return implode(',', $normalized);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|string $val
|
||||
* An argument to be normalized.
|
||||
* @param string $default
|
||||
* One of self::BOOL_YES or self::BOOK_NO if the provided value could not
|
||||
* deterministically be converted to a yes or no value.
|
||||
*
|
||||
* @return string
|
||||
* The given value as a command-line "yes|no" type of argument for ApiGen,
|
||||
* or the default value if none could be determined.
|
||||
*/
|
||||
protected static function asTextBool($val, $default)
|
||||
{
|
||||
if ($val === self::BOOL_YES || $val === self::BOOL_NO) {
|
||||
return $val;
|
||||
}
|
||||
if (!$val) {
|
||||
return self::BOOL_NO;
|
||||
}
|
||||
if ($val === true) {
|
||||
return self::BOOL_YES;
|
||||
}
|
||||
if (is_numeric($val) && $val != 0) {
|
||||
return self::BOOL_YES;
|
||||
}
|
||||
if (strcasecmp($val[0], 'y') === 0) {
|
||||
return self::BOOL_YES;
|
||||
}
|
||||
if (strcasecmp($val[0], 'n') === 0) {
|
||||
return self::BOOL_NO;
|
||||
}
|
||||
// meh, good enough, let apigen sort it out
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $config
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function config($config)
|
||||
{
|
||||
$this->option('config', $config);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string|\Traversable $src
|
||||
* One or more source values.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function source($src)
|
||||
{
|
||||
foreach (self::forceTraversable($src) as $source) {
|
||||
$this->option('source', $source);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dest
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function destination($dest)
|
||||
{
|
||||
$this->option('destination', $dest);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $exts
|
||||
* One or more extensions.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function extensions($exts)
|
||||
{
|
||||
$this->option('extensions', self::asList($exts));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $exclude
|
||||
* One or more exclusions.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function exclude($exclude)
|
||||
{
|
||||
foreach (self::forceTraversable($exclude) as $excl) {
|
||||
$this->option('exclude', $excl);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string|\Traversable $path
|
||||
* One or more skip-doc-path values.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function skipDocPath($path)
|
||||
{
|
||||
foreach (self::forceTraversable($path) as $skip) {
|
||||
$this->option('skip-doc-path', $skip);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string|\Traversable $prefix
|
||||
* One or more skip-doc-prefix values.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function skipDocPrefix($prefix)
|
||||
{
|
||||
foreach (self::forceTraversable($prefix) as $skip) {
|
||||
$this->option('skip-doc-prefix', $skip);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $charset
|
||||
* One or more charsets.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function charset($charset)
|
||||
{
|
||||
$this->option('charset', self::asList($charset));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function mainProjectNamePrefix($name)
|
||||
{
|
||||
$this->option('main', $name);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function title($title)
|
||||
{
|
||||
$this->option('title', $title);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $baseUrl
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function baseUrl($baseUrl)
|
||||
{
|
||||
$this->option('base-url', $baseUrl);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function googleCseId($id)
|
||||
{
|
||||
$this->option('google-cse-id', $id);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $trackingCode
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function googleAnalytics($trackingCode)
|
||||
{
|
||||
$this->option('google-analytics', $trackingCode);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $templateConfig
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function templateConfig($templateConfig)
|
||||
{
|
||||
$this->option('template-config', $templateConfig);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $tags
|
||||
* One or more supported html tags.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function allowedHtml($tags)
|
||||
{
|
||||
$this->option('allowed-html', self::asList($tags));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $groups
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function groups($groups)
|
||||
{
|
||||
$this->option('groups', $groups);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $types
|
||||
* One or more supported autocomplete types.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function autocomplete($types)
|
||||
{
|
||||
$this->option('autocomplete', self::asList($types));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $levels
|
||||
* One or more access levels.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function accessLevels($levels)
|
||||
{
|
||||
$this->option('access-levels', self::asList($levels));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean|string $internal
|
||||
* 'yes' or true if internal, 'no' or false if not.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function internal($internal)
|
||||
{
|
||||
$this->option('internal', self::asTextBool($internal, self::BOOL_NO));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|string $php
|
||||
* 'yes' or true to generate documentation for internal php classes, 'no'
|
||||
* or false otherwise.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function php($php)
|
||||
{
|
||||
$this->option('php', self::asTextBool($php, self::BOOL_YES));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|string $tree
|
||||
* 'yes' or true to generate a tree view of classes, 'no' or false
|
||||
* otherwise.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function tree($tree)
|
||||
{
|
||||
$this->option('tree', self::asTextBool($tree, self::BOOL_YES));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|string $dep
|
||||
* 'yes' or true to generate documentation for deprecated classes, 'no' or
|
||||
* false otherwise.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function deprecated($dep)
|
||||
{
|
||||
$this->option('deprecated', self::asTextBool($dep, self::BOOL_NO));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|string $todo
|
||||
* 'yes' or true to document tasks, 'no' or false otherwise.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function todo($todo)
|
||||
{
|
||||
$this->option('todo', self::asTextBool($todo, self::BOOL_NO));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|string $src
|
||||
* 'yes' or true to generate highlighted source code, 'no' or false
|
||||
* otherwise.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function sourceCode($src)
|
||||
{
|
||||
$this->option('source-code', self::asTextBool($src, self::BOOL_YES));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|string $zipped
|
||||
* 'yes' or true to generate downloadable documentation, 'no' or false
|
||||
* otherwise.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function download($zipped)
|
||||
{
|
||||
$this->option('download', self::asTextBool($zipped, self::BOOL_NO));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function report($path)
|
||||
{
|
||||
$this->option('report', $path);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|string $wipeout
|
||||
* 'yes' or true to clear out the destination directory, 'no' or false
|
||||
* otherwise.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function wipeout($wipeout)
|
||||
{
|
||||
$this->option('wipeout', self::asTextBool($wipeout, self::BOOL_YES));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|string $quiet
|
||||
* 'yes' or true for quiet, 'no' or false otherwise.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function quiet($quiet)
|
||||
{
|
||||
$this->option('quiet', self::asTextBool($quiet, self::BOOL_NO));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|string $bar
|
||||
* 'yes' or true to display a progress bar, 'no' or false otherwise.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function progressbar($bar)
|
||||
{
|
||||
$this->option('progressbar', self::asTextBool($bar, self::BOOL_YES));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|string $colors
|
||||
* 'yes' or true colorize the output, 'no' or false otherwise.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function colors($colors)
|
||||
{
|
||||
$this->option('colors', self::asTextBool($colors, self::BOOL_YES));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|string $check
|
||||
* 'yes' or true to check for updates, 'no' or false otherwise.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function updateCheck($check)
|
||||
{
|
||||
$this->option('update-check', self::asTextBool($check, self::BOOL_YES));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|string $debug
|
||||
* 'yes' or true to enable debug mode, 'no' or false otherwise.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function debug($debug)
|
||||
{
|
||||
$this->option('debug', self::asTextBool($debug, self::BOOL_NO));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return "$this->command $this->operation$this->arguments";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->printTaskInfo('Running ApiGen {args}', ['args' => $this->arguments]);
|
||||
return $this->executeCommand($this->getCommand());
|
||||
}
|
||||
}
|
||||
16
vendor/consolidation/robo/src/Task/ApiGen/Tasks.php
vendored
Normal file
16
vendor/consolidation/robo/src/Task/ApiGen/Tasks.php
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\ApiGen;
|
||||
|
||||
trait Tasks
|
||||
{
|
||||
/**
|
||||
* @param null|string $pathToApiGen
|
||||
*
|
||||
* @return \Robo\Task\ApiGen\ApiGen|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskApiGen($pathToApiGen = null)
|
||||
{
|
||||
return $this->task(ApiGen::class, $pathToApiGen);
|
||||
}
|
||||
}
|
||||
295
vendor/consolidation/robo/src/Task/Archive/Extract.php
vendored
Normal file
295
vendor/consolidation/robo/src/Task/Archive/Extract.php
vendored
Normal file
@ -0,0 +1,295 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Archive;
|
||||
|
||||
use Robo\Result;
|
||||
use Robo\Task\BaseTask;
|
||||
use Robo\Task\Filesystem\Tasks as FilesystemTaskLoader;
|
||||
use Robo\Contract\BuilderAwareInterface;
|
||||
use Robo\TaskAccessor;
|
||||
|
||||
/**
|
||||
* Extracts an archive.
|
||||
*
|
||||
* Note that often, distributions are packaged in tar or zip archives
|
||||
* where the topmost folder may contain variable information, such as
|
||||
* the release date, or the version of the package. This information
|
||||
* is very useful when unpacking by hand, but arbitrarily-named directories
|
||||
* are much less useful to scripts. Therefore, by default, Extract will
|
||||
* remove the top-level directory, and instead store all extracted files
|
||||
* into the directory specified by $archivePath.
|
||||
*
|
||||
* To keep the top-level directory when extracting, use
|
||||
* `preserveTopDirectory(true)`.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskExtract($archivePath)
|
||||
* ->to($destination)
|
||||
* ->preserveTopDirectory(false) // the default
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Extract extends BaseTask implements BuilderAwareInterface
|
||||
{
|
||||
use TaskAccessor;
|
||||
use FilesystemTaskLoader;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $filename;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $to;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $preserveTopDirectory = false;
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
*/
|
||||
public function __construct($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Location to store extracted files.
|
||||
*
|
||||
* @param string $to
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function to($to)
|
||||
{
|
||||
$this->to = $to;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $preserve
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function preserveTopDirectory($preserve = true)
|
||||
{
|
||||
$this->preserveTopDirectory = $preserve;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if (!file_exists($this->filename)) {
|
||||
$this->printTaskError("File {filename} does not exist", ['filename' => $this->filename]);
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!($mimetype = static::archiveType($this->filename))) {
|
||||
$this->printTaskError("Could not determine type of archive for {filename}", ['filename' => $this->filename]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$umask = 0777 - umask();
|
||||
|
||||
// We will first extract to $extractLocation and then move to $this->to
|
||||
$extractLocation = $this->getTempDir();
|
||||
@mkdir($extractLocation, $umask, true);
|
||||
|
||||
$destinationParentDir = dirname($this->to);
|
||||
if (!file_exists($destinationParentDir)) {
|
||||
@mkdir($destinationParentDir, $umask, true);
|
||||
}
|
||||
|
||||
$this->startTimer();
|
||||
|
||||
$this->printTaskInfo("Extracting {filename}", ['filename' => $this->filename]);
|
||||
|
||||
$result = $this->extractAppropriateType($mimetype, $extractLocation);
|
||||
if ($result->wasSuccessful()) {
|
||||
$this->printTaskInfo("{filename} extracted", ['filename' => $this->filename]);
|
||||
// Now, we want to move the extracted files to $this->to. There
|
||||
// are two possibilities that we must consider:
|
||||
//
|
||||
// (1) Archived files were encapsulated in a folder with an arbitrary name
|
||||
// (2) There was no encapsulating folder, and all the files in the archive
|
||||
// were extracted into $extractLocation
|
||||
//
|
||||
// In the case of (1), we want to move and rename the encapsulating folder
|
||||
// to $this->to.
|
||||
//
|
||||
// In the case of (2), we will just move and rename $extractLocation.
|
||||
$filesInExtractLocation = glob("$extractLocation/*");
|
||||
$hasEncapsulatingFolder = ((count($filesInExtractLocation) == 1) && is_dir($filesInExtractLocation[0]));
|
||||
if ($hasEncapsulatingFolder && !$this->preserveTopDirectory) {
|
||||
$this
|
||||
->taskFilesystemStack()
|
||||
->rename($filesInExtractLocation[0], $this->to)
|
||||
->remove($extractLocation)
|
||||
->run();
|
||||
} else {
|
||||
$this
|
||||
->taskFilesystemStack()
|
||||
->rename($extractLocation, $this->to)
|
||||
->run();
|
||||
}
|
||||
}
|
||||
$this->stopTimer();
|
||||
$result['time'] = $this->getExecutionTime();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mimetype
|
||||
* @param string $extractLocation
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function extractAppropriateType($mimetype, $extractLocation)
|
||||
{
|
||||
// Perform the extraction of a zip file.
|
||||
if (($mimetype == 'application/zip') || ($mimetype == 'application/x-zip')) {
|
||||
return $this->extractZip($extractLocation);
|
||||
}
|
||||
return $this->extractTar($extractLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $extractLocation
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function extractZip($extractLocation)
|
||||
{
|
||||
if (!extension_loaded('zlib')) {
|
||||
return Result::errorMissingExtension($this, 'zlib', 'zip extracting');
|
||||
}
|
||||
|
||||
$zip = new \ZipArchive();
|
||||
if (($status = $zip->open($this->filename)) !== true) {
|
||||
return Result::error($this, "Could not open zip archive {$this->filename}");
|
||||
}
|
||||
if (!$zip->extractTo($extractLocation)) {
|
||||
return Result::error($this, "Could not extract zip archive {$this->filename}");
|
||||
}
|
||||
$zip->close();
|
||||
|
||||
return Result::success($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $extractLocation
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function extractTar($extractLocation)
|
||||
{
|
||||
if (!class_exists('Archive_Tar')) {
|
||||
return Result::errorMissingPackage($this, 'Archive_Tar', 'pear/archive_tar');
|
||||
}
|
||||
$tar_object = new \Archive_Tar($this->filename);
|
||||
if (!$tar_object->extract($extractLocation)) {
|
||||
return Result::error($this, "Could not extract tar archive {$this->filename}");
|
||||
}
|
||||
|
||||
return Result::success($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
protected static function archiveType($filename)
|
||||
{
|
||||
$content_type = false;
|
||||
if (class_exists('finfo')) {
|
||||
$finfo = new \finfo(FILEINFO_MIME_TYPE);
|
||||
$content_type = $finfo->file($filename);
|
||||
// If finfo cannot determine the content type, then we will try other methods
|
||||
if ($content_type == 'application/octet-stream') {
|
||||
$content_type = false;
|
||||
}
|
||||
}
|
||||
// Examing the file's magic header bytes.
|
||||
if (!$content_type) {
|
||||
if ($file = fopen($filename, 'rb')) {
|
||||
$first = fread($file, 2);
|
||||
fclose($file);
|
||||
if ($first !== false) {
|
||||
// Interpret the two bytes as a little endian 16-bit unsigned int.
|
||||
$data = unpack('v', $first);
|
||||
switch ($data[1]) {
|
||||
case 0x8b1f:
|
||||
// First two bytes of gzip files are 0x1f, 0x8b (little-endian).
|
||||
// See https://www.gzip.org/zlib/rfc-gzip.html#header-trailer
|
||||
$content_type = 'application/x-gzip';
|
||||
break;
|
||||
|
||||
case 0x4b50:
|
||||
// First two bytes of zip files are 0x50, 0x4b ('PK') (little-endian).
|
||||
// See https://en.wikipedia.org/wiki/Zip_(file_format)#File_headers
|
||||
$content_type = 'application/zip';
|
||||
break;
|
||||
|
||||
case 0x5a42:
|
||||
// First two bytes of bzip2 files are 0x5a, 0x42 ('BZ') (big-endian).
|
||||
// See https://en.wikipedia.org/wiki/Bzip2#File_format
|
||||
$content_type = 'application/x-bzip2';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3. Lastly if above methods didn't work, try to guess the mime type from
|
||||
// the file extension. This is useful if the file has no identificable magic
|
||||
// header bytes (for example tarballs).
|
||||
if (!$content_type) {
|
||||
// Remove querystring from the filename, if present.
|
||||
$filename = basename(current(explode('?', $filename, 2)));
|
||||
$extension_mimetype = array(
|
||||
'.tar.gz' => 'application/x-gzip',
|
||||
'.tgz' => 'application/x-gzip',
|
||||
'.tar' => 'application/x-tar',
|
||||
);
|
||||
foreach ($extension_mimetype as $extension => $ct) {
|
||||
if (substr($filename, -strlen($extension)) === $extension) {
|
||||
$content_type = $ct;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $content_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getTempDir()
|
||||
{
|
||||
return $this->to . '-tmp' . rand() . time();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use $this->getTempDir() instead.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @see getTempDir
|
||||
*/
|
||||
protected static function getTmpDir()
|
||||
{
|
||||
return getcwd() . '/tmp' . rand() . time();
|
||||
}
|
||||
}
|
||||
291
vendor/consolidation/robo/src/Task/Archive/Pack.php
vendored
Normal file
291
vendor/consolidation/robo/src/Task/Archive/Pack.php
vendored
Normal file
@ -0,0 +1,291 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Archive;
|
||||
|
||||
use Robo\Contract\PrintedInterface;
|
||||
use Robo\Result;
|
||||
use Robo\Task\BaseTask;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
||||
/**
|
||||
* Creates a zip or tar archive.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskPack(
|
||||
* <archiveFile>)
|
||||
* ->add('README') // Puts file 'README' in archive at the root
|
||||
* ->add('project') // Puts entire contents of directory 'project' in archinve inside 'project'
|
||||
* ->addFile('dir/file.txt', 'file.txt') // Takes 'file.txt' from cwd and puts it in archive inside 'dir'.
|
||||
* ->exclude(['dir\/.*.zip', '.*.md']) // Add regex (or array of regex) to the excluded patterns list.
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Pack extends BaseTask implements PrintedInterface
|
||||
{
|
||||
/**
|
||||
* The list of items to be packed into the archive.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $items = [];
|
||||
|
||||
/**
|
||||
* The full path to the archive to be created.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $archiveFile;
|
||||
|
||||
/**
|
||||
* A list of regex patterns to exclude from the archive.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $ignoreList;
|
||||
/**
|
||||
* Construct the class.
|
||||
*
|
||||
* @param string $archiveFile
|
||||
* The full path and name of the archive file to create.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function __construct($archiveFile)
|
||||
{
|
||||
$this->archiveFile = $archiveFile;
|
||||
$this->ignoreList = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Satisfy the parent requirement.
|
||||
*
|
||||
* @return bool
|
||||
* Always returns true.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function getPrinted()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $archiveFile
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function archiveFile($archiveFile)
|
||||
{
|
||||
$this->archiveFile = $archiveFile;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an item to the archive. Like file_exists(), the parameter
|
||||
* may be a file or a directory.
|
||||
*
|
||||
* @param string $placementLocation
|
||||
* Relative path and name of item to store in archive.
|
||||
* @param string $filesystemLocation
|
||||
* Absolute or relative path to file or directory's location in filesystem.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addFile($placementLocation, $filesystemLocation)
|
||||
{
|
||||
$this->items[$placementLocation] = $filesystemLocation;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for addFile, in case anyone has angst about using
|
||||
* addFile with a directory.
|
||||
*
|
||||
* @param string $placementLocation
|
||||
* Relative path and name of directory to store in archive.
|
||||
* @param string $filesystemLocation
|
||||
* Absolute or relative path to directory or directory's location in filesystem.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addDir($placementLocation, $filesystemLocation)
|
||||
{
|
||||
$this->addFile($placementLocation, $filesystemLocation);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a file or directory, or list of same to the archive.
|
||||
*
|
||||
* @param string|array $item
|
||||
* If given a string, should contain the relative filesystem path to the
|
||||
* the item to store in archive; this will also be used as the item's
|
||||
* path in the archive, so absolute paths should not be used here.
|
||||
* If given an array, the key of each item should be the path to store
|
||||
* in the archive, and the value should be the filesystem path to the
|
||||
* item to store.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function add($item)
|
||||
{
|
||||
if (is_array($item)) {
|
||||
$this->items = array_merge($this->items, $item);
|
||||
} else {
|
||||
$this->addFile($item, $item);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow files or folder to be excluded from the archive. Use regex, without enclosing slashes.
|
||||
*
|
||||
* @param string|string[]
|
||||
* A regex (or array of) to be excluded.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function exclude($ignoreList)
|
||||
{
|
||||
$this->ignoreList = array_merge($this->ignoreList, (array) $ignoreList);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a zip archive for distribution.
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->startTimer();
|
||||
|
||||
// Use the file extension to determine what kind of archive to create.
|
||||
$fileInfo = new \SplFileInfo($this->archiveFile);
|
||||
$extension = strtolower($fileInfo->getExtension());
|
||||
if (empty($extension)) {
|
||||
return Result::error($this, "Archive filename must use an extension (e.g. '.zip') to specify the kind of archive to create.");
|
||||
}
|
||||
|
||||
try {
|
||||
// Inform the user which archive we are creating
|
||||
$this->printTaskInfo("Creating archive {filename}", ['filename' => $this->archiveFile]);
|
||||
if ($extension == 'zip') {
|
||||
$result = $this->archiveZip($this->archiveFile, $this->items);
|
||||
} else {
|
||||
$result = $this->archiveTar($this->archiveFile, $this->items);
|
||||
}
|
||||
$this->printTaskSuccess("{filename} created.", ['filename' => $this->archiveFile]);
|
||||
} catch (\Exception $e) {
|
||||
$this->printTaskError("Could not create {filename}. {exception}", ['filename' => $this->archiveFile, 'exception' => $e->getMessage(), '_style' => ['exception' => '']]);
|
||||
$result = Result::error($this, sprintf('Could not create %s. %s', $this->archiveFile, $e->getMessage()));
|
||||
}
|
||||
$this->stopTimer();
|
||||
$result['time'] = $this->getExecutionTime();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $archiveFile
|
||||
* @param array $items
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function archiveTar($archiveFile, $items)
|
||||
{
|
||||
if (!class_exists('Archive_Tar')) {
|
||||
return Result::errorMissingPackage($this, 'Archive_Tar', 'pear/archive_tar');
|
||||
}
|
||||
|
||||
$tar_object = new \Archive_Tar($archiveFile);
|
||||
if (!empty($this->ignoreList)) {
|
||||
$regexp = '#/' . join('$|/', $this->ignoreList) . '#';
|
||||
$tar_object->setIgnoreRegexp($regexp);
|
||||
}
|
||||
foreach ($items as $placementLocation => $filesystemLocation) {
|
||||
$p_remove_dir = $filesystemLocation;
|
||||
$p_add_dir = $placementLocation;
|
||||
if (is_file($filesystemLocation)) {
|
||||
$p_remove_dir = dirname($filesystemLocation);
|
||||
$p_add_dir = dirname($placementLocation);
|
||||
if (basename($filesystemLocation) != basename($placementLocation)) {
|
||||
return Result::error($this, "Tar archiver does not support renaming files during extraction; could not add $filesystemLocation as $placementLocation.");
|
||||
}
|
||||
}
|
||||
|
||||
if (!$tar_object->addModify([$filesystemLocation], $p_add_dir, $p_remove_dir)) {
|
||||
return Result::error($this, "Could not add $filesystemLocation to the archive.");
|
||||
}
|
||||
}
|
||||
|
||||
return Result::success($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $archiveFile
|
||||
* @param array $items
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function archiveZip($archiveFile, $items)
|
||||
{
|
||||
if (!extension_loaded('zlib') || !class_exists(\ZipArchive::class)) {
|
||||
return Result::errorMissingExtension($this, 'zlib', 'zip packing');
|
||||
}
|
||||
|
||||
$zip = new \ZipArchive();
|
||||
if (!$zip->open($archiveFile, \ZipArchive::CREATE)) {
|
||||
return Result::error($this, "Could not create zip archive {$archiveFile}");
|
||||
}
|
||||
$result = $this->addItemsToZip($zip, $items);
|
||||
$zip->close();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ZipArchive $zip
|
||||
* @param array $items
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function addItemsToZip($zip, $items)
|
||||
{
|
||||
foreach ($items as $placementLocation => $filesystemLocation) {
|
||||
if (is_dir($filesystemLocation)) {
|
||||
$finder = new Finder();
|
||||
$finder->files()->in($filesystemLocation)->ignoreDotFiles(false);
|
||||
if (!empty($this->ignoreList)) {
|
||||
// Add slashes so Symfony Finder patterns work like Archive_Tar ones.
|
||||
$zipIgnoreList = preg_filter('/^|$/', '/', $this->ignoreList);
|
||||
$finder->notName($zipIgnoreList)->notPath($zipIgnoreList);
|
||||
}
|
||||
|
||||
foreach ($finder as $file) {
|
||||
// Replace Windows slashes or resulting zip will have issues on *nixes.
|
||||
$relativePathname = str_replace('\\', '/', $file->getRelativePathname());
|
||||
|
||||
if (!$zip->addFile($file->getRealpath(), "{$placementLocation}/{$relativePathname}")) {
|
||||
return Result::error($this, "Could not add directory $filesystemLocation to the archive; error adding {$file->getRealpath()}.");
|
||||
}
|
||||
}
|
||||
} elseif (is_file($filesystemLocation)) {
|
||||
if (!$zip->addFile($filesystemLocation, $placementLocation)) {
|
||||
return Result::error($this, "Could not add file $filesystemLocation to the archive.");
|
||||
}
|
||||
} else {
|
||||
return Result::error($this, "Could not find $filesystemLocation for the archive.");
|
||||
}
|
||||
}
|
||||
|
||||
return Result::success($this);
|
||||
}
|
||||
}
|
||||
26
vendor/consolidation/robo/src/Task/Archive/Tasks.php
vendored
Normal file
26
vendor/consolidation/robo/src/Task/Archive/Tasks.php
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Archive;
|
||||
|
||||
trait Tasks
|
||||
{
|
||||
/**
|
||||
* @param string $filename
|
||||
*
|
||||
* @return \Robo\Task\Archive\Pack|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskPack($filename)
|
||||
{
|
||||
return $this->task(Pack::class, $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
*
|
||||
* @return \Robo\Task\Archive\Extract|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskExtract($filename)
|
||||
{
|
||||
return $this->task(Extract::class, $filename);
|
||||
}
|
||||
}
|
||||
214
vendor/consolidation/robo/src/Task/Assets/CssPreprocessor.php
vendored
Normal file
214
vendor/consolidation/robo/src/Task/Assets/CssPreprocessor.php
vendored
Normal file
@ -0,0 +1,214 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Assets;
|
||||
|
||||
use Robo\Result;
|
||||
use Robo\Task\BaseTask;
|
||||
|
||||
abstract class CssPreprocessor extends BaseTask
|
||||
{
|
||||
const FORMAT_NAME = '';
|
||||
|
||||
/**
|
||||
* Default compiler to use.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $compiler;
|
||||
|
||||
/**
|
||||
* Available compilers list
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $compilers = [];
|
||||
|
||||
/**
|
||||
* Compiler options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $compilerOptions = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $files = [];
|
||||
|
||||
/**
|
||||
* Constructor. Accepts array of file paths.
|
||||
*
|
||||
* @param array $input
|
||||
*/
|
||||
public function __construct(array $input)
|
||||
{
|
||||
$this->files = $input;
|
||||
|
||||
$this->setDefaultCompiler();
|
||||
}
|
||||
|
||||
protected function setDefaultCompiler()
|
||||
{
|
||||
if (isset($this->compilers[0])) {
|
||||
//set first compiler as default
|
||||
$this->compiler = $this->compilers[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets import directories
|
||||
* Alias for setImportPaths
|
||||
* @see CssPreprocessor::setImportPaths
|
||||
*
|
||||
* @param array|string $dirs
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function importDir($dirs)
|
||||
{
|
||||
return $this->setImportPaths($dirs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds import directory
|
||||
*
|
||||
* @param string $dir
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addImportPath($dir)
|
||||
{
|
||||
if (!isset($this->compilerOptions['importDirs'])) {
|
||||
$this->compilerOptions['importDirs'] = [];
|
||||
}
|
||||
|
||||
if (!in_array($dir, $this->compilerOptions['importDirs'], true)) {
|
||||
$this->compilerOptions['importDirs'][] = $dir;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets import directories
|
||||
*
|
||||
* @param array|string $dirs
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setImportPaths($dirs)
|
||||
{
|
||||
if (!is_array($dirs)) {
|
||||
$dirs = [$dirs];
|
||||
}
|
||||
|
||||
$this->compilerOptions['importDirs'] = $dirs;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $formatterName
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFormatter($formatterName)
|
||||
{
|
||||
$this->compilerOptions['formatter'] = $formatterName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the compiler.
|
||||
*
|
||||
* @param string $compiler
|
||||
* @param array $options
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function compiler($compiler, array $options = [])
|
||||
{
|
||||
$this->compiler = $compiler;
|
||||
$this->compilerOptions = array_merge($this->compilerOptions, $options);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles file
|
||||
*
|
||||
* @param $file
|
||||
*
|
||||
* @return bool|mixed
|
||||
*/
|
||||
protected function compile($file)
|
||||
{
|
||||
if (is_callable($this->compiler)) {
|
||||
return call_user_func($this->compiler, $file, $this->compilerOptions);
|
||||
}
|
||||
|
||||
if (method_exists($this, $this->compiler)) {
|
||||
return $this->{$this->compiler}($file);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if (!in_array($this->compiler, $this->compilers, true)
|
||||
&& !is_callable($this->compiler)
|
||||
) {
|
||||
$message = sprintf('Invalid ' . static::FORMAT_NAME . ' compiler %s!', $this->compiler);
|
||||
|
||||
return Result::error($this, $message);
|
||||
}
|
||||
|
||||
foreach ($this->files as $in => $out) {
|
||||
if (!file_exists($in)) {
|
||||
$message = sprintf('File %s not found.', $in);
|
||||
|
||||
return Result::error($this, $message);
|
||||
}
|
||||
if (file_exists($out) && !is_writable($out)) {
|
||||
return Result::error($this, 'Destination already exists and cannot be overwritten.');
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->files as $in => $out) {
|
||||
$css = $this->compile($in);
|
||||
|
||||
if ($css instanceof Result) {
|
||||
return $css;
|
||||
} elseif (false === $css) {
|
||||
$message = sprintf(
|
||||
ucfirst(static::FORMAT_NAME) . ' compilation failed for %s.',
|
||||
$in
|
||||
);
|
||||
|
||||
return Result::error($this, $message);
|
||||
}
|
||||
|
||||
$dst = $out . '.part';
|
||||
$write_result = file_put_contents($dst, $css);
|
||||
|
||||
if (false === $write_result) {
|
||||
$message = sprintf('File write failed: %s', $out);
|
||||
|
||||
@unlink($dst);
|
||||
return Result::error($this, $message);
|
||||
}
|
||||
|
||||
// Cannot be cross-volume: should always succeed
|
||||
@rename($dst, $out);
|
||||
|
||||
$this->printTaskSuccess('Wrote CSS to {filename}', ['filename' => $out]);
|
||||
}
|
||||
|
||||
return Result::success($this, 'All ' . static::FORMAT_NAME . ' files compiled.');
|
||||
}
|
||||
}
|
||||
761
vendor/consolidation/robo/src/Task/Assets/ImageMinify.php
vendored
Normal file
761
vendor/consolidation/robo/src/Task/Assets/ImageMinify.php
vendored
Normal file
@ -0,0 +1,761 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Assets;
|
||||
|
||||
use Robo\Result;
|
||||
use Robo\Exception\TaskException;
|
||||
use Robo\Task\BaseTask;
|
||||
use Robo\Task\Base\Exec;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\Filesystem\Filesystem as sfFilesystem;
|
||||
|
||||
/**
|
||||
* Minifies images.
|
||||
*
|
||||
* When the task is run without any specified minifier it will compress the
|
||||
* images based on the extension.
|
||||
*
|
||||
* ```php
|
||||
* $this->taskImageMinify('assets/images/*')
|
||||
* ->to('dist/images/')
|
||||
* ->run();
|
||||
* ```
|
||||
*
|
||||
* This will use the following minifiers based in the extension:
|
||||
*
|
||||
* - PNG: optipng
|
||||
* - GIF: gifsicle
|
||||
* - JPG, JPEG: jpegtran
|
||||
* - SVG: svgo
|
||||
*
|
||||
* When the required minifier is not installed on the system the task will try
|
||||
* to download it from the [imagemin](https://github.com/imagemin) repository
|
||||
* into a local directory.
|
||||
* This directory is `vendor/bin/` by default and may be changed:
|
||||
*
|
||||
* ```php
|
||||
* $this->taskImageMinify('assets/images/*')
|
||||
* ->setExecutableDir('/tmp/imagemin/bin/)
|
||||
* ->to('dist/images/')
|
||||
* ->run();
|
||||
* ```
|
||||
*
|
||||
* When the minifier is specified the task will use that for all the input
|
||||
* files. In that case it is useful to filter the files with the extension:
|
||||
*
|
||||
* ```php
|
||||
* $this->taskImageMinify('assets/images/*.png')
|
||||
* ->to('dist/images/')
|
||||
* ->minifier('pngcrush');
|
||||
* ->run();
|
||||
* ```
|
||||
*
|
||||
* The task supports the following minifiers:
|
||||
*
|
||||
* - optipng
|
||||
* - pngquant
|
||||
* - advpng
|
||||
* - pngout
|
||||
* - zopflipng
|
||||
* - pngcrush
|
||||
* - gifsicle
|
||||
* - jpegoptim
|
||||
* - jpeg-recompress
|
||||
* - jpegtran
|
||||
* - svgo (only minification, no downloading)
|
||||
*
|
||||
* You can also specifiy extra options for the minifiers:
|
||||
*
|
||||
* ```php
|
||||
* $this->taskImageMinify('assets/images/*.jpg')
|
||||
* ->to('dist/images/')
|
||||
* ->minifier('jpegtran', ['-progressive' => null, '-copy' => 'none'])
|
||||
* ->run();
|
||||
* ```
|
||||
*
|
||||
* This will execute as:
|
||||
* `jpegtran -copy none -progressive -optimize -outfile "dist/images/test.jpg" "/var/www/test/assets/images/test.jpg"`
|
||||
*/
|
||||
class ImageMinify extends BaseTask
|
||||
{
|
||||
/**
|
||||
* Destination directory for the minified images.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $to;
|
||||
|
||||
/**
|
||||
* Array of the source files.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dirs = [];
|
||||
|
||||
/**
|
||||
* Symfony 2 filesystem.
|
||||
*
|
||||
* @var sfFilesystem
|
||||
*/
|
||||
protected $fs;
|
||||
|
||||
/**
|
||||
* Target directory for the downloaded binary executables.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $executableTargetDir;
|
||||
|
||||
/**
|
||||
* Array for the downloaded binary executables.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $executablePaths = [];
|
||||
|
||||
/**
|
||||
* Array for the individual results of all the files.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $results = [];
|
||||
|
||||
/**
|
||||
* Default minifier to use.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $minifier;
|
||||
|
||||
/**
|
||||
* Array for minifier options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $minifierOptions = [];
|
||||
|
||||
/**
|
||||
* Supported minifiers.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $minifiers = [
|
||||
// Default 4
|
||||
'optipng',
|
||||
'gifsicle',
|
||||
'jpegtran',
|
||||
'svgo',
|
||||
// PNG
|
||||
'pngquant',
|
||||
'advpng',
|
||||
'pngout',
|
||||
'zopflipng',
|
||||
'pngcrush',
|
||||
// JPG
|
||||
'jpegoptim',
|
||||
'jpeg-recompress',
|
||||
];
|
||||
|
||||
/**
|
||||
* Binary repositories of Imagemin.
|
||||
*
|
||||
* @link https://github.com/imagemin
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $imageminRepos = [
|
||||
// PNG
|
||||
'optipng' => 'https://github.com/imagemin/optipng-bin',
|
||||
'pngquant' => 'https://github.com/imagemin/pngquant-bin',
|
||||
'advpng' => 'https://github.com/imagemin/advpng-bin',
|
||||
'pngout' => 'https://github.com/imagemin/pngout-bin',
|
||||
'zopflipng' => 'https://github.com/imagemin/zopflipng-bin',
|
||||
'pngcrush' => 'https://github.com/imagemin/pngcrush-bin',
|
||||
// Gif
|
||||
'gifsicle' => 'https://github.com/imagemin/gifsicle-bin',
|
||||
// JPG
|
||||
'jpegtran' => 'https://github.com/imagemin/jpegtran-bin',
|
||||
'jpegoptim' => 'https://github.com/imagemin/jpegoptim-bin',
|
||||
'cjpeg' => 'https://github.com/imagemin/mozjpeg-bin', // note: we do not support this minifier because it creates JPG from non-JPG files
|
||||
'jpeg-recompress' => 'https://github.com/imagemin/jpeg-recompress-bin',
|
||||
// WebP
|
||||
'cwebp' => 'https://github.com/imagemin/cwebp-bin', // note: we do not support this minifier because it creates WebP from non-WebP files
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string|string[] $dirs
|
||||
*/
|
||||
public function __construct($dirs)
|
||||
{
|
||||
is_array($dirs)
|
||||
? $this->dirs = $dirs
|
||||
: $this->dirs[] = $dirs;
|
||||
|
||||
$this->fs = new sfFilesystem();
|
||||
|
||||
// guess the best path for the executables based on __DIR__
|
||||
if (($pos = strpos(__DIR__, 'consolidation/robo')) !== false) {
|
||||
// the executables should be stored in vendor/bin
|
||||
$this->setExecutableDir(substr(__DIR__, 0, $pos) . 'bin');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
// find the files
|
||||
$files = $this->findFiles($this->dirs);
|
||||
|
||||
// minify the files
|
||||
$result = $this->minify($files);
|
||||
// check if there was an error
|
||||
if ($result instanceof Result) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$amount = (count($files) == 1 ? 'image' : 'images');
|
||||
$message = "Minified {filecount} out of {filetotal} $amount into {destination}";
|
||||
$context = ['filecount' => count($this->results['success']), 'filetotal' => count($files), 'destination' => $this->to];
|
||||
|
||||
if (count($this->results['success']) == count($files)) {
|
||||
$this->printTaskSuccess($message, $context);
|
||||
|
||||
return Result::success($this, $message, $context);
|
||||
} else {
|
||||
return Result::error($this, $message, $context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the target directory for executables (`vendor/bin/` by default)
|
||||
*
|
||||
* @param string $directory
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setExecutableDir($directory)
|
||||
{
|
||||
$this->executableTargetDir = $directory;
|
||||
|
||||
// check if the executables are already available in there
|
||||
foreach ($this->imageminRepos as $exec => $url) {
|
||||
$path = $this->executableTargetDir . '/' . $exec;
|
||||
// if this is Windows add a .exe extension
|
||||
if (substr($this->getOS(), 0, 3) == 'win') {
|
||||
$path .= '.exe';
|
||||
}
|
||||
if (is_file($path)) {
|
||||
$this->executablePaths[$exec] = $path;
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the target directory where the files will be copied to.
|
||||
*
|
||||
* @param string $target
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function to($target)
|
||||
{
|
||||
$this->to = rtrim($target, '/');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the minifier.
|
||||
*
|
||||
* @param string $minifier
|
||||
* @param array $options
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function minifier($minifier, array $options = [])
|
||||
{
|
||||
$this->minifier = $minifier;
|
||||
$this->minifierOptions = array_merge($this->minifierOptions, $options);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $dirs
|
||||
*
|
||||
* @return array|\Robo\Result
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
protected function findFiles($dirs)
|
||||
{
|
||||
$files = array();
|
||||
|
||||
// find the files
|
||||
foreach ($dirs as $k => $v) {
|
||||
// reset finder
|
||||
$finder = new Finder();
|
||||
|
||||
$dir = $k;
|
||||
$to = $v;
|
||||
// check if target was given with the to() method instead of key/value pairs
|
||||
if (is_int($k)) {
|
||||
$dir = $v;
|
||||
if (isset($this->to)) {
|
||||
$to = $this->to;
|
||||
} else {
|
||||
throw new TaskException($this, 'target directory is not defined');
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$finder->files()->in($dir);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
// if finder cannot handle it, try with in()->name()
|
||||
if (strpos($dir, '/') === false) {
|
||||
$dir = './' . $dir;
|
||||
}
|
||||
$parts = explode('/', $dir);
|
||||
$new_dir = implode('/', array_slice($parts, 0, -1));
|
||||
try {
|
||||
$finder->files()->in($new_dir)->name(array_pop($parts));
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return Result::fromException($this, $e);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($finder as $file) {
|
||||
// store the absolute path as key and target as value in the files array
|
||||
$files[$file->getRealpath()] = $this->getTarget($file->getRealPath(), $to);
|
||||
}
|
||||
$fileNoun = count($finder) == 1 ? ' file' : ' files';
|
||||
$this->printTaskInfo("Found {filecount} $fileNoun in {dir}", ['filecount' => count($finder), 'dir' => $dir]);
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param string $to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getTarget($file, $to)
|
||||
{
|
||||
$target = $to . '/' . basename($file);
|
||||
|
||||
return $target;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $files
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function minify($files)
|
||||
{
|
||||
// store the individual results into the results array
|
||||
$this->results = [
|
||||
'success' => [],
|
||||
'error' => [],
|
||||
];
|
||||
|
||||
// loop through the files
|
||||
foreach ($files as $from => $to) {
|
||||
$minifier = '';
|
||||
|
||||
if (!isset($this->minifier)) {
|
||||
// check filetype based on the extension
|
||||
$extension = strtolower(pathinfo($from, PATHINFO_EXTENSION));
|
||||
|
||||
// set the default minifiers based on the extension
|
||||
switch ($extension) {
|
||||
case 'png':
|
||||
$minifier = 'optipng';
|
||||
break;
|
||||
case 'jpg':
|
||||
case 'jpeg':
|
||||
$minifier = 'jpegtran';
|
||||
break;
|
||||
case 'gif':
|
||||
$minifier = 'gifsicle';
|
||||
break;
|
||||
case 'svg':
|
||||
$minifier = 'svgo';
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!in_array($this->minifier, $this->minifiers, true)
|
||||
&& !is_callable(strtr($this->minifier, '-', '_'))
|
||||
) {
|
||||
$message = sprintf('Invalid minifier %s!', $this->minifier);
|
||||
|
||||
return Result::error($this, $message);
|
||||
}
|
||||
$minifier = $this->minifier;
|
||||
}
|
||||
|
||||
// Convert minifier name to camelCase (e.g. jpeg-recompress)
|
||||
$funcMinifier = $this->camelCase($minifier);
|
||||
|
||||
// call the minifier method which prepares the command
|
||||
if (is_callable($funcMinifier)) {
|
||||
$command = call_user_func($funcMinifier, $from, $to, $this->minifierOptions);
|
||||
} elseif (method_exists($this, $funcMinifier)) {
|
||||
$command = $this->{$funcMinifier}($from, $to);
|
||||
} else {
|
||||
$message = sprintf('Minifier method <info>%s</info> cannot be found!', $funcMinifier);
|
||||
|
||||
return Result::error($this, $message);
|
||||
}
|
||||
|
||||
// launch the command
|
||||
$this->printTaskInfo('Minifying {filepath} with {minifier}', ['filepath' => $from, 'minifier' => $minifier]);
|
||||
$result = $this->executeCommand($command);
|
||||
|
||||
// check the return code
|
||||
if ($result->getExitCode() == 127) {
|
||||
$this->printTaskError('The {minifier} executable cannot be found', ['minifier' => $minifier]);
|
||||
// try to install from imagemin repository
|
||||
if (array_key_exists($minifier, $this->imageminRepos)) {
|
||||
$result = $this->installFromImagemin($minifier);
|
||||
if ($result instanceof Result) {
|
||||
if ($result->wasSuccessful()) {
|
||||
$this->printTaskSuccess($result->getMessage());
|
||||
// retry the conversion with the downloaded executable
|
||||
if (is_callable($minifier)) {
|
||||
$command = call_user_func($minifier, $from, $to, $this->minifierOptions);
|
||||
} elseif (method_exists($this, $minifier)) {
|
||||
$command = $this->{$minifier}($from, $to);
|
||||
}
|
||||
// launch the command
|
||||
$this->printTaskInfo('Minifying {filepath} with {minifier}', ['filepath' => $from, 'minifier' => $minifier]);
|
||||
$result = $this->executeCommand($command);
|
||||
} else {
|
||||
$this->printTaskError($result->getMessage());
|
||||
// the download was not successful
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// check the success of the conversion
|
||||
if ($result->getExitCode() !== 0) {
|
||||
$this->results['error'][] = $from;
|
||||
} else {
|
||||
$this->results['success'][] = $from;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getOS()
|
||||
{
|
||||
$os = php_uname('s');
|
||||
$os .= '/' . php_uname('m');
|
||||
// replace x86_64 to x64, because the imagemin repo uses that
|
||||
$os = str_replace('x86_64', 'x64', $os);
|
||||
// replace i386, i686, etc to x86, because of imagemin
|
||||
$os = preg_replace('/i[0-9]86/', 'x86', $os);
|
||||
// turn info to lowercase, because of imagemin
|
||||
$os = strtolower($os);
|
||||
|
||||
return $os;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $command
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function executeCommand($command)
|
||||
{
|
||||
// insert the options into the command
|
||||
$a = explode(' ', $command);
|
||||
$executable = array_shift($a);
|
||||
foreach ($this->minifierOptions as $key => $value) {
|
||||
// first prepend the value
|
||||
if (!empty($value)) {
|
||||
array_unshift($a, $value);
|
||||
}
|
||||
// then add the key
|
||||
if (!is_numeric($key)) {
|
||||
array_unshift($a, $key);
|
||||
}
|
||||
}
|
||||
// prefer the downloaded executable if it exists already
|
||||
if (array_key_exists($executable, $this->executablePaths)) {
|
||||
$executable = $this->executablePaths[$executable];
|
||||
}
|
||||
array_unshift($a, $executable);
|
||||
$command = implode(' ', $a);
|
||||
|
||||
// execute the command
|
||||
$exec = new Exec($command);
|
||||
|
||||
return $exec->inflect($this)->printOutput(false)->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $executable
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function installFromImagemin($executable)
|
||||
{
|
||||
// check if there is an url defined for the executable
|
||||
if (!array_key_exists($executable, $this->imageminRepos)) {
|
||||
$message = sprintf('The executable %s cannot be found in the defined imagemin repositories', $executable);
|
||||
|
||||
return Result::error($this, $message);
|
||||
}
|
||||
$this->printTaskInfo('Downloading the {executable} executable from the imagemin repository', ['executable' => $executable]);
|
||||
|
||||
$os = $this->getOS();
|
||||
$url = $this->imageminRepos[$executable] . '/blob/main/vendor/' . $os . '/' . $executable . '?raw=true';
|
||||
if (substr($os, 0, 3) == 'win') {
|
||||
// if it is win, add a .exe extension
|
||||
$url = $this->imageminRepos[$executable] . '/blob/main/vendor/' . $os . '/' . $executable . '.exe?raw=true';
|
||||
}
|
||||
$data = @file_get_contents($url, false, null);
|
||||
if ($data === false) {
|
||||
// there is something wrong with the url, try it without the version info
|
||||
$url = preg_replace('/x[68][64]\//', '', $url);
|
||||
$data = @file_get_contents($url, false, null);
|
||||
if ($data === false) {
|
||||
// there is still something wrong with the url if it is win, try with win32
|
||||
if (substr($os, 0, 3) == 'win') {
|
||||
$url = preg_replace('win/', 'win32/', $url);
|
||||
$data = @file_get_contents($url, false, null);
|
||||
if ($data === false) {
|
||||
// there is nothing more we can do
|
||||
$message = sprintf('Could not download the executable <info>%s</info>', $executable);
|
||||
|
||||
return Result::error($this, $message);
|
||||
}
|
||||
}
|
||||
// if it is not windows there is nothing we can do
|
||||
$message = sprintf('Could not download the executable <info>%s</info>', $executable);
|
||||
|
||||
return Result::error($this, $message);
|
||||
}
|
||||
}
|
||||
// check if target directory was set
|
||||
if (empty($this->executableTargetDir)) {
|
||||
return Result::error($this, 'No target directory for executables set');
|
||||
}
|
||||
// check if target directory exists
|
||||
if (!is_dir($this->executableTargetDir)) {
|
||||
// create and check access rights (directory created, but not readable)
|
||||
if (!mkdir($this->executableTargetDir) && !is_dir($this->executableTargetDir)) {
|
||||
$message = sprintf('Can not create target directory for executables in <info>%s</info>', $this->executableTargetDir);
|
||||
|
||||
return Result::error($this, $message);
|
||||
}
|
||||
}
|
||||
// save the executable into the target dir
|
||||
$path = $this->executableTargetDir . '/' . $executable;
|
||||
if (substr($os, 0, 3) == 'win') {
|
||||
// if it is win, add a .exe extension
|
||||
$path = $this->executableTargetDir . '/' . $executable . '.exe';
|
||||
}
|
||||
$result = file_put_contents($path, $data);
|
||||
if ($result === false) {
|
||||
$message = sprintf('Could not copy the executable <info>%s</info> to %s', $executable, $path);
|
||||
|
||||
return Result::error($this, $message);
|
||||
}
|
||||
// set the binary to executable
|
||||
chmod($path, 0755);
|
||||
|
||||
// if everything successful, store the executable path
|
||||
$this->executablePaths[$executable] = $this->executableTargetDir . '/' . $executable;
|
||||
// if it is win, add a .exe extension
|
||||
if (substr($os, 0, 3) == 'win') {
|
||||
$this->executablePaths[$executable] .= '.exe';
|
||||
}
|
||||
|
||||
$message = sprintf('Executable <info>%s</info> successfully downloaded', $executable);
|
||||
|
||||
return Result::success($this, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function optipng($from, $to)
|
||||
{
|
||||
$command = sprintf('optipng -quiet -out "%s" -- "%s"', $to, $from);
|
||||
if ($from != $to && is_file($to)) {
|
||||
// earlier versions of optipng do not overwrite the target without a backup
|
||||
// https://sourceforge.net/p/optipng/bugs/37/
|
||||
unlink($to);
|
||||
}
|
||||
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function jpegtran($from, $to)
|
||||
{
|
||||
$command = sprintf('jpegtran -optimize -outfile "%s" "%s"', $to, $from);
|
||||
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function gifsicle($from, $to)
|
||||
{
|
||||
$command = sprintf('gifsicle -o "%s" "%s"', $to, $from);
|
||||
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function svgo($from, $to)
|
||||
{
|
||||
$command = sprintf('svgo "%s" "%s"', $from, $to);
|
||||
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function pngquant($from, $to)
|
||||
{
|
||||
$command = sprintf('pngquant --force --output "%s" "%s"', $to, $from);
|
||||
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function advpng($from, $to)
|
||||
{
|
||||
// advpng does not have any output parameters, copy the file and then compress the copy
|
||||
$command = sprintf('advpng --recompress --quiet "%s"', $to);
|
||||
$this->fs->copy($from, $to, true);
|
||||
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function pngout($from, $to)
|
||||
{
|
||||
$command = sprintf('pngout -y -q "%s" "%s"', $from, $to);
|
||||
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function zopflipng($from, $to)
|
||||
{
|
||||
$command = sprintf('zopflipng -y "%s" "%s"', $from, $to);
|
||||
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function pngcrush($from, $to)
|
||||
{
|
||||
$command = sprintf('pngcrush -q -ow "%s" "%s"', $from, $to);
|
||||
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function jpegoptim($from, $to)
|
||||
{
|
||||
// jpegoptim only takes the destination directory as an argument
|
||||
$command = sprintf('jpegoptim --quiet -o --dest "%s" "%s"', dirname($to), $from);
|
||||
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function jpegRecompress($from, $to)
|
||||
{
|
||||
$command = sprintf('jpeg-recompress --quiet "%s" "%s"', $from, $to);
|
||||
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function camelCase($text)
|
||||
{
|
||||
// non-alpha and non-numeric characters become spaces
|
||||
$text = preg_replace('/[^a-z0-9]+/i', ' ', $text);
|
||||
$text = trim($text);
|
||||
// uppercase the first character of each word
|
||||
$text = ucwords($text);
|
||||
$text = str_replace(" ", "", $text);
|
||||
$text = lcfirst($text);
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
109
vendor/consolidation/robo/src/Task/Assets/Less.php
vendored
Normal file
109
vendor/consolidation/robo/src/Task/Assets/Less.php
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Assets;
|
||||
|
||||
use Robo\Result;
|
||||
|
||||
/**
|
||||
* Compiles less files.
|
||||
*
|
||||
* ```php
|
||||
* <?php
|
||||
* $this->taskLess([
|
||||
* 'less/default.less' => 'css/default.css'
|
||||
* ])
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*
|
||||
* Use one of both less compilers in your project:
|
||||
*
|
||||
* ```
|
||||
* "leafo/lessphp": "~0.5",
|
||||
* "oyejorge/less.php": "~1.5"
|
||||
* ```
|
||||
*
|
||||
* Specify directory (string or array) for less imports lookup:
|
||||
*
|
||||
* ```php
|
||||
* <?php
|
||||
* $this->taskLess([
|
||||
* 'less/default.less' => 'css/default.css'
|
||||
* ])
|
||||
* ->importDir('less')
|
||||
* ->compiler('lessphp')
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*
|
||||
* You can implement additional compilers by extending this task and adding a
|
||||
* method named after them and overloading the lessCompilers() method to
|
||||
* inject the name there.
|
||||
*/
|
||||
class Less extends CssPreprocessor
|
||||
{
|
||||
const FORMAT_NAME = 'less';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $compilers = [
|
||||
'less', // https://github.com/oyejorge/less.php
|
||||
'lessphp', //https://github.com/leafo/lessphp
|
||||
];
|
||||
|
||||
/**
|
||||
* lessphp compiler
|
||||
* @link https://github.com/leafo/lessphp
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function lessphp($file)
|
||||
{
|
||||
if (!class_exists('\lessc')) {
|
||||
return Result::errorMissingPackage($this, 'lessc', 'leafo/lessphp');
|
||||
}
|
||||
|
||||
$lessCode = file_get_contents($file);
|
||||
|
||||
$less = new \lessc();
|
||||
if (isset($this->compilerOptions['importDirs'])) {
|
||||
$less->setImportDir($this->compilerOptions['importDirs']);
|
||||
}
|
||||
|
||||
return $less->compile($lessCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* less compiler
|
||||
* @link https://github.com/oyejorge/less.php
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function less($file)
|
||||
{
|
||||
if (!class_exists('\Less_Parser')) {
|
||||
return Result::errorMissingPackage($this, 'Less_Parser', 'oyejorge/less.php');
|
||||
}
|
||||
|
||||
$lessCode = file_get_contents($file);
|
||||
|
||||
$parser = new \Less_Parser();
|
||||
$parser->SetOptions($this->compilerOptions);
|
||||
if (isset($this->compilerOptions['importDirs'])) {
|
||||
$importDirs = [];
|
||||
foreach ($this->compilerOptions['importDirs'] as $dir) {
|
||||
$importDirs[$dir] = $dir;
|
||||
}
|
||||
$parser->SetImportDirs($importDirs);
|
||||
}
|
||||
|
||||
$parser->parse($lessCode);
|
||||
|
||||
return $parser->getCss();
|
||||
}
|
||||
}
|
||||
299
vendor/consolidation/robo/src/Task/Assets/Minify.php
vendored
Normal file
299
vendor/consolidation/robo/src/Task/Assets/Minify.php
vendored
Normal file
@ -0,0 +1,299 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Assets;
|
||||
|
||||
use Robo\Result;
|
||||
use Robo\Task\BaseTask;
|
||||
|
||||
/**
|
||||
* Minifies an asset file (CSS or JS).
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskMinify('web/assets/theme.css')
|
||||
* ->run()
|
||||
* ?>
|
||||
* ```
|
||||
* Please install additional packages to use this task:
|
||||
*
|
||||
* ```
|
||||
* composer require patchwork/jsqueeze:^2.0
|
||||
* composer require natxet/cssmin:^3.0
|
||||
* ```
|
||||
*/
|
||||
class Minify extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $types = ['css', 'js'];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $text;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $dst;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* @var bool[]
|
||||
*/
|
||||
protected $squeezeOptions = [
|
||||
'singleLine' => true,
|
||||
'keepImportantComments' => true,
|
||||
'specialVarRx' => false,
|
||||
];
|
||||
|
||||
/**
|
||||
* Constructor. Accepts asset file path or string source.
|
||||
*
|
||||
* @param string $input
|
||||
*/
|
||||
public function __construct($input)
|
||||
{
|
||||
if (file_exists($input)) {
|
||||
$this->fromFile($input);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->fromText($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets destination. Tries to guess type from it.
|
||||
*
|
||||
* @param string $dst
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function to($dst)
|
||||
{
|
||||
$this->dst = $dst;
|
||||
|
||||
if (!empty($this->dst) && empty($this->type)) {
|
||||
$this->type($this->getExtension($this->dst));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets type with validation.
|
||||
*
|
||||
* @param string $type
|
||||
* Allowed values: "css", "js".
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function type($type)
|
||||
{
|
||||
$type = strtolower($type);
|
||||
|
||||
if (in_array($type, $this->types)) {
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets text from string source.
|
||||
*
|
||||
* @param string $text
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function fromText($text)
|
||||
{
|
||||
$this->text = (string)$text;
|
||||
unset($this->type);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets text from asset file path. Tries to guess type and set default destination.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function fromFile($path)
|
||||
{
|
||||
$this->text = file_get_contents($path);
|
||||
|
||||
unset($this->type);
|
||||
$this->type($this->getExtension($path));
|
||||
|
||||
if (empty($this->dst) && !empty($this->type)) {
|
||||
$ext_length = strlen($this->type) + 1;
|
||||
$this->dst = substr($path, 0, -$ext_length) . '.min.' . $this->type;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets file extension from path.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getExtension($path)
|
||||
{
|
||||
return pathinfo($path, PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Minifies and returns text.
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
protected function getMinifiedText()
|
||||
{
|
||||
switch ($this->type) {
|
||||
case 'css':
|
||||
if (!class_exists('\CssMin')) {
|
||||
return Result::errorMissingPackage($this, 'CssMin', 'natxet/cssmin');
|
||||
}
|
||||
|
||||
return \CssMin::minify($this->text);
|
||||
break;
|
||||
|
||||
case 'js':
|
||||
if (!class_exists('\JSqueeze') && !class_exists('\Patchwork\JSqueeze')) {
|
||||
return Result::errorMissingPackage($this, 'Patchwork\JSqueeze', 'patchwork/jsqueeze');
|
||||
}
|
||||
|
||||
if (class_exists('\JSqueeze')) {
|
||||
$jsqueeze = new \JSqueeze();
|
||||
} else {
|
||||
$jsqueeze = new \Patchwork\JSqueeze();
|
||||
}
|
||||
|
||||
return $jsqueeze->squeeze(
|
||||
$this->text,
|
||||
$this->squeezeOptions['singleLine'],
|
||||
$this->squeezeOptions['keepImportantComments'],
|
||||
$this->squeezeOptions['specialVarRx']
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Single line option for the JS minimisation.
|
||||
*
|
||||
* @param bool $singleLine
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function singleLine($singleLine)
|
||||
{
|
||||
$this->squeezeOptions['singleLine'] = (bool)$singleLine;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* keepImportantComments option for the JS minimisation.
|
||||
*
|
||||
* @param bool $keepImportantComments
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function keepImportantComments($keepImportantComments)
|
||||
{
|
||||
$this->squeezeOptions['keepImportantComments'] = (bool)$keepImportantComments;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set specialVarRx option for the JS minimisation.
|
||||
*
|
||||
* @param bool $specialVarRx
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function specialVarRx($specialVarRx)
|
||||
{
|
||||
$this->squeezeOptions['specialVarRx'] = (bool)$specialVarRx;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->getMinifiedText();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if (empty($this->type)) {
|
||||
return Result::error($this, 'Unknown asset type.');
|
||||
}
|
||||
|
||||
if (empty($this->dst)) {
|
||||
return Result::error($this, 'Unknown file destination.');
|
||||
}
|
||||
|
||||
if (file_exists($this->dst) && !is_writable($this->dst)) {
|
||||
return Result::error($this, 'Destination already exists and cannot be overwritten.');
|
||||
}
|
||||
|
||||
$size_before = strlen($this->text);
|
||||
$minified = $this->getMinifiedText();
|
||||
|
||||
if ($minified instanceof Result) {
|
||||
return $minified;
|
||||
} elseif (false === $minified) {
|
||||
return Result::error($this, 'Minification failed.');
|
||||
}
|
||||
|
||||
$size_after = strlen($minified);
|
||||
|
||||
// Minification did not reduce file size, so use original file.
|
||||
if ($size_after > $size_before) {
|
||||
$minified = $this->text;
|
||||
$size_after = $size_before;
|
||||
}
|
||||
|
||||
$dst = $this->dst . '.part';
|
||||
$write_result = file_put_contents($dst, $minified);
|
||||
|
||||
if (false === $write_result) {
|
||||
@unlink($dst);
|
||||
return Result::error($this, 'File write failed.');
|
||||
}
|
||||
// Cannot be cross-volume; should always succeed.
|
||||
@rename($dst, $this->dst);
|
||||
if ($size_before === 0) {
|
||||
$minified_percent = 0;
|
||||
} else {
|
||||
$minified_percent = number_format(100 - ($size_after / $size_before * 100), 1);
|
||||
}
|
||||
$this->printTaskSuccess('Wrote {filepath}', ['filepath' => $this->dst]);
|
||||
$context = [
|
||||
'bytes' => $this->formatBytes($size_after),
|
||||
'reduction' => $this->formatBytes(($size_before - $size_after)),
|
||||
'percentage' => $minified_percent,
|
||||
];
|
||||
$this->printTaskSuccess('Wrote {bytes} (reduced by {reduction} / {percentage})', $context);
|
||||
return Result::success($this, 'Asset minified.');
|
||||
}
|
||||
}
|
||||
94
vendor/consolidation/robo/src/Task/Assets/Scss.php
vendored
Normal file
94
vendor/consolidation/robo/src/Task/Assets/Scss.php
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Assets;
|
||||
|
||||
use Robo\Result;
|
||||
|
||||
/**
|
||||
* Compiles scss files.
|
||||
*
|
||||
* ```php
|
||||
* <?php
|
||||
* $this->taskScss([
|
||||
* 'scss/default.scss' => 'css/default.css'
|
||||
* ])
|
||||
* ->importDir('assets/styles')
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*
|
||||
* Use the following scss compiler in your project:
|
||||
*
|
||||
* ```
|
||||
* "scssphp/scssphp ": "~1.0.0",
|
||||
* ```
|
||||
*
|
||||
* You can implement additional compilers by extending this task and adding a
|
||||
* method named after them and overloading the scssCompilers() method to
|
||||
* inject the name there.
|
||||
*/
|
||||
class Scss extends CssPreprocessor
|
||||
{
|
||||
const FORMAT_NAME = 'scss';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $compilers = [
|
||||
'scssphp', // https://github.com/scssphp/scssphp
|
||||
];
|
||||
|
||||
/**
|
||||
* scssphp compiler
|
||||
* @link https://github.com/scssphp/scssphp
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function scssphp($file)
|
||||
{
|
||||
if (!class_exists('\ScssPhp\ScssPhp\Compiler')) {
|
||||
return Result::errorMissingPackage($this, 'scssphp', 'scssphp/scssphp');
|
||||
}
|
||||
|
||||
$scssCode = file_get_contents($file);
|
||||
$scss = new \ScssPhp\ScssPhp\Compiler();
|
||||
|
||||
// set options for the scssphp compiler
|
||||
if (isset($this->compilerOptions['importDirs'])) {
|
||||
$scss->setImportPaths($this->compilerOptions['importDirs']);
|
||||
}
|
||||
|
||||
if (isset($this->compilerOptions['formatter'])) {
|
||||
$scss->setFormatter($this->compilerOptions['formatter']);
|
||||
}
|
||||
|
||||
return $scss->compile($scssCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the formatter for scssphp
|
||||
*
|
||||
* The method setFormatter($formatterName) sets the current formatter to $formatterName,
|
||||
* the name of a class as a string that implements the formatting interface. See the source
|
||||
* for ScssPhp\ScssPhp\Formatter\Expanded for an example.
|
||||
*
|
||||
* Five formatters are included with scssphp/scssphp:
|
||||
* - ScssPhp\ScssPhp\Formatter\Expanded
|
||||
* - ScssPhp\ScssPhp\Formatter\Nested (default)
|
||||
* - ScssPhp\ScssPhp\Formatter\Compressed
|
||||
* - ScssPhp\ScssPhp\Formatter\Compact
|
||||
* - ScssPhp\ScssPhp\Formatter\Crunched
|
||||
*
|
||||
* @link https://scssphp.github.io/scssphp/docs/#output-formatting
|
||||
*
|
||||
* @param string $formatterName
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFormatter($formatterName)
|
||||
{
|
||||
return parent::setFormatter($formatterName);
|
||||
}
|
||||
}
|
||||
46
vendor/consolidation/robo/src/Task/Assets/Tasks.php
vendored
Normal file
46
vendor/consolidation/robo/src/Task/Assets/Tasks.php
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Assets;
|
||||
|
||||
trait Tasks
|
||||
{
|
||||
/**
|
||||
* @param string $input
|
||||
*
|
||||
* @return \Robo\Task\Assets\Minify|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskMinify($input)
|
||||
{
|
||||
return $this->task(Minify::class, $input);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $input
|
||||
*
|
||||
* @return \Robo\Task\Assets\ImageMinify|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskImageMinify($input)
|
||||
{
|
||||
return $this->task(ImageMinify::class, $input);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $input
|
||||
*
|
||||
* @return \Robo\Task\Assets\Less|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskLess($input)
|
||||
{
|
||||
return $this->task(Less::class, $input);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $input
|
||||
*
|
||||
* @return \Robo\Task\Assets\Scss|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskScss($input)
|
||||
{
|
||||
return $this->task(Scss::class, $input);
|
||||
}
|
||||
}
|
||||
145
vendor/consolidation/robo/src/Task/Base/Exec.php
vendored
Normal file
145
vendor/consolidation/robo/src/Task/Base/Exec.php
vendored
Normal file
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Base;
|
||||
|
||||
use Closure;
|
||||
use Robo\Contract\CommandInterface;
|
||||
use Robo\Contract\PrintedInterface;
|
||||
use Robo\Contract\SimulatedInterface;
|
||||
use Robo\Task\BaseTask;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Robo\Result;
|
||||
use Robo\Common\CommandReceiver;
|
||||
use Robo\Common\ExecOneCommand;
|
||||
|
||||
/**
|
||||
* Executes shell script. Closes it when running in background mode.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskExec('compass')->arg('watch')->run();
|
||||
* // or use shortcut
|
||||
* $this->_exec('compass watch');
|
||||
*
|
||||
* $this->taskExec('compass watch')->background()->run();
|
||||
*
|
||||
* if ($this->taskExec('phpunit .')->run()->wasSuccessful()) {
|
||||
* $this->say('tests passed');
|
||||
* }
|
||||
*
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Exec extends BaseTask implements CommandInterface, PrintedInterface, SimulatedInterface
|
||||
{
|
||||
use CommandReceiver;
|
||||
use ExecOneCommand;
|
||||
|
||||
/**
|
||||
* @var static[]
|
||||
*/
|
||||
protected static $instances = [];
|
||||
|
||||
/**
|
||||
* @var string|\Robo\Contract\CommandInterface
|
||||
*/
|
||||
protected $command;
|
||||
|
||||
private static $isSetupStopRunningJob = false;
|
||||
|
||||
/**
|
||||
* @param string|\Robo\Contract\CommandInterface $command
|
||||
*/
|
||||
public function __construct($command)
|
||||
{
|
||||
$this->command = $this->receiveCommand($command);
|
||||
|
||||
$this->setupStopRunningJobs();
|
||||
}
|
||||
|
||||
private function setupStopRunningJobs()
|
||||
{
|
||||
if (self::$isSetupStopRunningJob === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
$stopRunningJobs = Closure::fromCallable(self::class.'::stopRunningJobs');
|
||||
|
||||
if (function_exists('pcntl_signal')) {
|
||||
pcntl_signal(SIGTERM, $stopRunningJobs);
|
||||
}
|
||||
|
||||
register_shutdown_function($stopRunningJobs);
|
||||
|
||||
self::$isSetupStopRunningJob = true;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes command in background mode (asynchronously)
|
||||
*
|
||||
* @param bool $arg
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function background($arg = true)
|
||||
{
|
||||
self::$instances[] = $this;
|
||||
$this->background = $arg;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getCommandDescription()
|
||||
{
|
||||
return $this->getCommand();
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return trim($this->command . $this->arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function simulate($context)
|
||||
{
|
||||
$this->printAction($context);
|
||||
}
|
||||
|
||||
public static function stopRunningJobs()
|
||||
{
|
||||
foreach (self::$instances as $instance) {
|
||||
if ($instance) {
|
||||
unset($instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->hideProgressIndicator();
|
||||
// TODO: Symfony 4 requires that we supply the working directory.
|
||||
$result_data = $this->execute(Process::fromShellCommandline($this->getCommand(), getcwd()));
|
||||
$result = new Result(
|
||||
$this,
|
||||
$result_data->getExitCode(),
|
||||
$result_data->getMessage(),
|
||||
$result_data->getData()
|
||||
);
|
||||
$this->showProgressIndicator();
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
24
vendor/consolidation/robo/src/Task/Base/ExecStack.php
vendored
Normal file
24
vendor/consolidation/robo/src/Task/Base/ExecStack.php
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Base;
|
||||
|
||||
use Robo\Task\CommandStack;
|
||||
|
||||
/**
|
||||
* Execute commands one by one in stack.
|
||||
* Stack can be stopped on first fail if you call `stopOnFail()`.
|
||||
*
|
||||
* ```php
|
||||
* <?php
|
||||
* $this->taskExecStack()
|
||||
* ->stopOnFail()
|
||||
* ->exec('mkdir site')
|
||||
* ->exec('cd site')
|
||||
* ->run();
|
||||
*
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class ExecStack extends CommandStack
|
||||
{
|
||||
}
|
||||
216
vendor/consolidation/robo/src/Task/Base/ParallelExec.php
vendored
Normal file
216
vendor/consolidation/robo/src/Task/Base/ParallelExec.php
vendored
Normal file
@ -0,0 +1,216 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Base;
|
||||
|
||||
use Robo\Contract\CommandInterface;
|
||||
use Robo\Contract\PrintedInterface;
|
||||
use Robo\Result;
|
||||
use Robo\Task\BaseTask;
|
||||
use Symfony\Component\Process\Exception\ProcessTimedOutException;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Robo\Common\CommandReceiver;
|
||||
|
||||
/**
|
||||
* Class ParallelExecTask
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskParallelExec()
|
||||
* ->process('php ~/demos/script.php hey')
|
||||
* ->process('php ~/demos/script.php hoy')
|
||||
* ->process('php ~/demos/script.php gou')
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class ParallelExec extends BaseTask implements CommandInterface, PrintedInterface
|
||||
{
|
||||
use CommandReceiver;
|
||||
|
||||
/**
|
||||
* @var Process[]
|
||||
*/
|
||||
protected $processes = [];
|
||||
|
||||
/**
|
||||
* @var null|int
|
||||
*/
|
||||
protected $timeout = null;
|
||||
|
||||
/**
|
||||
* @var null|int
|
||||
*/
|
||||
protected $idleTimeout = null;
|
||||
|
||||
/**
|
||||
* @var null|int
|
||||
*/
|
||||
protected $waitInterval = 0;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $isPrinted = false;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPrinted()
|
||||
{
|
||||
return $this->isPrinted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isPrinted
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function printOutput($isPrinted = true)
|
||||
{
|
||||
$this->isPrinted = $isPrinted;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isPrinted
|
||||
*
|
||||
* @deprecated Use printOutput instead
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function printed($isPrinted = true)
|
||||
{
|
||||
return $this->printOutput($isPrinted);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|\Robo\Contract\CommandInterface $command
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function process($command)
|
||||
{
|
||||
// TODO: Symfony 4 requires that we supply the working directory.
|
||||
$this->processes[] = Process::fromShellCommandline($this->receiveCommand($command), getcwd());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops process if it runs longer then `$timeout` (seconds).
|
||||
*
|
||||
* @param int $timeout
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function timeout($timeout)
|
||||
{
|
||||
$this->timeout = $timeout;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops process if it does not output for time longer then `$timeout` (seconds).
|
||||
*
|
||||
* @param int $idleTimeout
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function idleTimeout($idleTimeout)
|
||||
{
|
||||
$this->idleTimeout = $idleTimeout;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parallel processing will wait `$waitInterval` seconds after launching each process and before
|
||||
* the next one.
|
||||
*
|
||||
* @param int $waitInterval
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function waitInterval($waitInterval)
|
||||
{
|
||||
$this->waitInterval = $waitInterval;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return implode(' && ', $this->processes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function progressIndicatorSteps()
|
||||
{
|
||||
return count($this->processes);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->startProgressIndicator();
|
||||
$running = [];
|
||||
$queue = $this->processes;
|
||||
$nextTime = time();
|
||||
while (true) {
|
||||
if (($nextTime <= time()) && !empty($queue)) {
|
||||
$process = array_shift($queue);
|
||||
$process->setIdleTimeout($this->idleTimeout);
|
||||
$process->setTimeout($this->timeout);
|
||||
$process->start();
|
||||
$this->printTaskInfo($process->getCommandLine());
|
||||
$running[] = $process;
|
||||
$nextTime = time() + $this->waitInterval;
|
||||
}
|
||||
foreach ($running as $k => $process) {
|
||||
try {
|
||||
$process->checkTimeout();
|
||||
} catch (ProcessTimedOutException $e) {
|
||||
$this->printTaskWarning("Process timed out for {command}", ['command' => $process->getCommandLine(), '_style' => ['command' => 'fg=white;bg=magenta']]);
|
||||
}
|
||||
if (!$process->isRunning()) {
|
||||
$this->advanceProgressIndicator();
|
||||
if ($this->isPrinted) {
|
||||
$this->printTaskInfo("Output for {command}:\n\n{output}", ['command' => $process->getCommandLine(), 'output' => $process->getOutput(), '_style' => ['command' => 'fg=white;bg=magenta']]);
|
||||
$errorOutput = $process->getErrorOutput();
|
||||
if ($errorOutput) {
|
||||
$this->printTaskError(rtrim($errorOutput));
|
||||
}
|
||||
}
|
||||
unset($running[$k]);
|
||||
}
|
||||
}
|
||||
if (empty($running) && empty($queue)) {
|
||||
break;
|
||||
}
|
||||
usleep(1000);
|
||||
}
|
||||
$this->stopProgressIndicator();
|
||||
|
||||
$errorMessage = '';
|
||||
$exitCode = 0;
|
||||
foreach ($this->processes as $p) {
|
||||
if ($p->getExitCode() === 0) {
|
||||
continue;
|
||||
}
|
||||
if (trim($p->getErrorOutput())) {
|
||||
$this->printTaskError("Error for {command} \n{output}", ['command' => $process->getCommandLine(), 'output' => $p->getErrorOutput()]);
|
||||
}
|
||||
$errorMessage .= "'" . $p->getCommandLine() . "' exited with code " . $p->getExitCode() . " \n";
|
||||
$exitCode = max($exitCode, $p->getExitCode());
|
||||
}
|
||||
if (!$errorMessage) {
|
||||
$this->printTaskSuccess('{process-count} processes finished running', ['process-count' => count($this->processes)]);
|
||||
}
|
||||
|
||||
return new Result($this, $exitCode, $errorMessage, ['time' => $this->getExecutionTime()]);
|
||||
}
|
||||
}
|
||||
18
vendor/consolidation/robo/src/Task/Base/Shortcuts.php
vendored
Normal file
18
vendor/consolidation/robo/src/Task/Base/Shortcuts.php
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Base;
|
||||
|
||||
trait Shortcuts
|
||||
{
|
||||
/**
|
||||
* Executes shell command
|
||||
*
|
||||
* @param string|\Robo\Contract\CommandInterface $command
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _exec($command)
|
||||
{
|
||||
return $this->taskExec($command)->run();
|
||||
}
|
||||
}
|
||||
76
vendor/consolidation/robo/src/Task/Base/SymfonyCommand.php
vendored
Normal file
76
vendor/consolidation/robo/src/Task/Base/SymfonyCommand.php
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Base;
|
||||
|
||||
use Robo\Robo;
|
||||
use Robo\Result;
|
||||
use Robo\Task\BaseTask;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
|
||||
/**
|
||||
* Executes Symfony Command
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // Symfony Command
|
||||
* $this->taskSymfonyCommand(new \Codeception\Command\Run('run'))
|
||||
* ->arg('suite','acceptance')
|
||||
* ->opt('debug')
|
||||
* ->run();
|
||||
*
|
||||
* // Artisan Command
|
||||
* $this->taskSymfonyCommand(new ModelGeneratorCommand())
|
||||
* ->arg('name', 'User')
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class SymfonyCommand extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @var \Symfony\Component\Console\Command\Command
|
||||
*/
|
||||
protected $command;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $input;
|
||||
|
||||
public function __construct(Command $command)
|
||||
{
|
||||
$this->command = $command;
|
||||
$this->input = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $arg
|
||||
* @param string $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function arg($arg, $value)
|
||||
{
|
||||
$this->input[$arg] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function opt($option, $value = null)
|
||||
{
|
||||
$this->input["--$option"] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->printTaskInfo('Running command {command}', ['command' => $this->command->getName()]);
|
||||
return new Result(
|
||||
$this,
|
||||
$this->command->run(new ArrayInput($this->input), $this->output())
|
||||
);
|
||||
}
|
||||
}
|
||||
50
vendor/consolidation/robo/src/Task/Base/Tasks.php
vendored
Normal file
50
vendor/consolidation/robo/src/Task/Base/Tasks.php
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Base;
|
||||
|
||||
trait Tasks
|
||||
{
|
||||
/**
|
||||
* @param string|\Robo\Contract\CommandInterface $command
|
||||
*
|
||||
* @return \Robo\Task\Base\Exec|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskExec($command)
|
||||
{
|
||||
return $this->task(Exec::class, $command);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Robo\Task\Base\ExecStack|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskExecStack()
|
||||
{
|
||||
return $this->task(ExecStack::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Robo\Task\Base\ParallelExec|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskParallelExec()
|
||||
{
|
||||
return $this->task(ParallelExec::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Symfony\Component\Console\Command\Command $command
|
||||
*
|
||||
* @return \Robo\Task\Base\SymfonyCommand|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskSymfonyCommand($command)
|
||||
{
|
||||
return $this->task(SymfonyCommand::class, $command);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Robo\Task\Base\Watch|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskWatch()
|
||||
{
|
||||
return $this->task(Watch::class, $this);
|
||||
}
|
||||
}
|
||||
125
vendor/consolidation/robo/src/Task/Base/Watch.php
vendored
Normal file
125
vendor/consolidation/robo/src/Task/Base/Watch.php
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Base;
|
||||
|
||||
use Lurker\ResourceWatcher;
|
||||
use Robo\Result;
|
||||
use Robo\Task\BaseTask;
|
||||
|
||||
/**
|
||||
* Runs task when specified file or dir was changed.
|
||||
* Uses Lurker library.
|
||||
* Monitor third parameter takes Lurker filesystem events types to watch.
|
||||
* By default its set to MODIFY event.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskWatch()
|
||||
* ->monitor(
|
||||
* 'composer.json',
|
||||
* function() {
|
||||
* $this->taskComposerUpdate()->run();
|
||||
* }
|
||||
* )->monitor(
|
||||
* 'src',
|
||||
* function() {
|
||||
* $this->taskExec('phpunit')->run();
|
||||
* },
|
||||
* \Lurker\Event\FilesystemEvent::ALL
|
||||
* )->monitor(
|
||||
* 'migrations',
|
||||
* function() {
|
||||
* //do something
|
||||
* },
|
||||
* [
|
||||
* \Lurker\Event\FilesystemEvent::CREATE,
|
||||
* \Lurker\Event\FilesystemEvent::DELETE
|
||||
* ]
|
||||
* )->run();
|
||||
* ?>
|
||||
* ```
|
||||
*
|
||||
* Pass through the changed file to the callable function
|
||||
*
|
||||
* ```
|
||||
* $this
|
||||
* ->taskWatch()
|
||||
* ->monitor(
|
||||
* 'filename',
|
||||
* function ($event) {
|
||||
* $resource = $event->getResource();
|
||||
* ... do something with (string)$resource ...
|
||||
* },
|
||||
* FilesystemEvent::ALL
|
||||
* )
|
||||
* ->run();
|
||||
* ```
|
||||
*
|
||||
* The $event parameter is a [standard Symfony file resource object](https://api.symfony.com/3.1/Symfony/Component/Config/Resource/FileResource.html)
|
||||
*/
|
||||
class Watch extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @var \Closure
|
||||
*/
|
||||
protected $closure;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $monitor = [];
|
||||
|
||||
/**
|
||||
* @var object
|
||||
*/
|
||||
protected $bindTo;
|
||||
|
||||
/**
|
||||
* @param $bindTo
|
||||
*/
|
||||
public function __construct($bindTo)
|
||||
{
|
||||
$this->bindTo = $bindTo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $paths
|
||||
* @param \Closure $callable
|
||||
* @param int|int[] $events
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function monitor($paths, \Closure $callable, $events = 2)
|
||||
{
|
||||
$this->monitor[] = [(array)$paths, $callable, (array)$events];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if (!class_exists('Lurker\\ResourceWatcher')) {
|
||||
return Result::errorMissingPackage($this, 'ResourceWatcher', 'totten/lurkerlite');
|
||||
}
|
||||
|
||||
$watcher = new ResourceWatcher();
|
||||
|
||||
foreach ($this->monitor as $k => $monitor) {
|
||||
/** @var \Closure $closure */
|
||||
$closure = $monitor[1];
|
||||
$closure->bindTo($this->bindTo);
|
||||
foreach ($monitor[0] as $i => $dir) {
|
||||
foreach ($monitor[2] as $j => $event) {
|
||||
$watcher->track("fs.$k.$i.$j", $dir, $event);
|
||||
$watcher->addListener("fs.$k.$i.$j", $closure);
|
||||
}
|
||||
$this->printTaskInfo('Watching {dir} for changes...', ['dir' => $dir]);
|
||||
}
|
||||
}
|
||||
|
||||
$watcher->start();
|
||||
return Result::success($this);
|
||||
}
|
||||
}
|
||||
67
vendor/consolidation/robo/src/Task/BaseTask.php
vendored
Normal file
67
vendor/consolidation/robo/src/Task/BaseTask.php
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task;
|
||||
|
||||
use Robo\Common\InflectionTrait;
|
||||
use Robo\Contract\InflectionInterface;
|
||||
use Robo\Common\TaskIO;
|
||||
use Robo\Contract\TaskInterface;
|
||||
use Robo\Contract\ProgressIndicatorAwareInterface;
|
||||
use Robo\Contract\VerbosityThresholdInterface;
|
||||
use Robo\Common\ProgressIndicatorAwareTrait;
|
||||
use Robo\Contract\ConfigAwareInterface;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Robo\Contract\OutputAwareInterface;
|
||||
|
||||
abstract class BaseTask implements TaskInterface, LoggerAwareInterface, VerbosityThresholdInterface, ConfigAwareInterface, ProgressIndicatorAwareInterface, InflectionInterface, OutputAwareInterface
|
||||
{
|
||||
use TaskIO; // uses LoggerAwareTrait, OutputAwareTrait, VerbosityThresholdTrait and ConfigAwareTrait
|
||||
use ProgressIndicatorAwareTrait;
|
||||
use InflectionTrait;
|
||||
|
||||
/**
|
||||
* ConfigAwareInterface uses this to decide where configuration
|
||||
* items come from. Default is this prefix + class name + key,
|
||||
* e.g. `task.Remote.Ssh.remoteDir`.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function configPrefix()
|
||||
{
|
||||
return 'task.';
|
||||
}
|
||||
|
||||
/**
|
||||
* ConfigAwareInterface uses this to decide where configuration
|
||||
* items come from. Default is this prefix + class name + key,
|
||||
* e.g. `task.Ssh.remoteDir`.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function configPostfix()
|
||||
{
|
||||
return '.settings';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function injectDependencies($child)
|
||||
{
|
||||
if ($child instanceof LoggerAwareInterface && $this->logger) {
|
||||
$child->setLogger($this->logger);
|
||||
}
|
||||
if ($child instanceof OutputAwareInterface) {
|
||||
$child->setOutput($this->output());
|
||||
}
|
||||
if ($child instanceof ProgressIndicatorAwareInterface && $this->progressIndicator) {
|
||||
$child->setProgressIndicator($this->progressIndicator);
|
||||
}
|
||||
if ($child instanceof ConfigAwareInterface && $this->getConfig()) {
|
||||
$child->setConfig($this->getConfig());
|
||||
}
|
||||
if ($child instanceof VerbosityThresholdInterface && $this->outputAdapter()) {
|
||||
$child->setOutputAdapter($this->outputAdapter());
|
||||
}
|
||||
}
|
||||
}
|
||||
97
vendor/consolidation/robo/src/Task/Bower/Base.php
vendored
Normal file
97
vendor/consolidation/robo/src/Task/Bower/Base.php
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Bower;
|
||||
|
||||
use Robo\Task\BaseTask;
|
||||
use Robo\Exception\TaskException;
|
||||
use Robo\Common\ExecOneCommand;
|
||||
|
||||
abstract class Base extends BaseTask
|
||||
{
|
||||
use ExecOneCommand;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $opts = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $action = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $command = '';
|
||||
|
||||
/**
|
||||
* adds `allow-root` option to bower
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function allowRoot()
|
||||
{
|
||||
$this->option('allow-root');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `force-latest` option to bower
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function forceLatest()
|
||||
{
|
||||
$this->option('force-latest');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `production` option to bower
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noDev()
|
||||
{
|
||||
$this->option('production');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `offline` option to bower
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function offline()
|
||||
{
|
||||
$this->option('offline');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base constructor.
|
||||
*
|
||||
* @param null|string $pathToBower
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
public function __construct($pathToBower = null)
|
||||
{
|
||||
$this->command = $pathToBower;
|
||||
if (!$this->command) {
|
||||
$this->command = $this->findExecutable('bower');
|
||||
}
|
||||
if (!$this->command) {
|
||||
throw new TaskException(__CLASS__, "Bower executable not found.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return "{$this->command} {$this->action}{$this->arguments}";
|
||||
}
|
||||
}
|
||||
37
vendor/consolidation/robo/src/Task/Bower/Install.php
vendored
Normal file
37
vendor/consolidation/robo/src/Task/Bower/Install.php
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Bower;
|
||||
|
||||
use Robo\Contract\CommandInterface;
|
||||
|
||||
/**
|
||||
* Bower Install
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // simple execution
|
||||
* $this->taskBowerInstall()->run();
|
||||
*
|
||||
* // prefer dist with custom path
|
||||
* $this->taskBowerInstall('path/to/my/bower')
|
||||
* ->noDev()
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Install extends Base implements CommandInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $action = 'install';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->printTaskInfo('Install Bower packages: {arguments}', ['arguments' => $this->arguments]);
|
||||
return $this->executeCommand($this->getCommand());
|
||||
}
|
||||
}
|
||||
26
vendor/consolidation/robo/src/Task/Bower/Tasks.php
vendored
Normal file
26
vendor/consolidation/robo/src/Task/Bower/Tasks.php
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Bower;
|
||||
|
||||
trait Tasks
|
||||
{
|
||||
/**
|
||||
* @param null|string $pathToBower
|
||||
*
|
||||
* @return \Robo\Task\Bower\Install|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskBowerInstall($pathToBower = null)
|
||||
{
|
||||
return $this->task(Install::class, $pathToBower);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $pathToBower
|
||||
*
|
||||
* @return \Robo\Task\Bower\Update|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskBowerUpdate($pathToBower = null)
|
||||
{
|
||||
return $this->task(Update::class, $pathToBower);
|
||||
}
|
||||
}
|
||||
35
vendor/consolidation/robo/src/Task/Bower/Update.php
vendored
Normal file
35
vendor/consolidation/robo/src/Task/Bower/Update.php
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Bower;
|
||||
|
||||
/**
|
||||
* Bower Update
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // simple execution
|
||||
* $this->taskBowerUpdate->run();
|
||||
*
|
||||
* // prefer dist with custom path
|
||||
* $this->taskBowerUpdate('path/to/my/bower')
|
||||
* ->noDev()
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Update extends Base
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $action = 'update';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->printTaskInfo('Update Bower packages: {arguments}', ['arguments' => $this->arguments]);
|
||||
return $this->executeCommand($this->getCommand());
|
||||
}
|
||||
}
|
||||
149
vendor/consolidation/robo/src/Task/CommandStack.php
vendored
Normal file
149
vendor/consolidation/robo/src/Task/CommandStack.php
vendored
Normal file
@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task;
|
||||
|
||||
use Robo\Common\ExecCommand;
|
||||
use Robo\Contract\PrintedInterface;
|
||||
use Robo\Result;
|
||||
use Robo\Contract\CommandInterface;
|
||||
use Robo\Exception\TaskException;
|
||||
use Robo\Common\CommandReceiver;
|
||||
|
||||
abstract class CommandStack extends BaseTask implements CommandInterface, PrintedInterface
|
||||
{
|
||||
use ExecCommand;
|
||||
use CommandReceiver;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $executable;
|
||||
|
||||
/**
|
||||
* @var \Robo\Result
|
||||
*/
|
||||
protected $result;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $exec = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $stopOnFail = false;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
$commands = [];
|
||||
foreach ($this->exec as $command) {
|
||||
$commands[] = $this->receiveCommand($command);
|
||||
}
|
||||
|
||||
return implode(' && ', $commands);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $executable
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function executable($executable)
|
||||
{
|
||||
$this->executable = $executable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[]|CommandInterface $command
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function exec($command)
|
||||
{
|
||||
if (is_array($command)) {
|
||||
$command = implode(' ', array_filter($command));
|
||||
}
|
||||
|
||||
if (is_string($command)) {
|
||||
$command = $this->executable . ' ' . $this->stripExecutableFromCommand($command);
|
||||
$command = trim($command);
|
||||
}
|
||||
|
||||
$this->exec[] = $command;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $stopOnFail
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function stopOnFail($stopOnFail = true)
|
||||
{
|
||||
$this->stopOnFail = $stopOnFail;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function result($result)
|
||||
{
|
||||
$this->result = $result;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $command
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function stripExecutableFromCommand($command)
|
||||
{
|
||||
$command = trim($command);
|
||||
$executable = $this->executable . ' ';
|
||||
if (strpos($command, $executable) === 0) {
|
||||
$command = substr($command, strlen($executable));
|
||||
}
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if (empty($this->exec)) {
|
||||
throw new TaskException($this, 'You must add at least one command');
|
||||
}
|
||||
// If 'stopOnFail' is not set, or if there is only one command to run,
|
||||
// then execute the single command to run.
|
||||
if (!$this->stopOnFail || (count($this->exec) == 1)) {
|
||||
$this->printTaskInfo('{command}', ['command' => $this->getCommand()]);
|
||||
return $this->executeCommand($this->getCommand());
|
||||
}
|
||||
|
||||
// When executing multiple commands in 'stopOnFail' mode, run them
|
||||
// one at a time so that the result will have the exact command
|
||||
// that failed available to the caller. This is at the expense of
|
||||
// losing the output from all successful commands.
|
||||
$data = [];
|
||||
$message = '';
|
||||
$result = null;
|
||||
foreach ($this->exec as $command) {
|
||||
$this->printTaskInfo("Executing {command}", ['command' => $command]);
|
||||
$result = $this->executeCommand($command);
|
||||
$result->accumulateExecutionTime($data);
|
||||
$message = $result->accumulateMessage($message);
|
||||
$data = $result->mergeData($data);
|
||||
if (!$result->wasSuccessful()) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
271
vendor/consolidation/robo/src/Task/Composer/Base.php
vendored
Normal file
271
vendor/consolidation/robo/src/Task/Composer/Base.php
vendored
Normal file
@ -0,0 +1,271 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Composer;
|
||||
|
||||
use Robo\Contract\CommandInterface;
|
||||
use Robo\Exception\TaskException;
|
||||
use Robo\Task\BaseTask;
|
||||
use Robo\Common\ExecOneCommand;
|
||||
|
||||
abstract class Base extends BaseTask implements CommandInterface
|
||||
{
|
||||
use ExecOneCommand;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $command = '';
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $built = false;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $prefer;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $dev;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $ansi;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $nointeraction;
|
||||
|
||||
/**
|
||||
* Action to use
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $action = '';
|
||||
|
||||
/**
|
||||
* @param null|string $pathToComposer
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
public function __construct($pathToComposer = null)
|
||||
{
|
||||
$this->command = $pathToComposer;
|
||||
if (!$this->command) {
|
||||
$this->command = $this->findExecutablePhar('composer');
|
||||
}
|
||||
if (!$this->command) {
|
||||
throw new TaskException(__CLASS__, "Neither local composer.phar nor global composer installation could be found.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `prefer-dist` option to composer
|
||||
*
|
||||
* @param bool $preferDist
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function preferDist($preferDist = true)
|
||||
{
|
||||
if (!$preferDist) {
|
||||
return $this->preferSource();
|
||||
}
|
||||
$this->prefer = '--prefer-dist';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `prefer-source` option to composer
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function preferSource()
|
||||
{
|
||||
$this->prefer = '--prefer-source';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `dev` option to composer
|
||||
*
|
||||
* @param bool $dev
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function dev($dev = true)
|
||||
{
|
||||
if (!$dev) {
|
||||
return $this->noDev();
|
||||
}
|
||||
$this->dev = '--dev';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `no-dev` option to composer
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noDev()
|
||||
{
|
||||
$this->dev = '--no-dev';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `ansi` option to composer
|
||||
*
|
||||
* @param bool $ansi
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function ansi($ansi = true)
|
||||
{
|
||||
if (!$ansi) {
|
||||
return $this->noAnsi();
|
||||
}
|
||||
$this->ansi = '--ansi';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `no-ansi` option to composer
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noAnsi()
|
||||
{
|
||||
$this->ansi = '--no-ansi';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $interaction
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function interaction($interaction = true)
|
||||
{
|
||||
if (!$interaction) {
|
||||
return $this->noInteraction();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `no-interaction` option to composer
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noInteraction()
|
||||
{
|
||||
$this->nointeraction = '--no-interaction';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `optimize-autoloader` option to composer
|
||||
*
|
||||
* @param bool $optimize
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function optimizeAutoloader($optimize = true)
|
||||
{
|
||||
if ($optimize) {
|
||||
$this->option('--optimize-autoloader');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `ignore-platform-reqs` option to composer
|
||||
*
|
||||
* @param bool $ignore
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function ignorePlatformRequirements($ignore = true)
|
||||
{
|
||||
$this->option('--ignore-platform-reqs');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* disable plugins
|
||||
*
|
||||
* @param bool $disable
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function disablePlugins($disable = true)
|
||||
{
|
||||
if ($disable) {
|
||||
$this->option('--no-plugins');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* skip scripts
|
||||
*
|
||||
* @param bool $disable
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noScripts($disable = true)
|
||||
{
|
||||
if ($disable) {
|
||||
$this->option('--no-scripts');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `--working-dir $dir` option to composer
|
||||
*
|
||||
* @param string $dir
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function workingDir($dir)
|
||||
{
|
||||
$this->option("--working-dir", $dir);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy class fields into command options as directed.
|
||||
*/
|
||||
public function buildCommand()
|
||||
{
|
||||
if (!isset($this->ansi) && $this->getConfig()->get(\Robo\Config\Config::DECORATED)) {
|
||||
$this->ansi();
|
||||
}
|
||||
if (!isset($this->nointeraction) && !$this->getConfig()->get(\Robo\Config\Config::INTERACTIVE)) {
|
||||
$this->noInteraction();
|
||||
}
|
||||
$this->option($this->prefer)
|
||||
->option($this->dev)
|
||||
->option($this->nointeraction)
|
||||
->option($this->ansi);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
if (!$this->built) {
|
||||
$this->buildCommand();
|
||||
$this->built = true;
|
||||
}
|
||||
return "{$this->command} {$this->action}{$this->arguments}";
|
||||
}
|
||||
}
|
||||
31
vendor/consolidation/robo/src/Task/Composer/CheckPlatformReqs.php
vendored
Normal file
31
vendor/consolidation/robo/src/Task/Composer/CheckPlatformReqs.php
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Composer;
|
||||
|
||||
/**
|
||||
* Composer Check Platform Requirements
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // simple execution
|
||||
* $this->taskComposerValidate()->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class CheckPlatformReqs extends Base
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $action = 'check-platform-reqs';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$command = $this->getCommand();
|
||||
$this->printTaskInfo('Checking platform requirements: {command}', ['command' => $command]);
|
||||
return $this->executeCommand($command);
|
||||
}
|
||||
}
|
||||
111
vendor/consolidation/robo/src/Task/Composer/Config.php
vendored
Normal file
111
vendor/consolidation/robo/src/Task/Composer/Config.php
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Composer;
|
||||
|
||||
/**
|
||||
* Composer Config
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // simple execution
|
||||
* $this->taskComposerConfig()->set('bin-dir', 'bin/')->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Config extends Base
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $action = 'config';
|
||||
|
||||
/**
|
||||
* Set a configuration value.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->arg($key);
|
||||
$this->arg($value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Operate on the global repository
|
||||
*
|
||||
* @param bool $useGlobal
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function useGlobal($useGlobal = true)
|
||||
{
|
||||
if ($useGlobal) {
|
||||
$this->option('global');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param string $uri
|
||||
* @param string $repoType
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function repository($id, $uri, $repoType = 'vcs')
|
||||
{
|
||||
$this->arg("repositories.$id");
|
||||
$this->arg($repoType);
|
||||
$this->arg($uri);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function removeRepository($id)
|
||||
{
|
||||
$this->option('unset', "repositories.$id");
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function disableRepository($id)
|
||||
{
|
||||
$this->arg("repositories.$id");
|
||||
$this->arg('false');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function enableRepository($id)
|
||||
{
|
||||
$this->arg("repositories.$id");
|
||||
$this->arg('true');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$command = $this->getCommand();
|
||||
$this->printTaskInfo('Configuring composer.json: {command}', ['command' => $command]);
|
||||
return $this->executeCommand($command);
|
||||
}
|
||||
}
|
||||
147
vendor/consolidation/robo/src/Task/Composer/CreateProject.php
vendored
Normal file
147
vendor/consolidation/robo/src/Task/Composer/CreateProject.php
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Composer;
|
||||
|
||||
/**
|
||||
* Composer CreateProject
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // simple execution
|
||||
* $this->taskComposerCreateProject()->source('foo/bar')->target('myBar')->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class CreateProject extends Base
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $action = 'create-project';
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected $source;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $target = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $version = '';
|
||||
|
||||
/**
|
||||
* @param string $source
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function source($source)
|
||||
{
|
||||
$this->source = $source;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $target
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function target($target)
|
||||
{
|
||||
$this->target = $target;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $version
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function version($version)
|
||||
{
|
||||
$this->version = $version;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $keep
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function keepVcs($keep = true)
|
||||
{
|
||||
if ($keep) {
|
||||
$this->option('--keep-vcs');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $noInstall
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noInstall($noInstall = true)
|
||||
{
|
||||
if ($noInstall) {
|
||||
$this->option('--no-install');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repository
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function repository($repository)
|
||||
{
|
||||
if (!empty($repository)) {
|
||||
$this->option('repository', $repository);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $stability
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function stability($stability)
|
||||
{
|
||||
if (!empty($stability)) {
|
||||
$this->option('stability', $stability);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildCommand()
|
||||
{
|
||||
$this->arg($this->source);
|
||||
if (!empty($this->target)) {
|
||||
$this->arg($this->target);
|
||||
}
|
||||
if (!empty($this->version)) {
|
||||
$this->arg($this->version);
|
||||
}
|
||||
|
||||
return parent::buildCommand();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$command = $this->getCommand();
|
||||
$this->printTaskInfo('Creating project: {command}', ['command' => $command]);
|
||||
return $this->executeCommand($command);
|
||||
}
|
||||
}
|
||||
65
vendor/consolidation/robo/src/Task/Composer/DumpAutoload.php
vendored
Normal file
65
vendor/consolidation/robo/src/Task/Composer/DumpAutoload.php
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Composer;
|
||||
|
||||
/**
|
||||
* Composer Dump Autoload
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // simple execution
|
||||
* $this->taskComposerDumpAutoload()->run();
|
||||
*
|
||||
* // dump auto loader with custom path
|
||||
* $this->taskComposerDumpAutoload('path/to/my/composer.phar')
|
||||
* ->preferDist()
|
||||
* ->run();
|
||||
*
|
||||
* // optimize autoloader dump with custom path
|
||||
* $this->taskComposerDumpAutoload('path/to/my/composer.phar')
|
||||
* ->optimize()
|
||||
* ->run();
|
||||
*
|
||||
* // optimize autoloader dump with custom path and no dev
|
||||
* $this->taskComposerDumpAutoload('path/to/my/composer.phar')
|
||||
* ->optimize()
|
||||
* ->noDev()
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class DumpAutoload extends Base
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $action = 'dump-autoload';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $optimize;
|
||||
|
||||
/**
|
||||
* @param bool $optimize
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function optimize($optimize = true)
|
||||
{
|
||||
if ($optimize) {
|
||||
$this->option("--optimize");
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$command = $this->getCommand();
|
||||
$this->printTaskInfo('Dumping Autoloader: {command}', ['command' => $command]);
|
||||
return $this->executeCommand($command);
|
||||
}
|
||||
}
|
||||
136
vendor/consolidation/robo/src/Task/Composer/Init.php
vendored
Normal file
136
vendor/consolidation/robo/src/Task/Composer/Init.php
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Composer;
|
||||
|
||||
/**
|
||||
* Composer Init
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // simple execution
|
||||
* $this->taskComposerInit()->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Init extends Base
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $action = 'init';
|
||||
|
||||
/**
|
||||
* @param string $projectName
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function projectName($projectName)
|
||||
{
|
||||
$this->option('name', $projectName);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $description
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function description($description)
|
||||
{
|
||||
$this->option('description', $description);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $author
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function author($author)
|
||||
{
|
||||
$this->option('author', $author);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function projectType($type)
|
||||
{
|
||||
$this->option('type', $type);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $homepage
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function homepage($homepage)
|
||||
{
|
||||
$this->option('homepage', $homepage);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 'require' is a keyword, so it cannot be a method name.
|
||||
*
|
||||
* @param string $project
|
||||
* @param null|string $version
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function dependency($project, $version = null)
|
||||
{
|
||||
if (isset($version)) {
|
||||
$project .= ":$version";
|
||||
}
|
||||
$this->option('require', $project);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $stability
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function stability($stability)
|
||||
{
|
||||
$this->option('stability', $stability);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $license
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function license($license)
|
||||
{
|
||||
$this->option('license', $license);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repository
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function repository($repository)
|
||||
{
|
||||
$this->option('repository', $repository);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$command = $this->getCommand();
|
||||
$this->printTaskInfo('Creating composer.json: {command}', ['command' => $command]);
|
||||
return $this->executeCommand($command);
|
||||
}
|
||||
}
|
||||
54
vendor/consolidation/robo/src/Task/Composer/Install.php
vendored
Normal file
54
vendor/consolidation/robo/src/Task/Composer/Install.php
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Composer;
|
||||
|
||||
/**
|
||||
* Composer Install
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // simple execution
|
||||
* $this->taskComposerInstall()->run();
|
||||
*
|
||||
* // prefer dist with custom path
|
||||
* $this->taskComposerInstall('path/to/my/composer.phar')
|
||||
* ->preferDist()
|
||||
* ->run();
|
||||
*
|
||||
* // optimize autoloader with custom path
|
||||
* $this->taskComposerInstall('path/to/my/composer.phar')
|
||||
* ->optimizeAutoloader()
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Install extends Base
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $action = 'install';
|
||||
|
||||
/**
|
||||
* adds `no-suggest` option to composer
|
||||
*
|
||||
* @param bool $noSuggest
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noSuggest($noSuggest = true)
|
||||
{
|
||||
$this->option('--no-suggest');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$command = $this->getCommand();
|
||||
$this->printTaskInfo('Installing Packages: {command}', ['command' => $command]);
|
||||
return $this->executeCommand($command);
|
||||
}
|
||||
}
|
||||
110
vendor/consolidation/robo/src/Task/Composer/Remove.php
vendored
Normal file
110
vendor/consolidation/robo/src/Task/Composer/Remove.php
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Composer;
|
||||
|
||||
/**
|
||||
* Composer Remove
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // simple execution
|
||||
* $this->taskComposerRemove()->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Remove extends Base
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $action = 'remove';
|
||||
|
||||
/**
|
||||
* 'remove' is a keyword, so it cannot be a method name.
|
||||
*
|
||||
* @param array|string $project
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function dependency(array|string $project): self
|
||||
{
|
||||
$project = (array)$project;
|
||||
$this->args($project);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $dev
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function dev($dev = true)
|
||||
{
|
||||
if ($dev) {
|
||||
$this->option('--dev');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $noProgress
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noProgress($noProgress = true)
|
||||
{
|
||||
if ($noProgress) {
|
||||
$this->option('--no-progress');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $noUpdate
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noUpdate($noUpdate = true)
|
||||
{
|
||||
if ($noUpdate) {
|
||||
$this->option('--no-update');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $updateNoDev
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function updateNoDev($updateNoDev = true)
|
||||
{
|
||||
if ($updateNoDev) {
|
||||
$this->option('--update-no-dev');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $updateWithDependencies
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noUpdateWithDependencies($updateWithDependencies = true)
|
||||
{
|
||||
if ($updateWithDependencies) {
|
||||
$this->option('--no-update-with-dependencies');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$command = $this->getCommand();
|
||||
$this->printTaskInfo('Removing packages: {command}', ['command' => $command]);
|
||||
return $this->executeCommand($command);
|
||||
}
|
||||
}
|
||||
79
vendor/consolidation/robo/src/Task/Composer/RequireDependency.php
vendored
Normal file
79
vendor/consolidation/robo/src/Task/Composer/RequireDependency.php
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Composer;
|
||||
|
||||
/**
|
||||
* Composer Require
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // simple execution
|
||||
* $this->taskComposerRequire()->dependency('foo/bar', '^.2.4.8')->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class RequireDependency extends Base
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $action = 'require';
|
||||
|
||||
/**
|
||||
* 'require' is a keyword, so it cannot be a method name.
|
||||
*
|
||||
* @param string $project
|
||||
* @param null|string $version
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function dependency($project, $version = null)
|
||||
{
|
||||
$project = (array)$project;
|
||||
|
||||
if (isset($version)) {
|
||||
$project = array_map(
|
||||
function ($item) use ($version) {
|
||||
return "$item:$version";
|
||||
},
|
||||
$project
|
||||
);
|
||||
}
|
||||
$this->args($project);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `no-suggest` option to composer
|
||||
*
|
||||
* @param bool $noSuggest
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noSuggest($noSuggest = true)
|
||||
{
|
||||
$this->option('--no-suggest');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `no-update` option to composer
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noUpdate(): self
|
||||
{
|
||||
$this->option('--no-update');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$command = $this->getCommand();
|
||||
$this->printTaskInfo('Requiring packages: {command}', ['command' => $command]);
|
||||
return $this->executeCommand($command);
|
||||
}
|
||||
}
|
||||
106
vendor/consolidation/robo/src/Task/Composer/Tasks.php
vendored
Normal file
106
vendor/consolidation/robo/src/Task/Composer/Tasks.php
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Composer;
|
||||
|
||||
trait Tasks
|
||||
{
|
||||
/**
|
||||
* @param null|string $pathToComposer
|
||||
*
|
||||
* @return \Robo\Task\Composer\Install|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskComposerInstall($pathToComposer = null)
|
||||
{
|
||||
return $this->task(Install::class, $pathToComposer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $pathToComposer
|
||||
*
|
||||
* @return \Robo\Task\Composer\Update|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskComposerUpdate($pathToComposer = null)
|
||||
{
|
||||
return $this->task(Update::class, $pathToComposer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $pathToComposer
|
||||
*
|
||||
* @return \Robo\Task\Composer\DumpAutoload|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskComposerDumpAutoload($pathToComposer = null)
|
||||
{
|
||||
return $this->task(DumpAutoload::class, $pathToComposer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $pathToComposer
|
||||
*
|
||||
* @return \Robo\Task\Composer\Init|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskComposerInit($pathToComposer = null)
|
||||
{
|
||||
return $this->task(Init::class, $pathToComposer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $pathToComposer
|
||||
*
|
||||
* @return \Robo\Task\Composer\Config|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskComposerConfig($pathToComposer = null)
|
||||
{
|
||||
return $this->task(Config::class, $pathToComposer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $pathToComposer
|
||||
*
|
||||
* @return \Robo\Task\Composer\Validate|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskComposerValidate($pathToComposer = null)
|
||||
{
|
||||
return $this->task(Validate::class, $pathToComposer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $pathToComposer
|
||||
*
|
||||
* @return \Robo\Task\Composer\Remove|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskComposerRemove($pathToComposer = null)
|
||||
{
|
||||
return $this->task(Remove::class, $pathToComposer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $pathToComposer
|
||||
*
|
||||
* @return \Robo\Task\Composer\RequireDependency|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskComposerRequire($pathToComposer = null)
|
||||
{
|
||||
return $this->task(RequireDependency::class, $pathToComposer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $pathToComposer
|
||||
*
|
||||
* @return \Robo\Task\Composer\CreateProject|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskComposerCreateProject($pathToComposer = null)
|
||||
{
|
||||
return $this->task(CreateProject::class, $pathToComposer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $pathToComposer
|
||||
*
|
||||
* @return \Robo\Task\Composer\CreateProject|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskCheckPlatformReqs($pathToComposer = null)
|
||||
{
|
||||
return $this->task(CheckPlatformReqs::class, $pathToComposer);
|
||||
}
|
||||
}
|
||||
54
vendor/consolidation/robo/src/Task/Composer/Update.php
vendored
Normal file
54
vendor/consolidation/robo/src/Task/Composer/Update.php
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Composer;
|
||||
|
||||
/**
|
||||
* Composer Update
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // simple execution
|
||||
* $this->taskComposerUpdate()->run();
|
||||
*
|
||||
* // prefer dist with custom path
|
||||
* $this->taskComposerUpdate('path/to/my/composer.phar')
|
||||
* ->preferDist()
|
||||
* ->run();
|
||||
*
|
||||
* // optimize autoloader with custom path
|
||||
* $this->taskComposerUpdate('path/to/my/composer.phar')
|
||||
* ->optimizeAutoloader()
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Update extends Base
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $action = 'update';
|
||||
|
||||
/**
|
||||
* adds `no-suggest` option to composer
|
||||
*
|
||||
* @param bool $noSuggest
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noSuggest($noSuggest = true)
|
||||
{
|
||||
$this->option('--no-suggest');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$command = $this->getCommand();
|
||||
$this->printTaskInfo('Updating Packages: {command}', ['command' => $command]);
|
||||
return $this->executeCommand($command);
|
||||
}
|
||||
}
|
||||
96
vendor/consolidation/robo/src/Task/Composer/Validate.php
vendored
Normal file
96
vendor/consolidation/robo/src/Task/Composer/Validate.php
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Composer;
|
||||
|
||||
/**
|
||||
* Composer Validate
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // simple execution
|
||||
* $this->taskComposerValidate()->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Validate extends Base
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $action = 'validate';
|
||||
|
||||
/**
|
||||
* @param bool $noCheckAll
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noCheckAll($noCheckAll = true)
|
||||
{
|
||||
if ($noCheckAll) {
|
||||
$this->option('--no-check-all');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $noCheckLock
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noCheckLock($noCheckLock = true)
|
||||
{
|
||||
if ($noCheckLock) {
|
||||
$this->option('--no-check-lock');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $noCheckPublish
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noCheckPublish($noCheckPublish = true)
|
||||
{
|
||||
if ($noCheckPublish) {
|
||||
$this->option('--no-check-publish');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $withDependencies
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function withDependencies($withDependencies = true)
|
||||
{
|
||||
if ($withDependencies) {
|
||||
$this->option('--with-dependencies');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $strict
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function strict($strict = true)
|
||||
{
|
||||
if ($strict) {
|
||||
$this->option('--strict');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$command = $this->getCommand();
|
||||
$this->printTaskInfo('Validating composer.json: {command}', ['command' => $command]);
|
||||
return $this->executeCommand($command);
|
||||
}
|
||||
}
|
||||
247
vendor/consolidation/robo/src/Task/Development/Changelog.php
vendored
Normal file
247
vendor/consolidation/robo/src/Task/Development/Changelog.php
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Development;
|
||||
|
||||
use Robo\Task\BaseTask;
|
||||
use Robo\Result;
|
||||
use Robo\Contract\BuilderAwareInterface;
|
||||
use Robo\Common\BuilderAwareTrait;
|
||||
|
||||
/**
|
||||
* Helps to manage changelog file.
|
||||
* Creates or updates `changelog.md` file with recent changes in current version.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $version = "0.1.0";
|
||||
* $this->taskChangelog()
|
||||
* ->version($version)
|
||||
* ->change("released to github")
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*
|
||||
* Changes can be asked from Console
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskChangelog()
|
||||
* ->version($version)
|
||||
* ->askForChanges()
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Changelog extends BaseTask implements BuilderAwareInterface
|
||||
{
|
||||
use BuilderAwareTrait;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $filename;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $log = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $anchor = "# Changelog";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $version = "";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $body = "";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $header = "";
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function filename($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the changelog body text.
|
||||
*
|
||||
* This method permits the raw changelog text to be set directly If this is set, $this->log changes will be ignored.
|
||||
*
|
||||
* @param string $body
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setBody($body)
|
||||
{
|
||||
$this->body = $body;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $header
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setHeader($header)
|
||||
{
|
||||
$this->header = $header;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $item
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function log($item)
|
||||
{
|
||||
$this->log[] = $item;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $anchor
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function anchor($anchor)
|
||||
{
|
||||
$this->anchor = $anchor;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $version
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function version($version)
|
||||
{
|
||||
$this->version = $version;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
*/
|
||||
public function __construct($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function changes(array $data)
|
||||
{
|
||||
$this->log = array_merge($this->log, $data);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $change
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function change($change)
|
||||
{
|
||||
$this->log[] = $change;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getChanges()
|
||||
{
|
||||
return $this->log;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if (empty($this->body)) {
|
||||
if (empty($this->log)) {
|
||||
return Result::error($this, "Changelog is empty");
|
||||
}
|
||||
$this->body = $this->generateBody();
|
||||
}
|
||||
if (empty($this->header)) {
|
||||
$this->header = $this->generateHeader();
|
||||
}
|
||||
|
||||
$text = $this->header . $this->body;
|
||||
|
||||
if (!file_exists($this->filename)) {
|
||||
$this->printTaskInfo('Creating {filename}', ['filename' => $this->filename]);
|
||||
$res = file_put_contents($this->filename, $this->anchor);
|
||||
if ($res === false) {
|
||||
return Result::error($this, "File {filename} cant be created", ['filename' => $this->filename]);
|
||||
}
|
||||
}
|
||||
|
||||
/** @var \Robo\Result $result */
|
||||
// trying to append to changelog for today
|
||||
$result = $this->collectionBuilder()->taskReplaceInFile($this->filename)
|
||||
->from($this->header)
|
||||
->to($text)
|
||||
->run();
|
||||
|
||||
if (!isset($result['replaced']) || !$result['replaced']) {
|
||||
$result = $this->collectionBuilder()->taskReplaceInFile($this->filename)
|
||||
->from($this->anchor)
|
||||
->to($this->anchor . "\n\n" . $text)
|
||||
->run();
|
||||
}
|
||||
|
||||
return new Result($this, $result->getExitCode(), $result->getMessage(), $this->log);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function generateBody()
|
||||
{
|
||||
$text = implode("\n", array_map([$this, 'processLogRow'], $this->log));
|
||||
$text .= "\n";
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function generateHeader()
|
||||
{
|
||||
return "#### {$this->version}\n\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $i
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function processLogRow($i)
|
||||
{
|
||||
return "* $i *" . date('Y-m-d') . "*";
|
||||
}
|
||||
}
|
||||
930
vendor/consolidation/robo/src/Task/Development/GenerateMarkdownDoc.php
vendored
Normal file
930
vendor/consolidation/robo/src/Task/Development/GenerateMarkdownDoc.php
vendored
Normal file
@ -0,0 +1,930 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Development;
|
||||
|
||||
use phpowermove\docblock\Docblock;
|
||||
use phpowermove\docblock\tags\AbstractDescriptionTag;
|
||||
use phpowermove\docblock\tags\AbstractTag;
|
||||
use phpowermove\docblock\tags\AbstractTypeTag;
|
||||
use phpowermove\docblock\tags\AbstractVarTypeTag;
|
||||
use phpowermove\docblock\tags\ParamTag;
|
||||
use phpowermove\docblock\tags\ReturnTag;
|
||||
use Robo\Task\BaseTask;
|
||||
use Robo\Result;
|
||||
use Robo\Contract\BuilderAwareInterface;
|
||||
use Robo\Common\BuilderAwareTrait;
|
||||
|
||||
/**
|
||||
* Simple documentation generator from source files.
|
||||
* Takes classes, properties and methods with their docblocks and writes down a markdown file.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskGenDoc('models.md')
|
||||
* ->docClass('Model\User') // take class Model\User
|
||||
* ->docClass('Model\Post') // take class Model\Post
|
||||
* ->filterMethods(function(\ReflectionMethod $r) {
|
||||
* return $r->isPublic() or $r->isProtected(); // process public and protected methods
|
||||
* })->processClass(function(\ReflectionClass $r, $text) {
|
||||
* return "Class ".$r->getName()."\n\n$text\n\n###Methods\n";
|
||||
* })->run();
|
||||
* ```
|
||||
*
|
||||
* By default this task generates a documentation for each public method of a class, interface or trait.
|
||||
* It combines method signature with a docblock. Both can be post-processed.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskGenDoc('models.md')
|
||||
* ->docClass('Model\User')
|
||||
* ->processClassSignature(false) // false can be passed to not include class signature
|
||||
* ->processClassDocBlock(function(\ReflectionClass $r, $text) {
|
||||
* return "[This is part of application model]\n" . $text;
|
||||
* })->processMethodSignature(function(\ReflectionMethod $r, $text) {
|
||||
* return "#### {$r->name}()";
|
||||
* })->processMethodDocBlock(function(\ReflectionMethod $r, $text) {
|
||||
* return strpos($r->name, 'save')===0 ? "[Saves to the database]\n" . $text : $text;
|
||||
* })->run();
|
||||
* ```
|
||||
*/
|
||||
class GenerateMarkdownDoc extends BaseTask implements BuilderAwareInterface
|
||||
{
|
||||
use BuilderAwareTrait;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $docClass = [];
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
protected $filterMethods;
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
protected $filterClasses;
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
protected $filterProperties;
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
protected $processClass;
|
||||
|
||||
/**
|
||||
* @var callable|false
|
||||
*/
|
||||
protected $processClassSignature;
|
||||
|
||||
/**
|
||||
* @var callable|false
|
||||
*/
|
||||
protected $processClassDocBlock;
|
||||
|
||||
/**
|
||||
* @var callable|false
|
||||
*/
|
||||
protected $processMethod;
|
||||
|
||||
/**
|
||||
* @var callable|false
|
||||
*/
|
||||
protected $processMethodSignature;
|
||||
|
||||
/**
|
||||
* @var callable|false
|
||||
*/
|
||||
protected $processMethodDocBlock;
|
||||
|
||||
/**
|
||||
* @var callable|false
|
||||
*/
|
||||
protected $processProperty;
|
||||
|
||||
/**
|
||||
* @var callable|false
|
||||
*/
|
||||
protected $processPropertySignature;
|
||||
|
||||
/**
|
||||
* @var callable|false
|
||||
*/
|
||||
protected $processPropertyDocBlock;
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
protected $reorder;
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
protected $reorderMethods;
|
||||
|
||||
/**
|
||||
* @todo Unused property.
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
protected $reorderProperties;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $filename;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $prepend = "";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $append = "";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $text;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $textForClass = [];
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function init($filename)
|
||||
{
|
||||
return new static($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
*/
|
||||
public function __construct($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a class you want to be documented.
|
||||
*
|
||||
* @param string $item
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function docClass($item)
|
||||
{
|
||||
$this->docClass[] = $item;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Using a callback function filter out methods that won't be documented.
|
||||
*
|
||||
* @param callable $filterMethods
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function filterMethods($filterMethods)
|
||||
{
|
||||
$this->filterMethods = $filterMethods;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Using a callback function filter out classes that won't be documented.
|
||||
*
|
||||
* @param callable $filterClasses
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function filterClasses($filterClasses)
|
||||
{
|
||||
$this->filterClasses = $filterClasses;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Using a callback function filter out properties that won't be documented.
|
||||
*
|
||||
* @param callable $filterProperties
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function filterProperties($filterProperties)
|
||||
{
|
||||
$this->filterProperties = $filterProperties;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post-process class documentation.
|
||||
*
|
||||
* @param callable $processClass
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function processClass($processClass)
|
||||
{
|
||||
$this->processClass = $processClass;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post-process class signature. Provide *false* to skip.
|
||||
*
|
||||
* @param callable|false $processClassSignature
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function processClassSignature($processClassSignature)
|
||||
{
|
||||
$this->processClassSignature = $processClassSignature;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post-process class docblock contents. Provide *false* to skip.
|
||||
*
|
||||
* @param callable|false $processClassDocBlock
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function processClassDocBlock($processClassDocBlock)
|
||||
{
|
||||
$this->processClassDocBlock = $processClassDocBlock;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post-process method documentation. Provide *false* to skip.
|
||||
*
|
||||
* @param callable|false $processMethod
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function processMethod($processMethod)
|
||||
{
|
||||
$this->processMethod = $processMethod;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post-process method signature. Provide *false* to skip.
|
||||
*
|
||||
* @param callable|false $processMethodSignature
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function processMethodSignature($processMethodSignature)
|
||||
{
|
||||
$this->processMethodSignature = $processMethodSignature;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post-process method docblock contents. Provide *false* to skip.
|
||||
*
|
||||
* @param callable|false $processMethodDocBlock
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function processMethodDocBlock($processMethodDocBlock)
|
||||
{
|
||||
$this->processMethodDocBlock = $processMethodDocBlock;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post-process property documentation. Provide *false* to skip.
|
||||
*
|
||||
* @param callable|false $processProperty
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function processProperty($processProperty)
|
||||
{
|
||||
$this->processProperty = $processProperty;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post-process property signature. Provide *false* to skip.
|
||||
*
|
||||
* @param callable|false $processPropertySignature
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function processPropertySignature($processPropertySignature)
|
||||
{
|
||||
$this->processPropertySignature = $processPropertySignature;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post-process property docblock contents. Provide *false* to skip.
|
||||
*
|
||||
* @param callable|false $processPropertyDocBlock
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function processPropertyDocBlock($processPropertyDocBlock)
|
||||
{
|
||||
$this->processPropertyDocBlock = $processPropertyDocBlock;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a function to reorder classes.
|
||||
*
|
||||
* @param callable $reorder
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function reorder($reorder)
|
||||
{
|
||||
$this->reorder = $reorder;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a function to reorder methods in class.
|
||||
*
|
||||
* @param callable $reorderMethods
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function reorderMethods($reorderMethods)
|
||||
{
|
||||
$this->reorderMethods = $reorderMethods;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable $reorderProperties
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function reorderProperties($reorderProperties)
|
||||
{
|
||||
$this->reorderProperties = $reorderProperties;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function filename($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts text at the beginning of markdown file.
|
||||
*
|
||||
* @param string $prepend
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function prepend($prepend)
|
||||
{
|
||||
$this->prepend = $prepend;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts text at the end of markdown file.
|
||||
*
|
||||
* @param string $append
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function append($append)
|
||||
{
|
||||
$this->append = $append;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function text($text)
|
||||
{
|
||||
$this->text = $text;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $item
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function textForClass($item)
|
||||
{
|
||||
$this->textForClass[] = $item;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
foreach ($this->docClass as $class) {
|
||||
$this->printTaskInfo("Processing {class}", ['class' => $class]);
|
||||
$this->textForClass[$class] = $this->documentClass($class);
|
||||
}
|
||||
|
||||
if (is_callable($this->reorder)) {
|
||||
$this->printTaskInfo("Applying reorder function");
|
||||
call_user_func_array($this->reorder, [$this->textForClass]);
|
||||
}
|
||||
|
||||
$this->text = implode("\n", $this->textForClass);
|
||||
|
||||
/** @var \Robo\Result $result */
|
||||
$result = $this->collectionBuilder()->taskWriteToFile($this->filename)
|
||||
->line($this->prepend)
|
||||
->text($this->text)
|
||||
->line($this->append)
|
||||
->run();
|
||||
|
||||
$this->printTaskSuccess('{filename} created. {class-count} classes documented', ['filename' => $this->filename, 'class-count' => count($this->docClass)]);
|
||||
|
||||
return new Result($this, $result->getExitCode(), $result->getMessage(), $this->textForClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
protected function documentClass($class)
|
||||
{
|
||||
if (!class_exists($class) && !trait_exists($class)) {
|
||||
return "";
|
||||
}
|
||||
$refl = new \ReflectionClass($class);
|
||||
|
||||
if (is_callable($this->filterClasses)) {
|
||||
$ret = call_user_func($this->filterClasses, $refl);
|
||||
if (!$ret) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
$doc = $this->documentClassSignature($refl);
|
||||
$doc .= "\n" . $this->documentClassDocBlock($refl);
|
||||
$doc .= "\n";
|
||||
|
||||
if (is_callable($this->processClass)) {
|
||||
$doc = call_user_func($this->processClass, $refl, $doc);
|
||||
}
|
||||
|
||||
$properties = [];
|
||||
foreach ($refl->getProperties() as $reflProperty) {
|
||||
$properties[] = $this->documentProperty($reflProperty);
|
||||
}
|
||||
|
||||
$properties = array_filter($properties);
|
||||
$doc .= implode("\n", $properties);
|
||||
|
||||
$methods = [];
|
||||
foreach ($refl->getMethods() as $reflMethod) {
|
||||
$methods[$reflMethod->name] = $this->documentMethod($reflMethod);
|
||||
}
|
||||
if (is_callable($this->reorderMethods)) {
|
||||
call_user_func_array($this->reorderMethods, [&$methods]);
|
||||
}
|
||||
|
||||
$methods = array_filter($methods);
|
||||
|
||||
$doc .= implode("\n", $methods) . "\n";
|
||||
|
||||
return $doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ReflectionClass $reflectionClass
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function documentClassSignature(\ReflectionClass $reflectionClass)
|
||||
{
|
||||
if ($this->processClassSignature === false) {
|
||||
return "";
|
||||
}
|
||||
|
||||
$signature = "## {$reflectionClass->name}\n\n";
|
||||
|
||||
if ($parent = $reflectionClass->getParentClass()) {
|
||||
$signature .= "* *Extends* `{$parent->name}`";
|
||||
}
|
||||
$interfaces = $reflectionClass->getInterfaceNames();
|
||||
if (count($interfaces)) {
|
||||
$signature .= "\n* *Implements* `" . implode('`, `', $interfaces) . '`';
|
||||
}
|
||||
$traits = $reflectionClass->getTraitNames();
|
||||
if (count($traits)) {
|
||||
$signature .= "\n* *Uses* `" . implode('`, `', $traits) . '`';
|
||||
}
|
||||
if (is_callable($this->processClassSignature)) {
|
||||
$signature = call_user_func($this->processClassSignature, $reflectionClass, $signature);
|
||||
}
|
||||
|
||||
return $signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ReflectionClass $reflectionClass
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function documentClassDocBlock(\ReflectionClass $reflectionClass)
|
||||
{
|
||||
if ($this->processClassDocBlock === false) {
|
||||
return "";
|
||||
}
|
||||
$doc = self::indentDoc($reflectionClass->getDocComment());
|
||||
if (is_callable($this->processClassDocBlock)) {
|
||||
$doc = call_user_func($this->processClassDocBlock, $reflectionClass, $doc);
|
||||
}
|
||||
return $doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ReflectionMethod $reflectedMethod
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function documentMethod(\ReflectionMethod $reflectedMethod)
|
||||
{
|
||||
if ($this->processMethod === false) {
|
||||
return "";
|
||||
}
|
||||
if (is_callable($this->filterMethods)) {
|
||||
$ret = call_user_func($this->filterMethods, $reflectedMethod);
|
||||
if (!$ret) {
|
||||
return "";
|
||||
}
|
||||
} else {
|
||||
if (!$reflectedMethod->isPublic()) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
$signature = $this->documentMethodSignature($reflectedMethod);
|
||||
$docblock = $this->documentMethodDocBlock($reflectedMethod);
|
||||
$methodDoc = "$signature\n\n$docblock";
|
||||
if (is_callable($this->processMethod)) {
|
||||
$methodDoc = call_user_func($this->processMethod, $reflectedMethod, $methodDoc);
|
||||
}
|
||||
return $methodDoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ReflectionProperty $reflectedProperty
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function documentProperty(\ReflectionProperty $reflectedProperty)
|
||||
{
|
||||
if ($this->processProperty === false) {
|
||||
return "";
|
||||
}
|
||||
if (is_callable($this->filterProperties)) {
|
||||
$ret = call_user_func($this->filterProperties, $reflectedProperty);
|
||||
if (!$ret) {
|
||||
return "";
|
||||
}
|
||||
} else {
|
||||
if (!$reflectedProperty->isPublic()) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
$signature = $this->documentPropertySignature($reflectedProperty);
|
||||
$docblock = $this->documentPropertyDocBlock($reflectedProperty);
|
||||
$propertyDoc = $signature . $docblock;
|
||||
if (is_callable($this->processProperty)) {
|
||||
$propertyDoc = call_user_func($this->processProperty, $reflectedProperty, $propertyDoc);
|
||||
}
|
||||
return $propertyDoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ReflectionProperty $reflectedProperty
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function documentPropertySignature(\ReflectionProperty $reflectedProperty)
|
||||
{
|
||||
if ($this->processPropertySignature === false) {
|
||||
return "";
|
||||
}
|
||||
$modifiers = implode(' ', \Reflection::getModifierNames($reflectedProperty->getModifiers()));
|
||||
$signature = "#### *$modifiers* {$reflectedProperty->name}";
|
||||
if (is_callable($this->processPropertySignature)) {
|
||||
$signature = call_user_func($this->processPropertySignature, $reflectedProperty, $signature);
|
||||
}
|
||||
return $signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ReflectionProperty $reflectedProperty
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function documentPropertyDocBlock(\ReflectionProperty $reflectedProperty)
|
||||
{
|
||||
if ($this->processPropertyDocBlock === false) {
|
||||
return "";
|
||||
}
|
||||
$propertyDoc = $reflectedProperty->getDocComment();
|
||||
// take from parent
|
||||
if (!$propertyDoc) {
|
||||
$parent = $reflectedProperty->getDeclaringClass();
|
||||
while ($parent = $parent->getParentClass()) {
|
||||
if ($parent->hasProperty($reflectedProperty->name)) {
|
||||
$propertyDoc = $parent->getProperty($reflectedProperty->name)->getDocComment();
|
||||
}
|
||||
}
|
||||
}
|
||||
$propertyDoc = self::indentDoc($propertyDoc, 7);
|
||||
$propertyDoc = preg_replace("~^@(.*?)([$\s])~", ' * `$1` $2', $propertyDoc); // format annotations
|
||||
if (is_callable($this->processPropertyDocBlock)) {
|
||||
$propertyDoc = call_user_func($this->processPropertyDocBlock, $reflectedProperty, $propertyDoc);
|
||||
}
|
||||
return ltrim($propertyDoc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ReflectionParameter $param
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function documentParam(\ReflectionParameter $param)
|
||||
{
|
||||
$text = "";
|
||||
$paramType = $param->getType();
|
||||
if ($paramType instanceof \ReflectionNamedType) {
|
||||
if ($paramType->getName() === 'array') {
|
||||
$text .= 'array ';
|
||||
}
|
||||
if (($paramType->getName() === 'callable')) {
|
||||
$text .= 'callable ';
|
||||
}
|
||||
}
|
||||
$text .= '$' . $param->name;
|
||||
if ($param->isDefaultValueAvailable()) {
|
||||
if ($param->allowsNull()) {
|
||||
$text .= ' = null';
|
||||
} else {
|
||||
$text .= ' = ' . str_replace("\n", ' ', var_export($param->getDefaultValue(), true));
|
||||
}
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $doc
|
||||
* @param int $indent
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function indentDoc($doc, $indent = 3)
|
||||
{
|
||||
if (!$doc) {
|
||||
return $doc;
|
||||
}
|
||||
return implode(
|
||||
"\n",
|
||||
array_map(
|
||||
function ($line) use ($indent) {
|
||||
return substr($line, $indent);
|
||||
},
|
||||
explode("\n", $doc)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ReflectionMethod $reflectedMethod
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function documentMethodSignature(\ReflectionMethod $reflectedMethod)
|
||||
{
|
||||
if ($this->processMethodSignature === false) {
|
||||
return "";
|
||||
}
|
||||
$modifiers = implode(' ', \Reflection::getModifierNames($reflectedMethod->getModifiers()));
|
||||
$params = implode(
|
||||
', ',
|
||||
array_map(
|
||||
function ($p) {
|
||||
return $this->documentParam($p);
|
||||
},
|
||||
$reflectedMethod->getParameters()
|
||||
)
|
||||
);
|
||||
$signature = "#### *$modifiers* {$reflectedMethod->name}($params)";
|
||||
if (is_callable($this->processMethodSignature)) {
|
||||
$signature = call_user_func($this->processMethodSignature, $reflectedMethod, $signature);
|
||||
}
|
||||
return $signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ReflectionMethod $reflectedMethod
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function documentMethodDocBlock(\ReflectionMethod $reflectedMethod)
|
||||
{
|
||||
if ($this->processMethodDocBlock === false) {
|
||||
return "";
|
||||
}
|
||||
$methodDoc = $reflectedMethod->getDocComment();
|
||||
// take from parent
|
||||
if (!$methodDoc) {
|
||||
$parent = $reflectedMethod->getDeclaringClass();
|
||||
while ($parent = $parent->getParentClass()) {
|
||||
if ($parent->hasMethod($reflectedMethod->name)) {
|
||||
$methodDoc = $parent->getMethod($reflectedMethod->name)->getDocComment();
|
||||
}
|
||||
}
|
||||
}
|
||||
// take from interface
|
||||
if (!$methodDoc) {
|
||||
$interfaces = $reflectedMethod->getDeclaringClass()->getInterfaces();
|
||||
foreach ($interfaces as $interface) {
|
||||
$i = new \ReflectionClass($interface->name);
|
||||
if ($i->hasMethod($reflectedMethod->name)) {
|
||||
$methodDoc = $i->getMethod($reflectedMethod->name)->getDocComment();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$methodDoc = $this->documentMethodParametersAndReturnType($reflectedMethod, $methodDoc);
|
||||
|
||||
if (is_callable($this->processMethodDocBlock)) {
|
||||
$methodDoc = call_user_func($this->processMethodDocBlock, $reflectedMethod, $methodDoc);
|
||||
}
|
||||
|
||||
return $methodDoc;
|
||||
}
|
||||
|
||||
protected function documentMethodParametersAndReturnType(\ReflectionMethod $method, string $text): string
|
||||
{
|
||||
$parameters = $method->getParameters();
|
||||
$class = $method->getDeclaringClass();
|
||||
|
||||
$docblock = new Docblock($text);
|
||||
/**
|
||||
* @var ParamTag[] $paramTags
|
||||
*/
|
||||
$paramTags = $docblock->getTags('param')->toArray();
|
||||
$existingParamTags = [];
|
||||
if ($paramTags !== []) {
|
||||
foreach ($paramTags as $paramTag) {
|
||||
$existingParamTags[$paramTag->getVariable()] = $paramTag;
|
||||
}
|
||||
}
|
||||
|
||||
$docblock->removeTags('param');
|
||||
|
||||
foreach ($parameters as $parameter) {
|
||||
$parameterName = $parameter->getName();
|
||||
if (isset($existingParamTags[$parameterName])) {
|
||||
$docblock->appendTag($existingParamTags[$parameterName]);
|
||||
} else {
|
||||
$newParamTag = new ParamTag();
|
||||
$newParamTag->setVariable($parameterName);
|
||||
$parameterType = $parameter->getType();
|
||||
if ($parameterType !== null) {
|
||||
$newParamTag->setType($this->stringifyType($parameterType, $class));
|
||||
}
|
||||
$docblock->appendTag($newParamTag);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$docblock->hasTag('return')) {
|
||||
$returnType = $method->getReturnType();
|
||||
if ($returnType !== null) {
|
||||
$returnTag = new ReturnTag();
|
||||
$returnTag->setType($this->stringifyType($returnType, $class));
|
||||
$docblock->appendTag($returnTag);
|
||||
}
|
||||
}
|
||||
|
||||
$result = '';
|
||||
/**
|
||||
* @var AbstractTag[] $sortedTags
|
||||
*/
|
||||
$sortedTags = $docblock->getSortedTags();
|
||||
|
||||
foreach ($sortedTags as $tag) {
|
||||
if ($tag instanceof AbstractTypeTag) {
|
||||
$result .= '* `' . $tag->getTagName() . ' ' . $tag->getType() . '`';
|
||||
|
||||
if ($tag instanceof AbstractVarTypeTag) {
|
||||
$result .= ' $' . $tag->getVariable();
|
||||
}
|
||||
if ($tag->getDescription() !== '') {
|
||||
$result .= ' ' . $tag->getDescription();
|
||||
}
|
||||
} else {
|
||||
$result .= preg_replace("~^@(.*?)([$\s])~", '* `$1`$2', $tag->toString());
|
||||
}
|
||||
$result .= "\n";
|
||||
}
|
||||
|
||||
$shortDescription = trim($docblock->getShortDescription());
|
||||
$longDescription = trim($docblock->getLongDescription());
|
||||
|
||||
if ($shortDescription !== '') {
|
||||
if ($result !== '') {
|
||||
$result .= "\n";
|
||||
}
|
||||
$result .= $shortDescription . "\n";
|
||||
}
|
||||
|
||||
if ($longDescription !== '') {
|
||||
if ($result !== '') {
|
||||
$result .= "\n";
|
||||
}
|
||||
$result .= $longDescription . "\n";
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copied from \Codeception\Lib\Generator\Actions
|
||||
*/
|
||||
private function stringifyType(\ReflectionType $type, \ReflectionClass $moduleClass): string
|
||||
{
|
||||
if ($type instanceof \ReflectionUnionType) {
|
||||
return $this->stringifyNamedTypes($type->getTypes(), $moduleClass, '|');
|
||||
} elseif ($type instanceof \ReflectionIntersectionType) {
|
||||
return $this->stringifyNamedTypes($type->getTypes(), $moduleClass, '&');
|
||||
} elseif ($type instanceof \ReflectionNamedType) {
|
||||
return sprintf(
|
||||
'%s%s',
|
||||
($type->allowsNull() && $type->getName() !== 'mixed') ? '?' : '',
|
||||
self::stringifyNamedType($type, $moduleClass)
|
||||
);
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Unsupported type class: ' . $type::class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ReflectionNamedType[] $types
|
||||
*/
|
||||
private function stringifyNamedTypes(array $types, \ReflectionClass $moduleClass, string $separator): string
|
||||
{
|
||||
$strings = [];
|
||||
foreach ($types as $type) {
|
||||
$strings[] = self::stringifyNamedType($type, $moduleClass);
|
||||
}
|
||||
|
||||
return implode($separator, $strings);
|
||||
}
|
||||
|
||||
public static function stringifyNamedType(\ReflectionNamedType $type, \ReflectionClass $moduleClass): string
|
||||
{
|
||||
$typeName = $type->getName();
|
||||
|
||||
if ($typeName === 'self') {
|
||||
$typeName = $moduleClass->getName();
|
||||
} elseif ($typeName === 'parent') {
|
||||
$typeName = $moduleClass->getParentClass()->getName();
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'%s%s',
|
||||
$type->isBuiltin() ? '' : '\\',
|
||||
$typeName
|
||||
);
|
||||
}
|
||||
|
||||
// end of copy
|
||||
}
|
||||
108
vendor/consolidation/robo/src/Task/Development/GenerateTask.php
vendored
Normal file
108
vendor/consolidation/robo/src/Task/Development/GenerateTask.php
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Development;
|
||||
|
||||
use Robo\Task\BaseTask;
|
||||
use Robo\Result;
|
||||
|
||||
/**
|
||||
* Generate a Robo Task that is a wrapper around an existing class.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskGenerateTask('Symfony\Component\Filesystem\Filesystem', 'FilesystemStack')
|
||||
* ->run();
|
||||
* ```
|
||||
*/
|
||||
class GenerateTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $className;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $wrapperClassName;
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @param string $wrapperClassName
|
||||
*/
|
||||
public function __construct($className, $wrapperClassName = '')
|
||||
{
|
||||
$this->className = $className;
|
||||
$this->wrapperClassName = $wrapperClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$delegate = new \ReflectionClass($this->className);
|
||||
$replacements = [];
|
||||
|
||||
$leadingCommentChars = " * ";
|
||||
$methodDescriptions = [];
|
||||
$methodImplementations = [];
|
||||
$immediateMethods = [];
|
||||
foreach ($delegate->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
|
||||
$methodName = $method->name;
|
||||
$getter = preg_match('/^(get|has|is)/', $methodName);
|
||||
$setter = preg_match('/^(set|unset)/', $methodName);
|
||||
$argPrototypeList = [];
|
||||
$argNameList = [];
|
||||
$needsImplementation = false;
|
||||
foreach ($method->getParameters() as $arg) {
|
||||
$argDescription = '$' . $arg->name;
|
||||
$argNameList[] = $argDescription;
|
||||
if ($arg->isOptional()) {
|
||||
$argDescription = $argDescription . ' = ' . str_replace("\n", "", var_export($arg->getDefaultValue(), true));
|
||||
// We will create wrapper methods for any method that
|
||||
// has default parameters.
|
||||
$needsImplementation = true;
|
||||
}
|
||||
$argPrototypeList[] = $argDescription;
|
||||
}
|
||||
$argPrototypeString = implode(', ', $argPrototypeList);
|
||||
$argNameListString = implode(', ', $argNameList);
|
||||
|
||||
if ($methodName[0] != '_') {
|
||||
$methodDescriptions[] = "@method $methodName($argPrototypeString)";
|
||||
|
||||
if ($getter) {
|
||||
$immediateMethods[] = " public function $methodName($argPrototypeString)\n {\n return \$this->delegate->$methodName($argNameListString);\n }";
|
||||
} elseif ($setter) {
|
||||
$immediateMethods[] = " public function $methodName($argPrototypeString)\n {\n \$this->delegate->$methodName($argNameListString);\n return \$this;\n }";
|
||||
} elseif ($needsImplementation) {
|
||||
// Include an implementation for the wrapper method if necessary
|
||||
$methodImplementations[] = " protected function _$methodName($argPrototypeString)\n {\n \$this->delegate->$methodName($argNameListString);\n }";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$classNameParts = explode('\\', $this->className);
|
||||
$delegate = array_pop($classNameParts);
|
||||
$delegateNamespace = implode('\\', $classNameParts);
|
||||
|
||||
if (empty($this->wrapperClassName)) {
|
||||
$this->wrapperClassName = $delegate;
|
||||
}
|
||||
|
||||
$replacements['{delegateNamespace}'] = $delegateNamespace;
|
||||
$replacements['{delegate}'] = $delegate;
|
||||
$replacements['{wrapperClassName}'] = $this->wrapperClassName;
|
||||
$replacements['{taskname}'] = "task$delegate";
|
||||
$replacements['{methodList}'] = $leadingCommentChars . implode("\n$leadingCommentChars", $methodDescriptions);
|
||||
$replacements['{immediateMethods}'] = "\n\n" . implode("\n\n", $immediateMethods);
|
||||
$replacements['{methodImplementations}'] = "\n\n" . implode("\n\n", $methodImplementations);
|
||||
|
||||
$template = file_get_contents(__DIR__ . '/../../../data/Task/Development/GeneratedWrapper.tmpl');
|
||||
$template = str_replace(array_keys($replacements), array_values($replacements), $template);
|
||||
|
||||
// Returning data in the $message will cause it to be printed.
|
||||
return Result::success($this, $template);
|
||||
}
|
||||
}
|
||||
158
vendor/consolidation/robo/src/Task/Development/GitHub.php
vendored
Normal file
158
vendor/consolidation/robo/src/Task/Development/GitHub.php
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Development;
|
||||
|
||||
use Robo\Exception\TaskException;
|
||||
use Robo\Task\BaseTask;
|
||||
|
||||
abstract class GitHub extends BaseTask
|
||||
{
|
||||
const GITHUB_URL = 'https://api.github.com';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $user = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $password = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $repo;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $owner;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $accessToken;
|
||||
|
||||
/**
|
||||
* @param string $repo
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function repo($repo)
|
||||
{
|
||||
$this->repo = $repo;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $owner
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function owner($owner)
|
||||
{
|
||||
$this->owner = $owner;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function uri($uri)
|
||||
{
|
||||
list($this->owner, $this->repo) = explode('/', $uri);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getUri()
|
||||
{
|
||||
return $this->owner . '/' . $this->repo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $user
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function user($user)
|
||||
{
|
||||
$this->user = $user;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $password
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function password($password)
|
||||
{
|
||||
$this->password = $password;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $token
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function accessToken($token)
|
||||
{
|
||||
$this->accessToken = $token;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @param array $params
|
||||
* @param string $method
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
protected function sendRequest($uri, $params = [], $method = 'POST')
|
||||
{
|
||||
if (!$this->owner or !$this->repo) {
|
||||
throw new TaskException($this, 'Repo URI is not set');
|
||||
}
|
||||
|
||||
$ch = curl_init();
|
||||
$url = sprintf('%s/repos/%s/%s', self::GITHUB_URL, $this->getUri(), $uri);
|
||||
$this->printTaskInfo($url);
|
||||
$this->printTaskInfo('{method} {url}', ['method' => $method, 'url' => $url]);
|
||||
|
||||
if (!empty($this->user)) {
|
||||
curl_setopt($ch, CURLOPT_USERPWD, $this->user . ':' . $this->password);
|
||||
}
|
||||
|
||||
if (!empty($this->accessToken)) {
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: ' . sprintf('token %s', $this->accessToken)]);
|
||||
}
|
||||
|
||||
curl_setopt_array(
|
||||
$ch,
|
||||
array(
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POST => $method != 'GET',
|
||||
CURLOPT_POSTFIELDS => json_encode($params),
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_USERAGENT => "Robo"
|
||||
)
|
||||
);
|
||||
|
||||
$output = curl_exec($ch);
|
||||
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$response = json_decode($output);
|
||||
|
||||
$this->printTaskInfo($output);
|
||||
return [$code, $response];
|
||||
}
|
||||
}
|
||||
209
vendor/consolidation/robo/src/Task/Development/GitHubRelease.php
vendored
Normal file
209
vendor/consolidation/robo/src/Task/Development/GitHubRelease.php
vendored
Normal file
@ -0,0 +1,209 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Development;
|
||||
|
||||
use Robo\Result;
|
||||
|
||||
/**
|
||||
* Publishes new GitHub release.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskGitHubRelease('0.1.0')
|
||||
* ->uri('consolidation-org/Robo')
|
||||
* ->description('Add stuff people need.')
|
||||
* ->change('Fix #123')
|
||||
* ->change('Add frobulation method to all widgets')
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class GitHubRelease extends GitHub
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tag;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $changes = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $draft = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $prerelease = false;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $comittish = 'master';
|
||||
|
||||
/**
|
||||
* @param string $tag
|
||||
*/
|
||||
public function __construct($tag)
|
||||
{
|
||||
$this->tag = $tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tag
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function tag($tag)
|
||||
{
|
||||
$this->tag = $tag;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $draft
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function draft($draft)
|
||||
{
|
||||
$this->draft = $draft;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function name($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $description
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function description($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $prerelease
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function prerelease($prerelease)
|
||||
{
|
||||
$this->prerelease = $prerelease;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $comittish
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function comittish($comittish)
|
||||
{
|
||||
$this->comittish = $comittish;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $description
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function appendDescription($description)
|
||||
{
|
||||
if (!empty($this->description)) {
|
||||
$this->description .= "\n\n";
|
||||
}
|
||||
$this->description .= $description;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function changes(array $changes)
|
||||
{
|
||||
$this->changes = array_merge($this->changes, $changes);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $change
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function change($change)
|
||||
{
|
||||
$this->changes[] = $change;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getBody()
|
||||
{
|
||||
$body = $this->description;
|
||||
if (!empty($this->changes)) {
|
||||
$changes = array_map(
|
||||
function ($line) {
|
||||
return "* $line";
|
||||
},
|
||||
$this->changes
|
||||
);
|
||||
$changesText = implode("\n", $changes);
|
||||
$body .= "### Changelog \n\n$changesText";
|
||||
}
|
||||
return $body;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->printTaskInfo('Releasing {tag}', ['tag' => $this->tag]);
|
||||
$this->startTimer();
|
||||
list($code, $data) = $this->sendRequest(
|
||||
'releases',
|
||||
[
|
||||
"tag_name" => $this->tag,
|
||||
"target_commitish" => $this->comittish,
|
||||
"name" => $this->name,
|
||||
"body" => $this->getBody(),
|
||||
"draft" => $this->draft,
|
||||
"prerelease" => $this->prerelease
|
||||
]
|
||||
);
|
||||
$this->stopTimer();
|
||||
|
||||
return new Result(
|
||||
$this,
|
||||
in_array($code, [200, 201]) ? 0 : 1,
|
||||
isset($data->message) ? $data->message : '',
|
||||
['response' => $data, 'time' => $this->getExecutionTime()]
|
||||
);
|
||||
}
|
||||
}
|
||||
81
vendor/consolidation/robo/src/Task/Development/OpenBrowser.php
vendored
Normal file
81
vendor/consolidation/robo/src/Task/Development/OpenBrowser.php
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Development;
|
||||
|
||||
use Robo\Task\BaseTask;
|
||||
use Robo\Common\ProcessUtils;
|
||||
use Robo\Result;
|
||||
|
||||
/**
|
||||
* Opens the default's user browser
|
||||
* code inspired from openBrowser() function in https://github.com/composer/composer/blob/master/src/Composer/Command/HomeCommand.php
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // open one browser window
|
||||
* $this->taskOpenBrowser('http://localhost')
|
||||
* ->run();
|
||||
*
|
||||
* // open two browser windows
|
||||
* $this->taskOpenBrowser([
|
||||
* 'http://localhost/mysite',
|
||||
* 'http://localhost/mysite2'
|
||||
* ])
|
||||
* ->run();
|
||||
* ```
|
||||
*/
|
||||
class OpenBrowser extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $urls = [];
|
||||
|
||||
/**
|
||||
* @param string|string[] $url
|
||||
*/
|
||||
public function __construct($url)
|
||||
{
|
||||
$this->urls = (array) $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$openCommand = $this->getOpenCommand();
|
||||
|
||||
if (empty($openCommand)) {
|
||||
return Result::error($this, 'no suitable browser opening command found');
|
||||
}
|
||||
|
||||
foreach ($this->urls as $url) {
|
||||
passthru(sprintf($openCommand, ProcessUtils::escapeArgument($url)));
|
||||
$this->printTaskInfo('Opened {url}', ['url' => $url]);
|
||||
}
|
||||
|
||||
return Result::success($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
private function getOpenCommand()
|
||||
{
|
||||
if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
|
||||
return 'start "web" explorer "%s"';
|
||||
}
|
||||
|
||||
passthru('which xdg-open', $linux);
|
||||
passthru('which open', $osx);
|
||||
|
||||
if (0 === $linux) {
|
||||
return 'xdg-open %s';
|
||||
}
|
||||
|
||||
if (0 === $osx) {
|
||||
return 'open %s';
|
||||
}
|
||||
}
|
||||
}
|
||||
257
vendor/consolidation/robo/src/Task/Development/PackPhar.php
vendored
Normal file
257
vendor/consolidation/robo/src/Task/Development/PackPhar.php
vendored
Normal file
@ -0,0 +1,257 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Development;
|
||||
|
||||
use Robo\Contract\ProgressIndicatorAwareInterface;
|
||||
use Robo\Contract\PrintedInterface;
|
||||
use Robo\Result;
|
||||
use Robo\Task\BaseTask;
|
||||
|
||||
/**
|
||||
* Creates Phar.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $pharTask = $this->taskPackPhar('package/codecept.phar')
|
||||
* ->compress()
|
||||
* ->stub('package/stub.php');
|
||||
*
|
||||
* $finder = Finder::create()
|
||||
* ->name('*.php')
|
||||
* ->in('src');
|
||||
*
|
||||
* foreach ($finder as $file) {
|
||||
* $pharTask->addFile('src/'.$file->getRelativePathname(), $file->getRealPath());
|
||||
* }
|
||||
*
|
||||
* $finder = Finder::create()->files()
|
||||
* ->name('*.php')
|
||||
* ->in('vendor');
|
||||
*
|
||||
* foreach ($finder as $file) {
|
||||
* $pharTask->addStripped('vendor/'.$file->getRelativePathname(), $file->getRealPath());
|
||||
* }
|
||||
* $pharTask->run();
|
||||
*
|
||||
* // verify Phar is packed correctly
|
||||
* $code = $this->_exec('php package/codecept.phar');
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class PackPhar extends BaseTask implements PrintedInterface, ProgressIndicatorAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var \Phar
|
||||
*/
|
||||
protected $phar;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
protected $compileDir = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $filename;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $compress = false;
|
||||
|
||||
protected $stub;
|
||||
|
||||
protected $bin;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $stubTemplate = <<<EOF
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
Phar::mapPhar();
|
||||
%s
|
||||
__HALT_COMPILER();
|
||||
EOF;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $files = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPrinted()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
*/
|
||||
public function __construct($filename)
|
||||
{
|
||||
$file = new \SplFileInfo($filename);
|
||||
$this->filename = $filename;
|
||||
if (file_exists($file->getRealPath())) {
|
||||
@unlink($file->getRealPath());
|
||||
}
|
||||
$this->phar = new \Phar($file->getPathname(), 0, $file->getFilename());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $compress
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function compress($compress = true)
|
||||
{
|
||||
$this->compress = $compress;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $stub
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function stub($stub)
|
||||
{
|
||||
$this->phar->setStub(file_get_contents($stub));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function progressIndicatorSteps()
|
||||
{
|
||||
// run() will call advanceProgressIndicator() once for each
|
||||
// file, one after calling stopBuffering, and again after compression.
|
||||
return count($this->files) + 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->printTaskInfo('Creating {filename}', ['filename' => $this->filename]);
|
||||
$this->phar->setSignatureAlgorithm(\Phar::SHA1);
|
||||
$this->phar->startBuffering();
|
||||
|
||||
$this->printTaskInfo('Packing {file-count} files into phar', ['file-count' => count($this->files)]);
|
||||
|
||||
$this->startProgressIndicator();
|
||||
foreach ($this->files as $path => $content) {
|
||||
$this->phar->addFromString($path, $content);
|
||||
$this->advanceProgressIndicator();
|
||||
}
|
||||
$this->phar->stopBuffering();
|
||||
$this->advanceProgressIndicator();
|
||||
|
||||
if ($this->compress and in_array('GZ', \Phar::getSupportedCompression())) {
|
||||
if (count($this->files) > 1000) {
|
||||
$this->printTaskInfo('Too many files. Compression DISABLED');
|
||||
} else {
|
||||
$this->printTaskInfo('{filename} compressed', ['filename' => $this->filename]);
|
||||
$this->phar = $this->phar->compressFiles(\Phar::GZ);
|
||||
}
|
||||
}
|
||||
$this->advanceProgressIndicator();
|
||||
$this->stopProgressIndicator();
|
||||
$this->printTaskSuccess('{filename} produced', ['filename' => $this->filename]);
|
||||
return Result::success($this, '', ['time' => $this->getExecutionTime()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param string $file
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addStripped($path, $file)
|
||||
{
|
||||
$this->files[$path] = $this->stripWhitespace(file_get_contents($file));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param string $file
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addFile($path, $file)
|
||||
{
|
||||
$this->files[$path] = file_get_contents($file);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Symfony\Component\Finder\SplFileInfo[] $files
|
||||
*/
|
||||
public function addFiles($files)
|
||||
{
|
||||
foreach ($files as $file) {
|
||||
$this->addFile($file->getRelativePathname(), $file->getRealPath());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function executable($file)
|
||||
{
|
||||
$source = file_get_contents($file);
|
||||
if (strpos($source, '#!/usr/bin/env php') === 0) {
|
||||
$source = substr($source, strpos($source, '<?php') + 5);
|
||||
}
|
||||
$this->phar->setStub(sprintf($this->stubTemplate, $source));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips whitespace from source. Taken from composer
|
||||
*
|
||||
* @param string $source
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function stripWhitespace($source)
|
||||
{
|
||||
if (!function_exists('token_get_all')) {
|
||||
return $source;
|
||||
}
|
||||
|
||||
$output = '';
|
||||
foreach (token_get_all($source) as $token) {
|
||||
if (is_string($token)) {
|
||||
$output .= $token;
|
||||
} elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) {
|
||||
if (substr($token[1], 0, 2) === '#[') {
|
||||
// Don't strip annotations
|
||||
$output .= $token[1];
|
||||
} else {
|
||||
$output .= str_repeat("\n", substr_count($token[1], "\n"));
|
||||
}
|
||||
} elseif (T_WHITESPACE === $token[0]) {
|
||||
// reduce wide spaces
|
||||
$whitespace = preg_replace('{[ \t]+}', ' ', $token[1]);
|
||||
// normalize newlines to \n
|
||||
$whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace);
|
||||
// trim leading spaces
|
||||
$whitespace = preg_replace('{\n +}', "\n", $whitespace);
|
||||
$output .= $whitespace;
|
||||
} else {
|
||||
$output .= $token[1];
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
87
vendor/consolidation/robo/src/Task/Development/PhpServer.php
vendored
Normal file
87
vendor/consolidation/robo/src/Task/Development/PhpServer.php
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Development;
|
||||
|
||||
use Robo\Task\Base\Exec;
|
||||
|
||||
/**
|
||||
* Runs PHP server and stops it when task finishes.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // run server in /public directory
|
||||
* $this->taskServer(8000)
|
||||
* ->dir('public')
|
||||
* ->run();
|
||||
*
|
||||
* // run with IP 0.0.0.0
|
||||
* $this->taskServer(8000)
|
||||
* ->host('0.0.0.0')
|
||||
* ->run();
|
||||
*
|
||||
* // execute server in background
|
||||
* $this->taskServer(8000)
|
||||
* ->background()
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class PhpServer extends Exec
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $port;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $host = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $command = 'php -S %s:%d ';
|
||||
|
||||
/**
|
||||
* @param int $port
|
||||
*/
|
||||
public function __construct($port)
|
||||
{
|
||||
$this->port = $port;
|
||||
|
||||
if (strtolower(PHP_OS) === 'linux') {
|
||||
$this->command = 'exec php -S %s:%d ';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $host
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function host($host)
|
||||
{
|
||||
$this->host = $host;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function dir($path)
|
||||
{
|
||||
$this->command .= "-t $path";
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return sprintf($this->command . $this->arguments, $this->host, $this->port);
|
||||
}
|
||||
}
|
||||
276
vendor/consolidation/robo/src/Task/Development/SemVer.php
vendored
Normal file
276
vendor/consolidation/robo/src/Task/Development/SemVer.php
vendored
Normal file
@ -0,0 +1,276 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Development;
|
||||
|
||||
use Robo\Result;
|
||||
use Robo\Contract\TaskInterface;
|
||||
use Robo\Exception\TaskException;
|
||||
|
||||
/**
|
||||
* Helps to maintain `.semver` file.
|
||||
*
|
||||
* ```php
|
||||
* <?php
|
||||
* $this->taskSemVer('.semver')
|
||||
* ->increment()
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
class SemVer implements TaskInterface
|
||||
{
|
||||
const SEMVER = "---\n:major: %d\n:minor: %d\n:patch: %d\n:special: '%s'\n:metadata: '%s'";
|
||||
|
||||
const REGEX = "/^\-\-\-\r?\n:major:\s(0|[1-9]\d*)\r?\n:minor:\s(0|[1-9]\d*)\r?\n:patch:\s(0|[1-9]\d*)\r?\n:special:\s'([a-zA-z0-9]*\.?(?:0|[1-9]\d*)?)'\r?\n:metadata:\s'((?:0|[1-9]\d*)?(?:\.[a-zA-z0-9\.]*)?)'/";
|
||||
|
||||
const REGEX_STRING = '/^(?<major>[0-9]+)\.(?<minor>[0-9]+)\.(?<patch>[0-9]+)(|-(?<special>[0-9a-zA-Z.]+))(|\+(?<metadata>[0-9a-zA-Z.]+))$/';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $format = 'v%M.%m.%p%s';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $specialSeparator = '-';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $metadataSeparator = '+';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $version = [
|
||||
'major' => 0,
|
||||
'minor' => 0,
|
||||
'patch' => 0,
|
||||
'special' => '',
|
||||
'metadata' => ''
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
*/
|
||||
public function __construct($filename = '')
|
||||
{
|
||||
$this->path = $filename;
|
||||
|
||||
if (file_exists($this->path)) {
|
||||
$semverFileContents = file_get_contents($this->path);
|
||||
$this->parseFile($semverFileContents);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$search = ['%M', '%m', '%p', '%s'];
|
||||
$replace = $this->version + ['extra' => ''];
|
||||
|
||||
foreach (['special', 'metadata'] as $key) {
|
||||
if (!empty($replace[$key])) {
|
||||
$separator = $key . 'Separator';
|
||||
$replace['extra'] .= $this->{$separator} . $replace[$key];
|
||||
}
|
||||
unset($replace[$key]);
|
||||
}
|
||||
|
||||
return str_replace($search, $replace, $this->format);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $version
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function version($version)
|
||||
{
|
||||
$this->parseString($version);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $format
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFormat($format)
|
||||
{
|
||||
$this->format = $format;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $separator
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setMetadataSeparator($separator)
|
||||
{
|
||||
$this->metadataSeparator = $separator;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $separator
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPrereleaseSeparator($separator)
|
||||
{
|
||||
$this->specialSeparator = $separator;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $what
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
public function increment($what = 'patch')
|
||||
{
|
||||
switch ($what) {
|
||||
case 'major':
|
||||
$this->version['major']++;
|
||||
$this->version['minor'] = 0;
|
||||
$this->version['patch'] = 0;
|
||||
break;
|
||||
case 'minor':
|
||||
$this->version['minor']++;
|
||||
$this->version['patch'] = 0;
|
||||
break;
|
||||
case 'patch':
|
||||
$this->version['patch']++;
|
||||
break;
|
||||
default:
|
||||
throw new TaskException(
|
||||
$this,
|
||||
'Bad argument, only one of the following is allowed: major, minor, patch'
|
||||
);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tag
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
public function prerelease($tag = 'RC')
|
||||
{
|
||||
if (!is_string($tag)) {
|
||||
throw new TaskException($this, 'Bad argument, only strings allowed.');
|
||||
}
|
||||
|
||||
$number = 0;
|
||||
|
||||
if (!empty($this->version['special'])) {
|
||||
list($current, $number) = explode('.', $this->version['special']);
|
||||
if ($tag != $current) {
|
||||
$number = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$number++;
|
||||
|
||||
$this->version['special'] = implode('.', [$tag, $number]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $data
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function metadata($data)
|
||||
{
|
||||
if (is_array($data)) {
|
||||
$data = implode('.', $data);
|
||||
}
|
||||
|
||||
$this->version['metadata'] = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$written = $this->dump();
|
||||
return new Result($this, (int)($written === false), $this->__toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
protected function dump()
|
||||
{
|
||||
if (empty($this->path)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$semver = sprintf(
|
||||
self::SEMVER,
|
||||
$this->version['major'],
|
||||
$this->version['minor'],
|
||||
$this->version['patch'],
|
||||
$this->version['special'],
|
||||
$this->version['metadata']
|
||||
);
|
||||
|
||||
if (file_put_contents($this->path, $semver) === false) {
|
||||
throw new TaskException($this, 'Failed to write semver file.');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $semverString
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
protected function parseString($semverString)
|
||||
{
|
||||
if (!preg_match_all(self::REGEX_STRING, $semverString, $matches)) {
|
||||
throw new TaskException($this, 'Bad semver value: ' . $semverString);
|
||||
}
|
||||
|
||||
$this->version = array_intersect_key($matches, $this->version);
|
||||
$this->version = array_map(function ($item) {
|
||||
return $item[0];
|
||||
}, $this->version);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $semverFileContents
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
protected function parseFile($semverFileContents)
|
||||
{
|
||||
if (!preg_match_all(self::REGEX, $semverFileContents, $matches)) {
|
||||
throw new TaskException($this, 'Bad semver file.');
|
||||
}
|
||||
|
||||
list(, $major, $minor, $patch, $special, $metadata) = array_map('current', $matches);
|
||||
$this->version = compact('major', 'minor', 'patch', 'special', 'metadata');
|
||||
}
|
||||
}
|
||||
87
vendor/consolidation/robo/src/Task/Development/Tasks.php
vendored
Normal file
87
vendor/consolidation/robo/src/Task/Development/Tasks.php
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Development;
|
||||
|
||||
trait Tasks
|
||||
{
|
||||
/**
|
||||
* @param string $filename
|
||||
*
|
||||
* @return \Robo\Task\Development\Changelog|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskChangelog($filename = 'CHANGELOG.md')
|
||||
{
|
||||
return $this->task(Changelog::class, $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
*
|
||||
* @return \Robo\Task\Development\GenerateMarkdownDoc|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskGenDoc($filename)
|
||||
{
|
||||
return $this->task(GenerateMarkdownDoc::class, $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @param string $wrapperClassName
|
||||
*
|
||||
* @return \Robo\Task\Development\GenerateTask|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskGenTask($className, $wrapperClassName = '')
|
||||
{
|
||||
return $this->task(GenerateTask::class, $className, $wrapperClassName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pathToSemVer
|
||||
*
|
||||
* @return \Robo\Task\Development\SemVer|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskSemVer($pathToSemVer = '.semver')
|
||||
{
|
||||
return $this->task(SemVer::class, $pathToSemVer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $port
|
||||
*
|
||||
* @return \Robo\Task\Development\PhpServer|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskServer($port = 8000)
|
||||
{
|
||||
return $this->task(PhpServer::class, $port);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
*
|
||||
* @return \Robo\Task\Development\PackPhar|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskPackPhar($filename)
|
||||
{
|
||||
return $this->task(PackPhar::class, $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tag
|
||||
*
|
||||
* @return \Robo\Task\Development\GitHubRelease|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskGitHubRelease($tag)
|
||||
{
|
||||
return $this->task(GitHubRelease::class, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $url
|
||||
*
|
||||
* @return \Robo\Task\Development\OpenBrowser|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskOpenBrowser($url)
|
||||
{
|
||||
return $this->task(OpenBrowser::class, $url);
|
||||
}
|
||||
}
|
||||
29
vendor/consolidation/robo/src/Task/Docker/Base.php
vendored
Normal file
29
vendor/consolidation/robo/src/Task/Docker/Base.php
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Docker;
|
||||
|
||||
use Robo\Common\ExecOneCommand;
|
||||
use Robo\Contract\CommandInterface;
|
||||
use Robo\Contract\PrintedInterface;
|
||||
use Robo\Task\BaseTask;
|
||||
|
||||
abstract class Base extends BaseTask implements CommandInterface, PrintedInterface
|
||||
{
|
||||
use ExecOneCommand;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $command = '';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$command = $this->getCommand();
|
||||
return $this->executeCommand($command);
|
||||
}
|
||||
|
||||
abstract public function getCommand();
|
||||
}
|
||||
74
vendor/consolidation/robo/src/Task/Docker/Build.php
vendored
Normal file
74
vendor/consolidation/robo/src/Task/Docker/Build.php
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Docker;
|
||||
|
||||
/**
|
||||
* Builds Docker image
|
||||
*
|
||||
* ```php
|
||||
* <?php
|
||||
* $this->taskDockerBuild()->run();
|
||||
*
|
||||
* $this->taskDockerBuild('path/to/dir')
|
||||
* ->tag('database')
|
||||
* ->run();
|
||||
*
|
||||
* ?>
|
||||
*
|
||||
* ```
|
||||
*
|
||||
* Class Build
|
||||
* @package Robo\Task\Docker
|
||||
*/
|
||||
class Build extends Base
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $buildKit = false;
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
*/
|
||||
public function __construct($path = '.')
|
||||
{
|
||||
$this->command = "docker build";
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
$command = $this->command;
|
||||
if ($this->buildKit) {
|
||||
$command = 'DOCKER_BUILDKIT=1 ' . $command;
|
||||
}
|
||||
return $command . ' ' . $this->arguments . ' ' . $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tag
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function tag($tag)
|
||||
{
|
||||
return $this->option('-t', $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function enableBuildKit()
|
||||
{
|
||||
$this->buildKit = true;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
67
vendor/consolidation/robo/src/Task/Docker/Commit.php
vendored
Normal file
67
vendor/consolidation/robo/src/Task/Docker/Commit.php
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Docker;
|
||||
|
||||
/**
|
||||
* Commits docker container to an image
|
||||
*
|
||||
* ```
|
||||
* $this->taskDockerCommit($containerId)
|
||||
* ->name('my/database')
|
||||
* ->run();
|
||||
*
|
||||
* // alternatively you can take the result from DockerRun task:
|
||||
*
|
||||
* $result = $this->taskDockerRun('db')
|
||||
* ->exec('./prepare_database.sh')
|
||||
* ->run();
|
||||
*
|
||||
* $task->dockerCommit($result)
|
||||
* ->name('my/database')
|
||||
* ->run();
|
||||
* ```
|
||||
*/
|
||||
class Commit extends Base
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $command = "docker commit";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $cid;
|
||||
|
||||
/**
|
||||
* @param string|\Robo\Task\Docker\Result $cidOrResult
|
||||
*/
|
||||
public function __construct($cidOrResult)
|
||||
{
|
||||
$this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return $this->command . ' ' . $this->cid . ' ' . $this->name . ' ' . $this->arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function name($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
96
vendor/consolidation/robo/src/Task/Docker/Exec.php
vendored
Normal file
96
vendor/consolidation/robo/src/Task/Docker/Exec.php
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Docker;
|
||||
|
||||
use Robo\Common\CommandReceiver;
|
||||
|
||||
/**
|
||||
* Executes command inside running Docker container
|
||||
*
|
||||
* ```php
|
||||
* <?php
|
||||
* $test = $this->taskDockerRun('test_env')
|
||||
* ->detached()
|
||||
* ->run();
|
||||
*
|
||||
* $this->taskDockerExec($test)
|
||||
* ->interactive()
|
||||
* ->exec('./runtests')
|
||||
* ->run();
|
||||
*
|
||||
* // alternatively use commands from other tasks
|
||||
*
|
||||
* $this->taskDockerExec($test)
|
||||
* ->interactive()
|
||||
* ->exec($this->taskCodecept()->suite('acceptance'))
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
class Exec extends Base
|
||||
{
|
||||
use CommandReceiver;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $command = "docker exec";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $cid;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $run = '';
|
||||
|
||||
/**
|
||||
* @param string|\Robo\Result $cidOrResult
|
||||
*/
|
||||
public function __construct($cidOrResult)
|
||||
{
|
||||
$this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function detached()
|
||||
{
|
||||
$this->option('-d');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function interactive($interactive = true)
|
||||
{
|
||||
if ($interactive) {
|
||||
$this->option('-i');
|
||||
}
|
||||
return parent::interactive($interactive);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|\Robo\Contract\CommandInterface $command
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function exec($command)
|
||||
{
|
||||
$this->run = $this->receiveCommand($command);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return $this->command . ' ' . $this->arguments . ' ' . $this->cid . ' ' . $this->run;
|
||||
}
|
||||
}
|
||||
34
vendor/consolidation/robo/src/Task/Docker/Pull.php
vendored
Normal file
34
vendor/consolidation/robo/src/Task/Docker/Pull.php
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Docker;
|
||||
|
||||
/**
|
||||
* Pulls an image from DockerHub
|
||||
*
|
||||
* ```php
|
||||
* <?php
|
||||
* $this->taskDockerPull('wordpress')
|
||||
* ->run();
|
||||
*
|
||||
* ?>
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
class Pull extends Base
|
||||
{
|
||||
/**
|
||||
* @param string $image
|
||||
*/
|
||||
public function __construct($image)
|
||||
{
|
||||
$this->command = "docker pull $image ";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return $this->command . ' ' . $this->arguments;
|
||||
}
|
||||
}
|
||||
33
vendor/consolidation/robo/src/Task/Docker/Remove.php
vendored
Normal file
33
vendor/consolidation/robo/src/Task/Docker/Remove.php
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Docker;
|
||||
|
||||
/**
|
||||
* Remove docker container
|
||||
*
|
||||
* ```php
|
||||
* <?php
|
||||
* $this->taskDockerRemove($container)
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
class Remove extends Base
|
||||
{
|
||||
/**
|
||||
* @param string $container
|
||||
*/
|
||||
public function __construct($container)
|
||||
{
|
||||
$this->command = "docker rm $container ";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return $this->command . ' ' . $this->arguments;
|
||||
}
|
||||
}
|
||||
36
vendor/consolidation/robo/src/Task/Docker/Result.php
vendored
Normal file
36
vendor/consolidation/robo/src/Task/Docker/Result.php
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Docker;
|
||||
|
||||
class Result extends \Robo\Result
|
||||
{
|
||||
|
||||
/**
|
||||
* Do not print result, as it was already printed
|
||||
*/
|
||||
protected function printResult()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function getCid()
|
||||
{
|
||||
if (isset($this['cid'])) {
|
||||
return $this['cid'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function getContainerName()
|
||||
{
|
||||
if (isset($this['name'])) {
|
||||
return $this['name'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
303
vendor/consolidation/robo/src/Task/Docker/Run.php
vendored
Normal file
303
vendor/consolidation/robo/src/Task/Docker/Run.php
vendored
Normal file
@ -0,0 +1,303 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Docker;
|
||||
|
||||
use Robo\Common\CommandReceiver;
|
||||
|
||||
/**
|
||||
* Performs `docker run` on a container.
|
||||
*
|
||||
* ```php
|
||||
* <?php
|
||||
* $this->taskDockerRun('mysql')->run();
|
||||
*
|
||||
* $result = $this->taskDockerRun('my_db_image')
|
||||
* ->env('DB', 'database_name')
|
||||
* ->volume('/path/to/data', '/data')
|
||||
* ->detached()
|
||||
* ->publish(3306)
|
||||
* ->name('my_mysql')
|
||||
* ->run();
|
||||
*
|
||||
* // retrieve container's cid:
|
||||
* $this->say("Running container ".$result->getCid());
|
||||
*
|
||||
* // execute script inside container
|
||||
* $result = $this->taskDockerRun('db')
|
||||
* ->exec('prepare_test_data.sh')
|
||||
* ->run();
|
||||
*
|
||||
* $this->taskDockerCommit($result)
|
||||
* ->name('test_db')
|
||||
* ->run();
|
||||
*
|
||||
* // link containers
|
||||
* $mysql = $this->taskDockerRun('mysql')
|
||||
* ->name('wp_db') // important to set name for linked container
|
||||
* ->env('MYSQL_ROOT_PASSWORD', '123456')
|
||||
* ->run();
|
||||
*
|
||||
* $this->taskDockerRun('wordpress')
|
||||
* ->link($mysql)
|
||||
* ->publish(80, 8080)
|
||||
* ->detached()
|
||||
* ->run();
|
||||
*
|
||||
* ?>
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
class Run extends Base
|
||||
{
|
||||
use CommandReceiver;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $image = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $run = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $cidFile;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $dir;
|
||||
|
||||
/**
|
||||
* @param string $image
|
||||
*/
|
||||
public function __construct($image)
|
||||
{
|
||||
$this->image = $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPrinted()
|
||||
{
|
||||
return $this->isPrinted;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
if ($this->isPrinted) {
|
||||
$this->option('-i');
|
||||
}
|
||||
if ($this->cidFile) {
|
||||
$this->option('cidfile', $this->cidFile);
|
||||
}
|
||||
return trim('docker run ' . $this->arguments . ' ' . $this->image . ' ' . $this->run);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function detached()
|
||||
{
|
||||
$this->option('-d');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function interactive($interactive = true)
|
||||
{
|
||||
if ($interactive) {
|
||||
$this->option('-i');
|
||||
}
|
||||
return parent::interactive($interactive);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|\Robo\Contract\CommandInterface $run
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function exec($run)
|
||||
{
|
||||
$this->run = $this->receiveCommand($run);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param null|string $to
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function volume($from, $to = null)
|
||||
{
|
||||
$volume = $to ? "$from:$to" : $from;
|
||||
$this->option('-v', $volume);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set environment variables.
|
||||
* n.b. $this->env($variable, $value) also available here,
|
||||
* inherited from ExecTrait.
|
||||
*
|
||||
* @param array $env
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function envVars(array $env)
|
||||
{
|
||||
foreach ($env as $variable => $value) {
|
||||
$this->setDockerEnv($variable, $value);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $variable
|
||||
* @param null|string $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function setDockerEnv($variable, $value = null)
|
||||
{
|
||||
$env = $value ? "$variable=$value" : $variable;
|
||||
return $this->option("-e", $env);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|int $port
|
||||
* @param null|int $portTo
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function publish($port = null, $portTo = null)
|
||||
{
|
||||
if (!$port) {
|
||||
return $this->option('-P');
|
||||
}
|
||||
if ($portTo) {
|
||||
$port = "$port:$portTo";
|
||||
}
|
||||
return $this->option('-p', $port);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dir
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function containerWorkdir($dir)
|
||||
{
|
||||
return $this->option('-w', $dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $user
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function user($user)
|
||||
{
|
||||
return $this->option('-u', $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function privileged()
|
||||
{
|
||||
return $this->option('--privileged');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function name($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this->option('name', $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|\Robo\Task\Docker\Result $name
|
||||
* @param string $alias
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function link($name, $alias)
|
||||
{
|
||||
if ($name instanceof Result) {
|
||||
$name = $name->getContainerName();
|
||||
}
|
||||
$this->option('link', "$name:$alias");
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dir
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function tmpDir($dir)
|
||||
{
|
||||
$this->dir = $dir;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTmpDir()
|
||||
{
|
||||
return $this->dir ? $this->dir : sys_get_temp_dir();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUniqId()
|
||||
{
|
||||
return uniqid();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->cidFile = $this->getTmpDir() . '/docker_' . $this->getUniqId() . '.cid';
|
||||
$result = parent::run();
|
||||
$result['cid'] = $this->getCid();
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
protected function getCid()
|
||||
{
|
||||
if (!$this->cidFile || !file_exists($this->cidFile)) {
|
||||
return null;
|
||||
}
|
||||
$cid = trim(file_get_contents($this->cidFile));
|
||||
@unlink($this->cidFile);
|
||||
return $cid;
|
||||
}
|
||||
}
|
||||
42
vendor/consolidation/robo/src/Task/Docker/Start.php
vendored
Normal file
42
vendor/consolidation/robo/src/Task/Docker/Start.php
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Docker;
|
||||
|
||||
/**
|
||||
* Starts Docker container
|
||||
*
|
||||
* ```php
|
||||
* <?php
|
||||
* $this->taskDockerStart($cidOrResult)
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Start extends Base
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $command = "docker start";
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
protected $cid;
|
||||
|
||||
/**
|
||||
* @param string|\Robo\Task\Docker\Result $cidOrResult
|
||||
*/
|
||||
public function __construct($cidOrResult)
|
||||
{
|
||||
$this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return $this->command . ' ' . $this->arguments . ' ' . $this->cid;
|
||||
}
|
||||
}
|
||||
42
vendor/consolidation/robo/src/Task/Docker/Stop.php
vendored
Normal file
42
vendor/consolidation/robo/src/Task/Docker/Stop.php
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Docker;
|
||||
|
||||
/**
|
||||
* Stops Docker container
|
||||
*
|
||||
* ```php
|
||||
* <?php
|
||||
* $this->taskDockerStop($cidOrResult)
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Stop extends Base
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $command = "docker stop";
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
protected $cid;
|
||||
|
||||
/**
|
||||
* @param string|\Robo\Task\Docker\Result $cidOrResult
|
||||
*/
|
||||
public function __construct($cidOrResult)
|
||||
{
|
||||
$this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return $this->command . ' ' . $this->arguments . ' ' . $this->cid;
|
||||
}
|
||||
}
|
||||
86
vendor/consolidation/robo/src/Task/Docker/Tasks.php
vendored
Normal file
86
vendor/consolidation/robo/src/Task/Docker/Tasks.php
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Docker;
|
||||
|
||||
trait Tasks
|
||||
{
|
||||
/**
|
||||
* @param string $image
|
||||
*
|
||||
* @return \Robo\Task\Docker\Run|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskDockerRun($image)
|
||||
{
|
||||
return $this->task(Run::class, $image);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $image
|
||||
*
|
||||
* @return \Robo\Task\Docker\Pull|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskDockerPull($image)
|
||||
{
|
||||
return $this->task(Pull::class, $image);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
*
|
||||
* @return \Robo\Task\Docker\Build|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskDockerBuild($path = '.')
|
||||
{
|
||||
return $this->task(Build::class, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|\Robo\Task\Docker\Result $cidOrResult
|
||||
*
|
||||
* @return \Robo\Task\Docker\Stop|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskDockerStop($cidOrResult)
|
||||
{
|
||||
return $this->task(Stop::class, $cidOrResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|\Robo\Task\Docker\Result $cidOrResult
|
||||
*
|
||||
* @return \Robo\Task\Docker\Commit|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskDockerCommit($cidOrResult)
|
||||
{
|
||||
return $this->task(Commit::class, $cidOrResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|\Robo\Task\Docker\Result $cidOrResult
|
||||
*
|
||||
* @return \Robo\Task\Docker\Start|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskDockerStart($cidOrResult)
|
||||
{
|
||||
return $this->task(Start::class, $cidOrResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|\Robo\Task\Docker\Result $cidOrResult
|
||||
*
|
||||
* @return \Robo\Task\Docker\Remove|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskDockerRemove($cidOrResult)
|
||||
{
|
||||
return $this->task(Remove::class, $cidOrResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|\Robo\Task\Docker\Result $cidOrResult
|
||||
*
|
||||
* @return \Robo\Task\Docker\Exec|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskDockerExec($cidOrResult)
|
||||
{
|
||||
return $this->task(Exec::class, $cidOrResult);
|
||||
}
|
||||
}
|
||||
102
vendor/consolidation/robo/src/Task/File/Concat.php
vendored
Normal file
102
vendor/consolidation/robo/src/Task/File/Concat.php
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\File;
|
||||
|
||||
use Iterator;
|
||||
use Robo\Common\ResourceExistenceChecker;
|
||||
use Robo\Result;
|
||||
use Robo\Task\BaseTask;
|
||||
|
||||
/**
|
||||
* Merges files into one. Used for preparing assets.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskConcat([
|
||||
* 'web/assets/screen.css',
|
||||
* 'web/assets/print.css',
|
||||
* 'web/assets/theme.css'
|
||||
* ])
|
||||
* ->to('web/assets/style.css')
|
||||
* ->run()
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Concat extends BaseTask
|
||||
{
|
||||
use ResourceExistenceChecker;
|
||||
|
||||
/**
|
||||
* @var array|\Iterator
|
||||
*/
|
||||
protected $files;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $dst;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array|\Iterator $files
|
||||
*/
|
||||
public function __construct($files)
|
||||
{
|
||||
$this->files = $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the destination file
|
||||
*
|
||||
* @param string $dst
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function to($dst)
|
||||
{
|
||||
$this->dst = $dst;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if (is_null($this->dst) || "" === $this->dst) {
|
||||
return Result::error($this, 'You must specify a destination file with to() method.');
|
||||
}
|
||||
|
||||
if (!$this->checkResources($this->files, 'file')) {
|
||||
return Result::error($this, 'Source files are missing!');
|
||||
}
|
||||
|
||||
if (file_exists($this->dst) && !is_writable($this->dst)) {
|
||||
return Result::error($this, 'Destination already exists and cannot be overwritten.');
|
||||
}
|
||||
|
||||
$dump = '';
|
||||
|
||||
foreach ($this->files as $path) {
|
||||
foreach (glob($path) as $file) {
|
||||
$dump .= file_get_contents($file) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$this->printTaskInfo('Writing {destination}', ['destination' => $this->dst]);
|
||||
|
||||
$dst = $this->dst . '.part';
|
||||
$write_result = file_put_contents($dst, $dump);
|
||||
|
||||
if (false === $write_result) {
|
||||
@unlink($dst);
|
||||
return Result::error($this, 'File write failed.');
|
||||
}
|
||||
// Cannot be cross-volume; should always succeed.
|
||||
@rename($dst, $this->dst);
|
||||
|
||||
return Result::success($this);
|
||||
}
|
||||
}
|
||||
159
vendor/consolidation/robo/src/Task/File/Replace.php
vendored
Normal file
159
vendor/consolidation/robo/src/Task/File/Replace.php
vendored
Normal file
@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\File;
|
||||
|
||||
use Robo\Result;
|
||||
use Robo\Task\BaseTask;
|
||||
|
||||
/**
|
||||
* Performs search and replace inside a files.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskReplaceInFile('VERSION')
|
||||
* ->from('0.2.0')
|
||||
* ->to('0.3.0')
|
||||
* ->run();
|
||||
*
|
||||
* $this->taskReplaceInFile('README.md')
|
||||
* ->from(date('Y')-1)
|
||||
* ->to(date('Y'))
|
||||
* ->run();
|
||||
*
|
||||
* $this->taskReplaceInFile('config.yml')
|
||||
* ->regex('~^service:~')
|
||||
* ->to('services:')
|
||||
* ->run();
|
||||
*
|
||||
* $this->taskReplaceInFile('box/robo.txt')
|
||||
* ->from(array('##dbname##', '##dbhost##'))
|
||||
* ->to(array('robo', 'localhost'))
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Replace extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $filename;
|
||||
|
||||
/**
|
||||
* @var string|string[]
|
||||
*/
|
||||
protected $from;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
protected $limit = -1;
|
||||
|
||||
/**
|
||||
* @var string|string[]
|
||||
*/
|
||||
protected $to;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $regex;
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
*/
|
||||
public function __construct($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function filename($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* String(s) to be replaced.
|
||||
*
|
||||
* @param string|string[] $from
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function from($from)
|
||||
{
|
||||
$this->from = $from;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Value(s) to be set as a replacement.
|
||||
*
|
||||
* @param string|string[] $to
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function to($to)
|
||||
{
|
||||
$this->to = $to;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Regex to match string to be replaced.
|
||||
*
|
||||
* @param string $regex
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function regex($regex)
|
||||
{
|
||||
$this->regex = $regex;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If used with $this->regexp() how many counts will be replaced
|
||||
*
|
||||
* @param int $limit
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function limit($limit)
|
||||
{
|
||||
$this->limit = $limit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if (!file_exists($this->filename)) {
|
||||
return Result::error($this, 'File {filename} does not exist', ['filename' => $this->filename]);
|
||||
}
|
||||
|
||||
$text = file_get_contents($this->filename);
|
||||
if ($this->regex) {
|
||||
$text = preg_replace($this->regex, $this->to, $text, $this->limit, $count);
|
||||
} else {
|
||||
$text = str_replace($this->from, $this->to, $text, $count);
|
||||
}
|
||||
if ($count > 0) {
|
||||
$res = file_put_contents($this->filename, $text);
|
||||
if ($res === false) {
|
||||
return Result::error($this, "Error writing to file {filename}.", ['filename' => $this->filename]);
|
||||
}
|
||||
$this->printTaskSuccess("{filename} updated. {count} items replaced", ['filename' => $this->filename, 'count' => $count]);
|
||||
} else {
|
||||
$this->printTaskInfo("{filename} unchanged. {count} items replaced", ['filename' => $this->filename, 'count' => $count]);
|
||||
}
|
||||
return Result::success($this, '', ['replaced' => $count]);
|
||||
}
|
||||
}
|
||||
49
vendor/consolidation/robo/src/Task/File/Tasks.php
vendored
Normal file
49
vendor/consolidation/robo/src/Task/File/Tasks.php
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\File;
|
||||
|
||||
trait Tasks
|
||||
{
|
||||
/**
|
||||
* @param array|\Iterator $files
|
||||
*
|
||||
* @return \Robo\Task\File\Concat|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskConcat($files)
|
||||
{
|
||||
return $this->task(Concat::class, $files);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return \Robo\Task\File\Replace|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskReplaceInFile($file)
|
||||
{
|
||||
return $this->task(Replace::class, $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return \Robo\Task\File\Write|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskWriteToFile($file)
|
||||
{
|
||||
return $this->task(Write::class, $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @param string $extension
|
||||
* @param string $baseDir
|
||||
* @param bool $includeRandomPart
|
||||
*
|
||||
* @return \Robo\Task\File\TmpFile|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskTmpFile($filename = 'tmp', $extension = '', $baseDir = '', $includeRandomPart = true)
|
||||
{
|
||||
return $this->task(TmpFile::class, $filename, $extension, $baseDir, $includeRandomPart);
|
||||
}
|
||||
}
|
||||
72
vendor/consolidation/robo/src/Task/File/TmpFile.php
vendored
Normal file
72
vendor/consolidation/robo/src/Task/File/TmpFile.php
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\File;
|
||||
|
||||
use Robo\Contract\CompletionInterface;
|
||||
|
||||
/**
|
||||
* Create a temporary file that is automatically cleaned up
|
||||
* once the task collection is is part of completes. When created,
|
||||
* it is given a random filename.
|
||||
*
|
||||
* This temporary file may be manipulated exacatly like taskWrite().
|
||||
* It is deleted as soon as the collection it is a part of completes
|
||||
* or rolls back.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $collection = $this->collectionBuilder();
|
||||
* $tmpFilePath = $collection->taskTmpFile()
|
||||
* ->line('-----')
|
||||
* ->line(date('Y-m-d').' '.$title)
|
||||
* ->line('----')
|
||||
* ->getPath();
|
||||
* $collection->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class TmpFile extends Write implements CompletionInterface
|
||||
{
|
||||
/**
|
||||
* @param string $filename
|
||||
* @param string $extension
|
||||
* @param string $baseDir
|
||||
* @param bool $includeRandomPart
|
||||
*/
|
||||
public function __construct($filename = 'tmp', $extension = '', $baseDir = '', $includeRandomPart = true)
|
||||
{
|
||||
if (empty($baseDir)) {
|
||||
$baseDir = sys_get_temp_dir();
|
||||
}
|
||||
if ($includeRandomPart) {
|
||||
$random = static::randomString();
|
||||
$filename = "{$filename}_{$random}";
|
||||
}
|
||||
$filename .= $extension;
|
||||
parent::__construct("{$baseDir}/{$filename}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a suitably random string to use as the suffix for our
|
||||
* temporary file.
|
||||
*
|
||||
* @param int $length
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function randomString($length = 12)
|
||||
{
|
||||
return substr(str_shuffle('23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'), 0, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete this file when our collection completes.
|
||||
* If this temporary file is not part of a collection,
|
||||
* then it will be deleted when the program terminates,
|
||||
* presuming that it was created by taskTmpFile() or _tmpFile().
|
||||
*/
|
||||
public function complete()
|
||||
{
|
||||
unlink($this->getPath());
|
||||
}
|
||||
}
|
||||
342
vendor/consolidation/robo/src/Task/File/Write.php
vendored
Normal file
342
vendor/consolidation/robo/src/Task/File/Write.php
vendored
Normal file
@ -0,0 +1,342 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\File;
|
||||
|
||||
use Robo\Result;
|
||||
use Robo\Task\BaseTask;
|
||||
|
||||
/**
|
||||
* Writes to file.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskWriteToFile('blogpost.md')
|
||||
* ->line('-----')
|
||||
* ->line(date('Y-m-d').' '.$title)
|
||||
* ->line('----')
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Write extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $stack = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $filename;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $append = false;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
protected $originalContents = null;
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
*/
|
||||
public function __construct($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function filename($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $append
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function append($append = true)
|
||||
{
|
||||
$this->append = $append;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* add a line.
|
||||
*
|
||||
* @param string $line
|
||||
*
|
||||
* @return $this
|
||||
* The current instance.
|
||||
*/
|
||||
public function line($line)
|
||||
{
|
||||
$this->text($line . "\n");
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* add more lines.
|
||||
*
|
||||
* @param array $lines
|
||||
*
|
||||
* @return $this
|
||||
* The current instance.
|
||||
*/
|
||||
public function lines(array $lines)
|
||||
{
|
||||
$this->text(implode("\n", $lines) . "\n");
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* add a text.
|
||||
*
|
||||
* @param string $text
|
||||
*
|
||||
* @return $this
|
||||
* The current instance.
|
||||
*/
|
||||
public function text($text)
|
||||
{
|
||||
$this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* add a text from a file.
|
||||
*
|
||||
* Note that the file is read in the run() method of this task.
|
||||
* To load text from the current state of a file (e.g. one that may
|
||||
* be deleted or altered by other tasks prior the execution of this one),
|
||||
* use:
|
||||
* $task->text(file_get_contents($filename));
|
||||
*
|
||||
* @param string $filename
|
||||
*
|
||||
* @return $this
|
||||
* The current instance.
|
||||
*/
|
||||
public function textFromFile($filename)
|
||||
{
|
||||
$this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* substitute a placeholder with value, placeholder must be enclosed by `{}`.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $val
|
||||
*
|
||||
* @return $this
|
||||
* The current instance.
|
||||
*/
|
||||
public function place($name, $val)
|
||||
{
|
||||
$this->replace('{' . $name . '}', $val);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* replace any string with value.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $replacement
|
||||
*
|
||||
* @return $this
|
||||
* The current instance.
|
||||
*/
|
||||
public function replace($string, $replacement)
|
||||
{
|
||||
$this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* replace any string with value using regular expression.
|
||||
*
|
||||
* @param string $pattern
|
||||
* @param string $replacement
|
||||
*
|
||||
* @return $this
|
||||
* The current instance.
|
||||
*/
|
||||
public function regexReplace($pattern, $replacement)
|
||||
{
|
||||
$this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the provided text to the end of the buffer if the provided
|
||||
* regex pattern matches any text already in the buffer.
|
||||
*
|
||||
* @param string $pattern
|
||||
* @param string $text
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function appendIfMatches($pattern, $text)
|
||||
{
|
||||
$this->stack[] = array_merge(['appendIfMatchesCollect'], [$pattern, $text, true]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the provided text to the end of the buffer unless the provided
|
||||
* regex pattern matches any text already in the buffer.
|
||||
*
|
||||
* @param string $pattern
|
||||
* @param string $text
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function appendUnlessMatches($pattern, $text)
|
||||
{
|
||||
$this->stack[] = array_merge(['appendIfMatchesCollect'], [$pattern, $text, false]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $contents
|
||||
* @param string $filename
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function textFromFileCollect($contents, $filename)
|
||||
{
|
||||
if (file_exists($filename)) {
|
||||
$contents .= file_get_contents($filename);
|
||||
}
|
||||
return $contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $contents
|
||||
* @param string|string[] $string
|
||||
* @param string|string[] $replacement
|
||||
*
|
||||
* @return string|string[]
|
||||
*/
|
||||
protected function replaceCollect($contents, $string, $replacement)
|
||||
{
|
||||
return str_replace($string, $replacement, $contents);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $contents
|
||||
* @param string|string[] $pattern
|
||||
* @param string|string[] $replacement
|
||||
*
|
||||
* @return string|string[]
|
||||
*/
|
||||
protected function regexReplaceCollect($contents, $pattern, $replacement)
|
||||
{
|
||||
return preg_replace($pattern, $replacement, $contents);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $contents
|
||||
* @param string $text
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function textCollect($contents, $text)
|
||||
{
|
||||
return $contents . $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $contents
|
||||
* @param string $pattern
|
||||
* @param string $text
|
||||
* @param bool $shouldMatch
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function appendIfMatchesCollect($contents, $pattern, $text, $shouldMatch)
|
||||
{
|
||||
if (preg_match($pattern, $contents) == $shouldMatch) {
|
||||
$contents .= $text;
|
||||
}
|
||||
return $contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function originalContents()
|
||||
{
|
||||
if (!isset($this->originalContents)) {
|
||||
$this->originalContents = '';
|
||||
if (file_exists($this->filename)) {
|
||||
$this->originalContents = file_get_contents($this->filename);
|
||||
}
|
||||
}
|
||||
return $this->originalContents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function wouldChange()
|
||||
{
|
||||
return $this->originalContents() != $this->getContentsToWrite();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getContentsToWrite()
|
||||
{
|
||||
$contents = "";
|
||||
if ($this->append) {
|
||||
$contents = $this->originalContents();
|
||||
}
|
||||
foreach ($this->stack as $action) {
|
||||
$command = array_shift($action);
|
||||
if (method_exists($this, $command)) {
|
||||
array_unshift($action, $contents);
|
||||
$contents = call_user_func_array([$this, $command], $action);
|
||||
}
|
||||
}
|
||||
return $contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->printTaskInfo("Writing to {filename}.", ['filename' => $this->filename]);
|
||||
$contents = $this->getContentsToWrite();
|
||||
if (!file_exists(dirname($this->filename))) {
|
||||
mkdir(dirname($this->filename), 0777, true);
|
||||
}
|
||||
$res = file_put_contents($this->filename, $contents);
|
||||
if ($res === false) {
|
||||
return Result::error($this, "File {$this->filename} couldn't be created");
|
||||
}
|
||||
|
||||
return Result::success($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->filename;
|
||||
}
|
||||
}
|
||||
31
vendor/consolidation/robo/src/Task/Filesystem/BaseDir.php
vendored
Normal file
31
vendor/consolidation/robo/src/Task/Filesystem/BaseDir.php
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Filesystem;
|
||||
|
||||
use Robo\Task\BaseTask;
|
||||
use Symfony\Component\Filesystem\Filesystem as sfFilesystem;
|
||||
|
||||
abstract class BaseDir extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $dirs = [];
|
||||
|
||||
/**
|
||||
* @var \Symfony\Component\Filesystem\Filesystem
|
||||
*/
|
||||
protected $fs;
|
||||
|
||||
/**
|
||||
* @param string|string[] $dirs
|
||||
*/
|
||||
public function __construct($dirs)
|
||||
{
|
||||
is_array($dirs)
|
||||
? $this->dirs = $dirs
|
||||
: $this->dirs[] = $dirs;
|
||||
|
||||
$this->fs = new sfFilesystem();
|
||||
}
|
||||
}
|
||||
64
vendor/consolidation/robo/src/Task/Filesystem/CleanDir.php
vendored
Normal file
64
vendor/consolidation/robo/src/Task/Filesystem/CleanDir.php
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Filesystem;
|
||||
|
||||
use Robo\Common\ResourceExistenceChecker;
|
||||
use Robo\Result;
|
||||
|
||||
/**
|
||||
* Deletes all files from specified dir, ignoring git files.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskCleanDir(['tmp','logs'])->run();
|
||||
* // as shortcut
|
||||
* $this->_cleanDir('app/cache');
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class CleanDir extends BaseDir
|
||||
{
|
||||
use ResourceExistenceChecker;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if (!$this->checkResources($this->dirs, 'dir')) {
|
||||
return Result::error($this, 'Source directories are missing!');
|
||||
}
|
||||
foreach ($this->dirs as $dir) {
|
||||
$this->emptyDir($dir);
|
||||
$this->printTaskInfo("Cleaned {dir}", ['dir' => $dir]);
|
||||
}
|
||||
return Result::success($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
*/
|
||||
protected function emptyDir($path)
|
||||
{
|
||||
$iterator = new \RecursiveIteratorIterator(
|
||||
new \RecursiveDirectoryIterator($path),
|
||||
\RecursiveIteratorIterator::CHILD_FIRST
|
||||
);
|
||||
|
||||
foreach ($iterator as $path) {
|
||||
if ($path->isDir()) {
|
||||
$dir = (string)$path;
|
||||
if (basename($dir) === '.' || basename($dir) === '..') {
|
||||
continue;
|
||||
}
|
||||
$this->fs->remove($dir);
|
||||
} else {
|
||||
$file = (string)$path;
|
||||
if (basename($file) === '.gitignore' || basename($file) === '.gitkeep') {
|
||||
continue;
|
||||
}
|
||||
$this->fs->remove($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
175
vendor/consolidation/robo/src/Task/Filesystem/CopyDir.php
vendored
Normal file
175
vendor/consolidation/robo/src/Task/Filesystem/CopyDir.php
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Filesystem;
|
||||
|
||||
use Robo\Common\ResourceExistenceChecker;
|
||||
use Robo\Result;
|
||||
use Robo\Exception\TaskException;
|
||||
|
||||
/**
|
||||
* Copies one dir into another
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskCopyDir(['dist/config' => 'config'])->run();
|
||||
* // as shortcut
|
||||
* $this->_copyDir('dist/config', 'config');
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class CopyDir extends BaseDir
|
||||
{
|
||||
use ResourceExistenceChecker;
|
||||
|
||||
/**
|
||||
* Explicitly declare our consturctor, so that
|
||||
* our copyDir() method does not look like a php4 constructor.
|
||||
*
|
||||
* @param string|string[] $dirs
|
||||
*/
|
||||
public function __construct($dirs)
|
||||
{
|
||||
parent::__construct($dirs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $chmod = 0755;
|
||||
|
||||
/**
|
||||
* Files to exclude on copying.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $exclude = [];
|
||||
|
||||
/**
|
||||
* Overwrite destination files newer than source files.
|
||||
*/
|
||||
protected $overwrite = true;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if (!$this->checkResources($this->dirs, 'dir')) {
|
||||
return Result::error($this, 'Source directories are missing!');
|
||||
}
|
||||
foreach ($this->dirs as $src => $dst) {
|
||||
$this->copyDir($src, $dst);
|
||||
$this->printTaskInfo('Copied from {source} to {destination}', ['source' => $src, 'destination' => $dst]);
|
||||
}
|
||||
return Result::success($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default folder permissions for the destination if it doesn't exist
|
||||
*
|
||||
* @link https://en.wikipedia.org/wiki/Chmod
|
||||
* @link https://php.net/manual/en/function.mkdir.php
|
||||
* @link https://php.net/manual/en/function.chmod.php
|
||||
*
|
||||
* @param int $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function dirPermissions($value)
|
||||
{
|
||||
$this->chmod = (int)$value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* List files to exclude.
|
||||
*
|
||||
* @param string[] $exclude
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function exclude($exclude = [])
|
||||
{
|
||||
$this->exclude = $this->simplifyForCompare($exclude);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destination files newer than source files are overwritten.
|
||||
*
|
||||
* @param bool $overwrite
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function overwrite($overwrite)
|
||||
{
|
||||
$this->overwrite = $overwrite;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a directory to another location.
|
||||
*
|
||||
* @param string $src Source directory
|
||||
* @param string $dst Destination directory
|
||||
* @param string $parent Parent directory
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
protected function copyDir($src, $dst, $parent = '')
|
||||
{
|
||||
$dir = @opendir($src);
|
||||
if (false === $dir) {
|
||||
throw new TaskException($this, "Cannot open source directory '" . $src . "'");
|
||||
}
|
||||
if (!is_dir($dst)) {
|
||||
mkdir($dst, $this->chmod, true);
|
||||
}
|
||||
while (false !== ($file = readdir($dir))) {
|
||||
// Support basename and full path exclusion.
|
||||
if ($this->excluded($file, $src, $parent)) {
|
||||
continue;
|
||||
}
|
||||
$srcFile = $src . '/' . $file;
|
||||
$destFile = $dst . '/' . $file;
|
||||
if (is_dir($srcFile)) {
|
||||
$this->copyDir($srcFile, $destFile, $parent . $file . DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
$this->fs->copy($srcFile, $destFile, $this->overwrite);
|
||||
}
|
||||
}
|
||||
closedir($dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if the current item is excluded.
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $src
|
||||
* @param string $parent
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function excluded($file, $src, $parent)
|
||||
{
|
||||
return
|
||||
($file == '.') ||
|
||||
($file == '..') ||
|
||||
in_array($file, $this->exclude) ||
|
||||
in_array($this->simplifyForCompare($parent . $file), $this->exclude) ||
|
||||
in_array($this->simplifyForCompare($src . DIRECTORY_SEPARATOR . $file), $this->exclude);
|
||||
}
|
||||
|
||||
/**
|
||||
* Avoid problems comparing paths on Windows that may have a
|
||||
* combination of DIRECTORY_SEPARATOR and /.
|
||||
*
|
||||
* @param string$item
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function simplifyForCompare($item)
|
||||
{
|
||||
return str_replace(DIRECTORY_SEPARATOR, '/', $item);
|
||||
}
|
||||
}
|
||||
37
vendor/consolidation/robo/src/Task/Filesystem/DeleteDir.php
vendored
Normal file
37
vendor/consolidation/robo/src/Task/Filesystem/DeleteDir.php
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Filesystem;
|
||||
|
||||
use Robo\Common\ResourceExistenceChecker;
|
||||
use Robo\Result;
|
||||
|
||||
/**
|
||||
* Deletes dir
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskDeleteDir('tmp')->run();
|
||||
* // as shortcut
|
||||
* $this->_deleteDir(['tmp', 'log']);
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class DeleteDir extends BaseDir
|
||||
{
|
||||
use ResourceExistenceChecker;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if (!$this->checkResources($this->dirs, 'dir')) {
|
||||
return Result::error($this, 'Source directories are missing!');
|
||||
}
|
||||
foreach ($this->dirs as $dir) {
|
||||
$this->fs->remove($dir);
|
||||
$this->printTaskInfo("Deleted {dir}...", ['dir' => $dir]);
|
||||
}
|
||||
return Result::success($this);
|
||||
}
|
||||
}
|
||||
155
vendor/consolidation/robo/src/Task/Filesystem/FilesystemStack.php
vendored
Normal file
155
vendor/consolidation/robo/src/Task/Filesystem/FilesystemStack.php
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Filesystem;
|
||||
|
||||
use Robo\Task\StackBasedTask;
|
||||
use Symfony\Component\Filesystem\Filesystem as sfFilesystem;
|
||||
use Symfony\Component\Filesystem\Exception\IOException;
|
||||
use Robo\Contract\BuilderAwareInterface;
|
||||
use Robo\Common\BuilderAwareTrait;
|
||||
|
||||
/**
|
||||
* Wrapper for [Symfony Filesystem](https://symfony.com/doc/current/components/filesystem.html) Component.
|
||||
* Comands are executed in stack and can be stopped on first fail with `stopOnFail` option.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskFilesystemStack()
|
||||
* ->mkdir('logs')
|
||||
* ->touch('logs/.gitignore')
|
||||
* ->chgrp('www', 'www-data')
|
||||
* ->symlink('/var/log/nginx/error.log', 'logs/error.log')
|
||||
* ->run();
|
||||
*
|
||||
* // one line
|
||||
* $this->_touch('.gitignore');
|
||||
* $this->_mkdir('logs');
|
||||
*
|
||||
* ?>
|
||||
* ```
|
||||
*
|
||||
* @method $this mkdir(string|array|\Traversable $dir, int $mode = 0777)
|
||||
* @method $this touch(string|array|\Traversable $file, int $time = null, int $atime = null)
|
||||
* @method $this copy(string $from, string $to, bool $force = false)
|
||||
* @method $this chmod(string|array|\Traversable $file, int $permissions, int $umask = 0000, bool $recursive = false)
|
||||
* @method $this chgrp(string|array|\Traversable $file, string $group, bool $recursive = false)
|
||||
* @method $this chown(string|array|\Traversable $file, string $user, bool $recursive = false)
|
||||
* @method $this remove(string|array|\Traversable $file)
|
||||
* @method $this rename(string $from, string $to, bool $force = false)
|
||||
* @method $this symlink(string $from, string $to, bool $copyOnWindows = false)
|
||||
* @method $this mirror(string $from, string $to, \Traversable $iterator = null, array $options = [])
|
||||
*/
|
||||
class FilesystemStack extends StackBasedTask implements BuilderAwareInterface
|
||||
{
|
||||
use BuilderAwareTrait;
|
||||
|
||||
/**
|
||||
* @var \Symfony\Component\Filesystem\Filesystem
|
||||
*/
|
||||
protected $fs;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->fs = new sfFilesystem();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Symfony\Component\Filesystem\Filesystem
|
||||
*/
|
||||
protected function getDelegate()
|
||||
{
|
||||
return $this->fs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
* @param bool $force
|
||||
*/
|
||||
protected function _copy($from, $to, $force = false)
|
||||
{
|
||||
$this->fs->copy($from, $to, $force);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[]|\Traversable $file
|
||||
* @param int $permissions
|
||||
* @param int $umask
|
||||
* @param bool $recursive
|
||||
*/
|
||||
protected function _chmod($file, $permissions, $umask = 0000, $recursive = false)
|
||||
{
|
||||
$this->fs->chmod($file, $permissions, $umask, $recursive);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[]|\Traversable $file
|
||||
* @param string $group
|
||||
* @param bool $recursive
|
||||
*/
|
||||
protected function _chgrp($file, $group, $recursive = null)
|
||||
{
|
||||
$this->fs->chgrp($file, $group, $recursive);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[]|\Traversable $file
|
||||
* @param string $user
|
||||
* @param bool $recursive
|
||||
*/
|
||||
protected function _chown($file, $user, $recursive = null)
|
||||
{
|
||||
$this->fs->chown($file, $user, $recursive);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $origin
|
||||
* @param string $target
|
||||
* @param bool $overwrite
|
||||
*
|
||||
* @return null|true|\Robo\Result
|
||||
*/
|
||||
protected function _rename($origin, $target, $overwrite = false)
|
||||
{
|
||||
// we check that target does not exist
|
||||
if ((!$overwrite && is_readable($target)) || (file_exists($target) && !is_writable($target))) {
|
||||
throw new IOException(sprintf('Cannot rename because the target "%s" already exists.', $target), 0, null, $target);
|
||||
}
|
||||
|
||||
// Due to a bug (limitation) in PHP, cross-volume renames do not work.
|
||||
// See: https://bugs.php.net/bug.php?id=54097
|
||||
if (true !== @rename($origin, $target)) {
|
||||
return $this->crossVolumeRename($origin, $target);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $origin
|
||||
* @param string $target
|
||||
*
|
||||
* @return null|\Robo\Result
|
||||
*/
|
||||
protected function crossVolumeRename($origin, $target)
|
||||
{
|
||||
// First step is to try to get rid of the target. If there
|
||||
// is a single, deletable file, then we will just unlink it.
|
||||
if (is_file($target)) {
|
||||
unlink($target);
|
||||
}
|
||||
// If the target still exists, we will try to delete it.
|
||||
// TODO: Note that if this fails partway through, then we cannot
|
||||
// adequately rollback. Perhaps we need to preflight the operation
|
||||
// and determine if everything inside of $target is writable.
|
||||
if (file_exists($target)) {
|
||||
$this->fs->remove($target);
|
||||
}
|
||||
|
||||
/** @var \Robo\Result $result */
|
||||
$result = $this->collectionBuilder()->taskCopyDir([$origin => $target])->run();
|
||||
if (!$result->wasSuccessful()) {
|
||||
return $result;
|
||||
}
|
||||
$this->fs->remove($origin);
|
||||
}
|
||||
}
|
||||
294
vendor/consolidation/robo/src/Task/Filesystem/FlattenDir.php
vendored
Normal file
294
vendor/consolidation/robo/src/Task/Filesystem/FlattenDir.php
vendored
Normal file
@ -0,0 +1,294 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Filesystem;
|
||||
|
||||
use Robo\Result;
|
||||
use Robo\Exception\TaskException;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
||||
/**
|
||||
* Searches for files in a nested directory structure and copies them to
|
||||
* a target directory with or without the parent directories. The task was
|
||||
* inspired by [gulp-flatten](https://www.npmjs.com/package/gulp-flatten).
|
||||
*
|
||||
* Example directory structure:
|
||||
*
|
||||
* ```
|
||||
* └── assets
|
||||
* ├── asset-library1
|
||||
* │ ├── README.md
|
||||
* │ └── asset-library1.min.js
|
||||
* └── asset-library2
|
||||
* ├── README.md
|
||||
* └── asset-library2.min.js
|
||||
* ```
|
||||
*
|
||||
* The following code will search the `*.min.js` files and copy them
|
||||
* inside a new `dist` folder:
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskFlattenDir(['assets/*.min.js' => 'dist'])->run();
|
||||
* // or use shortcut
|
||||
* $this->_flattenDir('assets/*.min.js', 'dist');
|
||||
* ?>
|
||||
* ```
|
||||
*
|
||||
* You can also define the target directory with an additional method, instead of
|
||||
* key/value pairs. More similar to the gulp-flatten syntax:
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskFlattenDir(['assets/*.min.js'])
|
||||
* ->to('dist')
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*
|
||||
* You can also append parts of the parent directories to the target path. If you give
|
||||
* the value `1` to the `includeParents()` method, then the top parent will be appended
|
||||
* to the target directory resulting in a path such as `dist/assets/asset-library1.min.js`.
|
||||
*
|
||||
* If you give a negative number, such as `-1` (the same as specifying `array(0, 1)` then
|
||||
* the bottom parent will be appended, resulting in a path such as
|
||||
* `dist/asset-library1/asset-library1.min.js`.
|
||||
*
|
||||
* The top parent directory will always be starting from the relative path to the current
|
||||
* directory. You can override that with the `parentDir()` method. If in the above example
|
||||
* you would specify `assets`, then the top parent directory would be `asset-library1`.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskFlattenDir(['assets/*.min.js' => 'dist'])
|
||||
* ->parentDir('assets')
|
||||
* ->includeParents(1)
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class FlattenDir extends BaseDir
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $chmod = 0755;
|
||||
|
||||
/**
|
||||
* @var int[]
|
||||
*/
|
||||
protected $parents = array(0, 0);
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $parentDir = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $to;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct($dirs)
|
||||
{
|
||||
parent::__construct($dirs);
|
||||
$this->parentDir = getcwd();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
// find the files
|
||||
$files = $this->findFiles($this->dirs);
|
||||
|
||||
// copy the files
|
||||
$this->copyFiles($files);
|
||||
|
||||
$fileNoun = count($files) == 1 ? ' file' : ' files';
|
||||
$this->printTaskSuccess("Copied {count} $fileNoun to {destination}", ['count' => count($files), 'destination' => $this->to]);
|
||||
|
||||
return Result::success($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default folder permissions for the destination if it does not exist.
|
||||
*
|
||||
* @link https://en.wikipedia.org/wiki/Chmod
|
||||
* @link https://php.net/manual/en/function.mkdir.php
|
||||
* @link https://php.net/manual/en/function.chmod.php
|
||||
*
|
||||
* @param int $permission
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function dirPermissions($permission)
|
||||
{
|
||||
$this->chmod = (int) $permission;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value from which direction and how much parent dirs should be included.
|
||||
* Accepts a positive or negative integer or an array with two integer values.
|
||||
*
|
||||
* @param int|int[] $parents
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws TaskException
|
||||
*/
|
||||
public function includeParents($parents)
|
||||
{
|
||||
if (is_int($parents)) {
|
||||
// if an integer is given check whether it is for top or bottom parent
|
||||
if ($parents >= 0) {
|
||||
$this->parents[0] = $parents;
|
||||
return $this;
|
||||
}
|
||||
$this->parents[1] = 0 - $parents;
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (is_array($parents)) {
|
||||
// check if the array has two values no more, no less
|
||||
if (count($parents) == 2) {
|
||||
$this->parents = $parents;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
throw new TaskException($this, 'includeParents expects an integer or an array with two values');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parent directory from which the relative parent directories will be calculated.
|
||||
*
|
||||
* @param string $dir
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function parentDir($dir)
|
||||
{
|
||||
if (!$this->fs->isAbsolutePath($dir)) {
|
||||
// attach the relative path to current working directory
|
||||
$dir = getcwd() . '/' . $dir;
|
||||
}
|
||||
$this->parentDir = $dir;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the target directory where the files will be copied to.
|
||||
*
|
||||
* @param string $target
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function to($target)
|
||||
{
|
||||
$this->to = rtrim($target, '/');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $dirs
|
||||
*
|
||||
* @return array|\Robo\Result
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
protected function findFiles($dirs)
|
||||
{
|
||||
$files = array();
|
||||
|
||||
// find the files
|
||||
foreach ($dirs as $k => $v) {
|
||||
// reset finder
|
||||
$finder = new Finder();
|
||||
|
||||
$dir = $k;
|
||||
$to = $v;
|
||||
// check if target was given with the to() method instead of key/value pairs
|
||||
if (is_int($k)) {
|
||||
$dir = $v;
|
||||
if (isset($this->to)) {
|
||||
$to = $this->to;
|
||||
} else {
|
||||
throw new TaskException($this, 'target directory is not defined');
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$finder->files()->in($dir);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
// if finder cannot handle it, try with in()->name()
|
||||
if (strpos($dir, '/') === false) {
|
||||
$dir = './' . $dir;
|
||||
}
|
||||
$parts = explode('/', $dir);
|
||||
$new_dir = implode('/', array_slice($parts, 0, -1));
|
||||
try {
|
||||
$finder->files()->in($new_dir)->name(array_pop($parts));
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return Result::fromException($this, $e);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($finder as $file) {
|
||||
// store the absolute path as key and target as value in the files array
|
||||
$files[$file->getRealpath()] = $this->getTarget($file->getRealPath(), $to);
|
||||
}
|
||||
$fileNoun = count($files) == 1 ? ' file' : ' files';
|
||||
$this->printTaskInfo("Found {count} $fileNoun in {dir}", ['count' => count($files), 'dir' => $dir]);
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param string $to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getTarget($file, $to)
|
||||
{
|
||||
$target = $to . '/' . basename($file);
|
||||
if ($this->parents !== array(0, 0)) {
|
||||
// if the parent is set, create additional directories inside target
|
||||
// get relative path to parentDir
|
||||
$rel_path = $this->fs->makePathRelative(dirname($file), $this->parentDir);
|
||||
// get top parents and bottom parents
|
||||
$parts = explode('/', rtrim($rel_path, '/'));
|
||||
$prefix_dir = '';
|
||||
$prefix_dir .= ($this->parents[0] > 0 ? implode('/', array_slice($parts, 0, $this->parents[0])) . '/' : '');
|
||||
$prefix_dir .= ($this->parents[1] > 0 ? implode('/', array_slice($parts, (0 - $this->parents[1]), $this->parents[1])) : '');
|
||||
$prefix_dir = rtrim($prefix_dir, '/');
|
||||
$target = $to . '/' . $prefix_dir . '/' . basename($file);
|
||||
}
|
||||
|
||||
return $target;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $files
|
||||
*/
|
||||
protected function copyFiles($files)
|
||||
{
|
||||
// copy the files
|
||||
foreach ($files as $from => $to) {
|
||||
// check if target dir exists
|
||||
if (!is_dir(dirname($to))) {
|
||||
$this->fs->mkdir(dirname($to), $this->chmod);
|
||||
}
|
||||
$this->fs->copy($from, $to);
|
||||
}
|
||||
}
|
||||
}
|
||||
41
vendor/consolidation/robo/src/Task/Filesystem/MirrorDir.php
vendored
Normal file
41
vendor/consolidation/robo/src/Task/Filesystem/MirrorDir.php
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Filesystem;
|
||||
|
||||
use Robo\Result;
|
||||
|
||||
/**
|
||||
* Mirrors a directory to another
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskMirrorDir(['dist/config/' => 'config/'])->run();
|
||||
* // or use shortcut
|
||||
* $this->_mirrorDir('dist/config/', 'config/');
|
||||
*
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class MirrorDir extends BaseDir
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
foreach ($this->dirs as $src => $dst) {
|
||||
$this->fs->mirror(
|
||||
$src,
|
||||
$dst,
|
||||
null,
|
||||
[
|
||||
'override' => true,
|
||||
'copy_on_windows' => true,
|
||||
'delete' => true
|
||||
]
|
||||
);
|
||||
$this->printTaskInfo("Mirrored from {source} to {destination}", ['source' => $src, 'destination' => $dst]);
|
||||
}
|
||||
return Result::success($this);
|
||||
}
|
||||
}
|
||||
160
vendor/consolidation/robo/src/Task/Filesystem/Shortcuts.php
vendored
Normal file
160
vendor/consolidation/robo/src/Task/Filesystem/Shortcuts.php
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Filesystem;
|
||||
|
||||
trait Shortcuts
|
||||
{
|
||||
/**
|
||||
* @param string $src
|
||||
* @param string $dst
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _copyDir($src, $dst)
|
||||
{
|
||||
return $this->taskCopyDir([$src => $dst])->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $src
|
||||
* @param string $dst
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _mirrorDir($src, $dst)
|
||||
{
|
||||
return $this->taskMirrorDir([$src => $dst])->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $dir
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _deleteDir($dir)
|
||||
{
|
||||
return $this->taskDeleteDir($dir)->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $dir
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _cleanDir($dir)
|
||||
{
|
||||
return $this->taskCleanDir($dir)->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
* @param bool $overwrite
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _rename($from, $to, $overwrite = false)
|
||||
{
|
||||
return $this->taskFilesystemStack()->rename($from, $to, $overwrite)->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $dir
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _mkdir($dir)
|
||||
{
|
||||
return $this->taskFilesystemStack()->mkdir($dir)->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $prefix
|
||||
* @param string $base
|
||||
* @param bool $includeRandomPart
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _tmpDir($prefix = 'tmp', $base = '', $includeRandomPart = true)
|
||||
{
|
||||
$result = $this->taskTmpDir($prefix, $base, $includeRandomPart)->run();
|
||||
return isset($result['path']) ? $result['path'] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _touch($file)
|
||||
{
|
||||
return $this->taskFilesystemStack()->touch($file)->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $file
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _remove($file)
|
||||
{
|
||||
return $this->taskFilesystemStack()->remove($file)->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $file
|
||||
* @param string $group
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _chgrp($file, $group)
|
||||
{
|
||||
return $this->taskFilesystemStack()->chgrp($file, $group)->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $file
|
||||
* @param int $permissions
|
||||
* @param int $umask
|
||||
* @param bool $recursive
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _chmod($file, $permissions, $umask = 0000, $recursive = false)
|
||||
{
|
||||
return $this->taskFilesystemStack()->chmod($file, $permissions, $umask, $recursive)->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _symlink($from, $to)
|
||||
{
|
||||
return $this->taskFilesystemStack()->symlink($from, $to)->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _copy($from, $to)
|
||||
{
|
||||
return $this->taskFilesystemStack()->copy($from, $to)->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _flattenDir($from, $to)
|
||||
{
|
||||
return $this->taskFlattenDir([$from => $to])->run();
|
||||
}
|
||||
}
|
||||
86
vendor/consolidation/robo/src/Task/Filesystem/Tasks.php
vendored
Normal file
86
vendor/consolidation/robo/src/Task/Filesystem/Tasks.php
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Filesystem;
|
||||
|
||||
trait Tasks
|
||||
{
|
||||
/**
|
||||
* @param string|string[] $dirs
|
||||
*
|
||||
* @return \Robo\Task\Filesystem\CleanDir|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskCleanDir($dirs)
|
||||
{
|
||||
return $this->task(CleanDir::class, $dirs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $dirs
|
||||
*
|
||||
* @return \Robo\Task\Filesystem\DeleteDir|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskDeleteDir($dirs)
|
||||
{
|
||||
return $this->task(DeleteDir::class, $dirs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $prefix
|
||||
* @param string $base
|
||||
* @param bool $includeRandomPart
|
||||
*
|
||||
* @return \Robo\Task\Filesystem\WorkDir|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskTmpDir($prefix = 'tmp', $base = '', $includeRandomPart = true)
|
||||
{
|
||||
return $this->task(TmpDir::class, $prefix, $base, $includeRandomPart);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $finalDestination
|
||||
*
|
||||
* @return \Robo\Task\Filesystem\TmpDir|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskWorkDir($finalDestination)
|
||||
{
|
||||
return $this->task(WorkDir::class, $finalDestination);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $dirs
|
||||
*
|
||||
* @return \Robo\Task\Filesystem\CopyDir|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskCopyDir($dirs)
|
||||
{
|
||||
return $this->task(CopyDir::class, $dirs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $dirs
|
||||
*
|
||||
* @return \Robo\Task\Filesystem\MirrorDir|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskMirrorDir($dirs)
|
||||
{
|
||||
return $this->task(MirrorDir::class, $dirs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $dirs
|
||||
*
|
||||
* @return \Robo\Task\Filesystem\FlattenDir|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskFlattenDir($dirs)
|
||||
{
|
||||
return $this->task(FlattenDir::class, $dirs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Robo\Task\Filesystem\FilesystemStack|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskFilesystemStack()
|
||||
{
|
||||
return $this->task(FilesystemStack::class);
|
||||
}
|
||||
}
|
||||
173
vendor/consolidation/robo/src/Task/Filesystem/TmpDir.php
vendored
Normal file
173
vendor/consolidation/robo/src/Task/Filesystem/TmpDir.php
vendored
Normal file
@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Filesystem;
|
||||
|
||||
use Robo\Result;
|
||||
use Robo\Contract\CompletionInterface;
|
||||
|
||||
/**
|
||||
* Create a temporary directory that is automatically cleaned up
|
||||
* once the task collection is is part of completes.
|
||||
*
|
||||
* Use WorkDir if you do not want the directory to be deleted.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // Delete on rollback or on successful completion.
|
||||
* // Note that in this example, everything is deleted at
|
||||
* // the end of $collection->run().
|
||||
* $collection = $this->collectionBuilder();
|
||||
* $tmpPath = $collection->tmpDir()->getPath();
|
||||
* $collection->taskFilesystemStack()
|
||||
* ->mkdir("$tmpPath/log")
|
||||
* ->touch("$tmpPath/log/error.txt");
|
||||
* $collection->run();
|
||||
* // as shortcut (deleted when program exits)
|
||||
* $tmpPath = $this->_tmpDir();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class TmpDir extends BaseDir implements CompletionInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $base;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $prefix;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $cwd;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $savedWorkingDirectory;
|
||||
|
||||
/**
|
||||
* @param string $prefix
|
||||
* @param string $base
|
||||
* @param bool $includeRandomPart
|
||||
*/
|
||||
public function __construct($prefix = 'tmp', $base = '', $includeRandomPart = true)
|
||||
{
|
||||
if (empty($base)) {
|
||||
$base = sys_get_temp_dir();
|
||||
}
|
||||
$path = "{$base}/{$prefix}";
|
||||
if ($includeRandomPart) {
|
||||
$path = static::randomLocation($path);
|
||||
}
|
||||
parent::__construct(["$path"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a random part to a path, ensuring that the directory does
|
||||
* not (currently) exist.
|
||||
*
|
||||
* @param string $path The base/prefix path to add a random component to
|
||||
* @param int $length Number of digits in the random part
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function randomLocation($path, $length = 12)
|
||||
{
|
||||
$random = static::randomString($length);
|
||||
while (is_dir("{$path}_{$random}")) {
|
||||
$random = static::randomString($length);
|
||||
}
|
||||
return "{$path}_{$random}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a suitably random string to use as the suffix for our
|
||||
* temporary directory.
|
||||
*
|
||||
* @param int $length
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function randomString($length = 12)
|
||||
{
|
||||
return substr(str_shuffle('23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'), 0, max($length, 3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag that we should cwd to the temporary directory when it is
|
||||
* created, and restore the old working directory when it is deleted.
|
||||
*
|
||||
* @param bool $shouldChangeWorkingDirectory
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function cwd($shouldChangeWorkingDirectory = true)
|
||||
{
|
||||
$this->cwd = $shouldChangeWorkingDirectory;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
// Save the current working directory
|
||||
$this->savedWorkingDirectory = getcwd();
|
||||
foreach ($this->dirs as $dir) {
|
||||
$this->fs->mkdir($dir);
|
||||
$this->printTaskInfo("Created {dir}...", ['dir' => $dir]);
|
||||
|
||||
// Change the current working directory, if requested
|
||||
if ($this->cwd) {
|
||||
chdir($dir);
|
||||
}
|
||||
}
|
||||
|
||||
return Result::success($this, '', ['path' => $this->getPath()]);
|
||||
}
|
||||
|
||||
protected function restoreWorkingDirectory()
|
||||
{
|
||||
// Restore the current working directory, if we redirected it.
|
||||
if ($this->cwd) {
|
||||
chdir($this->savedWorkingDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
protected function deleteTmpDir()
|
||||
{
|
||||
foreach ($this->dirs as $dir) {
|
||||
$this->fs->remove($dir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete this directory when our collection completes.
|
||||
* If this temporary directory is not part of a collection,
|
||||
* then it will be deleted when the program terminates,
|
||||
* presuming that it was created by taskTmpDir() or _tmpDir().
|
||||
*/
|
||||
public function complete()
|
||||
{
|
||||
$this->restoreWorkingDirectory();
|
||||
$this->deleteTmpDir();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to the path to the temporary directory, so that
|
||||
* it may be used to create other tasks. Note that the directory
|
||||
* is not actually created until the task runs.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->dirs[0];
|
||||
}
|
||||
}
|
||||
126
vendor/consolidation/robo/src/Task/Filesystem/WorkDir.php
vendored
Normal file
126
vendor/consolidation/robo/src/Task/Filesystem/WorkDir.php
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Filesystem;
|
||||
|
||||
use Robo\Result;
|
||||
use Robo\Contract\RollbackInterface;
|
||||
use Robo\Contract\BuilderAwareInterface;
|
||||
use Robo\Common\BuilderAwareTrait;
|
||||
|
||||
/**
|
||||
* Create a temporary working directory that is automatically renamed to its
|
||||
* final desired location if all of the tasks in the collection succeed. If
|
||||
* there is a rollback, then the working directory is deleted.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $collection = $this->collectionBuilder();
|
||||
* $workingPath = $collection->workDir("build")->getPath();
|
||||
* $collection->taskFilesystemStack()
|
||||
* ->mkdir("$workingPath/log")
|
||||
* ->touch("$workingPath/log/error.txt");
|
||||
* $collection->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class WorkDir extends TmpDir implements RollbackInterface, BuilderAwareInterface
|
||||
{
|
||||
use BuilderAwareTrait;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $finalDestination;
|
||||
|
||||
/**
|
||||
* @param string $finalDestination
|
||||
*/
|
||||
public function __construct($finalDestination)
|
||||
{
|
||||
$this->finalDestination = $finalDestination;
|
||||
|
||||
// Create a temporary directory to work in. We will place our
|
||||
// temporary directory in the same location as the final destination
|
||||
// directory, so that the work directory can be moved into place
|
||||
// without having to be copied, e.g. in a cross-volume rename scenario.
|
||||
parent::__construct(basename($finalDestination), dirname($finalDestination));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create our working directory.
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
// Destination cannot be empty
|
||||
if (empty($this->finalDestination)) {
|
||||
return Result::error($this, "Destination directory not specified.");
|
||||
}
|
||||
|
||||
// Before we do anything else, ensure that any directory in the
|
||||
// final destination is writable, so that we can at a minimum
|
||||
// move it out of the way before placing our results there.
|
||||
if (is_dir($this->finalDestination)) {
|
||||
if (!is_writable($this->finalDestination)) {
|
||||
return Result::error($this, "Destination directory {dir} exists and cannot be overwritten.", ['dir' => $this->finalDestination]);
|
||||
}
|
||||
}
|
||||
|
||||
return parent::run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Move our working directory into its final destination once the
|
||||
* collection it belongs to completes.
|
||||
*/
|
||||
public function complete()
|
||||
{
|
||||
$this->restoreWorkingDirectory();
|
||||
|
||||
// Delete the final destination, if it exists.
|
||||
// Move it out of the way first, in case it cannot
|
||||
// be completely deleted.
|
||||
if (file_exists($this->finalDestination)) {
|
||||
$temporaryLocation = static::randomLocation($this->finalDestination . '_TO_DELETE_');
|
||||
// This should always work, because we already created a temporary
|
||||
// folder in the parent directory of the final destination, and we
|
||||
// have already checked to confirm that the final destination is
|
||||
// writable.
|
||||
rename($this->finalDestination, $temporaryLocation);
|
||||
// This may silently fail, leaving artifacts behind, if there
|
||||
// are permissions problems with some items somewhere inside
|
||||
// the folder being deleted.
|
||||
$this->fs->remove($temporaryLocation);
|
||||
}
|
||||
|
||||
// Move our working directory over the final destination.
|
||||
// This should never be a cross-volume rename, so this should
|
||||
// always succeed.
|
||||
$workDir = reset($this->dirs);
|
||||
if (file_exists($workDir)) {
|
||||
rename($workDir, $this->finalDestination);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete our working directory
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
$this->restoreWorkingDirectory();
|
||||
$this->deleteTmpDir();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to the path to the temporary directory, so that
|
||||
* it may be used to create other tasks. Note that the directory
|
||||
* is not actually created until the task runs.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->dirs[0];
|
||||
}
|
||||
}
|
||||
98
vendor/consolidation/robo/src/Task/Gulp/Base.php
vendored
Normal file
98
vendor/consolidation/robo/src/Task/Gulp/Base.php
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Gulp;
|
||||
|
||||
use Robo\Task\BaseTask;
|
||||
use Robo\Exception\TaskException;
|
||||
use Robo\Common\ProcessUtils;
|
||||
use Robo\Common\ExecOneCommand;
|
||||
|
||||
abstract class Base extends BaseTask
|
||||
{
|
||||
use ExecOneCommand;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $command = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $opts = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $task = '';
|
||||
|
||||
/**
|
||||
* adds `silent` option to gulp
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function silent()
|
||||
{
|
||||
$this->option('silent');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `--no-color` option to gulp
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noColor()
|
||||
{
|
||||
$this->option('no-color');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `--color` option to gulp
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function color()
|
||||
{
|
||||
$this->option('color');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `--tasks-simple` option to gulp
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function simple()
|
||||
{
|
||||
$this->option('tasks-simple');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $task
|
||||
* @param null|string $pathToGulp
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
public function __construct($task, $pathToGulp = null)
|
||||
{
|
||||
$this->task = $task;
|
||||
$this->command = $pathToGulp;
|
||||
if (!$this->command) {
|
||||
$this->command = $this->findExecutable('gulp');
|
||||
}
|
||||
if (!$this->command) {
|
||||
throw new TaskException(__CLASS__, "Gulp executable not found.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return "{$this->command} " . ProcessUtils::escapeArgument($this->task) . "{$this->arguments}";
|
||||
}
|
||||
}
|
||||
36
vendor/consolidation/robo/src/Task/Gulp/Run.php
vendored
Normal file
36
vendor/consolidation/robo/src/Task/Gulp/Run.php
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Gulp;
|
||||
|
||||
use Robo\Contract\CommandInterface;
|
||||
|
||||
/**
|
||||
* Gulp Run
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // simple execution
|
||||
* $this->taskGulpRun()->run();
|
||||
*
|
||||
* // run task 'clean' with --silent option
|
||||
* $this->taskGulpRun('clean')
|
||||
* ->silent()
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Run extends Base implements CommandInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if (strlen($this->arguments)) {
|
||||
$this->printTaskInfo('Running Gulp task: {gulp_task} with arguments: {arguments}', ['gulp_task' => $this->task, 'arguments' => $this->arguments]);
|
||||
} else {
|
||||
$this->printTaskInfo('Running Gulp task: {gulp_task} without arguments', ['gulp_task' => $this->task]);
|
||||
}
|
||||
return $this->executeCommand($this->getCommand());
|
||||
}
|
||||
}
|
||||
17
vendor/consolidation/robo/src/Task/Gulp/Tasks.php
vendored
Normal file
17
vendor/consolidation/robo/src/Task/Gulp/Tasks.php
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Gulp;
|
||||
|
||||
trait Tasks
|
||||
{
|
||||
/**
|
||||
* @param string $task
|
||||
* @param null|string $pathToGulp
|
||||
*
|
||||
* @return \Robo\Task\Gulp\Run|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskGulpRun($task = 'default', $pathToGulp = null)
|
||||
{
|
||||
return $this->task(Run::class, $task, $pathToGulp);
|
||||
}
|
||||
}
|
||||
47
vendor/consolidation/robo/src/Task/Logfile/BaseLogfile.php
vendored
Normal file
47
vendor/consolidation/robo/src/Task/Logfile/BaseLogfile.php
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Logfile;
|
||||
|
||||
use Robo\Task\BaseTask;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
|
||||
abstract class BaseLogfile extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @var string|string[] Array with log files.
|
||||
*/
|
||||
protected $logfiles = [];
|
||||
|
||||
/**
|
||||
* @var \Symfony\Component\Filesystem\Filesystem
|
||||
*/
|
||||
protected $filesystem;
|
||||
|
||||
/**
|
||||
* @var int|bool Octal file mode for log files like 0600.
|
||||
*/
|
||||
protected $chmod = false;
|
||||
|
||||
/**
|
||||
* @param string|string[] $logfiles
|
||||
*/
|
||||
public function __construct($logfiles)
|
||||
{
|
||||
is_array($logfiles)
|
||||
? $this->logfiles = $logfiles
|
||||
: $this->logfiles[] = $logfiles;
|
||||
|
||||
$this->filesystem = new Filesystem();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $chmod
|
||||
* @return $this
|
||||
*/
|
||||
public function chmod(int $chmod)
|
||||
{
|
||||
$this->chmod = $chmod;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
163
vendor/consolidation/robo/src/Task/Logfile/RotateLog.php
vendored
Normal file
163
vendor/consolidation/robo/src/Task/Logfile/RotateLog.php
vendored
Normal file
@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Logfile;
|
||||
|
||||
use Robo\Result;
|
||||
|
||||
/**
|
||||
* Rotates a log (or any other) file
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskRotateLog(['logfile.log'])->run();
|
||||
* // or use shortcut
|
||||
* $this->_rotateLog(['logfile.log']);
|
||||
*
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class RotateLog extends BaseLogfile
|
||||
{
|
||||
/**
|
||||
* @var int Number of copies to keep, default is 3.
|
||||
*/
|
||||
protected $keep = 3;
|
||||
|
||||
/**
|
||||
* @var string|string[] Logfile to rotate.
|
||||
*/
|
||||
private $logfile;
|
||||
|
||||
/**
|
||||
* @param string|string[] $logfiles
|
||||
*/
|
||||
public function __construct($logfiles)
|
||||
{
|
||||
parent::__construct($logfiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $keep
|
||||
* @return RotateLog
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function keep(int $keep): self
|
||||
{
|
||||
if ($keep < 1) {
|
||||
throw new \InvalidArgumentException(
|
||||
'Keep should be greater than one, to truncate a logfile use taskTruncateLog($logfile).'
|
||||
);
|
||||
}
|
||||
|
||||
$this->keep = $keep;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run(): Result
|
||||
{
|
||||
foreach ($this->logfiles as $logfile) {
|
||||
$this->loadLogfile($logfile)
|
||||
->process();
|
||||
}
|
||||
|
||||
return Result::success($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $logfile
|
||||
* @return RotateLog
|
||||
*/
|
||||
private function loadLogfile(string $logfile): self
|
||||
{
|
||||
$this->logfile = new \SplFileInfo($logfile);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return RotateLog
|
||||
*/
|
||||
private function process(): self
|
||||
{
|
||||
$rotation = 0;
|
||||
foreach (scandir($this->logfile->getPath(), SCANDIR_SORT_DESCENDING) as $origin) {
|
||||
$origin = new \SplFileInfo($this->logfile->getPath().'/'.$origin);
|
||||
if ($origin->isFile() && $this->isLogfile($origin)) {
|
||||
if ($this->version($origin) < $this->keep) {
|
||||
$rotated = $this->rotate($origin);
|
||||
$this->printTaskInfo(
|
||||
'Rotated from {origin} to {rotated}',
|
||||
[
|
||||
'origin' => $origin->getPathname(),
|
||||
'rotated' => $rotated
|
||||
]
|
||||
);
|
||||
} elseif ($this->version($origin) > $this->keep) {
|
||||
$this->filesystem->remove($origin->getPathname());
|
||||
}
|
||||
}
|
||||
|
||||
$rotation++;
|
||||
}
|
||||
|
||||
$this->filesystem->dumpFile($this->logfile->getPathname(), false);
|
||||
if ($this->chmod) {
|
||||
$this->filesystem->chmod($this->logfile->getPathname(), $this->chmod);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \SplFileInfo $origin
|
||||
* @return bool
|
||||
*/
|
||||
private function isLogfile(\SplFileInfo $origin): bool
|
||||
{
|
||||
if (substr($origin->getFilename(), 0, strlen($this->logfile->getFilename())) != $this->logfile->getFilename()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \SplFileInfo $origin
|
||||
* @return int
|
||||
*/
|
||||
private function version(\SplFileInfo $origin): int
|
||||
{
|
||||
return $origin->getExtension() === $this->logfile->getExtension()
|
||||
? 0
|
||||
: $origin->getExtension();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \SplFileInfo $origin
|
||||
* @return int
|
||||
*/
|
||||
private function next(\SplFileInfo $origin): int
|
||||
{
|
||||
return $this->version($origin) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \SplFileInfo $origin
|
||||
* @return string
|
||||
*/
|
||||
private function rotate(\SplFileInfo $origin): string
|
||||
{
|
||||
$rotated = $this->logfile->getPathname().'.'.$this->next($origin);
|
||||
if ($this->next($origin) === $this->keep) {
|
||||
$this->filesystem->remove($rotated);
|
||||
}
|
||||
|
||||
$this->filesystem->rename($origin->getPathname(), $rotated);
|
||||
|
||||
return $rotated;
|
||||
}
|
||||
}
|
||||
28
vendor/consolidation/robo/src/Task/Logfile/Shortcuts.php
vendored
Normal file
28
vendor/consolidation/robo/src/Task/Logfile/Shortcuts.php
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Logfile;
|
||||
|
||||
use Robo\Result;
|
||||
|
||||
trait Shortcuts
|
||||
{
|
||||
/**
|
||||
* @param string|string[] $logfile
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _rotateLog($logfile): Result
|
||||
{
|
||||
return $this->taskRotateLog($logfile)->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $logfile
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _truncateLog($logfile): Result
|
||||
{
|
||||
return $this->taskTruncateLog($logfile)->run();
|
||||
}
|
||||
}
|
||||
28
vendor/consolidation/robo/src/Task/Logfile/Tasks.php
vendored
Normal file
28
vendor/consolidation/robo/src/Task/Logfile/Tasks.php
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Logfile;
|
||||
|
||||
use Robo\Collection\CollectionBuilder;
|
||||
|
||||
trait Tasks
|
||||
{
|
||||
/**
|
||||
* @param string|string[] $logfile
|
||||
*
|
||||
* @return \Robo\Task\Logfile\RotateLog|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskRotateLog($logfile): CollectionBuilder
|
||||
{
|
||||
return $this->task(RotateLog::class, $logfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $logfile
|
||||
*
|
||||
* @return \Robo\Task\Logfile\TruncateLog|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskTruncateLog($logfile): CollectionBuilder
|
||||
{
|
||||
return $this->task(TruncateLog::class, $logfile);
|
||||
}
|
||||
}
|
||||
36
vendor/consolidation/robo/src/Task/Logfile/TruncateLog.php
vendored
Normal file
36
vendor/consolidation/robo/src/Task/Logfile/TruncateLog.php
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Logfile;
|
||||
|
||||
use Robo\Result;
|
||||
|
||||
/**
|
||||
* Truncates a log (or any other) file
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskTruncateLog(['logfile.log'])->run();
|
||||
* // or use shortcut
|
||||
* $this->_truncateLog(['logfile.log']);
|
||||
*
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class TruncateLog extends BaseLogfile
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run(): Result
|
||||
{
|
||||
foreach ($this->logfiles as $logfile) {
|
||||
$this->filesystem->dumpFile($logfile, false);
|
||||
if ($this->chmod) {
|
||||
$this->filesystem->chmod($logfile, $this->chmod);
|
||||
}
|
||||
$this->printTaskInfo("Truncated {logfile}", ['logfile' => $logfile]);
|
||||
}
|
||||
|
||||
return Result::success($this);
|
||||
}
|
||||
}
|
||||
62
vendor/consolidation/robo/src/Task/Npm/Base.php
vendored
Normal file
62
vendor/consolidation/robo/src/Task/Npm/Base.php
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Npm;
|
||||
|
||||
use Robo\Task\BaseTask;
|
||||
use Robo\Exception\TaskException;
|
||||
use Robo\Common\ExecOneCommand;
|
||||
|
||||
abstract class Base extends BaseTask
|
||||
{
|
||||
use ExecOneCommand;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $command = '';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $opts = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $action = '';
|
||||
|
||||
/**
|
||||
* adds `production` option to npm
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noDev()
|
||||
{
|
||||
$this->option('production');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $pathToNpm
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
public function __construct($pathToNpm = null)
|
||||
{
|
||||
$this->command = $pathToNpm;
|
||||
if (!$this->command) {
|
||||
$this->command = $this->findExecutable('npm');
|
||||
}
|
||||
if (!$this->command) {
|
||||
throw new TaskException(__CLASS__, "Npm executable not found.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return "{$this->command} {$this->action}{$this->arguments}";
|
||||
}
|
||||
}
|
||||
37
vendor/consolidation/robo/src/Task/Npm/Install.php
vendored
Normal file
37
vendor/consolidation/robo/src/Task/Npm/Install.php
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Npm;
|
||||
|
||||
use Robo\Contract\CommandInterface;
|
||||
|
||||
/**
|
||||
* Npm Install
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // simple execution
|
||||
* $this->taskNpmInstall()->run();
|
||||
*
|
||||
* // prefer dist with custom path
|
||||
* $this->taskNpmInstall('path/to/my/npm')
|
||||
* ->noDev()
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Install extends Base implements CommandInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $action = 'install';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->printTaskInfo('Install Npm packages: {arguments}', ['arguments' => $this->arguments]);
|
||||
return $this->executeCommand($this->getCommand());
|
||||
}
|
||||
}
|
||||
26
vendor/consolidation/robo/src/Task/Npm/Tasks.php
vendored
Normal file
26
vendor/consolidation/robo/src/Task/Npm/Tasks.php
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Npm;
|
||||
|
||||
trait Tasks
|
||||
{
|
||||
/**
|
||||
* @param null|string $pathToNpm
|
||||
*
|
||||
* @return \Robo\Task\Npm\Install|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskNpmInstall($pathToNpm = null)
|
||||
{
|
||||
return $this->task(Install::class, $pathToNpm);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $pathToNpm
|
||||
*
|
||||
* @return \Robo\Task\Npm\Update|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskNpmUpdate($pathToNpm = null)
|
||||
{
|
||||
return $this->task(Update::class, $pathToNpm);
|
||||
}
|
||||
}
|
||||
35
vendor/consolidation/robo/src/Task/Npm/Update.php
vendored
Normal file
35
vendor/consolidation/robo/src/Task/Npm/Update.php
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Npm;
|
||||
|
||||
/**
|
||||
* Npm Update
|
||||
*
|
||||
* ```php
|
||||
* <?php
|
||||
* // simple execution
|
||||
* $this->taskNpmUpdate()->run();
|
||||
*
|
||||
* // prefer dist with custom path
|
||||
* $this->taskNpmUpdate('path/to/my/npm')
|
||||
* ->noDev()
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Update extends Base
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $action = 'update';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->printTaskInfo('Update Npm packages: {arguments}', ['arguments' => $this->arguments]);
|
||||
return $this->executeCommand($this->getCommand());
|
||||
}
|
||||
}
|
||||
488
vendor/consolidation/robo/src/Task/Remote/Rsync.php
vendored
Normal file
488
vendor/consolidation/robo/src/Task/Remote/Rsync.php
vendored
Normal file
@ -0,0 +1,488 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Remote;
|
||||
|
||||
use Robo\Contract\CommandInterface;
|
||||
use Robo\Task\BaseTask;
|
||||
use Robo\Exception\TaskException;
|
||||
use Robo\Common\ExecOneCommand;
|
||||
|
||||
/**
|
||||
* Executes rsync in a flexible manner.
|
||||
*
|
||||
* ``` php
|
||||
* $this->taskRsync()
|
||||
* ->fromPath('src/')
|
||||
* ->toHost('localhost')
|
||||
* ->toUser('dev')
|
||||
* ->toPath('/var/www/html/app/')
|
||||
* ->remoteShell('ssh -i public_key')
|
||||
* ->recursive()
|
||||
* ->excludeVcs()
|
||||
* ->checksum()
|
||||
* ->wholeFile()
|
||||
* ->verbose()
|
||||
* ->progress()
|
||||
* ->humanReadable()
|
||||
* ->stats()
|
||||
* ->run();
|
||||
* ```
|
||||
*
|
||||
* You could also clone the task and do a dry-run first:
|
||||
*
|
||||
* ``` php
|
||||
* $rsync = $this->taskRsync()
|
||||
* ->fromPath('src/')
|
||||
* ->toPath('example.com:/var/www/html/app/')
|
||||
* ->archive()
|
||||
* ->excludeVcs()
|
||||
* ->progress()
|
||||
* ->stats();
|
||||
*
|
||||
* $dryRun = clone $rsync;
|
||||
* $dryRun->dryRun()->run();
|
||||
* if ('y' === $this->ask('Do you want to run (y/n)')) {
|
||||
* $rsync->run();
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class Rsync extends BaseTask implements CommandInterface
|
||||
{
|
||||
use ExecOneCommand;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $command;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $fromUser;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $fromHost;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $fromPath;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $toUser;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $toHost;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $toPath;
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public static function init()
|
||||
{
|
||||
return new static();
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->command = 'rsync';
|
||||
}
|
||||
|
||||
/**
|
||||
* This can either be a full rsync path spec (user@host:path) or just a path.
|
||||
* In case of the former do not specify host and user.
|
||||
*
|
||||
* @param string|array $path
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function fromPath($path)
|
||||
{
|
||||
$this->fromPath = $path;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This can either be a full rsync path spec (user@host:path) or just a path.
|
||||
* In case of the former do not specify host and user.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function toPath($path)
|
||||
{
|
||||
$this->toPath = $path;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fromUser
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function fromUser($fromUser)
|
||||
{
|
||||
$this->fromUser = $fromUser;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fromHost
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function fromHost($fromHost)
|
||||
{
|
||||
$this->fromHost = $fromHost;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $toUser
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function toUser($toUser)
|
||||
{
|
||||
$this->toUser = $toUser;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $toHost
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function toHost($toHost)
|
||||
{
|
||||
$this->toHost = $toHost;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function progress()
|
||||
{
|
||||
$this->option(__FUNCTION__);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function stats()
|
||||
{
|
||||
$this->option(__FUNCTION__);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function recursive()
|
||||
{
|
||||
$this->option(__FUNCTION__);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function verbose()
|
||||
{
|
||||
$this->option(__FUNCTION__);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function checksum()
|
||||
{
|
||||
$this->option(__FUNCTION__);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function archive()
|
||||
{
|
||||
$this->option(__FUNCTION__);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function compress()
|
||||
{
|
||||
$this->option(__FUNCTION__);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function owner()
|
||||
{
|
||||
$this->option(__FUNCTION__);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function group()
|
||||
{
|
||||
$this->option(__FUNCTION__);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function times()
|
||||
{
|
||||
$this->option(__FUNCTION__);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$this->option(__FUNCTION__);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $seconds
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function timeout($seconds)
|
||||
{
|
||||
$this->option(__FUNCTION__, $seconds);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function humanReadable()
|
||||
{
|
||||
$this->option('human-readable');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function wholeFile()
|
||||
{
|
||||
$this->option('whole-file');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function dryRun()
|
||||
{
|
||||
$this->option('dry-run');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function itemizeChanges()
|
||||
{
|
||||
$this->option('itemize-changes');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Excludes .git, .svn and .hg items at any depth.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function excludeVcs()
|
||||
{
|
||||
return $this->exclude([
|
||||
'.git',
|
||||
'.svn',
|
||||
'.hg',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $pattern
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function exclude($pattern)
|
||||
{
|
||||
return $this->optionList(__FUNCTION__, $pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
public function excludeFrom($file)
|
||||
{
|
||||
if (!is_readable($file)) {
|
||||
throw new TaskException($this, "Exclude file $file is not readable");
|
||||
}
|
||||
|
||||
return $this->option('exclude-from', $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $pattern
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function includeFilter($pattern)
|
||||
{
|
||||
return $this->optionList('include', $pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $pattern
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function filter($pattern)
|
||||
{
|
||||
return $this->optionList(__FUNCTION__, $pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
public function filesFrom($file)
|
||||
{
|
||||
if (!is_readable($file)) {
|
||||
throw new TaskException($this, "Files-from file $file is not readable");
|
||||
}
|
||||
|
||||
return $this->option('files-from', $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $command
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function remoteShell($command)
|
||||
{
|
||||
$this->option('rsh', "$command");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$command = $this->getCommand();
|
||||
|
||||
return $this->executeCommand($command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns command that can be executed.
|
||||
* This method is used to pass generated command from one task to another.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
foreach ((array)$this->fromPath as $from) {
|
||||
$this->option(null, $this->getFromPathSpec($from));
|
||||
}
|
||||
$this->option(null, $this->getToPathSpec());
|
||||
|
||||
return $this->command . $this->arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getFromPathSpec($from)
|
||||
{
|
||||
return $this->getPathSpec($this->fromHost, $this->fromUser, $from);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getToPathSpec()
|
||||
{
|
||||
return $this->getPathSpec($this->toHost, $this->toUser, $this->toPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $host
|
||||
* @param string $user
|
||||
* @param string $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getPathSpec($host, $user, $path)
|
||||
{
|
||||
$spec = isset($path) ? $path : '';
|
||||
if (!empty($host)) {
|
||||
$spec = "{$host}:{$spec}";
|
||||
}
|
||||
if (!empty($user)) {
|
||||
$spec = "{$user}@{$spec}";
|
||||
}
|
||||
|
||||
return $spec;
|
||||
}
|
||||
}
|
||||
276
vendor/consolidation/robo/src/Task/Remote/Ssh.php
vendored
Normal file
276
vendor/consolidation/robo/src/Task/Remote/Ssh.php
vendored
Normal file
@ -0,0 +1,276 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Remote;
|
||||
|
||||
use Robo\Contract\CommandInterface;
|
||||
use Robo\Contract\PrintedInterface;
|
||||
use Robo\Exception\TaskException;
|
||||
use Robo\Task\BaseTask;
|
||||
use Robo\Contract\SimulatedInterface;
|
||||
use Robo\Common\CommandReceiver;
|
||||
use Robo\Common\ExecOneCommand;
|
||||
|
||||
/**
|
||||
* Runs multiple commands on a remote server.
|
||||
* Per default, commands are combined with &&, unless stopOnFail is false.
|
||||
*
|
||||
* ```php
|
||||
* <?php
|
||||
*
|
||||
* $this->taskSshExec('remote.example.com', 'user')
|
||||
* ->remoteDir('/var/www/html')
|
||||
* ->exec('ls -la')
|
||||
* ->exec('chmod g+x logs')
|
||||
* ->run();
|
||||
*
|
||||
* ```
|
||||
*
|
||||
* You can even exec other tasks (which implement CommandInterface):
|
||||
*
|
||||
* ```php
|
||||
* $gitTask = $this->taskGitStack()
|
||||
* ->checkout('master')
|
||||
* ->pull();
|
||||
*
|
||||
* $this->taskSshExec('remote.example.com')
|
||||
* ->remoteDir('/var/www/html/site')
|
||||
* ->exec($gitTask)
|
||||
* ->run();
|
||||
* ```
|
||||
*
|
||||
* You can configure the remote directory for all future calls:
|
||||
*
|
||||
* ```php
|
||||
* \Robo\Task\Remote\Ssh::configure('remoteDir', '/some-dir');
|
||||
* ```
|
||||
*/
|
||||
class Ssh extends BaseTask implements CommandInterface, SimulatedInterface, PrintedInterface
|
||||
{
|
||||
use CommandReceiver;
|
||||
use ExecOneCommand;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
protected $hostname;
|
||||
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $stopOnFail = true;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $exec = [];
|
||||
|
||||
/**
|
||||
* Changes to the given directory before running commands.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $remoteDir;
|
||||
|
||||
/**
|
||||
* @param null|string $hostname
|
||||
* @param null|string $user
|
||||
*/
|
||||
public function __construct($hostname = null, $user = null)
|
||||
{
|
||||
$this->hostname = $hostname;
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $hostname
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function hostname($hostname)
|
||||
{
|
||||
$this->hostname = $hostname;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $user
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function user($user)
|
||||
{
|
||||
$this->user = $user;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not to chain commands together with && and stop the chain if one command fails.
|
||||
*
|
||||
* @param bool $stopOnFail
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function stopOnFail($stopOnFail = true)
|
||||
{
|
||||
$this->stopOnFail = $stopOnFail;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes to the given directory before running commands.
|
||||
*
|
||||
* @param string $remoteDir
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function remoteDir($remoteDir)
|
||||
{
|
||||
$this->remoteDir = $remoteDir;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function identityFile($filename)
|
||||
{
|
||||
$this->option('-i', $filename);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $port
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function port($port)
|
||||
{
|
||||
$this->option('-p', $port);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function forcePseudoTty()
|
||||
{
|
||||
$this->option('-t');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function quiet()
|
||||
{
|
||||
$this->option('-q');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function verbose()
|
||||
{
|
||||
$this->option('-v');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[]|CommandInterface $command
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function exec($command)
|
||||
{
|
||||
if (is_array($command)) {
|
||||
$command = implode(' ', array_filter($command));
|
||||
}
|
||||
|
||||
$this->exec[] = $command;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns command that can be executed.
|
||||
* This method is used to pass generated command from one task to another.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
$commands = [];
|
||||
foreach ($this->exec as $command) {
|
||||
$commands[] = $this->receiveCommand($command);
|
||||
}
|
||||
|
||||
$remoteDir = $this->remoteDir ? $this->remoteDir : $this->getConfigValue('remoteDir');
|
||||
if (!empty($remoteDir)) {
|
||||
array_unshift($commands, sprintf('cd "%s"', $remoteDir));
|
||||
}
|
||||
$command = implode($this->stopOnFail ? ' && ' : ' ; ', $commands);
|
||||
|
||||
return $this->sshCommand($command);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->validateParameters();
|
||||
$command = $this->getCommand();
|
||||
return $this->executeCommand($command);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function simulate($context)
|
||||
{
|
||||
$command = $this->getCommand();
|
||||
$this->printTaskInfo("Running {command}", ['command' => $command] + $context);
|
||||
}
|
||||
|
||||
protected function validateParameters()
|
||||
{
|
||||
if (empty($this->hostname)) {
|
||||
throw new TaskException($this, 'Please set a hostname');
|
||||
}
|
||||
if (empty($this->exec)) {
|
||||
throw new TaskException($this, 'Please add at least one command');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ssh command string running $command on the remote.
|
||||
*
|
||||
* @param string|CommandInterface $command
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function sshCommand($command)
|
||||
{
|
||||
$command = $this->receiveCommand($command);
|
||||
$sshOptions = $this->arguments;
|
||||
$hostSpec = $this->hostname;
|
||||
if ($this->user) {
|
||||
$hostSpec = $this->user . '@' . $hostSpec;
|
||||
}
|
||||
|
||||
return "ssh{$sshOptions} {$hostSpec} '{$command}'";
|
||||
}
|
||||
}
|
||||
25
vendor/consolidation/robo/src/Task/Remote/Tasks.php
vendored
Normal file
25
vendor/consolidation/robo/src/Task/Remote/Tasks.php
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Remote;
|
||||
|
||||
trait Tasks
|
||||
{
|
||||
/**
|
||||
* @return \Robo\Task\Remote\Rsync|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskRsync()
|
||||
{
|
||||
return $this->task(Rsync::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $hostname
|
||||
* @param null|string $user
|
||||
*
|
||||
* @return \Robo\Task\Remote\Ssh|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskSshExec($hostname = null, $user = null)
|
||||
{
|
||||
return $this->task(Ssh::class, $hostname, $user);
|
||||
}
|
||||
}
|
||||
169
vendor/consolidation/robo/src/Task/Simulator.php
vendored
Normal file
169
vendor/consolidation/robo/src/Task/Simulator.php
vendored
Normal file
@ -0,0 +1,169 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task;
|
||||
|
||||
use Robo\Contract\WrappedTaskInterface;
|
||||
use Robo\Exception\TaskException;
|
||||
use Robo\TaskInfo;
|
||||
use Robo\Result;
|
||||
use Robo\Contract\TaskInterface;
|
||||
use Robo\Contract\SimulatedInterface;
|
||||
use Robo\Log\RoboLogLevel;
|
||||
use Robo\Contract\CommandInterface;
|
||||
|
||||
class Simulator extends BaseTask implements CommandInterface
|
||||
{
|
||||
/**
|
||||
* @var \Robo\Contract\TaskInterface
|
||||
*/
|
||||
protected $task;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $constructorParameters;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $stack = [];
|
||||
|
||||
/**
|
||||
* @param \Robo\Contract\TaskInterface $task
|
||||
* @param array $constructorParameters
|
||||
*/
|
||||
public function __construct(TaskInterface $task, $constructorParameters)
|
||||
{
|
||||
// TODO: If we ever want to convert the simulated task back into
|
||||
// an executable task, then we should save the wrapped task.
|
||||
$this->task = ($task instanceof WrappedTaskInterface) ? $task->original() : $task;
|
||||
$this->constructorParameters = $constructorParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $function
|
||||
* @param array $args
|
||||
*
|
||||
* @return \Robo\Result|$this
|
||||
*/
|
||||
public function __call($function, $args)
|
||||
{
|
||||
$this->stack[] = array_merge([$function], $args);
|
||||
$result = call_user_func_array([$this->task, $function], $args);
|
||||
return $result == $this->task ? $this : $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$callchain = '';
|
||||
foreach ($this->stack as $action) {
|
||||
$command = array_shift($action);
|
||||
$parameters = $this->formatParameters($action);
|
||||
$callchain .= "\n ->$command(<fg=green>$parameters</>)";
|
||||
}
|
||||
$context = $this->getTaskContext(
|
||||
[
|
||||
'_level' => RoboLogLevel::SIMULATED_ACTION,
|
||||
'simulated' => TaskInfo::formatTaskName($this->task),
|
||||
'parameters' => $this->formatParameters($this->constructorParameters),
|
||||
'_style' => ['simulated' => 'fg=blue;options=bold'],
|
||||
]
|
||||
);
|
||||
|
||||
// RoboLogLevel::SIMULATED_ACTION
|
||||
$this->printTaskInfo(
|
||||
"Simulating {simulated}({parameters})$callchain",
|
||||
$context
|
||||
);
|
||||
|
||||
$result = null;
|
||||
if ($this->task instanceof SimulatedInterface) {
|
||||
$result = $this->task->simulate($context);
|
||||
}
|
||||
if (!isset($result)) {
|
||||
$result = Result::success($this);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Danger: reach through the simulated wrapper and pull out the command
|
||||
* to be executed. This is used when using a simulated task with another
|
||||
* simulated task that runs commands, e.g. the Remote\Ssh task. Using
|
||||
* a simulated CommandInterface task with a non-simulated task may produce
|
||||
* unexpected results (e.g. execution!).
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
if (!$this->task instanceof CommandInterface) {
|
||||
throw new TaskException($this->task, 'Simulated task that is not a CommandInterface used as a CommandInterface.');
|
||||
}
|
||||
return $this->task->getCommand();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $action
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function formatParameters($action)
|
||||
{
|
||||
$parameterList = array_map([$this, 'convertParameter'], $action);
|
||||
return implode(', ', $parameterList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $item
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function convertParameter($item)
|
||||
{
|
||||
if (is_callable($item)) {
|
||||
return 'inline_function(...)';
|
||||
}
|
||||
if (is_array($item)) {
|
||||
return $this->shortenParameter(var_export($item, true));
|
||||
}
|
||||
if (is_object($item)) {
|
||||
return '[' . get_class($item) . ' object]';
|
||||
}
|
||||
if (is_string($item)) {
|
||||
return $this->shortenParameter("'$item'");
|
||||
}
|
||||
if (is_null($item)) {
|
||||
return 'null';
|
||||
}
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $item
|
||||
* @param string $shortForm
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function shortenParameter($item, $shortForm = '')
|
||||
{
|
||||
$maxLength = 80;
|
||||
$tailLength = 20;
|
||||
if (strlen($item) < $maxLength) {
|
||||
return $item;
|
||||
}
|
||||
if (!empty($shortForm)) {
|
||||
return $shortForm;
|
||||
}
|
||||
$item = trim($item);
|
||||
$tail = preg_replace("#.*\n#ms", '', substr($item, -$tailLength));
|
||||
$head = preg_replace("#\n.*#ms", '', substr($item, 0, $maxLength - (strlen($tail) + 5)));
|
||||
return "$head ... $tail";
|
||||
}
|
||||
}
|
||||
237
vendor/consolidation/robo/src/Task/StackBasedTask.php
vendored
Normal file
237
vendor/consolidation/robo/src/Task/StackBasedTask.php
vendored
Normal file
@ -0,0 +1,237 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task;
|
||||
|
||||
use Robo\Result;
|
||||
|
||||
/**
|
||||
* Extend StackBasedTask to create a Robo task that
|
||||
* runs a sequence of commands.
|
||||
*
|
||||
* This is particularly useful for wrapping an existing
|
||||
* object-oriented API. Doing it this way requires
|
||||
* less code than manually adding a method for each wrapped
|
||||
* function in the delegate. Additionally, wrapping the
|
||||
* external class in a StackBasedTask creates a loosely-coupled
|
||||
* interface -- i.e. if a new method is added to the delegate
|
||||
* class, it is not necessary to update your wrapper, as the
|
||||
* new functionality will be inherited.
|
||||
*
|
||||
* For example, you have:
|
||||
*
|
||||
* $frobinator = new Frobinator($a, $b, $c)
|
||||
* ->friz()
|
||||
* ->fraz()
|
||||
* ->frob();
|
||||
*
|
||||
* We presume that the existing library throws an exception on error.
|
||||
*
|
||||
* You want:
|
||||
*
|
||||
* $result = $this->taskFrobinator($a, $b, $c)
|
||||
* ->friz()
|
||||
* ->fraz()
|
||||
* ->frob()
|
||||
* ->run();
|
||||
*
|
||||
* Execution is deferred until run(), and a Robo\Result instance is
|
||||
* returned. Additionally, using Robo will covert Exceptions
|
||||
* into RoboResult objects.
|
||||
*
|
||||
* To create a new Robo task:
|
||||
*
|
||||
* - Make a new class that extends StackBasedTask
|
||||
* - Give it a constructor that creates a new Frobinator
|
||||
* - Override getDelegate(), and return the Frobinator instance
|
||||
*
|
||||
* Finally, add your new class to Tasks.php as usual,
|
||||
* and you are all done.
|
||||
*
|
||||
* If you need to add any methods to your task that should run
|
||||
* immediately (e.g. to set parameters used at run() time), just
|
||||
* implement them in your derived class.
|
||||
*
|
||||
* If you need additional methods that should run deferred, just
|
||||
* define them as 'protected function _foo()'. Then, users may
|
||||
* call $this->taskFrobinator()->foo() to get deferred execution
|
||||
* of _foo().
|
||||
*/
|
||||
abstract class StackBasedTask extends BaseTask
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $stack = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $stopOnFail = true;
|
||||
|
||||
/**
|
||||
* @param bool $stop
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function stopOnFail($stop = true)
|
||||
{
|
||||
$this->stopOnFail = $stop;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes should override the getDelegate() method, and
|
||||
* return an instance of the API class being wrapped. When this
|
||||
* is done, any method of the delegate is available as a method of
|
||||
* this class. Calling one of the delegate's methods will defer
|
||||
* execution until the run() method is called.
|
||||
*
|
||||
* @return null|object
|
||||
*/
|
||||
protected function getDelegate()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes that have more than one delegate may override
|
||||
* getCommandList to add as many delegate commands as desired to
|
||||
* the list of potential functions that __call() tried to find.
|
||||
*
|
||||
* @param string $function
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getDelegateCommandList($function)
|
||||
{
|
||||
return [[$this, "_$function"], [$this->getDelegate(), $function]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Print progress about the commands being executed
|
||||
*
|
||||
* @param string $command
|
||||
* @param string $action
|
||||
*/
|
||||
protected function printTaskProgress($command, $action)
|
||||
{
|
||||
$this->printTaskInfo('{command} {action}', ['command' => "{$command[1]}", 'action' => json_encode($action, JSON_UNESCAPED_SLASHES)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes can override processResult to add more
|
||||
* logic to result handling from functions. By default, it
|
||||
* is assumed that if a function returns in int, then
|
||||
* 0 == success, and any other value is the error code.
|
||||
*
|
||||
* @param int|\Robo\Result $function_result
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function processResult($function_result)
|
||||
{
|
||||
if (is_int($function_result)) {
|
||||
if ($function_result) {
|
||||
return Result::error($this, $function_result);
|
||||
}
|
||||
}
|
||||
return Result::success($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Record a function to call later.
|
||||
*
|
||||
* @param string $command
|
||||
* @param array $args
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function addToCommandStack($command, $args)
|
||||
{
|
||||
$this->stack[] = array_merge([$command], $args);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Any API function provided by the delegate that executes immediately
|
||||
* may be handled by __call automatically. These operations will all
|
||||
* be deferred until this task's run() method is called.
|
||||
*
|
||||
* @param string $function
|
||||
* @param array $args
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function __call($function, $args)
|
||||
{
|
||||
foreach ($this->getDelegateCommandList($function) as $command) {
|
||||
if (method_exists($command[0], $command[1])) {
|
||||
// Otherwise, we'll defer calling this function
|
||||
// until run(), and return $this.
|
||||
$this->addToCommandStack($command, $args);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
$message = "Method $function does not exist.\n";
|
||||
throw new \BadMethodCallException($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function progressIndicatorSteps()
|
||||
{
|
||||
// run() will call advanceProgressIndicator() once for each
|
||||
// file, one after calling stopBuffering, and again after compression.
|
||||
return count($this->stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run all of the queued objects on the stack
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->startProgressIndicator();
|
||||
$result = Result::success($this);
|
||||
|
||||
foreach ($this->stack as $action) {
|
||||
$command = array_shift($action);
|
||||
$this->printTaskProgress($command, $action);
|
||||
$this->advanceProgressIndicator();
|
||||
// TODO: merge data from the result on this call
|
||||
// with data from the result on the previous call?
|
||||
// For now, the result always comes from the last function.
|
||||
$result = $this->callTaskMethod($command, $action);
|
||||
if ($this->stopOnFail && $result && !$result->wasSuccessful()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->stopProgressIndicator();
|
||||
|
||||
// todo: add timing information to the result
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute one task method
|
||||
*
|
||||
* @param string $command
|
||||
* @param array $action
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function callTaskMethod($command, $action)
|
||||
{
|
||||
try {
|
||||
$function_result = call_user_func_array($command, $action);
|
||||
return $this->processResult($function_result);
|
||||
} catch (\Exception $e) {
|
||||
$this->printTaskError($e->getMessage());
|
||||
return Result::fromException($this, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
187
vendor/consolidation/robo/src/Task/Testing/Atoum.php
vendored
Normal file
187
vendor/consolidation/robo/src/Task/Testing/Atoum.php
vendored
Normal file
@ -0,0 +1,187 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Testing;
|
||||
|
||||
use Robo\Contract\CommandInterface;
|
||||
use Robo\Contract\PrintedInterface;
|
||||
use Robo\Task\BaseTask;
|
||||
use Robo\Common\ExecOneCommand;
|
||||
|
||||
/**
|
||||
* Runs [atoum](http://atoum.org/) tests
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskAtoum()
|
||||
* ->files('path/to/test.php')
|
||||
* ->configFile('config/dev.php')
|
||||
* ->run()
|
||||
*
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class Atoum extends BaseTask implements CommandInterface, PrintedInterface
|
||||
{
|
||||
use ExecOneCommand;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $command;
|
||||
|
||||
/**
|
||||
* Atoum constructor.
|
||||
*
|
||||
* @param null|string $pathToAtoum
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
public function __construct($pathToAtoum = null)
|
||||
{
|
||||
$this->command = $pathToAtoum;
|
||||
if (!$this->command) {
|
||||
$this->command = $this->findExecutable('atoum');
|
||||
}
|
||||
if (!$this->command) {
|
||||
throw new \Robo\Exception\TaskException(__CLASS__, "Neither local atoum nor global composer installation not found");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag or Tags to filter.
|
||||
*
|
||||
* @param string|string[] $tags
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function tags($tags)
|
||||
{
|
||||
return $this->addMultipleOption('tags', $tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display result using the light reporter.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function lightReport()
|
||||
{
|
||||
$this->option("--use-light-report");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display result using the tap reporter.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function tap()
|
||||
{
|
||||
$this->option("use-tap-report");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Path to the bootstrap file.
|
||||
|
||||
* @param string $file
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function bootstrap($file)
|
||||
{
|
||||
$this->option("bootstrap", $file);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Path to the config file.
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function configFile($file)
|
||||
{
|
||||
$this->option('-c', $file);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use atoum's debug mode.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function debug()
|
||||
{
|
||||
$this->option("debug");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test file or test files to run.
|
||||
*
|
||||
* @param string|string[]
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function files($files)
|
||||
{
|
||||
return $this->addMultipleOption('f', $files);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test directory or directories to run.
|
||||
*
|
||||
* @param string|string[]
|
||||
* A single directory or a list of directories.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function directories($directories)
|
||||
{
|
||||
return $this->addMultipleOption('directories', $directories);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $option
|
||||
* @param string|string[] $values
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function addMultipleOption($option, $values)
|
||||
{
|
||||
if (is_string($values)) {
|
||||
$values = [$values];
|
||||
}
|
||||
|
||||
foreach ($values as $value) {
|
||||
$this->option($option, $value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return $this->command . $this->arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->printTaskInfo('Running atoum ' . $this->arguments);
|
||||
|
||||
return $this->executeCommand($this->getCommand());
|
||||
}
|
||||
}
|
||||
162
vendor/consolidation/robo/src/Task/Testing/Behat.php
vendored
Normal file
162
vendor/consolidation/robo/src/Task/Testing/Behat.php
vendored
Normal file
@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Testing;
|
||||
|
||||
use Robo\Contract\CommandInterface;
|
||||
use Robo\Contract\PrintedInterface;
|
||||
use Robo\Task\BaseTask;
|
||||
use Robo\Common\ExecOneCommand;
|
||||
|
||||
/**
|
||||
* Executes Behat tests
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskBehat()
|
||||
* ->format('pretty')
|
||||
* ->noInteraction()
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
class Behat extends BaseTask implements CommandInterface, PrintedInterface
|
||||
{
|
||||
use ExecOneCommand;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $command;
|
||||
|
||||
/**
|
||||
* @var string[] $formaters available formaters for format option
|
||||
*/
|
||||
protected $formaters = ['progress', 'pretty', 'junit'];
|
||||
|
||||
/**
|
||||
* @var string[] $verbose_levels available verbose levels
|
||||
*/
|
||||
protected $verbose_levels = ['v', 'vv'];
|
||||
|
||||
/**
|
||||
* Behat constructor.
|
||||
*
|
||||
* @param null|string $pathToBehat
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
public function __construct($pathToBehat = null)
|
||||
{
|
||||
$this->command = $pathToBehat;
|
||||
if (!$this->command) {
|
||||
$this->command = $this->findExecutable('behat');
|
||||
}
|
||||
if (!$this->command) {
|
||||
throw new \Robo\Exception\TaskException(__CLASS__, "Neither composer nor phar installation of Behat found");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function stopOnFail()
|
||||
{
|
||||
$this->option('stop-on-failure');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function noInteraction()
|
||||
{
|
||||
$this->option('no-interaction');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $config_file
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function config($config_file)
|
||||
{
|
||||
$this->option('config', $config_file);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function colors()
|
||||
{
|
||||
$this->option('colors');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function noColors()
|
||||
{
|
||||
$this->option('no-colors');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $suite
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function suite($suite)
|
||||
{
|
||||
$this->option('suite', $suite);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $level
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function verbose($level = 'v')
|
||||
{
|
||||
if (!in_array($level, $this->verbose_levels)) {
|
||||
throw new \InvalidArgumentException('expected ' . implode(',', $this->verbose_levels));
|
||||
}
|
||||
$this->option('-' . $level);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $formater
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function format($formater)
|
||||
{
|
||||
if (!in_array($formater, $this->formaters)) {
|
||||
throw new \InvalidArgumentException('expected ' . implode(',', $this->formaters));
|
||||
}
|
||||
$this->option('format', $formater);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return $this->command . $this->arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->printTaskInfo('Running behat {arguments}', ['arguments' => $this->arguments]);
|
||||
return $this->executeCommand($this->getCommand());
|
||||
}
|
||||
}
|
||||
287
vendor/consolidation/robo/src/Task/Testing/Codecept.php
vendored
Normal file
287
vendor/consolidation/robo/src/Task/Testing/Codecept.php
vendored
Normal file
@ -0,0 +1,287 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Testing;
|
||||
|
||||
use Robo\Contract\PrintedInterface;
|
||||
use Robo\Exception\TaskException;
|
||||
use Robo\Task\BaseTask;
|
||||
use Robo\Contract\CommandInterface;
|
||||
use Robo\Common\ExecOneCommand;
|
||||
|
||||
/**
|
||||
* Executes Codeception tests
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* // config
|
||||
* $this->taskCodecept()
|
||||
* ->suite('acceptance')
|
||||
* ->env('chrome')
|
||||
* ->group('admin')
|
||||
* ->xml()
|
||||
* ->html()
|
||||
* ->run();
|
||||
*
|
||||
* ?>
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
class Codecept extends BaseTask implements CommandInterface, PrintedInterface
|
||||
{
|
||||
use ExecOneCommand;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $command;
|
||||
protected $providedPathToCodeception;
|
||||
|
||||
/**
|
||||
* @param string $pathToCodeception
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
public function __construct($pathToCodeception = '')
|
||||
{
|
||||
$this->providedPathToCodeception = $pathToCodeception;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $suite
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function suite($suite)
|
||||
{
|
||||
$this->option(null, $suite);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $testName
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function test($testName)
|
||||
{
|
||||
$this->option(null, $testName);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* set group option. Can be called multiple times
|
||||
*
|
||||
* @param string $group
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function group($group)
|
||||
{
|
||||
$this->option("group", $group);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $group
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function excludeGroup($group)
|
||||
{
|
||||
$this->option("skip-group", $group);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate json report
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function json($file = null)
|
||||
{
|
||||
$this->option("json", $file);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate xml JUnit report
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function xml($file = null)
|
||||
{
|
||||
$this->option("xml", $file);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate html report
|
||||
*
|
||||
* @param string $dir
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function html($dir = null)
|
||||
{
|
||||
$this->option("html", $dir);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate tap report
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function tap($file = null)
|
||||
{
|
||||
$this->option("tap", $file);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* provides config file other then default `codeception.yml` with `-c` option
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function configFile($file)
|
||||
{
|
||||
$this->option("-c", $file);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* collect codecoverage in raw format. You may pass name of cov file to save results
|
||||
*
|
||||
* @param null|string $cov
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function coverage($cov = null)
|
||||
{
|
||||
$this->option("coverage", $cov);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* execute in silent mode
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function silent()
|
||||
{
|
||||
$this->option("silent");
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* collect code coverage in xml format. You may pass name of xml file to save results
|
||||
*
|
||||
* @param string $xml
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function coverageXml($xml = null)
|
||||
{
|
||||
$this->option("coverage-xml", $xml);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* collect code coverage and generate html report. You may pass
|
||||
*
|
||||
* @param string $html
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function coverageHtml($html = null)
|
||||
{
|
||||
$this->option("coverage-html", $html);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $env
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function env($env)
|
||||
{
|
||||
$this->option("env", $env);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function debug()
|
||||
{
|
||||
$this->option("debug");
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function noRebuild()
|
||||
{
|
||||
$this->option("no-rebuild");
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function noExit()
|
||||
{
|
||||
$this->option("no-exit");
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $failGroup
|
||||
* @return $this
|
||||
*/
|
||||
public function failGroup($failGroup)
|
||||
{
|
||||
$this->option('override', "extensions: config: Codeception\\Extension\\RunFailed: fail-group: {$failGroup}");
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
if (!$this->command) {
|
||||
$this->command = $this->providedPathToCodeception;
|
||||
if (!$this->command) {
|
||||
$this->command = $this->findExecutable('codecept');
|
||||
}
|
||||
if (!$this->command) {
|
||||
debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||
throw new TaskException(__CLASS__, "Neither composer nor phar installation of Codeception found.");
|
||||
}
|
||||
$this->command .= ' run';
|
||||
}
|
||||
|
||||
return $this->command . $this->arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$command = $this->getCommand();
|
||||
$this->printTaskInfo('Executing {command}', ['command' => $command]);
|
||||
return $this->executeCommand($command);
|
||||
}
|
||||
}
|
||||
210
vendor/consolidation/robo/src/Task/Testing/PHPUnit.php
vendored
Normal file
210
vendor/consolidation/robo/src/Task/Testing/PHPUnit.php
vendored
Normal file
@ -0,0 +1,210 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Testing;
|
||||
|
||||
use Robo\Contract\CommandInterface;
|
||||
use Robo\Contract\PrintedInterface;
|
||||
use Robo\Task\BaseTask;
|
||||
use Robo\Common\ExecOneCommand;
|
||||
|
||||
/**
|
||||
* Runs PHPUnit tests
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskPHPUnit()
|
||||
* ->group('core')
|
||||
* ->bootstrap('test/bootstrap.php')
|
||||
* ->run()
|
||||
*
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class PHPUnit extends BaseTask implements CommandInterface, PrintedInterface
|
||||
{
|
||||
use ExecOneCommand;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $command;
|
||||
|
||||
/**
|
||||
* Directory of test files or single test file to run. Appended to
|
||||
* the command and arguments.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $files = '';
|
||||
|
||||
/**
|
||||
* PHPUnit constructor.
|
||||
*
|
||||
* @param null|string $pathToPhpUnit
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
public function __construct($pathToPhpUnit = null)
|
||||
{
|
||||
$this->command = $pathToPhpUnit;
|
||||
if (!$this->command) {
|
||||
$this->command = $this->findExecutablePhar('phpunit');
|
||||
}
|
||||
if (!$this->command) {
|
||||
throw new \Robo\Exception\TaskException(__CLASS__, "Neither local phpunit nor global composer installation not found");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filter
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function filter($filter)
|
||||
{
|
||||
$this->option('filter', $filter);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $group
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function group($group)
|
||||
{
|
||||
$this->option("group", $group);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $group
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function excludeGroup($group)
|
||||
{
|
||||
$this->option("exclude-group", $group);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `log-json` option to runner
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function json($file = null)
|
||||
{
|
||||
$this->option("log-json", $file);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds `log-junit` option
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function xml($file = null)
|
||||
{
|
||||
$this->option("log-junit", $file);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function tap($file = "")
|
||||
{
|
||||
$this->option("log-tap", $file);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function bootstrap($file)
|
||||
{
|
||||
$this->option("bootstrap", $file);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function configFile($file)
|
||||
{
|
||||
$this->option('-c', $file);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function debug()
|
||||
{
|
||||
$this->option("debug");
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Directory of test files or single test file to run.
|
||||
*
|
||||
* @param string $files
|
||||
* A single test file or a directory containing test files.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*
|
||||
* @deprecated Use file() or dir() method instead
|
||||
*/
|
||||
public function files($files)
|
||||
{
|
||||
if (!empty($this->files) || is_array($files)) {
|
||||
throw new \Robo\Exception\TaskException(__CLASS__, "Only one file or directory may be provided.");
|
||||
}
|
||||
$this->files = ' ' . $files;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the provided file.
|
||||
*
|
||||
* @param string $file
|
||||
* Path to file to test.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function file($file)
|
||||
{
|
||||
return $this->files($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return $this->command . $this->arguments . $this->files;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->printTaskInfo('Running PHPUnit {arguments}', ['arguments' => $this->arguments]);
|
||||
return $this->executeCommand($this->getCommand());
|
||||
}
|
||||
}
|
||||
154
vendor/consolidation/robo/src/Task/Testing/Phpspec.php
vendored
Normal file
154
vendor/consolidation/robo/src/Task/Testing/Phpspec.php
vendored
Normal file
@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Testing;
|
||||
|
||||
use Robo\Contract\PrintedInterface;
|
||||
use Robo\Task\BaseTask;
|
||||
use Robo\Contract\CommandInterface;
|
||||
use Robo\Common\ExecOneCommand;
|
||||
|
||||
/**
|
||||
* Executes Phpspec tests
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskPhpspec()
|
||||
* ->format('pretty')
|
||||
* ->noInteraction()
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
class Phpspec extends BaseTask implements CommandInterface, PrintedInterface
|
||||
{
|
||||
use ExecOneCommand;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $command;
|
||||
|
||||
/**
|
||||
* @var string[] $formaters
|
||||
* Available formaters for format option.
|
||||
*/
|
||||
protected $formaters = ['progress', 'html', 'pretty', 'junit', 'dot', 'tap'];
|
||||
|
||||
/**
|
||||
* @var array $verbose_levels
|
||||
* Available verbose levels.
|
||||
*/
|
||||
protected $verbose_levels = ['v', 'vv', 'vvv'];
|
||||
|
||||
/**
|
||||
* Phpspec constructor.
|
||||
*
|
||||
* @param null|string $pathToPhpspec
|
||||
*
|
||||
* @throws \Robo\Exception\TaskException
|
||||
*/
|
||||
public function __construct($pathToPhpspec = null)
|
||||
{
|
||||
$this->command = $pathToPhpspec;
|
||||
if (!$this->command) {
|
||||
$this->command = $this->findExecutable('phpspec');
|
||||
}
|
||||
if (!$this->command) {
|
||||
throw new \Robo\Exception\TaskException(__CLASS__, "Neither composer nor phar installation of Phpspec found");
|
||||
}
|
||||
$this->arg('run');
|
||||
}
|
||||
|
||||
public function stopOnFail()
|
||||
{
|
||||
$this->option('stop-on-failure');
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function noCodeGeneration()
|
||||
{
|
||||
$this->option('no-code-generation');
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function quiet()
|
||||
{
|
||||
$this->option('quiet');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $level
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function verbose($level = 'v')
|
||||
{
|
||||
if (!in_array($level, $this->verbose_levels)) {
|
||||
throw new \InvalidArgumentException('expected ' . implode(',', $this->verbose_levels));
|
||||
}
|
||||
$this->option('-' . $level);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function noAnsi()
|
||||
{
|
||||
$this->option('no-ansi');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function noInteraction()
|
||||
{
|
||||
$this->option('no-interaction');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $config_file
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function config($config_file)
|
||||
{
|
||||
$this->option('config', $config_file);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $formater
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function format($formater)
|
||||
{
|
||||
if (!in_array($formater, $this->formaters)) {
|
||||
throw new \InvalidArgumentException('expected ' . implode(',', $this->formaters));
|
||||
}
|
||||
$this->option('format', $formater);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return $this->command . $this->arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->printTaskInfo('Running phpspec {arguments}', ['arguments' => $this->arguments]);
|
||||
return $this->executeCommand($this->getCommand());
|
||||
}
|
||||
}
|
||||
56
vendor/consolidation/robo/src/Task/Testing/Tasks.php
vendored
Normal file
56
vendor/consolidation/robo/src/Task/Testing/Tasks.php
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Testing;
|
||||
|
||||
trait Tasks
|
||||
{
|
||||
/**
|
||||
* @param null|string $pathToCodeception
|
||||
*
|
||||
* @return \Robo\Task\Testing\Codecept|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskCodecept($pathToCodeception = null)
|
||||
{
|
||||
return $this->task(Codecept::class, $pathToCodeception);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $pathToPhpUnit
|
||||
*
|
||||
* @return \Robo\Task\Testing\PHPUnit|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskPhpUnit($pathToPhpUnit = null)
|
||||
{
|
||||
return $this->task(PHPUnit::class, $pathToPhpUnit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $pathToPhpspec
|
||||
*
|
||||
* @return \Robo\Task\Testing\Phpspec|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskPhpspec($pathToPhpspec = null)
|
||||
{
|
||||
return $this->task(Phpspec::class, $pathToPhpspec);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $pathToAtoum
|
||||
*
|
||||
* @return \Robo\Task\Testing\Atoum|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskAtoum($pathToAtoum = null)
|
||||
{
|
||||
return $this->task(Atoum::class, $pathToAtoum);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string $pathToBehat
|
||||
*
|
||||
* @return \Robo\Task\Testing\Behat|\Robo\Collection\CollectionBuilder
|
||||
*/
|
||||
protected function taskBehat($pathToBehat = null)
|
||||
{
|
||||
return $this->task(Behat::class, $pathToBehat);
|
||||
}
|
||||
}
|
||||
179
vendor/consolidation/robo/src/Task/Vcs/GitStack.php
vendored
Normal file
179
vendor/consolidation/robo/src/Task/Vcs/GitStack.php
vendored
Normal file
@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Vcs;
|
||||
|
||||
use Robo\Task\CommandStack;
|
||||
use Robo\Common\ProcessUtils;
|
||||
|
||||
/**
|
||||
* Runs Git commands in stack. You can use `stopOnFail()` to point that stack should be terminated on first fail.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskGitStack()
|
||||
* ->stopOnFail()
|
||||
* ->add('-A')
|
||||
* ->commit('adding everything')
|
||||
* ->push('origin','master')
|
||||
* ->tag('0.6.0')
|
||||
* ->push('origin','0.6.0')
|
||||
* ->run()
|
||||
*
|
||||
* $this->taskGitStack()
|
||||
* ->stopOnFail()
|
||||
* ->add('doc/*')
|
||||
* ->commit('doc updated')
|
||||
* ->push()
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class GitStack extends CommandStack
|
||||
{
|
||||
/**
|
||||
* @param string $pathToGit
|
||||
*/
|
||||
public function __construct($pathToGit = 'git')
|
||||
{
|
||||
$this->executable = $pathToGit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `git clone`
|
||||
*
|
||||
* @param string $repo
|
||||
* @param string $to
|
||||
* @param string $branch
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function cloneRepo($repo, $to = "", $branch = "")
|
||||
{
|
||||
$cmd = ['clone', $repo, $to];
|
||||
if (!empty($branch)) {
|
||||
$cmd[] = "--branch $branch";
|
||||
}
|
||||
return $this->exec($cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `git clone` with depth 1 as default
|
||||
*
|
||||
* @param string $repo
|
||||
* @param string $to
|
||||
* @param string $branch
|
||||
* @param int $depth
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function cloneShallow($repo, $to = '', $branch = "", $depth = 1)
|
||||
{
|
||||
$cmd = ["clone --depth $depth", $repo, $to];
|
||||
if (!empty($branch)) {
|
||||
$cmd[] = "--branch $branch";
|
||||
}
|
||||
|
||||
return $this->exec($cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `git add` command with files to add pattern
|
||||
*
|
||||
* @param string $pattern
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function add($pattern)
|
||||
{
|
||||
return $this->exec([__FUNCTION__, $pattern]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `git commit` command with a message
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $options
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function commit($message, $options = "")
|
||||
{
|
||||
$message = ProcessUtils::escapeArgument($message);
|
||||
return $this->exec([__FUNCTION__, "-m $message", $options]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `git pull` command.
|
||||
*
|
||||
* @param string $origin
|
||||
* @param string $branch
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function pull($origin = '', $branch = '')
|
||||
{
|
||||
return $this->exec([__FUNCTION__, $origin, $branch]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `git push` command
|
||||
*
|
||||
* @param string $origin
|
||||
* @param string $branch
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function push($origin = '', $branch = '')
|
||||
{
|
||||
return $this->exec([__FUNCTION__, $origin, $branch]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs git merge
|
||||
*
|
||||
* @param string $branch
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function merge($branch)
|
||||
{
|
||||
return $this->exec([__FUNCTION__, $branch]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `git checkout` command
|
||||
*
|
||||
* @param string $branch
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function checkout($branch)
|
||||
{
|
||||
return $this->exec([__FUNCTION__, $branch]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `git tag` command
|
||||
*
|
||||
* @param string $tag_name
|
||||
* @param string $message
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function tag($tag_name, $message = "")
|
||||
{
|
||||
if ($message != "") {
|
||||
$message = "-m '$message'";
|
||||
}
|
||||
return $this->exec([__FUNCTION__, $message, $tag_name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->printTaskInfo("Running git commands...");
|
||||
return parent::run();
|
||||
}
|
||||
}
|
||||
154
vendor/consolidation/robo/src/Task/Vcs/HgStack.php
vendored
Normal file
154
vendor/consolidation/robo/src/Task/Vcs/HgStack.php
vendored
Normal file
@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Vcs;
|
||||
|
||||
use Robo\Task\CommandStack;
|
||||
|
||||
/**
|
||||
* Runs hg commands in stack. You can use `stopOnFail()` to point that stack should be terminated on first fail.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->hgStack
|
||||
* ->cloneRepo('https://bitbucket.org/durin42/hgsubversion')
|
||||
* ->pull()
|
||||
* ->add()
|
||||
* ->commit('changed')
|
||||
* ->push()
|
||||
* ->tag('0.6.0')
|
||||
* ->push('0.6.0')
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class HgStack extends CommandStack
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $pathToHg
|
||||
*/
|
||||
public function __construct($pathToHg = 'hg')
|
||||
{
|
||||
$this->executable = $pathToHg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `hg clone`
|
||||
*
|
||||
* @param string $repo
|
||||
* @param string $to
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function cloneRepo($repo, $to = '')
|
||||
{
|
||||
return $this->exec(['clone', $repo, $to]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `hg add` command with files to add by pattern
|
||||
*
|
||||
* @param string $include
|
||||
* @param string $exclude
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function add($include = '', $exclude = '')
|
||||
{
|
||||
if (strlen($include) > 0) {
|
||||
$include = "-I {$include}";
|
||||
}
|
||||
|
||||
if (strlen($exclude) > 0) {
|
||||
$exclude = "-X {$exclude}";
|
||||
}
|
||||
|
||||
return $this->exec([__FUNCTION__, $include, $exclude]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `hg commit` command with a message
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $options
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function commit($message, $options = '')
|
||||
{
|
||||
return $this->exec([__FUNCTION__, "-m '{$message}'", $options]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `hg pull` command.
|
||||
*
|
||||
* @param string $branch
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function pull($branch = '')
|
||||
{
|
||||
if (strlen($branch) > 0) {
|
||||
$branch = "-b '{$branch}''";
|
||||
}
|
||||
|
||||
return $this->exec([__FUNCTION__, $branch]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `hg push` command
|
||||
*
|
||||
* @param string $branch
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function push($branch = '')
|
||||
{
|
||||
if (strlen($branch) > 0) {
|
||||
$branch = "-b '{$branch}'";
|
||||
}
|
||||
|
||||
return $this->exec([__FUNCTION__, $branch]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs hg merge
|
||||
*
|
||||
* @param string $revision
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function merge($revision = '')
|
||||
{
|
||||
if (strlen($revision) > 0) {
|
||||
$revision = "-r {$revision}";
|
||||
}
|
||||
|
||||
return $this->exec([__FUNCTION__, $revision]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `hg tag` command
|
||||
*
|
||||
* @param string $tag_name
|
||||
* @param string $message
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function tag($tag_name, $message = '')
|
||||
{
|
||||
if ($message !== '') {
|
||||
$message = "-m '{$message}'";
|
||||
}
|
||||
return $this->exec([__FUNCTION__, $message, $tag_name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->printTaskInfo('Running hg commands...');
|
||||
return parent::run();
|
||||
}
|
||||
}
|
||||
36
vendor/consolidation/robo/src/Task/Vcs/Shortcuts.php
vendored
Normal file
36
vendor/consolidation/robo/src/Task/Vcs/Shortcuts.php
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Vcs;
|
||||
|
||||
trait Shortcuts
|
||||
{
|
||||
/**
|
||||
* @param string $url
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _svnCheckout($url)
|
||||
{
|
||||
return $this->taskSvnStack()->checkout($url)->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _gitClone($url)
|
||||
{
|
||||
return $this->taskGitStack()->cloneRepo($url)->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*
|
||||
* @return \Robo\Result
|
||||
*/
|
||||
protected function _hgClone($url)
|
||||
{
|
||||
return $this->taskHgStack()->cloneRepo($url)->run();
|
||||
}
|
||||
}
|
||||
107
vendor/consolidation/robo/src/Task/Vcs/SvnStack.php
vendored
Normal file
107
vendor/consolidation/robo/src/Task/Vcs/SvnStack.php
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace Robo\Task\Vcs;
|
||||
|
||||
use Robo\Contract\CommandInterface;
|
||||
use Robo\Result;
|
||||
use Robo\Task\CommandStack;
|
||||
|
||||
/**
|
||||
* Runs Svn commands in stack. You can use `stopOnFail()` to point that stack should be terminated on first fail.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $this->taskSvnStack()
|
||||
* ->checkout('http://svn.collab.net/repos/svn/trunk')
|
||||
* ->run()
|
||||
*
|
||||
* // alternatively
|
||||
* $this->_svnCheckout('http://svn.collab.net/repos/svn/trunk');
|
||||
*
|
||||
* $this->taskSvnStack('username', 'password')
|
||||
* ->stopOnFail()
|
||||
* ->update()
|
||||
* ->add('doc/*')
|
||||
* ->commit('doc updated')
|
||||
* ->run();
|
||||
* ?>
|
||||
* ```
|
||||
*/
|
||||
class SvnStack extends CommandStack implements CommandInterface
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $stopOnFail = false;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $result;
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param string $pathToSvn
|
||||
*/
|
||||
public function __construct($username = '', $password = '', $pathToSvn = 'svn')
|
||||
{
|
||||
$this->executable = $pathToSvn;
|
||||
if (!empty($username)) {
|
||||
$this->executable .= " --username $username";
|
||||
}
|
||||
if (!empty($password)) {
|
||||
$this->executable .= " --password $password";
|
||||
}
|
||||
$this->result = Result::success($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates `svn update` command
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function update($path = '')
|
||||
{
|
||||
return $this->exec("update $path");
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `svn add` command with files to add pattern
|
||||
*
|
||||
* @param string $pattern
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function add($pattern = '')
|
||||
{
|
||||
return $this->exec("add $pattern");
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `svn commit` command with a message
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $options
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function commit($message, $options = "")
|
||||
{
|
||||
return $this->exec("commit -m '$message' $options");
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `svn checkout` command
|
||||
*
|
||||
* @param string $branch
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function checkout($branch)
|
||||
{
|
||||
return $this->exec("checkout $branch");
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user