Initial Drupal 11 with DDEV setup
This commit is contained in:
113
vendor/consolidation/site-process/src/Util/ArgumentProcessor.php
vendored
Normal file
113
vendor/consolidation/site-process/src/Util/ArgumentProcessor.php
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
<?php
|
||||
namespace Consolidation\SiteProcess\Util;
|
||||
|
||||
use Consolidation\SiteAlias\SiteAliasInterface;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Consolidation\SiteProcess\Transport\TransportInterface;
|
||||
|
||||
/**
|
||||
* ArgumentProcessor takes a set of arguments and options from the caller
|
||||
* and processes them with the provided site alias to produce a final
|
||||
* executable command that will run either locally or on a remote system,
|
||||
* as applicable.
|
||||
*/
|
||||
class ArgumentProcessor
|
||||
{
|
||||
private $short_options = ['vv', 'vvv'];
|
||||
|
||||
public function getShortOptions(): array
|
||||
{
|
||||
return $this->short_options;
|
||||
}
|
||||
|
||||
public function setShortOptions(array $short_options): void
|
||||
{
|
||||
$this->short_options = $short_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* selectArgs selects the appropriate set of arguments for the command
|
||||
* to be executed and orders them as needed.
|
||||
*
|
||||
* @param SiteAliasInterface $siteAlias Description of
|
||||
* @param array $args Command and arguments to execute (source)
|
||||
* @param array $options key / value pair of option and value in include
|
||||
* in final arguments
|
||||
* @param array $optionsPassedAsArgs key / value pair of option and value
|
||||
* to include in final arguments after the '--' argument.
|
||||
* @return array Command and arguments to execute
|
||||
*/
|
||||
public function selectArgs(SiteAliasInterface $siteAlias, $args, $options = [], $optionsPassedAsArgs = [])
|
||||
{
|
||||
// Split args into three arrays separated by the `--`
|
||||
list($leadingArgs, $dashDash, $remaingingArgs) = $this->findArgSeparator($args);
|
||||
$convertedOptions = $this->convertOptions($options);
|
||||
$convertedOptionsPassedAsArgs = $this->convertOptions($optionsPassedAsArgs);
|
||||
|
||||
// If the caller provided options that should be passed as args, then we
|
||||
// always need a `--`, whether or not one existed to begin with in $args
|
||||
if (!empty($convertedOptionsPassedAsArgs)) {
|
||||
$dashDash = ['--'];
|
||||
}
|
||||
|
||||
// Combine our separated args in the correct order. $dashDash will
|
||||
// always be `['--']` if $optionsPassedAsArgs or $remaingingArgs are
|
||||
// not empty, and otherwise will usually be empty.
|
||||
return array_merge(
|
||||
$leadingArgs,
|
||||
$convertedOptions,
|
||||
$dashDash,
|
||||
$convertedOptionsPassedAsArgs,
|
||||
$remaingingArgs
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* findArgSeparator finds the "--" argument in the provided arguments list,
|
||||
* if present, and returns the arguments in three sets.
|
||||
*
|
||||
* @return array of three arrays, leading, "--" and trailing
|
||||
*/
|
||||
protected function findArgSeparator($args)
|
||||
{
|
||||
$pos = array_search('--', $args);
|
||||
if ($pos === false) {
|
||||
return [$args, [], []];
|
||||
}
|
||||
|
||||
return [
|
||||
array_slice($args, 0, $pos),
|
||||
['--'],
|
||||
array_slice($args, $pos + 1),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* convertOptions takes an associative array of options (key / value) and
|
||||
* converts it to an array of strings in the form --key=value.
|
||||
*
|
||||
* @param array $options in key => value form
|
||||
* @return array options in --option=value form
|
||||
*/
|
||||
protected function convertOptions($options)
|
||||
{
|
||||
$result = [];
|
||||
foreach ($options as $option => $value) {
|
||||
$dashes = str_repeat('-', $this->dashCount($option));
|
||||
if ($value === true || $value === null) {
|
||||
$result[] = $dashes . $option;
|
||||
} elseif ($value === false) {
|
||||
// Ignore this option.
|
||||
} else {
|
||||
$result[] = "{$dashes}{$option}={$value}";
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function dashCount($name): int
|
||||
{
|
||||
return in_array($name, $this->getShortOptions()) ? 1 : 2;
|
||||
}
|
||||
}
|
||||
145
vendor/consolidation/site-process/src/Util/Escape.php
vendored
Normal file
145
vendor/consolidation/site-process/src/Util/Escape.php
vendored
Normal file
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
namespace Consolidation\SiteProcess\Util;
|
||||
|
||||
use Consolidation\SiteAlias\SiteAliasInterface;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Consolidation\Config\Util\Interpolator;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Consolidation\SiteProcess\Util\ShellOperatorInterface;
|
||||
|
||||
/**
|
||||
* Escape will shell-escape commandline arguments for different platforms.
|
||||
*/
|
||||
class Escape
|
||||
{
|
||||
/**
|
||||
* argsForSite escapes each argument in an array for the given site.
|
||||
*/
|
||||
public static function argsForSite(SiteAliasInterface $siteAlias, $args)
|
||||
{
|
||||
return array_map(
|
||||
function ($arg) use ($siteAlias) {
|
||||
return Escape::forSite($siteAlias, $arg);
|
||||
},
|
||||
$args
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* forSite escapes the provided argument for the specified alias record.
|
||||
*/
|
||||
public static function forSite(SiteAliasInterface $siteAlias, $arg)
|
||||
{
|
||||
return static::shellArg($arg, $siteAlias->os());
|
||||
}
|
||||
|
||||
/**
|
||||
* shellArg escapes the provided argument for the specified OS
|
||||
*
|
||||
* @param string|ShellOperatorInterface $arg The argument to escape
|
||||
* @param string|null $os The OS to escape for. Optional; defaults to LINUX
|
||||
*
|
||||
* @return string The escaped string
|
||||
*/
|
||||
public static function shellArg($arg, $os = null)
|
||||
{
|
||||
// Short-circuit escaping for simple params (keep stuff readable);
|
||||
// also skip escaping for shell operators (e.g. &&), which must not
|
||||
// be escaped.
|
||||
if (($arg instanceof ShellOperatorInterface) || preg_match('|^[a-zA-Z0-9@=.:/_-]*$|', $arg)) {
|
||||
return (string) $arg;
|
||||
}
|
||||
|
||||
if (static::isWindows($os)) {
|
||||
return static::windowsArg($arg);
|
||||
}
|
||||
return static::linuxArg($arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* isWindows determines whether the provided OS is Windows.
|
||||
*
|
||||
* @param string|null $os The OS to escape for.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isWindows($os = null)
|
||||
{
|
||||
// In most cases, $os will be NULL and PHP_OS will be returned. However,
|
||||
// if an OS is specified in $os, return that instead.
|
||||
$os = $os ?: PHP_OS;
|
||||
return strtoupper(substr($os, 0, 3)) === 'WIN';
|
||||
}
|
||||
|
||||
/**
|
||||
* linuxArg is the Linux version of escapeshellarg().
|
||||
*
|
||||
* This is intended to work the same way that escapeshellarg() does on
|
||||
* Linux. If we need to escape a string that will be used remotely on
|
||||
* a Linux system, then we need our own implementation of escapeshellarg,
|
||||
* because the Windows version behaves differently.
|
||||
*
|
||||
* Note that we behave somewhat differently than the built-in escapeshellarg()
|
||||
* with respect to whitespace replacement in order
|
||||
*
|
||||
* @param string $arg The argument to escape
|
||||
*
|
||||
* @return string The escaped string
|
||||
*/
|
||||
public static function linuxArg($arg)
|
||||
{
|
||||
// For single quotes existing in the string, we will "exit"
|
||||
// single-quote mode, add a \' and then "re-enter"
|
||||
// single-quote mode. The result of this is that
|
||||
// 'quote' becomes '\''quote'\''
|
||||
$arg = preg_replace('/\'/', '\'\\\'\'', $arg);
|
||||
|
||||
// Replace "\t", "\n", "\r", "\0", "\x0B" with a whitespace.
|
||||
// Note that this replacement makes Drush's escapeshellarg work differently
|
||||
// than the built-in escapeshellarg in PHP on Linux, as these characters
|
||||
// usually are NOT replaced. However, this was done deliberately to be more
|
||||
// conservative when running _drush_escapeshellarg_linux on Windows
|
||||
// (this can happen when generating a command to run on a remote Linux server.)
|
||||
//
|
||||
// TODO: Perhaps we should only do this if the local system is Windows?
|
||||
// n.b. that would be a little more complicated to test.
|
||||
$arg = str_replace(["\t", "\n", "\r", "\0", "\x0B"], ' ', $arg);
|
||||
|
||||
// Add surrounding quotes.
|
||||
$arg = "'" . $arg . "'";
|
||||
|
||||
return $arg;
|
||||
}
|
||||
|
||||
/**
|
||||
* windowsArg is the Windows version of escapeshellarg().
|
||||
*
|
||||
* @param string $arg The argument to escape
|
||||
*
|
||||
* @return string The escaped string
|
||||
*/
|
||||
public static function windowsArg($arg)
|
||||
{
|
||||
if ('' === $arg || null === $arg) {
|
||||
return '""';
|
||||
}
|
||||
if (false !== strpos($arg, "\0")) {
|
||||
$arg = str_replace("\0", '?', $arg);
|
||||
}
|
||||
if (!preg_match('/[\/()%!^"<>&|\s]/', $arg)) {
|
||||
return $arg;
|
||||
}
|
||||
// Double up existing backslashes
|
||||
$arg = preg_replace('/(\\\\+)$/', '$1$1', $arg);
|
||||
|
||||
// Replacing whitespace for good measure (see comment above).
|
||||
$arg = str_replace(["\t", "\n", "\r", "\0", "\x0B"], ' ', $arg);
|
||||
|
||||
$arg = str_replace(['"', '^', '%', '!'], ['""', '"^^"', '"^%"', '"^!"'], $arg);
|
||||
|
||||
// Add surrounding quotes.
|
||||
$arg = '"' . $arg . '"';
|
||||
|
||||
return $arg;
|
||||
}
|
||||
}
|
||||
123
vendor/consolidation/site-process/src/Util/RealtimeOutputHandler.php
vendored
Normal file
123
vendor/consolidation/site-process/src/Util/RealtimeOutputHandler.php
vendored
Normal file
@ -0,0 +1,123 @@
|
||||
<?php
|
||||
namespace Consolidation\SiteProcess\Util;
|
||||
|
||||
use Symfony\Component\Process\Process;
|
||||
use Consolidation\Config\Util\Interpolator;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Output\NullOutput;
|
||||
|
||||
/**
|
||||
* RealtimeOutput can be provided to a process object when you want
|
||||
* to display the output of the running command as it is being produced.
|
||||
*/
|
||||
class RealtimeOutputHandler
|
||||
{
|
||||
protected $stdout;
|
||||
protected $stderr;
|
||||
protected $stdoutMarker = '';
|
||||
protected $stderrMarker = '';
|
||||
|
||||
/**
|
||||
* Provide the output streams to use for stdout and stderr
|
||||
*/
|
||||
const MARKER_ERR = '> ';
|
||||
|
||||
public function __construct(OutputInterface $stdout, OutputInterface $stderr)
|
||||
{
|
||||
$this->stdout = $stdout;
|
||||
$this->stderr = $stderr;
|
||||
|
||||
$this->stdoutMarker = '';
|
||||
$this->stderrMarker = self::MARKER_ERR;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gives us an opportunity to adapt to the settings of the
|
||||
* process object (e.g. do we need to do anything differently if
|
||||
* it is in tty mode, etc.)
|
||||
*/
|
||||
public function configure(Process $process)
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* setStderrMarker defines the string that should be added at
|
||||
* the beginning of every line of stderr that is printed.
|
||||
*/
|
||||
public function setStderrMarker($marker)
|
||||
{
|
||||
$this->stderrMarker = $marker;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* setStdoutMarker defines the string that should be added at
|
||||
* the beginning of every line of stdout that is printed.
|
||||
*/
|
||||
public function setStdoutMarker($marker)
|
||||
{
|
||||
$this->stdoutMarker = $marker;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* hideStdout overrides whatever was formerly stored in $this->stdout
|
||||
* with a null output buffer so that none of the standard output data
|
||||
* is visible.
|
||||
*/
|
||||
public function hideStdout()
|
||||
{
|
||||
$this->stdout = new NullOutput();
|
||||
$this->stdoutMarker = '';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* hideStderr serves the same function as hideStdout, but for the
|
||||
* standard error stream. Note that it is not useful to unconditionally
|
||||
* call both hideStdout and hideStderr; if no output is desired, then
|
||||
* the RealtimeOutputHandler should not be used.
|
||||
*/
|
||||
public function hideStderr()
|
||||
{
|
||||
$this->stderr = new NullOutput();
|
||||
$this->stderrMarker = '';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this object is used as a callable, then run 'handleOutput'.
|
||||
*/
|
||||
public function __invoke($type, $buffer)
|
||||
{
|
||||
$this->handleOutput($type, $buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method when you want real-time output from a Process call.
|
||||
* @param string $type
|
||||
* @param string $buffer
|
||||
*/
|
||||
public function handleOutput($type, $buffer)
|
||||
{
|
||||
if (Process::ERR === $type) {
|
||||
$this->stderr->write($this->addMarker($buffer, $this->stderrMarker), false, OutputInterface::OUTPUT_RAW);
|
||||
} else {
|
||||
$this->stdout->write($this->addMarker($buffer, $this->stdoutMarker), false, OutputInterface::OUTPUT_RAW);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that every line in $buffer begins with a MARKER_ERR.
|
||||
*/
|
||||
protected function addMarker($buffer, $marker)
|
||||
{
|
||||
// Exit early if there is no marker to add
|
||||
if (empty($marker)) {
|
||||
return $buffer;
|
||||
}
|
||||
// Add a marker on the beginning of every line.
|
||||
return $marker . rtrim(implode("\n" . $marker, explode("\n", $buffer)), $marker);
|
||||
}
|
||||
}
|
||||
52
vendor/consolidation/site-process/src/Util/Shell.php
vendored
Normal file
52
vendor/consolidation/site-process/src/Util/Shell.php
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
namespace Consolidation\SiteProcess\Util;
|
||||
|
||||
/**
|
||||
* Shell::op is a static factory that will create shell operators for use
|
||||
* in command line arguments list. Shell operators are characters that have
|
||||
* special meaning to the shell, such as "output redirection". When a shell
|
||||
* operator object is used, it indicates that this element is intended to
|
||||
* be used as an operator, and is not simply some other parameter to be escaped.
|
||||
*/
|
||||
class Shell implements ShellOperatorInterface
|
||||
{
|
||||
protected $value;
|
||||
|
||||
public static function op($operator)
|
||||
{
|
||||
static::validateOp($operator);
|
||||
return new self($operator);
|
||||
}
|
||||
|
||||
public static function preEscaped($value)
|
||||
{
|
||||
return new self($value);
|
||||
}
|
||||
|
||||
public function __construct($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
protected static function validateOp($operator)
|
||||
{
|
||||
$valid = [
|
||||
'&&',
|
||||
'||',
|
||||
'|',
|
||||
'<',
|
||||
'>',
|
||||
'>>',
|
||||
';',
|
||||
];
|
||||
|
||||
if (!in_array($operator, $valid)) {
|
||||
throw new \Exception($operator . ' is not a valid shell operator.');
|
||||
}
|
||||
}
|
||||
}
|
||||
10
vendor/consolidation/site-process/src/Util/ShellOperatorInterface.php
vendored
Normal file
10
vendor/consolidation/site-process/src/Util/ShellOperatorInterface.php
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace Consolidation\SiteProcess\Util;
|
||||
|
||||
/**
|
||||
* ShellOperatorInterface is a marker interface indicating that the object
|
||||
* represents a shell operator.
|
||||
*/
|
||||
interface ShellOperatorInterface
|
||||
{
|
||||
}
|
||||
27
vendor/consolidation/site-process/src/Util/Tty.php
vendored
Normal file
27
vendor/consolidation/site-process/src/Util/Tty.php
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace Consolidation\SiteProcess\Util;
|
||||
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
/**
|
||||
* Wrapper for universal support of TTY-related functionality across versions of
|
||||
* Symfony Process.
|
||||
*/
|
||||
class Tty
|
||||
{
|
||||
/**
|
||||
* In Symfony Process 4+, this is simply a wrapper for Process::isTtySupported().
|
||||
* In lower versions, it mimics the same functionality.
|
||||
*/
|
||||
public static function isTtySupported()
|
||||
{
|
||||
// Start off by checking STDIN with `posix_isatty`, as that appears to be more reliable
|
||||
if (function_exists('posix_isatty')) {
|
||||
return posix_isatty(STDIN);
|
||||
}
|
||||
if (method_exists('\Symfony\Component\Process\Process', 'isTtySupported')) {
|
||||
return Process::isTtySupported();
|
||||
}
|
||||
return (bool) @proc_open('echo 1 >/dev/null', array(array('file', '/dev/tty', 'r'), array('file', '/dev/tty', 'w'), array('file', '/dev/tty', 'w')), $pipes);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user