diff --git a/.platform/services.yaml b/.platform/services.yaml deleted file mode 100644 index e69de29bb..000000000 diff --git a/config/.gitignore b/config/.gitignore new file mode 100644 index 000000000..14d86ad62 --- /dev/null +++ b/config/.gitignore @@ -0,0 +1 @@ +/cache diff --git a/config/services.yaml b/config/services.yaml new file mode 100644 index 000000000..2597d4e03 --- /dev/null +++ b/config/services.yaml @@ -0,0 +1,48 @@ +# Configuration file for services (dependency injection). +# +# See https://symfony.com/doc/current/service_container.html +services: + _defaults: + autowire: true + autoconfigure: false + public: false + + # Set up all classes in src/Command as console commands. + Platformsh\Cli\Command\: + resource: '../src/Command/*' + tags: [console.command] + + # Set up all classes in src/Service as services automatically. + Platformsh\Cli\Service\: + resource: '../src/Service/*' + + # A few services are not inside the \Platformsh\Cli\Service namespace. + Platformsh\Cli\Local\ApplicationFinder: {} + Platformsh\Cli\Local\LocalBuild: {} + Platformsh\Cli\Local\LocalProject: + public: true + Platformsh\Cli\SshCert\Certifier: {} + + # A couple of other services have to be public. + Platformsh\Cli\Service\LegacyMigration: + public: true + Platformsh\Cli\Service\SelfUpdateChecker: + public: true + + # Configure the cache service, which is created via a factory. + Doctrine\Common\Cache\CacheProvider: + public: true + factory: 'Platformsh\Cli\Service\CacheFactory::createCacheProvider' + arguments: ['@Platformsh\Cli\Service\Config'] + + # Configure synthetic services, which are created and set after the + # container is compiled. + Platformsh\Cli\Application: + public: true + synthetic: true + Symfony\Component\Console\Output\OutputInterface: + public: true + synthetic: true + Symfony\Component\Console\Input\InputInterface: + public: true + synthetic: true diff --git a/services.yaml b/services.yaml deleted file mode 100644 index c5a2b8879..000000000 --- a/services.yaml +++ /dev/null @@ -1,165 +0,0 @@ -# Services are classes providing functionality needed in multiple places. -# -# See https://symfony.com/doc/3.4/service_container.html -# -# Public services can be accessed from the CommandBase->getService() method. -# Private services are only used by other services, via dependency injection. -services: - _defaults: - # Services are public by default. - public: true - - # Auto-wiring is disabled for simplicity (at least because the @input - # and @output services will be overridden). - autowire: false - - # Auto-configuring is not necessary. - autoconfigure: false - - activity_loader: - class: '\Platformsh\Cli\Service\ActivityLoader' - arguments: ['@output'] - - activity_monitor: - class: '\Platformsh\Cli\Service\ActivityMonitor' - arguments: ['@output', '@config', '@api'] - - api: - class: '\Platformsh\Cli\Service\Api' - arguments: ['@config', '@cache', '@output', '@token_config', '@file_lock'] - - app_finder: - class: '\Platformsh\Cli\Local\ApplicationFinder' - arguments: ['@config'] - - cache: - class: '\Doctrine\Common\Cache\CacheProvider' - factory: ['@cache_factory', 'createCacheProvider'] - arguments: ['@config'] - - cache_factory: - class: '\Platformsh\Cli\Service\CacheFactory' - public: false - - certifier: - class: '\Platformsh\Cli\SshCert\Certifier' - arguments: ['@api', '@config', '@shell', '@fs', '@output', '@file_lock'] - - config: - class: '\Platformsh\Cli\Service\Config' - - curl_cli: - class: '\Platformsh\Cli\Service\CurlCli' - arguments: ['@api'] - - drush: - class: '\Platformsh\Cli\Service\Drush' - arguments: ['@config', '@shell', '@local.project', '@api', '@app_finder'] - - file_lock: - class: '\Platformsh\Cli\Service\FileLock' - arguments: ['@config'] - - fs: - class: '\Platformsh\Cli\Service\Filesystem' - arguments: ['@shell'] - - git: - class: '\Platformsh\Cli\Service\Git' - arguments: ['@shell', '@ssh'] - - git_data_api: - class: '\Platformsh\Cli\Service\GitDataApi' - arguments: ['@api', '@cache'] - - identifier: - class: '\Platformsh\Cli\Service\Identifier' - arguments: ['@config', '@api', '@output', '@cache'] - - # This is a placeholder that will be overridden in the command invocation. - input: - class: '\Symfony\Component\Console\Input\ArrayInput' - public: false - arguments: [[]] - - local.build: - class: '\Platformsh\Cli\Local\LocalBuild' - arguments: ['@config', '@output', '@shell', '@fs', '@git', '@local.dependency_installer', '@app_finder'] - - local.dependency_installer: - class: '\Platformsh\Cli\Local\DependencyInstaller' - arguments: ['@output', '@shell'] - public: false - - local.project: - class: '\Platformsh\Cli\Local\LocalProject' - arguments: ['@config', '@git'] - - mount: - class: '\Platformsh\Cli\Service\Mount' - - # This is a placeholder that will be overridden in the command invocation. - output: - class: '\Symfony\Component\Console\Output\ConsoleOutput' - public: false - - property_formatter: - class: '\Platformsh\Cli\Service\PropertyFormatter' - arguments: ['@input'] - - question_helper: - class: '\Platformsh\Cli\Service\QuestionHelper' - arguments: ['@input', '@output'] - - remote_env_vars: - class: '\Platformsh\Cli\Service\RemoteEnvVars' - arguments: ['@ssh', '@cache', '@config'] - public: false - - relationships: - class: '\Platformsh\Cli\Service\Relationships' - arguments: ['@remote_env_vars'] - - rsync: - class: '\Platformsh\Cli\Service\Rsync' - arguments: ['@shell', '@ssh', '@ssh_diagnostics'] - - self_updater: - class: '\Platformsh\Cli\Service\SelfUpdater' - arguments: ['@input', '@output', '@config', '@question_helper'] - - shell: - class: '\Platformsh\Cli\Service\Shell' - arguments: ['@output'] - - ssh: - class: '\Platformsh\Cli\Service\Ssh' - arguments: ['@input', '@output', '@config', '@certifier', '@ssh_config', '@ssh_key'] - - ssh_config: - class: '\Platformsh\Cli\Service\SshConfig' - arguments: ['@config', '@fs', '@output', '@ssh_key', '@certifier'] - - ssh_diagnostics: - class: '\Platformsh\Cli\Service\SshDiagnostics' - arguments: ['@ssh', '@output', '@certifier', '@ssh_key', '@api', '@config'] - - ssh_key: - class: '\Platformsh\Cli\Service\SshKey' - arguments: ['@config', '@api', '@output'] - - state: - class: '\Platformsh\Cli\Service\State' - arguments: ['@config'] - - table: - class: '\Platformsh\Cli\Service\Table' - arguments: ['@input', '@output'] - - token_config: - class: '\Platformsh\Cli\Service\TokenConfig' - arguments: ['@config'] - - url: - class: '\Platformsh\Cli\Service\Url' - arguments: ['@shell', '@input', '@output'] diff --git a/src/Application.php b/src/Application.php index 7bcc9be89..868c9c099 100644 --- a/src/Application.php +++ b/src/Application.php @@ -1,16 +1,21 @@ cliConfig = new Config(); - $this->envPrefix = $this->cliConfig->get('application.env_prefix'); - parent::__construct($this->cliConfig->get('application.name'), $this->cliConfig->getVersion()); + // Initialize configuration (from config.yaml). + $this->config = $config ?: new Config(); + $this->envPrefix = $this->config->get('application.env_prefix'); + parent::__construct($this->config->get('application.name'), $this->config->getVersion()); // Use the configured timezone, or fall back to the system timezone. date_default_timezone_set( - $this->cliConfig->getWithDefault('application.timezone', TimezoneUtil::getTimezone()) + $this->config->getWithDefault('application.timezone', null) + ?: TimezoneUtil::getTimezone() ); - $this->addCommands($this->getCommands()); + // Set this application as the synthetic service named + // "Platformsh\Cli\Application". + $this->container()->set(__CLASS__, $this); - $this->setDefaultCommand('welcome'); + // Set up the command loader, which will load commands that are tagged + // appropriately in the services.yaml container configuration (any + // services tagged with "console.command"). + /** @var \Symfony\Component\Console\CommandLoader\CommandLoaderInterface $loader */ + $loader = $this->container()->get('console.command_loader'); + $this->setCommandLoader($loader); + // Set "welcome" as the default command. + $this->setDefaultCommand(WelcomeCommand::getDefaultName()); + + // Set up an event subscriber, which will listen for Console events. $dispatcher = new EventDispatcher(); - $dispatcher->addSubscriber(new EventSubscriber($this->cliConfig)); + /** @var CacheProvider $cache */ + $cache = $this->container()->get(CacheProvider::class); + // TODO + //$dispatcher->addSubscriber(new EventSubscriber($cache, $this->config)); $this->setDispatcher($dispatcher); } + /** + * {@inheritDoc} + */ + public function getVersion(): string { + return $this->config->getVersion(); + } + + /** + * Re-compile the container and alias caches. + */ + public function warmCaches(): void { + $this->container(true); + } + + /** + * {@inheritdoc} + * + * Prevent commands being enabled, according to config.yaml configuration. + */ + public function add(ConsoleCommand $command): ?ConsoleCommand + { + if (!$this->config->isCommandEnabled($command->getName())) { + $command->setApplication(null); + return null; + } + + return parent::add($command); + } + + /** + * Returns the Dependency Injection Container for the whole application. + * + * @param bool $recompile + * + * @return ContainerInterface + */ + private function container(bool $recompile = false) + { + $cacheFile = __DIR__ . '/../config/cache/container.php'; + $servicesFile = __DIR__ . '/../config/services.yaml'; + + if (!isset($this->container)) { + if (file_exists($cacheFile) && !getenv('PLATFORMSH_CLI_DEBUG') && !$recompile) { + // Load the cached container. + require_once $cacheFile; + $this->container = new \ProjectServiceContainer(); + } else { + // Compile a new container. + $this->container = new ContainerBuilder(); + try { + (new YamlFileLoader($this->container, new FileLocator())) + ->load($servicesFile); + } catch (\Exception $e) { + throw new \RuntimeException(sprintf( + 'Failed to load services.yaml file %s: %s', + $servicesFile, + $e->getMessage() + )); + } + $this->container->addCompilerPass(new AddConsoleCommandPass()); + $this->container->compile(); + $dumper = new PhpDumper($this->container); + if (!is_dir(dirname($cacheFile))) { + mkdir(dirname($cacheFile), 0755, true); + } + file_put_contents($cacheFile, $dumper->dump()); + } + } + + return $this->container; + } + /** * {@inheritdoc} */ @@ -90,206 +186,8 @@ protected function getDefaultInputDefinition(): InputDefinition */ protected function getDefaultCommands(): array { - // Override the default commands to add a custom HelpCommand and - // ListCommand. - return [new Command\HelpCommand(), new Command\ListCommand()]; - } - - /** - * @return \Symfony\Component\Console\Command\Command[] - */ - protected function getCommands() - { - static $commands = []; - if (count($commands)) { - return $commands; - } - - $commands[] = new Command\ApiCurlCommand(); - $commands[] = new Command\BotCommand(); - $commands[] = new Command\ClearCacheCommand(); - $commands[] = new Command\CompletionCommand(); - $commands[] = new Command\DecodeCommand(); - $commands[] = new Command\DocsCommand(); - $commands[] = new Command\LegacyMigrateCommand(); - $commands[] = new Command\MultiCommand(); - $commands[] = new Command\Activity\ActivityCancelCommand(); - $commands[] = new Command\Activity\ActivityGetCommand(); - $commands[] = new Command\Activity\ActivityListCommand(); - $commands[] = new Command\Activity\ActivityLogCommand(); - $commands[] = new Command\App\AppConfigGetCommand(); - $commands[] = new Command\App\AppListCommand(); - $commands[] = new Command\Auth\AuthInfoCommand(); - $commands[] = new Command\Auth\AuthTokenCommand(); - $commands[] = new Command\Auth\LogoutCommand(); - $commands[] = new Command\Auth\ApiTokenLoginCommand(); - $commands[] = new Command\Auth\BrowserLoginCommand(); - $commands[] = new Command\Auth\VerifyPhoneNumberCommand(); - $commands[] = new Command\BlueGreen\BlueGreenConcludeCommand(); - $commands[] = new Command\BlueGreen\BlueGreenDeployCommand(); - $commands[] = new Command\BlueGreen\BlueGreenEnableCommand(); - $commands[] = new Command\Certificate\CertificateAddCommand(); - $commands[] = new Command\Certificate\CertificateDeleteCommand(); - $commands[] = new Command\Certificate\CertificateGetCommand(); - $commands[] = new Command\Certificate\CertificateListCommand(); - $commands[] = new Command\Commit\CommitGetCommand(); - $commands[] = new Command\Commit\CommitListCommand(); - $commands[] = new Command\Db\DbSqlCommand(); - $commands[] = new Command\Db\DbDumpCommand(); - $commands[] = new Command\Db\DbSizeCommand(); - $commands[] = new Command\Domain\DomainAddCommand(); - $commands[] = new Command\Domain\DomainDeleteCommand(); - $commands[] = new Command\Domain\DomainGetCommand(); - $commands[] = new Command\Domain\DomainListCommand(); - $commands[] = new Command\Domain\DomainUpdateCommand(); - $commands[] = new Command\Environment\EnvironmentActivateCommand(); - $commands[] = new Command\Environment\EnvironmentBranchCommand(); - $commands[] = new Command\Environment\EnvironmentCheckoutCommand(); - $commands[] = new Command\Environment\EnvironmentCurlCommand(); - $commands[] = new Command\Environment\EnvironmentDeleteCommand(); - $commands[] = new Command\Environment\EnvironmentDrushCommand(); - $commands[] = new Command\Environment\EnvironmentHttpAccessCommand(); - $commands[] = new Command\Environment\EnvironmentListCommand(); - $commands[] = new Command\Environment\EnvironmentLogCommand(); - $commands[] = new Command\Environment\EnvironmentInfoCommand(); - $commands[] = new Command\Environment\EnvironmentInitCommand(); - $commands[] = new Command\Environment\EnvironmentMergeCommand(); - $commands[] = new Command\Environment\EnvironmentPauseCommand(); - $commands[] = new Command\Environment\EnvironmentPushCommand(); - $commands[] = new Command\Environment\EnvironmentRedeployCommand(); - $commands[] = new Command\Environment\EnvironmentRelationshipsCommand(); - $commands[] = new Command\Environment\EnvironmentResumeCommand(); - $commands[] = new Command\Environment\EnvironmentSshCommand(); - $commands[] = new Command\Environment\EnvironmentScpCommand(); - $commands[] = new Command\Environment\EnvironmentSynchronizeCommand(); - $commands[] = new Command\Environment\EnvironmentUrlCommand(); - $commands[] = new Command\Environment\EnvironmentSetRemoteCommand(); - $commands[] = new Command\Environment\EnvironmentXdebugCommand(); - $commands[] = new Command\Integration\IntegrationAddCommand(); - $commands[] = new Command\Integration\IntegrationDeleteCommand(); - $commands[] = new Command\Integration\IntegrationGetCommand(); - $commands[] = new Command\Integration\IntegrationListCommand(); - $commands[] = new Command\Integration\IntegrationUpdateCommand(); - $commands[] = new Command\Integration\IntegrationValidateCommand(); - $commands[] = new Command\Integration\Activity\IntegrationActivityGetCommand(); - $commands[] = new Command\Integration\Activity\IntegrationActivityListCommand(); - $commands[] = new Command\Integration\Activity\IntegrationActivityLogCommand(); - $commands[] = new Command\Local\LocalBuildCommand(); - $commands[] = new Command\Local\LocalCleanCommand(); - $commands[] = new Command\Local\LocalDrushAliasesCommand(); - $commands[] = new Command\Local\LocalDirCommand(); - $commands[] = new Command\Mount\MountListCommand(); - $commands[] = new Command\Mount\MountDownloadCommand(); - $commands[] = new Command\Mount\MountSizeCommand(); - $commands[] = new Command\Mount\MountUploadCommand(); - $commands[] = new Command\Organization\OrganizationCreateCommand(); - $commands[] = new Command\Organization\OrganizationCurlCommand(); - $commands[] = new Command\Organization\OrganizationDeleteCommand(); - $commands[] = new Command\Organization\OrganizationInfoCommand(); - $commands[] = new Command\Organization\OrganizationListCommand(); - $commands[] = new Command\Organization\OrganizationSubscriptionListCommand(); - $commands[] = new Command\Organization\Billing\OrganizationAddressCommand(); - $commands[] = new Command\Organization\Billing\OrganizationProfileCommand(); - $commands[] = new Command\Organization\User\OrganizationUserAddCommand(); - $commands[] = new Command\Organization\User\OrganizationUserDeleteCommand(); - $commands[] = new Command\Organization\User\OrganizationUserGetCommand(); - $commands[] = new Command\Organization\User\OrganizationUserListCommand(); - $commands[] = new Command\Organization\User\OrganizationUserProjectsCommand(); - $commands[] = new Command\Organization\User\OrganizationUserUpdateCommand(); - $commands[] = new Command\Metrics\AllMetricsCommand(); - $commands[] = new Command\Metrics\CpuCommand(); - $commands[] = new Command\Metrics\CurlCommand(); - $commands[] = new Command\Metrics\DiskUsageCommand(); - $commands[] = new Command\Metrics\MemCommand(); - $commands[] = new Command\Project\ProjectClearBuildCacheCommand(); - $commands[] = new Command\Project\ProjectCurlCommand(); - $commands[] = new Command\Project\ProjectCreateCommand(); - $commands[] = new Command\Project\ProjectDeleteCommand(); - $commands[] = new Command\Project\ProjectGetCommand(); - $commands[] = new Command\Project\ProjectListCommand(); - $commands[] = new Command\Project\ProjectInfoCommand(); - $commands[] = new Command\Project\ProjectSetRemoteCommand(); - $commands[] = new Command\Project\Variable\ProjectVariableDeleteCommand(); - $commands[] = new Command\Project\Variable\ProjectVariableGetCommand(); - $commands[] = new Command\Project\Variable\ProjectVariableSetCommand(); - $commands[] = new Command\Repo\CatCommand(); - $commands[] = new Command\Repo\LsCommand(); - $commands[] = new Command\Repo\ReadCommand(); - $commands[] = new Command\Route\RouteListCommand(); - $commands[] = new Command\Route\RouteGetCommand(); - $commands[] = new Command\Self\SelfBuildCommand(); - $commands[] = new Command\Self\SelfConfigCommand(); - $commands[] = new Command\Self\SelfInstallCommand(); - $commands[] = new Command\Self\SelfUpdateCommand(); - $commands[] = new Command\Self\SelfReleaseCommand(); - $commands[] = new Command\Self\SelfStatsCommand(); - $commands[] = new Command\Server\ServerRunCommand(); - $commands[] = new Command\Server\ServerStartCommand(); - $commands[] = new Command\Server\ServerListCommand(); - $commands[] = new Command\Server\ServerStopCommand(); - $commands[] = new Command\Service\MongoDB\MongoDumpCommand(); - $commands[] = new Command\Service\MongoDB\MongoExportCommand(); - $commands[] = new Command\Service\MongoDB\MongoRestoreCommand(); - $commands[] = new Command\Service\MongoDB\MongoShellCommand(); - $commands[] = new Command\Service\RedisCliCommand(); - $commands[] = new Command\Service\ServiceListCommand(); - $commands[] = new Command\Session\SessionSwitchCommand(); - $commands[] = new Command\Backup\BackupCreateCommand(); - $commands[] = new Command\Backup\BackupDeleteCommand(); - $commands[] = new Command\Backup\BackupGetCommand(); - $commands[] = new Command\Backup\BackupListCommand(); - $commands[] = new Command\Backup\BackupRestoreCommand(); - $commands[] = new Command\Resources\ResourcesGetCommand(); - $commands[] = new Command\Resources\ResourcesSizeListCommand(); - $commands[] = new Command\Resources\ResourcesSetCommand(); - $commands[] = new Command\Resources\Build\BuildResourcesGetCommand(); - $commands[] = new Command\Resources\Build\BuildResourcesSetCommand(); - $commands[] = new Command\RuntimeOperation\ListCommand(); - $commands[] = new Command\RuntimeOperation\RunCommand(); - $commands[] = new Command\SourceOperation\ListCommand(); - $commands[] = new Command\SourceOperation\RunCommand(); - $commands[] = new Command\SshCert\SshCertInfoCommand(); - $commands[] = new Command\SshCert\SshCertLoadCommand(); - $commands[] = new Command\SshKey\SshKeyAddCommand(); - $commands[] = new Command\SshKey\SshKeyDeleteCommand(); - $commands[] = new Command\SshKey\SshKeyListCommand(); - $commands[] = new Command\SubscriptionInfoCommand(); - $commands[] = new Command\Team\TeamCreateCommand(); - $commands[] = new Command\Team\TeamDeleteCommand(); - $commands[] = new Command\Team\TeamGetCommand(); - $commands[] = new Command\Team\TeamListCommand(); - $commands[] = new Command\Team\TeamUpdateCommand(); - $commands[] = new Command\Team\Project\TeamProjectAddCommand(); - $commands[] = new Command\Team\Project\TeamProjectDeleteCommand(); - $commands[] = new Command\Team\Project\TeamProjectListCommand(); - $commands[] = new Command\Team\User\TeamUserAddCommand(); - $commands[] = new Command\Team\User\TeamUserDeleteCommand(); - $commands[] = new Command\Team\User\TeamUserListCommand(); - $commands[] = new Command\Tunnel\TunnelCloseCommand(); - $commands[] = new Command\Tunnel\TunnelInfoCommand(); - $commands[] = new Command\Tunnel\TunnelListCommand(); - $commands[] = new Command\Tunnel\TunnelOpenCommand(); - $commands[] = new Command\Tunnel\TunnelSingleCommand(); - $commands[] = new Command\User\UserAddCommand(); - $commands[] = new Command\User\UserDeleteCommand(); - $commands[] = new Command\User\UserListCommand(); - $commands[] = new Command\User\UserGetCommand(); - $commands[] = new Command\User\UserUpdateCommand(); - $commands[] = new Command\Variable\VariableCreateCommand(); - $commands[] = new Command\Variable\VariableDeleteCommand(); - $commands[] = new Command\Variable\VariableDisableCommand(); - $commands[] = new Command\Variable\VariableEnableCommand(); - $commands[] = new Command\Variable\VariableGetCommand(); - $commands[] = new Command\Variable\VariableListCommand(); - $commands[] = new Command\Variable\VariableSetCommand(); - $commands[] = new Command\Variable\VariableUpdateCommand(); - $commands[] = new Command\Version\VersionListCommand(); - $commands[] = new Command\WelcomeCommand(); - $commands[] = new Command\WebCommand(); - $commands[] = new Command\WinkyCommand(); - $commands[] = new Command\Worker\WorkerListCommand(); - - return $commands; + // All commands are lazy-loaded. + return []; } /** @@ -321,6 +219,20 @@ public function getHelp(): string */ protected function configureIO(InputInterface $input, OutputInterface $output): void { + // Set the input and output in the service container. + $this->container()->set(InputInterface::class, $input); + $this->container()->set(OutputInterface::class, $output); + + parent::configureIO($input, $output); + + // Set the input to non-interactive if the yes or no options are used, + // or if the PLATFORMSH_CLI_NO_INTERACTION variable is not empty. + // The --no-interaction option is handled in the parent method. + if ($input->hasParameterOption(['--yes', '-y', '--no', '-n']) + || getenv($this->envPrefix . 'NO_INTERACTION')) { + $input->setInteractive(false); + } + // Allow the NO_COLOR, CLICOLOR_FORCE, and TERM environment variables to // override whether colors are used in the output. // See: https://no-color.org @@ -394,7 +306,7 @@ protected function configureIO(InputInterface $input, OutputInterface $output): // Turn off error reporting in quiet mode. if ($shellVerbosity === -1) { - error_reporting(false); + error_reporting(0); ini_set('display_errors', '0'); } else { // Display errors by default. In verbose mode, display all PHP @@ -426,6 +338,32 @@ protected function doRunCommand(ConsoleCommand $command, InputInterface $input, // @todo find a better solution for this? $this->currentCommand->getSynopsis(); + // Work around a bug in Console which means the default command's input + // is always considered to be interactive. + if ($command->getName() === 'welcome' + && isset($GLOBALS['argv']) + && array_intersect($GLOBALS['argv'], ['-n', '--no', '-y', '---yes'])) { + $input->setInteractive(false); + } + +// // Check for automatic updates. +// $noChecks = in_array($command->getName(), ['welcome', '_completion']); +// if ($input->isInteractive() && !$noChecks) { +// /** @var SelfUpdateChecker $checker */ +// $checker = $this->container()->get(SelfUpdateChecker::class); +// $checker->checkUpdates(); +// } +// +// if (!$noChecks && $command->getName() !== 'legacy-migrate') { +// /** @var LocalProject $localProject */ +// $localProject = $this->container()->get(LocalProject::class); +// if ($localProject->getLegacyProjectRoot()) { +// /** @var LegacyMigration $legacyMigration */ +// $legacyMigration = $this->container()->get(LegacyMigration::class); +// $legacyMigration->check(); +// } +// } + return parent::doRunCommand($command, $input, $output); } @@ -442,78 +380,24 @@ public function setCurrentCommand(ConsoleCommand $command = null) } /** - * {@inheritdoc} + * Get the current command. + * + * @return ConsoleCommand|null */ - public function renderException(\Exception $e, OutputInterface $output) + public function getCurrentCommand() { - $output->writeln('', OutputInterface::VERBOSITY_QUIET); - $main = $e; - - do { - $exceptionName = get_class($e); - if (($pos = strrpos($exceptionName, '\\')) !== false) { - $exceptionName = substr($exceptionName, $pos + 1); - } - $title = sprintf(' [%s] ', $exceptionName); - - $len = strlen($title); - - $width = (new Terminal())->getWidth() - 1; - $formatter = $output->getFormatter(); - $lines = array(); - foreach (preg_split('/\r?\n/', $e->getMessage()) as $line) { - foreach (str_split($line, $width - 4) as $chunk) { - // pre-format lines to get the right string length - $lineLength = strlen(preg_replace('/\[[^m]*m/', '', $formatter->format($chunk))) + 4; - $lines[] = array($chunk, $lineLength); - - $len = max($lineLength, $len); - } - } + return $this->currentCommand; + } - $messages = array(); - $messages[] = $emptyLine = $formatter->format(sprintf('%s', str_repeat(' ', $len))); - $messages[] = $formatter->format(sprintf('%s%s', $title, str_repeat(' ', max(0, $len - strlen($title))))); - foreach ($lines as $line) { - $messages[] = $formatter->format(sprintf(' %s %s', $line[0], str_repeat(' ', $len - $line[1]))); - } - $messages[] = $emptyLine; - $messages[] = ''; - - $output->writeln($messages, OutputInterface::OUTPUT_RAW | OutputInterface::VERBOSITY_QUIET); - - if ($output->isDebug()) { - $output->writeln('Exception trace:', OutputInterface::VERBOSITY_QUIET); - - // exception related properties - $trace = $e->getTrace(); - array_unshift($trace, array( - 'function' => '', - 'file' => $e->getFile() !== null ? $e->getFile() : 'n/a', - 'line' => $e->getLine() !== null ? $e->getLine() : 'n/a', - 'args' => array(), - )); - - for ($i = 0, $count = count($trace); $i < $count; ++$i) { - $class = isset($trace[$i]['class']) ? $trace[$i]['class'] : ''; - $type = isset($trace[$i]['type']) ? $trace[$i]['type'] : ''; - $function = $trace[$i]['function']; - $file = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a'; - $line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a'; - - $output->writeln(sprintf(' %s%s%s() at %s:%s', $class, $type, $function, $file, $line), OutputInterface::VERBOSITY_QUIET); - } + public function renderThrowable(\Throwable $e, OutputInterface $output): void + { + $output->writeln('', OutputInterface::VERBOSITY_QUIET); - $output->writeln('', OutputInterface::VERBOSITY_QUIET); - } - } while (($c = $e) && ($e = $e->getPrevious()) && $e->getMessage() !== $c->getMessage()); + $this->doRenderThrowable($e, $output); if (isset($this->currentCommand) && $this->currentCommand->getName() !== 'welcome' - && ($main instanceof ConsoleInvalidArgumentException - || $main instanceof ConsoleInvalidOptionException - || $main instanceof ConsoleRuntimeException - )) { + && $e instanceof ExceptionInterface) { $output->writeln( sprintf('Usage: %s', $this->currentCommand->getSynopsis()), OutputInterface::VERBOSITY_QUIET @@ -521,7 +405,7 @@ public function renderException(\Exception $e, OutputInterface $output) $output->writeln('', OutputInterface::VERBOSITY_QUIET); $output->writeln(sprintf( 'For more information, type: %s help %s', - $this->cliConfig->get('application.executable'), + $this->config->get('application.executable'), $this->currentCommand->getName() ), OutputInterface::VERBOSITY_QUIET); $output->writeln('', OutputInterface::VERBOSITY_QUIET); diff --git a/src/Command/CommandBase.php b/src/Command/CommandBase.php index 0cdd29298..683b3b64a 100644 --- a/src/Command/CommandBase.php +++ b/src/Command/CommandBase.php @@ -17,6 +17,7 @@ use Platformsh\Cli\Model\Host\LocalHost; use Platformsh\Cli\Model\Host\RemoteHost; use Platformsh\Cli\Model\RemoteContainer; +use Platformsh\Cli\Service\Config; use Platformsh\Cli\Service\Shell; use Platformsh\Cli\Service\Ssh; use Platformsh\Cli\Util\OsUtil; @@ -1972,6 +1973,7 @@ private function container() self::$container = new ContainerBuilder(); $loader = new YamlFileLoader(self::$container, new FileLocator()); $loader->load(CLI_ROOT . '/services.yaml'); + self::$container->compile(); } return self::$container; @@ -1987,7 +1989,7 @@ protected function config() static $config; if (!isset($config)) { /** @var \Platformsh\Cli\Service\Config $config */ - $config = $this->getService('config'); + $config = $this->getService(Config::class); } return $config;