Initial Drupal 11 with DDEV setup
This commit is contained in:
		
							
								
								
									
										642
									
								
								vendor/consolidation/robo/src/Runtime/Runner.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										642
									
								
								vendor/consolidation/robo/src/Runtime/Runner.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,642 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Robo\Runtime;
 | 
			
		||||
 | 
			
		||||
use Robo\Robo;
 | 
			
		||||
use Composer\Autoload\ClassLoader;
 | 
			
		||||
use Symfony\Component\Console\Input\ArgvInput;
 | 
			
		||||
use Symfony\Component\Console\Input\StringInput;
 | 
			
		||||
use Robo\Contract\BuilderAwareInterface;
 | 
			
		||||
use Robo\Collection\CollectionBuilder;
 | 
			
		||||
use Robo\Common\IO;
 | 
			
		||||
use Robo\Exception\TaskExitException;
 | 
			
		||||
use League\Container\ContainerAwareInterface;
 | 
			
		||||
use League\Container\ContainerAwareTrait;
 | 
			
		||||
use League\Container\Exception\ContainerException;
 | 
			
		||||
use Consolidation\Config\Util\EnvConfig;
 | 
			
		||||
use Symfony\Component\Console\Output\NullOutput;
 | 
			
		||||
 | 
			
		||||
