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;