class Runner implements ContainerAwareInterface
 | 
			
		||||
{
 | 
			
		||||
    use IO;
 | 
			
		||||
    use ContainerAwareTrait;
 | 
			
		||||
 | 
			
		||||
    const ROBOCLASS = 'RoboFile';
 | 
			
		||||
    const ROBOFILE = 'RoboFile.php';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
    protected $roboClass;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
    protected $roboFile;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Working dir of Robo.
 | 
			
		||||
     *
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
    protected $dir;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var string[]
 | 
			
		||||
     */
 | 
			
		||||
    protected $errorConditions = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * GitHub Repo for SelfUpdate.
 | 
			
		||||
     *
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
    protected $selfUpdateRepository = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Filename to load configuration from (set to 'robo.yml' for RoboFiles).
 | 
			
		||||
     *
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
    protected $configFilename = 'conf.yml';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var string prefix for environment variable configuration overrides
 | 
			
		||||
     */
 | 
			
		||||
    protected $envConfigPrefix = false;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var null|\Composer\Autoload\ClassLoader
 | 
			
		||||
     */
 | 
			
		||||
    protected $classLoader = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
    protected $relativePluginNamespace;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Class Constructor
 | 
			
		||||
     *
 | 
			
		||||
     * @param null|string $roboClass
 | 
			
		||||
     * @param null|string $roboFile
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct($roboClass = null, $roboFile = null)
 | 
			
		||||
    {
 | 
			
		||||
        // set the const as class properties to allow overwriting in child classes
 | 
			
		||||
        $this->roboClass = $roboClass ? $roboClass : self::ROBOCLASS ;
 | 
			
		||||
        $this->roboFile  = $roboFile ? $roboFile : self::ROBOFILE;
 | 
			
		||||
        $this->dir = getcwd();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $msg
 | 
			
		||||
     * @param string $errorType
 | 
			
		||||
     */
 | 
			
		||||
    protected function errorCondition($msg, $errorType)
 | 
			
		||||
    {
 | 
			
		||||
        $this->errorConditions[$msg] = $errorType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param \Symfony\Component\Console\Output\OutputInterface $output
 | 
			
		||||
     *
 | 
			
		||||
     * @return bool
 | 
			
		||||
     */
 | 
			
		||||
    protected function loadRoboFile($output)
 | 
			
		||||
    {
 | 
			
		||||
        // If we have not been provided an output object, make a temporary one.
 | 
			
		||||
        if (!$output) {
 | 
			
		||||
            $output = new \Symfony\Component\Console\Output\ConsoleOutput();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If $this->roboClass is a single class that has not already
 | 
			
		||||
        // been loaded, then we will try to obtain it from $this->roboFile.
 | 
			
		||||
        // If $this->roboClass is an array, we presume all classes requested
 | 
			
		||||
        // are available via the autoloader.
 | 
			
		||||
        if (is_array($this->roboClass) || class_exists($this->roboClass)) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        if (!file_exists($this->dir)) {
 | 
			
		||||
            $this->errorCondition("Path `{$this->dir}` is invalid; please provide a valid absolute path to the Robofile to load.", 'red');
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $realDir = realpath($this->dir);
 | 
			
		||||
 | 
			
		||||
        $roboFilePath = $realDir . DIRECTORY_SEPARATOR . $this->roboFile;
 | 
			
		||||
        if (!file_exists($roboFilePath)) {
 | 
			
		||||
            $requestedRoboFilePath = $this->dir . DIRECTORY_SEPARATOR . $this->roboFile;
 | 
			
		||||
            $this->errorCondition("Requested RoboFile `$requestedRoboFilePath` is invalid, please provide valid absolute path to load Robofile.", 'red');
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        require_once $roboFilePath;
 | 
			
		||||
 | 
			
		||||
        if (!class_exists($this->roboClass)) {
 | 
			
		||||
            $this->errorCondition("Class {$this->roboClass} was not loaded.", 'red');
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param array $argv
 | 
			
		||||
     * @param null|string $appName
 | 
			
		||||
     * @param null|string $appVersion
 | 
			
		||||
     * @param null|\Symfony\Component\Console\Output\OutputInterface $output
 | 
			
		||||
     *
 | 
			
		||||
     * @return int
 | 
			
		||||
     */
 | 
			
		||||
    public function execute($argv, $appName = null, $appVersion = null, $output = null)
 | 
			
		||||
    {
 | 
			
		||||
        $argv = $this->shebang($argv);
 | 
			
		||||
        $argv = $this->processRoboOptions($argv);
 | 
			
		||||
        $app = null;
 | 
			
		||||
        if ($appName && $appVersion) {
 | 
			
		||||
            $app = Robo::createDefaultApplication($appName, $appVersion);
 | 
			
		||||
        }
 | 
			
		||||
        $commandFiles = $this->getRoboFileCommands($output);
 | 
			
		||||
        return $this->run($argv, $output, $app, $commandFiles, $this->classLoader);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Return an initialized application loaded with specified commands and configuration.
 | 
			
		||||
     *
 | 
			
		||||
     * This should ONLY be used for testing purposes. Works well in conjunction with Symfony's CommandTester.
 | 
			
		||||
     *
 | 
			
		||||
     * @see https://symfony.com/doc/current/console.html#testing-commands
 | 
			
		||||
     * @see CommandTestertTest
 | 
			
		||||
     * @see CommandTesterTrait
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|null $appName
 | 
			
		||||
     *   Name of the application.
 | 
			
		||||
     * @param string|null $appVersion
 | 
			
		||||
     *   Version of the application.
 | 
			
		||||
     * @param string|array|null $commandFile
 | 
			
		||||
     *   Name of the specific command file, or array of commands, that should be included with the application.
 | 
			
		||||
     * @param \Robo\Config\Config|null $config
 | 
			
		||||
     *   Robo configuration to be used with the application.
 | 
			
		||||
     * @param \Composer\Autoload\ClassLoader|null $classLoader
 | 
			
		||||
     *   Class loader to use.
 | 
			
		||||
     *
 | 
			
		||||
     * @return \Robo\Application
 | 
			
		||||
     *   Initialized application based on passed configuration and command classes.
 | 
			
		||||
     */
 | 
			
		||||
    public function getAppForTesting($appName = null, $appVersion = null, $commandFile = null, $config = null, $classLoader = null)
 | 
			
		||||
    {
 | 
			
		||||
        $app = Robo::createDefaultApplication($appName, $appVersion);
 | 
			
		||||
        $output = new NullOutput();
 | 
			
		||||
        $container = Robo::createDefaultContainer(null, $output, $app, $config, $classLoader);
 | 
			
		||||
        if (!is_null($commandFile) && (is_array($commandFile) || is_string($commandFile))) {
 | 
			
		||||
            if (is_string($commandFile)) {
 | 
			
		||||
                $commandFile = [$commandFile];
 | 
			
		||||
            }
 | 
			
		||||
            $this->registerCommandClasses($app, $commandFile);
 | 
			
		||||
        }
 | 
			
		||||
        return $app;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a list of locations where config files may be loaded
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $userConfig
 | 
			
		||||
     *
 | 
			
		||||
     * @return string[]
 | 
			
		||||
     */
 | 
			
		||||
    protected function getConfigFilePaths($userConfig)
 | 
			
		||||
    {
 | 
			
		||||
        // Look for application config at the root of the application.
 | 
			
		||||
        // Find the root relative to this file, considering that Robo itself
 | 
			
		||||
        // might be the application, or it might be in the `vendor` directory.
 | 
			
		||||
        $roboAppConfig = dirname(__DIR__) . '/' . basename($userConfig);
 | 
			
		||||
        if (basename(dirname(__DIR__, 3)) == 'vendor') {
 | 
			
		||||
            $roboAppConfig = dirname(__DIR__, 4) . '/' . basename($userConfig);
 | 
			
		||||
        }
 | 
			
		||||
        $configFiles = [$roboAppConfig, $userConfig];
 | 
			
		||||
        if (dirname($userConfig) != '.') {
 | 
			
		||||
            $configFiles[] = basename($userConfig);
 | 
			
		||||
        }
 | 
			
		||||
        return $configFiles;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param null|array|\Symfony\Component\Console\Input\InputInterface $input
 | 
			
		||||
     * @param null|\Symfony\Component\Console\Output\OutputInterface $output
 | 
			
		||||
     * @param null|\Robo\Application $app
 | 
			
		||||
     * @param array[] $commandFiles
 | 
			
		||||
     * @param null|ClassLoader $classLoader
 | 
			
		||||
     *
 | 
			
		||||
     * @return int
 | 
			
		||||
     */
 | 
			
		||||
    public function run($input = null, $output = null, $app = null, $commandFiles = [], $classLoader = null)
 | 
			
		||||
    {
 | 
			
		||||
        // Create default input and output objects if they were not provided
 | 
			
		||||
        if (!$input) {
 | 
			
		||||
            $input = new StringInput('');
 | 
			
		||||
        }
 | 
			
		||||
        if (is_array($input)) {
 | 
			
		||||
            $input = new ArgvInput($input);
 | 
			
		||||
        }
 | 
			
		||||
        if (!$output) {
 | 
			
		||||
            $output = new \Symfony\Component\Console\Output\ConsoleOutput();
 | 
			
		||||
        }
 | 
			
		||||
        $this->setInput($input);
 | 
			
		||||
        $this->setOutput($output);
 | 
			
		||||
 | 
			
		||||
        // If we were not provided a container, then create one
 | 
			
		||||
        try {
 | 
			
		||||
            $this->getContainer();
 | 
			
		||||
        } catch (ContainerException $e) {
 | 
			
		||||
            $configFiles = $this->getConfigFilePaths($this->configFilename);
 | 
			
		||||
            $config = Robo::createConfiguration($configFiles);
 | 
			
		||||
            if ($this->envConfigPrefix) {
 | 
			
		||||
                $envConfig = new EnvConfig($this->envConfigPrefix);
 | 
			
		||||
                $config->addContext('env', $envConfig);
 | 
			
		||||
            }
 | 
			
		||||
            $container = Robo::createDefaultContainer($input, $output, $app, $config, $classLoader);
 | 
			
		||||
            $this->setContainer($container);
 | 
			
		||||
            // Automatically register a shutdown function and
 | 
			
		||||
            // an error handler when we provide the container.
 | 
			
		||||
            $this->installRoboHandlers();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!$app) {
 | 
			
		||||
            $app = Robo::application();
 | 
			
		||||
        }
 | 
			
		||||
        if ($app instanceof \Robo\Application) {
 | 
			
		||||
            $app->addSelfUpdateCommand($this->getSelfUpdateRepository());
 | 
			
		||||
            if (!isset($commandFiles)) {
 | 
			
		||||
                $this->errorCondition("Robo is not initialized here. Please run `robo init` to create a new RoboFile.", 'yellow');
 | 
			
		||||
                $app->addInitRoboFileCommand($this->roboFile, $this->roboClass);
 | 
			
		||||
                $commandFiles = [];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!empty($this->relativePluginNamespace)) {
 | 
			
		||||
            $commandClasses = $this->discoverCommandClasses($this->relativePluginNamespace);
 | 
			
		||||
            $commandFiles = array_merge((array)$commandFiles, $commandClasses);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->registerCommandClasses($app, $commandFiles);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            $statusCode = $app->run($input, $output);
 | 
			
		||||
        } catch (TaskExitException $e) {
 | 
			
		||||
            $statusCode = $e->getCode() ?: 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If there were any error conditions in bootstrapping Robo,
 | 
			
		||||
        // print them only if the requested command did not complete
 | 
			
		||||
        // successfully.
 | 
			
		||||
        if ($statusCode) {
 | 
			
		||||
            foreach ($this->errorConditions as $msg => $color) {
 | 
			
		||||
                // TODO: This was 'yell'. Add styling?
 | 
			
		||||
                $output->writeln($msg); // used to wrap at 40 and write in $color
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $statusCode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param \Symfony\Component\Console\Output\OutputInterface $output
 | 
			
		||||
     *
 | 
			
		||||
     * @return null|string
 | 
			
		||||
     */
 | 
			
		||||
    protected function getRoboFileCommands($output)
 | 
			
		||||
    {
 | 
			
		||||
        if (!$this->loadRoboFile($output)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        return $this->roboClass;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param \Robo\Application $app
 | 
			
		||||
     * @param array $commandClasses
 | 
			
		||||
     */
 | 
			
		||||
    public function registerCommandClasses($app, $commandClasses)
 | 
			
		||||
    {
 | 
			
		||||
        foreach ((array)$commandClasses as $commandClass) {
 | 
			
		||||
            $this->registerCommandClass($app, $commandClass);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $relativeNamespace
 | 
			
		||||
     *
 | 
			
		||||
     * @return string[]
 | 
			
		||||
     */
 | 
			
		||||
    protected function discoverCommandClasses($relativeNamespace)
 | 
			
		||||
    {
 | 
			
		||||
        /** @var \Robo\ClassDiscovery\RelativeNamespaceDiscovery $discovery */
 | 
			
		||||
        $discovery = Robo::service('relativeNamespaceDiscovery');
 | 
			
		||||
        $discovery->setRelativeNamespace($relativeNamespace . '\Commands')
 | 
			
		||||
            ->setSearchPattern('/.*Commands?\.php$/');
 | 
			
		||||
        return $discovery->getClasses();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param \Robo\Application $app
 | 
			
		||||
     * @param string|BuilderAwareInterface|ContainerAwareInterface $commandClass
 | 
			
		||||
     *
 | 
			
		||||
     * @return null|object
 | 
			
		||||
     */
 | 
			
		||||
    public function registerCommandClass($app, $commandClass)
 | 
			
		||||
    {
 | 
			
		||||
        $container = Robo::getContainer();
 | 
			
		||||
        $roboCommandFileInstance = $this->instantiateCommandClass($commandClass);
 | 
			
		||||
        if (!$roboCommandFileInstance) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Register commands for all of the public methods in the RoboFile.
 | 
			
		||||
        $commandFactory = $container->get('commandFactory');
 | 
			
		||||
        $commandList = $commandFactory->createCommandsFromClass($roboCommandFileInstance);
 | 
			
		||||
        foreach ($commandList as $command) {
 | 
			
		||||
            $app->add($command);
 | 
			
		||||
        }
 | 
			
		||||
        return $roboCommandFileInstance;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string|\Robo\Contract\BuilderAwareInterface|\League\Container\ContainerAwareInterface $commandClass
 | 
			
		||||
     *
 | 
			
		||||
     * @return null|object
 | 
			
		||||
     */
 | 
			
		||||
    protected function instantiateCommandClass($commandClass)
 | 
			
		||||
    {
 | 
			
		||||
        $container = Robo::getContainer();
 | 
			
		||||
 | 
			
		||||
        // Register the RoboFile with the container and then immediately
 | 
			
		||||
        // fetch it; this ensures that all of the inflectors will run.
 | 
			
		||||
        // If the command class is already an instantiated object, then
 | 
			
		||||
        // just use it exactly as it was provided to us.
 | 
			
		||||
        if (is_string($commandClass)) {
 | 
			
		||||
            if (!class_exists($commandClass)) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            $reflectionClass = new \ReflectionClass($commandClass);
 | 
			
		||||
            if ($reflectionClass->isAbstract()) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $commandFileName = "{$commandClass}Commands";
 | 
			
		||||
            Robo::addShared($container, $commandFileName, $commandClass);
 | 
			
		||||
            $commandClass = $container->get($commandFileName);
 | 
			
		||||
        }
 | 
			
		||||
        // If the command class is a Builder Aware Interface, then
 | 
			
		||||
        // ensure that it has a builder.  Every command class needs
 | 
			
		||||
        // its own collection builder, as they have references to each other.
 | 
			
		||||
        if ($commandClass instanceof BuilderAwareInterface) {
 | 
			
		||||
            $builder = CollectionBuilder::create($container, $commandClass);
 | 
			
		||||
            $commandClass->setBuilder($builder);
 | 
			
		||||
        }
 | 
			
		||||
        if ($commandClass instanceof ContainerAwareInterface) {
 | 
			
		||||
            $commandClass->setContainer($container);
 | 
			
		||||
        }
 | 
			
		||||
        return $commandClass;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function installRoboHandlers()
 | 
			
		||||
    {
 | 
			
		||||
        register_shutdown_function(array($this, 'shutdown'));
 | 
			
		||||
        set_error_handler(array($this, 'handleError'));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Process a shebang script, if one was used to launch this Runner.
 | 
			
		||||
     *
 | 
			
		||||
     * @param array $args
 | 
			
		||||
     *
 | 
			
		||||
     * @return array $args
 | 
			
		||||
     *   With shebang script removed.
 | 
			
		||||
     */
 | 
			
		||||
    protected function shebang($args)
 | 
			
		||||
    {
 | 
			
		||||
        // Option 1: Shebang line names Robo, but includes no parameters.
 | 
			
		||||
        // #!/bin/env robo
 | 
			
		||||
        // The robo class may contain multiple commands; the user may
 | 
			
		||||
        // select which one to run, or even get a list of commands or
 | 
			
		||||
        // run 'help' on any of the available commands as usual.
 | 
			
		||||
        if ((count($args) > 1) && $this->isShebangFile($args[1])) {
 | 
			
		||||
            return array_merge([$args[0]], array_slice($args, 2));
 | 
			
		||||
        }
 | 
			
		||||
        // Option 2: Shebang line stipulates which command to run.
 | 
			
		||||
        // #!/bin/env robo mycommand
 | 
			
		||||
        // The robo class must contain a public method named 'mycommand'.
 | 
			
		||||
        // This command will be executed every time.  Arguments and options
 | 
			
		||||
        // may be provided on the commandline as usual.
 | 
			
		||||
        if ((count($args) > 2) && $this->isShebangFile($args[2])) {
 | 
			
		||||
            return array_merge([$args[0]], explode(' ', $args[1]), array_slice($args, 3));
 | 
			
		||||
        }
 | 
			
		||||
        return $args;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Determine if the specified argument is a path to a shebang script.
 | 
			
		||||
     * If so, load it.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $filepath
 | 
			
		||||
     *   File to check.
 | 
			
		||||
     *
 | 
			
		||||
     * @return bool
 | 
			
		||||
     *   Returns TRUE if shebang script was processed.
 | 
			
		||||
     */
 | 
			
		||||
    protected function isShebangFile($filepath)
 | 
			
		||||
    {
 | 
			
		||||
        // Avoid trying to call $filepath on remote URLs
 | 
			
		||||
        if ((strpos($filepath, '://') !== false) && (substr($filepath, 0, 7) != 'file://')) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (!is_file($filepath)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        $fp = fopen($filepath, "r");
 | 
			
		||||
        if ($fp === false) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        $line = fgets($fp);
 | 
			
		||||
        $result = $this->isShebangLine($line);
 | 
			
		||||
        if ($result) {
 | 
			
		||||
            while ($line = fgets($fp)) {
 | 
			
		||||
                $line = trim($line);
 | 
			
		||||
                if ($line == '<?php') {
 | 
			
		||||
                    $script = stream_get_contents($fp);
 | 
			
		||||
                    if (preg_match('#^class *([^ ]+)#m', $script, $matches)) {
 | 
			
		||||
                        $this->roboClass = $matches[1];
 | 
			
		||||
                        eval($script);
 | 
			
		||||
                        $result = true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        fclose($fp);
 | 
			
		||||
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Test to see if the provided line is a robo 'shebang' line.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $line
 | 
			
		||||
     *
 | 
			
		||||
     * @return bool
 | 
			
		||||
     */
 | 
			
		||||
    protected function isShebangLine($line)
 | 
			
		||||
    {
 | 
			
		||||
        return ((substr($line, 0, 2) == '#!') && (strstr($line, 'robo') !== false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check for Robo-specific arguments such as --load-from, process them,
 | 
			
		||||
     * and remove them from the array.  We have to process --load-from before
 | 
			
		||||
     * we set up Symfony Console.
 | 
			
		||||
     *
 | 
			
		||||
     * @param array $argv
 | 
			
		||||
     *
 | 
			
		||||
     * @return array
 | 
			
		||||
     */
 | 
			
		||||
    protected function processRoboOptions($argv)
 | 
			
		||||
    {
 | 
			
		||||
        // loading from other directory
 | 
			
		||||
        $pos = $this->arraySearchBeginsWith('--load-from', $argv) ?: array_search('-f', $argv);
 | 
			
		||||
        if ($pos === false) {
 | 
			
		||||
            return $argv;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $passThru = array_search('--', $argv);
 | 
			
		||||
        if (($passThru !== false) && ($passThru < $pos)) {
 | 
			
		||||
            return $argv;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (substr($argv[$pos], 0, 12) == '--load-from=') {
 | 
			
		||||
            $this->dir = substr($argv[$pos], 12);
 | 
			
		||||
        } elseif (isset($argv[$pos + 1])) {
 | 
			
		||||
            $this->dir = $argv[$pos + 1];
 | 
			
		||||
            unset($argv[$pos + 1]);
 | 
			
		||||
        }
 | 
			
		||||
        unset($argv[$pos]);
 | 
			
		||||
        // Make adjustments if '--load-from' points at a file.
 | 
			
		||||
        if (is_file($this->dir) || (substr($this->dir, -4) == '.php')) {
 | 
			
		||||
            $this->roboFile = basename($this->dir);
 | 
			
		||||
            $this->dir = dirname($this->dir);
 | 
			
		||||
            $className = basename($this->roboFile, '.php');
 | 
			
		||||
            if ($className != $this->roboFile) {
 | 
			
		||||
                $this->roboClass = $className;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // Convert directory to a real path, but only if the
 | 
			
		||||
        // path exists. We do not want to lose the original
 | 
			
		||||
        // directory if the user supplied a bad value.
 | 
			
		||||
        $realDir = realpath($this->dir);
 | 
			
		||||
        if ($realDir) {
 | 
			
		||||
            chdir($realDir);
 | 
			
		||||
            $this->dir = $realDir;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $argv;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $needle
 | 
			
		||||
     * @param string[] $haystack
 | 
			
		||||
     *
 | 
			
		||||
     * @return bool|int
 | 
			
		||||
     */
 | 
			
		||||
    protected function arraySearchBeginsWith($needle, $haystack)
 | 
			
		||||
    {
 | 
			
		||||
        for ($i = 0; $i < count($haystack); ++$i) {
 | 
			
		||||
            if (substr($haystack[$i], 0, strlen($needle)) == $needle) {
 | 
			
		||||
                return $i;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function shutdown()
 | 
			
		||||
    {
 | 
			
		||||
        $error = error_get_last();
 | 
			
		||||
        if (!is_array($error)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        $this->writeln(sprintf("<error>ERROR: %s \nin %s:%d\n</error>", $error['message'], $error['file'], $error['line']));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This is just a proxy error handler that checks the current error_reporting level.
 | 
			
		||||
     * In case error_reporting is disabled the error is marked as handled, otherwise
 | 
			
		||||
     * the normal internal error handling resumes.
 | 
			
		||||
     *
 | 
			
		||||
     * @return bool
 | 
			
		||||
     */
 | 
			
		||||
    public function handleError()
 | 
			
		||||
    {
 | 
			
		||||
        if (error_reporting() === 0) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function getSelfUpdateRepository()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->selfUpdateRepository;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param $selfUpdateRepository
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this
 | 
			
		||||
     */
 | 
			
		||||
    public function setSelfUpdateRepository($selfUpdateRepository)
 | 
			
		||||
    {
 | 
			
		||||
        $this->selfUpdateRepository = $selfUpdateRepository;
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $configFilename
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this
 | 
			
		||||
     */
 | 
			
		||||
    public function setConfigurationFilename($configFilename)
 | 
			
		||||
    {
 | 
			
		||||
        $this->configFilename = $configFilename;
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $envConfigPrefix
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this
 | 
			
		||||
     */
 | 
			
		||||
    public function setEnvConfigPrefix($envConfigPrefix)
 | 
			
		||||
    {
 | 
			
		||||
        $this->envConfigPrefix = $envConfigPrefix;
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param \Composer\Autoload\ClassLoader $classLoader
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this
 | 
			
		||||
     */
 | 
			
		||||
    public function setClassLoader(ClassLoader $classLoader)
 | 
			
		||||
    {
 | 
			
		||||
        $this->classLoader = $classLoader;
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $relativeNamespace
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this
 | 
			
		||||
     */
 | 
			
		||||
    public function setRelativePluginNamespace($relativeNamespace)
 | 
			
		||||
    {
 | 
			
		||||
        $this->relativePluginNamespace = $relativeNamespace;
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user