Hello community, here is the log from the commit of package platformsh-cli for openSUSE:Factory checked in at 2018-02-20 17:55:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/platformsh-cli (Old) and /work/SRC/openSUSE:Factory/.platformsh-cli.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "platformsh-cli" Tue Feb 20 17:55:41 2018 rev:36 rq:578163 version:3.29.1 Changes: -------- --- /work/SRC/openSUSE:Factory/platformsh-cli/platformsh-cli.changes 2018-02-13 10:32:20.082756333 +0100 +++ /work/SRC/openSUSE:Factory/.platformsh-cli.new/platformsh-cli.changes 2018-02-20 17:55:46.816941304 +0100 @@ -1,0 +2,15 @@ +Mon Feb 19 17:19:37 UTC 2018 - [email protected] + +- Update to version 3.29.1: + * Release v3.29.1 + * Add self:release command + * Fix array to string conversion in project identifier + * [auth:browser-login] Always show help message + * [activity:get] [activity:log] Match partial activity IDs + * New line tweak [skip changelog] + * Add self:stats command + * [project:create] Get the list of regions dynamically + * [activity:log] Do not require ANSI check for polling/logging + * Merge metadata back from master [skip changelog] + +------------------------------------------------------------------- Old: ---- platformsh-cli-3.29.0.tar.xz New: ---- platformsh-cli-3.29.1.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ platformsh-cli.spec ++++++ --- /var/tmp/diff_new_pack.5mtXT3/_old 2018-02-20 17:55:48.168892624 +0100 +++ /var/tmp/diff_new_pack.5mtXT3/_new 2018-02-20 17:55:48.172892480 +0100 @@ -17,7 +17,7 @@ Name: platformsh-cli -Version: 3.29.0 +Version: 3.29.1 Release: 0 Summary: Tool for managing Platform.sh services from the command line # See licenses.txt for dependency licenses. ++++++ _service ++++++ --- /var/tmp/diff_new_pack.5mtXT3/_old 2018-02-20 17:55:48.208891184 +0100 +++ /var/tmp/diff_new_pack.5mtXT3/_new 2018-02-20 17:55:48.216890896 +0100 @@ -2,7 +2,7 @@ <service name="tar_scm" mode="disabled"> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> - <param name="revision">refs/tags/v3.29.0</param> + <param name="revision">refs/tags/v3.29.1</param> <param name="url">git://github.com/platformsh/platformsh-cli.git</param> <param name="scm">git</param> <param name="changesgenerate">enable</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.5mtXT3/_old 2018-02-20 17:55:48.240890032 +0100 +++ /var/tmp/diff_new_pack.5mtXT3/_new 2018-02-20 17:55:48.240890032 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">git://github.com/platformsh/platformsh-cli.git</param> - <param name="changesrevision">55eff65515f99bd641aff9905c3b664f1119fc79</param> + <param name="changesrevision">eca9da9648826c4932b4b74f5fc6d4d3717dc6e3</param> </service> </servicedata> ++++++ licenses.txt ++++++ --- /var/tmp/diff_new_pack.5mtXT3/_old 2018-02-20 17:55:48.300887871 +0100 +++ /var/tmp/diff_new_pack.5mtXT3/_new 2018-02-20 17:55:48.300887871 +0100 @@ -16,8 +16,8 @@ padraic/humbug_get_contents 1.0.4 BSD-3-Clause padraic/phar-updater 1.0.4 BSD-3-Clause paragonie/random_compat v2.0.11 MIT -platformsh/client v0.14.1 MIT -platformsh/console-form v0.0.15 MIT +platformsh/client v0.15.0 MIT +platformsh/console-form v0.0.16 MIT psr/container 1.0.0 MIT psr/log 1.0.2 MIT react/promise v2.5.1 MIT ++++++ platformsh-cli-3.29.0.tar.xz -> platformsh-cli-3.29.1.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.29.0/composer.json new/platformsh-cli-3.29.1/composer.json --- old/platformsh-cli-3.29.0/composer.json 2018-02-12 10:10:33.000000000 +0100 +++ new/platformsh-cli-3.29.1/composer.json 2018-02-19 13:10:22.000000000 +0100 @@ -7,8 +7,8 @@ "doctrine/cache": "~1.5", "guzzlehttp/guzzle": "^5.3", "guzzlehttp/ringphp": "^1.1", - "platformsh/console-form": ">=0.0.14 <2.0", - "platformsh/client": ">=0.14.0 <2.0", + "platformsh/console-form": ">=0.0.16 <2.0", + "platformsh/client": ">=0.15.0 <2.0", "symfony/console": "^3.0 !=3.2.5 !=3.2.6", "symfony/yaml": "^3.0 || ^2.6", "symfony/finder": "^3.0", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.29.0/composer.lock new/platformsh-cli-3.29.1/composer.lock --- old/platformsh-cli-3.29.0/composer.lock 2018-02-12 10:10:33.000000000 +0100 +++ new/platformsh-cli-3.29.1/composer.lock 2018-02-19 13:10:22.000000000 +0100 @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "99aec30edb51fe7608bde25ca891ca04", + "content-hash": "61139468c3903d4897f8fcfece451e34", "packages": [ { "name": "cocur/slugify", @@ -643,16 +643,16 @@ }, { "name": "platformsh/client", - "version": "v0.14.1", + "version": "v0.15.0", "source": { "type": "git", "url": "https://github.com/platformsh/platformsh-client-php.git", - "reference": "b1c5ff8a0cd896a80aa7330a42d7be9e9ef0dd98" + "reference": "1ab0bd8d229dda78b4a545379fd107de4ead872c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/b1c5ff8a0cd896a80aa7330a42d7be9e9ef0dd98", - "reference": "b1c5ff8a0cd896a80aa7330a42d7be9e9ef0dd98", + "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/1ab0bd8d229dda78b4a545379fd107de4ead872c", + "reference": "1ab0bd8d229dda78b4a545379fd107de4ead872c", "shasum": "" }, "require": { @@ -688,20 +688,20 @@ } ], "description": "Platform.sh API client", - "time": "2018-01-19T10:05:52+00:00" + "time": "2018-02-12T10:31:29+00:00" }, { "name": "platformsh/console-form", - "version": "v0.0.15", + "version": "v0.0.16", "source": { "type": "git", "url": "https://github.com/platformsh/console-form.git", - "reference": "f8d6ec0d810e24e3a028bfffae905325289b8559" + "reference": "57931bde54bcc13ae0c784a71b41bcf32f1adeba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/platformsh/console-form/zipball/f8d6ec0d810e24e3a028bfffae905325289b8559", - "reference": "f8d6ec0d810e24e3a028bfffae905325289b8559", + "url": "https://api.github.com/repos/platformsh/console-form/zipball/57931bde54bcc13ae0c784a71b41bcf32f1adeba", + "reference": "57931bde54bcc13ae0c784a71b41bcf32f1adeba", "shasum": "" }, "require": { @@ -727,7 +727,7 @@ } ], "description": "A lightweight Symfony Console form system.", - "time": "2017-12-11T15:23:12+00:00" + "time": "2018-02-12T11:15:24+00:00" }, { "name": "psr/container", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.29.0/config.yaml new/platformsh-cli-3.29.1/config.yaml --- old/platformsh-cli-3.29.0/config.yaml 2018-02-12 10:10:33.000000000 +0100 +++ new/platformsh-cli-3.29.1/config.yaml 2018-02-19 13:10:22.000000000 +0100 @@ -1,7 +1,7 @@ # Metadata about the CLI application itself. application: name: 'Platform.sh CLI' - version: '3.29.0' + version: '3.29.1' executable: 'platform' package_name: 'platformsh/cli' installer_url: 'https://platform.sh/cli/installer' @@ -10,6 +10,7 @@ user_state_file: '.platformsh/state.json' env_prefix: 'PLATFORMSH_CLI_' tmp_sub_dir: 'platformsh-cli-tmp' + github_repo: 'platformsh/platformsh-cli' # The default interactive login method: either 'browser' or 'password'. # This can be overridden in the user config file. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.29.0/dist/manifest.json new/platformsh-cli-3.29.1/dist/manifest.json --- old/platformsh-cli-3.29.0/dist/manifest.json 2018-02-12 10:10:33.000000000 +0100 +++ new/platformsh-cli-3.29.1/dist/manifest.json 2018-02-19 13:10:22.000000000 +0100 @@ -1,10 +1,10 @@ [ { "name": "platform.phar", - "sha1": "2f269ba903905599f2b2f6f94cde8174c551a25a", - "sha256": "7ca20c402d2514abb374fc4ec0deac04d2d1a0979e66336b3a4305806c414a38", - "url": "https://github.com/platformsh/platformsh-cli/releases/download/v3.29.0/platform.phar", - "version": "3.29.0", + "sha1": "11d95c5f2e68a534cb19b7be34c146ce5d0ec142", + "sha256": "e3c41764818063bbdb9f59145d187cf8abd8dbc03a6aeadb7f4984b3fde00a59", + "url": "https://github.com/platformsh/platformsh-cli/releases/download/v3.29.1/platform.phar", + "version": "3.29.1", "php": { "min": "5.5.9" }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.29.0/src/Application.php new/platformsh-cli-3.29.1/src/Application.php --- old/platformsh-cli-3.29.0/src/Application.php 2018-02-12 10:10:33.000000000 +0100 +++ new/platformsh-cli-3.29.1/src/Application.php 2018-02-19 13:10:22.000000000 +0100 @@ -157,6 +157,8 @@ $commands[] = new Command\Self\SelfBuildCommand(); $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(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.29.0/src/Command/Activity/ActivityGetCommand.php new/platformsh-cli-3.29.1/src/Command/Activity/ActivityGetCommand.php --- old/platformsh-cli-3.29.0/src/Command/Activity/ActivityGetCommand.php 2018-02-12 10:10:33.000000000 +0100 +++ new/platformsh-cli-3.29.1/src/Command/Activity/ActivityGetCommand.php 2018-02-19 13:10:22.000000000 +0100 @@ -43,9 +43,14 @@ $activity = $this->getSelectedProject() ->getActivity($id); if (!$activity) { - $this->stdErr->writeln("Activity not found: <error>$id</error>"); + $activities = $this->getSelectedEnvironment() + ->getActivities(0, $input->getOption('type')); + $activity = $this->api()->matchPartialId($id, $activities, 'Activity'); + if (!$activity) { + $this->stdErr->writeln("Activity not found: <error>$id</error>"); - return 1; + return 1; + } } } else { if ($this->hasSelectedEnvironment() && !$input->getOption('all')) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.29.0/src/Command/Activity/ActivityLogCommand.php new/platformsh-cli-3.29.1/src/Command/Activity/ActivityLogCommand.php --- old/platformsh-cli-3.29.0/src/Command/Activity/ActivityLogCommand.php 2018-02-12 10:10:33.000000000 +0100 +++ new/platformsh-cli-3.29.1/src/Command/Activity/ActivityLogCommand.php 2018-02-19 13:10:22.000000000 +0100 @@ -46,9 +46,14 @@ $activity = $this->getSelectedProject() ->getActivity($id); if (!$activity) { - $this->stdErr->writeln("Activity not found: <error>$id</error>"); + $activities = $this->getSelectedEnvironment() + ->getActivities(0, $input->getOption('type')); + $activity = $this->api()->matchPartialId($id, $activities, 'Activity'); + if (!$activity) { + $this->stdErr->writeln("Activity not found: <error>$id</error>"); - return 1; + return 1; + } } } else { if ($this->hasSelectedEnvironment() && !$input->getOption('all')) { @@ -79,7 +84,7 @@ ]); $refresh = $input->getOption('refresh'); - if ($refresh > 0 && !$this->runningViaMulti && $output->isDecorated() && !$activity->isComplete()) { + if ($refresh > 0 && !$this->runningViaMulti && !$activity->isComplete()) { $activity->wait( null, function ($log) use ($output) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.29.0/src/Command/Auth/BrowserLoginCommand.php new/platformsh-cli-3.29.1/src/Command/Auth/BrowserLoginCommand.php --- old/platformsh-cli-3.29.0/src/Command/Auth/BrowserLoginCommand.php 2018-02-12 10:10:33.000000000 +0100 +++ new/platformsh-cli-3.29.1/src/Command/Auth/BrowserLoginCommand.php 2018-02-19 13:10:22.000000000 +0100 @@ -128,24 +128,30 @@ } else { $this->stdErr->writeln('Please open the following URL in a browser and log in:'); $this->stdErr->writeln('<info>' . $localUrl . '</info>'); - $this->stdErr->writeln(''); - $this->stdErr->writeln(sprintf( - 'For help, quit this process (e.g. with Ctrl+C), and run: <info>%s help login</info>', - $this->config()->get('application.executable') - )); } + // Show some help. + $this->stdErr->writeln(''); + $this->stdErr->writeln('<options=bold>Help:</>'); + $this->stdErr->writeln(' Use Ctrl+C to quit this process.'); + $executable = $this->config()->get('application.executable'); + $this->stdErr->writeln(sprintf(' To log in within the terminal instead, quit and run: <info>%s auth:password-login</info>', $executable)); + $this->stdErr->writeln(sprintf(' For more info, quit and run: <info>%s help login</info>', $executable)); + $this->stdErr->writeln(''); + // Wait for the file to be filled with an OAuth2 authorization code. $code = null; while ($process->isRunning() && empty($code)) { usleep(300000); if (!file_exists($codeFile)) { $this->stdErr->writeln('File not found: <error>' . $codeFile . '</error>'); + $this->stdErr->writeln(''); break; } $code = file_get_contents($codeFile); if ($code === false) { $this->stdErr->writeln('Failed to read file: <error>' . $codeFile . '</error>'); + $this->stdErr->writeln(''); break; } } @@ -154,8 +160,6 @@ $process->stop(); (new Filesystem())->remove([$listenerDir]); - $this->stdErr->writeln(''); - if (empty($code)) { $this->stdErr->writeln('Failed to get an authorization code. Please try again.'); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.29.0/src/Command/Project/ProjectCreateCommand.php new/platformsh-cli-3.29.1/src/Command/Project/ProjectCreateCommand.php --- old/platformsh-cli-3.29.0/src/Command/Project/ProjectCreateCommand.php 2018-02-12 10:10:33.000000000 +0100 +++ new/platformsh-cli-3.29.1/src/Command/Project/ProjectCreateCommand.php 2018-02-19 13:10:22.000000000 +0100 @@ -189,19 +189,27 @@ /** * Return a list of regions. * - * The default list is in the config `service.available_regions`. This can - * be overridden by the user config `experimental.available_regions`. + * The default list is in the config `service.available_regions`. This is + * replaced at runtime by an API call. * - * @return string[] + * @param bool $runtime + * + * @return array */ - protected function getAvailableRegions() + protected function getAvailableRegions($runtime = false) { - $config = $this->config(); - if ($config->has('experimental.available_regions')) { - return $config->get('experimental.available_regions'); + if ($runtime) { + $regions = []; + foreach ($this->api()->getClient()->getRegions() as $region) { + if ($region->available) { + $regions[$region->id] = $region->label; + } + } + } else { + $regions = (array) $this->config()->get('service.available_regions'); } - return $config->get('service.available_regions'); + return $regions; } /** @@ -222,7 +230,9 @@ 'optionName' => 'region', 'description' => 'The region where the project will be hosted', 'options' => $this->getAvailableRegions(), - 'allowOther' => true, + 'optionsCallback' => function () { + return $this->getAvailableRegions(true); + }, ]), 'plan' => new OptionsField('Plan', [ 'optionName' => 'plan', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.29.0/src/Command/Self/SelfReleaseCommand.php new/platformsh-cli-3.29.1/src/Command/Self/SelfReleaseCommand.php --- old/platformsh-cli-3.29.0/src/Command/Self/SelfReleaseCommand.php 1970-01-01 01:00:00.000000000 +0100 +++ new/platformsh-cli-3.29.1/src/Command/Self/SelfReleaseCommand.php 2018-02-19 13:10:22.000000000 +0100 @@ -0,0 +1,252 @@ +<?php +namespace Platformsh\Cli\Command\Self; + +use GuzzleHttp\Client; +use Platformsh\Cli\Command\CommandBase; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class SelfReleaseCommand extends CommandBase +{ + protected $hiddenInList = true; + + protected function configure() + { + $this + ->setName('self:release') + ->setDescription('Build and release a new version') + ->addOption('phar', null, InputOption::VALUE_REQUIRED, 'The path to a newly built Phar file') + ->addOption('repo', null, InputOption::VALUE_REQUIRED, 'The GitHub repository', $this->config()->has('application.github_repo') ? $this->config()->get('application.github_repo') : null); + } + + public function isEnabled() + { + return $this->config()->has('application.github_repo') + && (!extension_loaded('Phar') || !\Phar::running(false)); + } + + /** + * @throws \Exception + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + /** @var \Platformsh\Cli\Service\QuestionHelper $questionHelper */ + $questionHelper = $this->getService('question_helper'); + + /** @var \Platformsh\Cli\Service\Shell $shell */ + $shell = $this->getService('shell'); + + /** @var \Platformsh\Cli\Service\Git $git */ + $git = $this->getService('git'); + $git->setDefaultRepositoryDir(CLI_ROOT); + + if ($git->getCurrentBranch(CLI_ROOT, true) !== 'master') { + $this->stdErr->writeln('You must be on the master branch to make a release.'); + + return 1; + } + + if ($git->execute(['diff', 'master...development'], CLI_ROOT, true) && $questionHelper->confirm('Merge changes from development?')) { + $git->execute(['merge', 'development'], CLI_ROOT, true); + } + + $gitStatus = $git->execute(['status', '--porcelain'], CLI_ROOT, true); + if (is_string($gitStatus) && !empty($gitStatus)) { + foreach (explode("\n", $gitStatus) as $statusLine) { + if (strpos($statusLine, ' config.yaml') === false) { + $this->stdErr->writeln('There are uncommitted changes in Git. Cannot proceed.'); + + return 1; + } + } + } + + if (getenv('GITHUB_TOKEN')) { + $gitHubToken = getenv('GITHUB_TOKEN'); + } else { + $this->stdErr->writeln('The GITHUB_TOKEN environment variable must be set'); + + return 1; + } + + $newVersion = $this->config()->get('application.version'); + $this->stdErr->writeln('The version number defined in the config.yaml file is: <comment>' . $newVersion . '</comment>'); + + if (substr($newVersion, 0, 1) === 'v') { + $this->stdErr->writeln('The version number should not be prefixed by `v`.'); + + return 1; + } + if (!$questionHelper->confirm('Is <comment>' . $newVersion . '</comment> the correct new version number?')) { + $this->stdErr->writeln('Update the version number in config.yaml and re-run this command.'); + + return 1; + } + + $tagName = 'v' . $newVersion; + $http = new Client(); + $repo = $input->getOption('repo') ?: $this->config()->get('application.github_repo'); + $repoUrl = implode('/', array_map('rawurlencode', explode('/', $repo))); + $repoApiUrl = 'https://api.github.com/repos/' . $repoUrl; + $repoGitUrl = '[email protected]:' . $repo . '.git'; + + $existsResponse = $http->get($repoApiUrl . '/releases/tags/' . $tagName, [ + 'headers' => [ + 'Authorization' => 'token ' . $gitHubToken, + 'Accept' => 'application/vnd.github.v3+json', + 'Content-Type' => 'application/json', + ], + 'exceptions' => false, + 'debug' => $output->isDebug(), + ]); + if ($existsResponse->getStatusCode() !== 404) { + if ($existsResponse->getStatusCode() >= 300) { + $this->stdErr->writeln('Failed to check for an existing release on GitHub.'); + + return 1; + } + $this->stdErr->writeln('A release tagged ' . $tagName . ' already exists on GitHub.'); + + return 1; + } + + $pharFilename = $input->getOption('phar'); + if ($pharFilename && !file_exists($pharFilename)) { + $this->stdErr->writeln('File not found: <error>' . $pharFilename . '</error>'); + + return 1; + } + if (!$pharFilename) { + $pharFilename = CLI_ROOT . '/' . $this->config()->get('application.executable') . '.phar'; + $result = $this->runOtherCommand('self:build', [ + '--output' => $pharFilename, + ]); + if ($result !== 0) { + $this->stdErr->writeln('The build failed'); + + return $result; + } + } else { + $versionInPhar = $shell->execute(['php', $pharFilename, '--version'], null, true); + if (strpos($versionInPhar, $newVersion) === false) { + $this->stdErr->writeln('The file ' . $pharFilename . ' reports a different version: "' . $versionInPhar . '"'); + + return 1; + } + } + + $gitStatus = $git->execute(['status', '--porcelain'], CLI_ROOT, true); + if (is_string($gitStatus) && !empty($gitStatus)) { + $this->stdErr->writeln('Committing changes to Git'); + + $result = $shell->executeSimple('git commit --patch config.yaml dist/manifest.json --message ' . escapeshellarg('Release v' . $newVersion) . ' --edit', CLI_ROOT); + if ($result !== 0) { + return $result; + } + } + + $latest = $http->get($repoApiUrl . '/releases/latest', [ + 'headers' => [ + 'Authorization' => 'token ' . $gitHubToken, + 'Accept' => 'application/vnd.github.v3+json', + 'Content-Type' => 'application/json', + ], + 'debug' => $output->isDebug(), + ])->json(); + $lastVersion = $latest['tag_name']; + + $changelog = $git->execute([ + 'log', + '--pretty=format:* %s', + '--no-merges', + '--invert-grep', + '--grep=(Release v|\[skip changelog\])', + '--perl-regexp', + '--regexp-ignore-case', + $lastVersion . '...' . $tagName + ], CLI_ROOT, true); + if (empty($changelog)) { + $this->stdErr->writeln('Failed to find changelog for ' . $lastVersion . '...' . $tagName); + + return 1; + } + + $this->stdErr->writeln('Creating tag <info>' . $tagName . '</info>'); + $git->execute(['tag', '--force', $tagName], CLI_ROOT, true); + + if (!$questionHelper->confirm('Push changes and tag to <comment>master</comment> branch on ' . $repoGitUrl . '?')) { + return 1; + } + $shell->execute(['git', 'push', $repoGitUrl, 'HEAD:master'], CLI_ROOT, true); + $shell->execute(['git', 'push', '--force', $repoGitUrl, $tagName], CLI_ROOT, true); + + $lastReleasePublicUrl = 'https://github.com/' . $repoUrl . '/releases/' . $lastVersion; + $pharPublicFilename = $this->config()->get('application.executable') . '.phar'; + $releaseDescription = sprintf('Changes since [%s](%s):', $lastVersion, $lastReleasePublicUrl) + . "\n\n" . $changelog + . "\n\n" . sprintf('SHA-256 checksum for `%s`:', $pharPublicFilename) + . "\n" . sprintf('`%s`', hash_file('sha256', $pharFilename)); + + $this->stdErr->writeln(''); + $this->stdErr->writeln('Creating new release ' . $tagName . ' on GitHub'); + $this->stdErr->writeln('Release description:'); + $this->stdErr->writeln(preg_replace('/^/m', ' ', $releaseDescription)); + $this->stdErr->writeln(''); + + if (!$questionHelper->confirm('Is this OK?')) { + return 1; + } + + $http = new Client(); + $response = $http->post($repoApiUrl . '/releases', [ + 'headers' => [ + 'Authorization' => 'token ' . $gitHubToken, + 'Accept' => 'application/vnd.github.v3+json', + 'Content-Type' => 'application/json', + ], + 'json' => [ + 'tag_name' => $tagName, + 'name' => $tagName, + 'body' => $releaseDescription, + 'draft' => true, + ], + 'debug' => $output->isDebug(), + ]); + $release = $response->json(); + $releaseUrl = $repoApiUrl . '/releases/' . $release['id']; + $uploadUrl = preg_replace('/\{.+?\}/', '', $release['upload_url']); + + $this->stdErr->writeln('Uploading the Phar file to the release'); + $fileResource = fopen($pharFilename, 'r'); + if (!$fileResource) { + throw new \RuntimeException('Failed to open file for reading: ' . $fileResource); + } + $http->post($uploadUrl . '?name=' . rawurldecode($pharPublicFilename), [ + 'headers' => [ + 'Authorization' => 'token ' . $gitHubToken, + 'Accept' => 'application/vnd.github.v3+json', + 'Content-Type' => 'application/octet-stream', + ], + 'body' => $fileResource, + 'debug' => $output->isDebug(), + ]); + + $this->stdErr->writeln('Publishing the release'); + $http->patch($releaseUrl, [ + 'headers' => [ + 'Authorization' => 'token ' . $gitHubToken, + 'Accept' => 'application/vnd.github.v3+json', + 'Content-Type' => 'application/json', + ], + 'json' => ['draft' => false], + 'debug' => $output->isDebug(), + ]); + + $this->stdErr->writeln(''); + $this->stdErr->writeln('Release successfully published'); + $this->stdErr->writeln('https://github.com/' . $repoUrl . '/releases/latest'); + + return 0; + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.29.0/src/Command/Self/SelfStatsCommand.php new/platformsh-cli-3.29.1/src/Command/Self/SelfStatsCommand.php --- old/platformsh-cli-3.29.0/src/Command/Self/SelfStatsCommand.php 1970-01-01 01:00:00.000000000 +0100 +++ new/platformsh-cli-3.29.1/src/Command/Self/SelfStatsCommand.php 2018-02-19 13:10:22.000000000 +0100 @@ -0,0 +1,65 @@ +<?php +namespace Platformsh\Cli\Command\Self; + +use Platformsh\Cli\Command\CommandBase; +use Platformsh\Cli\Service\PropertyFormatter; +use Platformsh\Cli\Service\Table; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class SelfStatsCommand extends CommandBase +{ + protected $hiddenInList = true; + + protected function configure() + { + $this + ->setName('self:stats') + ->setDescription('View stats on GitHub package downloads'); + Table::configureInput($this->getDefinition()); + PropertyFormatter::configureInput($this->getDefinition()); + } + + public function isEnabled() + { + return $this->config()->has('application.github_repo'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $repo = $this->config()->get('application.github_repo'); + $repoUrl = implode('/', array_map('rawurlencode', explode('/', $repo))); + $releases = $this->api() + ->getHttpClient() + ->get('https://api.github.com/repos/' . $repoUrl . '/releases', [ + 'headers' => [ + 'Accept' => 'application/vnd.github.v3+json', + ], + 'auth' => false, + ])->json(); + + /** @var \Platformsh\Cli\Service\Table $table */ + $table = $this->getService('table'); + /** @var \Platformsh\Cli\Service\PropertyFormatter $formatter */ + $formatter = $this->getService('property_formatter'); + $headers = ['Release', 'Date', 'Asset', 'Downloads']; + $rows = []; + foreach ($releases as $release) { + if (!empty($release['assets'])) { + foreach ($release['assets'] as $asset) { + $row = []; + $row[] = $release['name']; + $time = !empty($release['published_at']) ? $release['published_at'] : $release['created_at']; + $row[] = $formatter->format($time, 'created_at'); + $row[] = $asset['name']; + $row[] = $formatter->format($asset['download_count']); + $rows[] = $row; + } + } + } + + $table->render($rows, $headers); + + return 0; + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.29.0/src/Command/User/UserAddCommand.php new/platformsh-cli-3.29.1/src/Command/User/UserAddCommand.php --- old/platformsh-cli-3.29.0/src/Command/User/UserAddCommand.php 2018-02-12 10:10:33.000000000 +0100 +++ new/platformsh-cli-3.29.1/src/Command/User/UserAddCommand.php 2018-02-19 13:10:22.000000000 +0100 @@ -59,6 +59,9 @@ $choices[$account['email']] = $this->getUserLabel($access); } $email = $questionHelper->choose($choices, 'Enter a number to choose a user to update:'); + if (count($choices) > 1) { + $this->stdErr->writeln(''); + } } else { $question = new Question("Enter the user's email address: "); $question->setValidator(function ($answer) { @@ -66,8 +69,8 @@ }); $question->setMaxAttempts(5); $email = $questionHelper->ask($input, $this->stdErr, $question); + $this->stdErr->writeln(''); } - $this->stdErr->writeln(''); } $this->validateEmail($email); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.29.0/src/Command/User/UserRoleCommand.php new/platformsh-cli-3.29.1/src/Command/User/UserRoleCommand.php --- old/platformsh-cli-3.29.0/src/Command/User/UserRoleCommand.php 2018-02-12 10:10:33.000000000 +0100 +++ new/platformsh-cli-3.29.1/src/Command/User/UserRoleCommand.php 2018-02-19 13:10:22.000000000 +0100 @@ -59,7 +59,9 @@ $choices[$account['email']] = sprintf('%s (%s)', $account['display_name'], $account['email']); } $email = $questionHelper->choose($choices, 'Enter a number to choose a user:'); - $this->stdErr->writeln(''); + if (count($choices) > 1) { + $this->stdErr->writeln(''); + } } $projectAccess = $this->api()->loadProjectAccessByEmail($project, $email); if (!$projectAccess) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.29.0/src/Service/Identifier.php new/platformsh-cli-3.29.1/src/Service/Identifier.php --- old/platformsh-cli-3.29.0/src/Service/Identifier.php 2018-02-12 10:10:33.000000000 +0100 +++ new/platformsh-cli-3.29.1/src/Service/Identifier.php 2018-02-19 13:10:22.000000000 +0100 @@ -147,7 +147,7 @@ * * @param string $url * - * @return string + * @return string|false */ private function getClusterHeader($url) { @@ -162,14 +162,16 @@ 'connect_timeout' => 5, 'allow_redirects' => false, ]); - $cluster = $response->getHeader($this->config->get('service.header_prefix') . '-cluster'); + $cluster = $response->getHeaderAsArray($this->config->get('service.header_prefix') . '-cluster'); $this->cache->save($cacheKey, $cluster, 86400); } catch (RequestException $e) { $this->debug($e->getMessage()); + + return false; } } - return $cluster; + return is_array($cluster) ? reset($cluster) : false; } /** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.29.0/src/Service/Url.php new/platformsh-cli-3.29.1/src/Service/Url.php --- old/platformsh-cli-3.29.0/src/Service/Url.php 2018-02-12 10:10:33.000000000 +0100 +++ new/platformsh-cli-3.29.1/src/Service/Url.php 2018-02-19 13:10:22.000000000 +0100 @@ -73,6 +73,7 @@ // If the user wants to pipe the output to another command, stop here. if ($this->input->hasOption('pipe') && $this->input->getOption('pipe')) { $open = false; + $print = true; } // Check if the user has requested not to use a browser. elseif ($browserOption === '0') { ++++++ platformsh-cli-vendor.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/autoload.php new/vendor/autoload.php --- old/vendor/autoload.php 2018-02-12 22:57:57.119722174 +0100 +++ new/vendor/autoload.php 2018-02-19 18:19:43.443949293 +0100 @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit1000482ab31b6ea30c0fe42bed510766::getLoader(); +return ComposerAutoloaderInit76f933238b0cbdfc8a10ca06f30d0bbc::getLoader(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/composer/autoload_real.php new/vendor/composer/autoload_real.php --- old/vendor/composer/autoload_real.php 2018-02-12 22:57:57.119722174 +0100 +++ new/vendor/composer/autoload_real.php 2018-02-19 18:19:43.443949293 +0100 @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit1000482ab31b6ea30c0fe42bed510766 +class ComposerAutoloaderInit76f933238b0cbdfc8a10ca06f30d0bbc { private static $loader; @@ -19,15 +19,15 @@ return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit1000482ab31b6ea30c0fe42bed510766', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit76f933238b0cbdfc8a10ca06f30d0bbc', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit1000482ab31b6ea30c0fe42bed510766', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit76f933238b0cbdfc8a10ca06f30d0bbc', 'loadClassLoader')); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { require_once __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit1000482ab31b6ea30c0fe42bed510766::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit76f933238b0cbdfc8a10ca06f30d0bbc::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -48,19 +48,19 @@ $loader->register(true); if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit1000482ab31b6ea30c0fe42bed510766::$files; + $includeFiles = Composer\Autoload\ComposerStaticInit76f933238b0cbdfc8a10ca06f30d0bbc::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire1000482ab31b6ea30c0fe42bed510766($fileIdentifier, $file); + composerRequire76f933238b0cbdfc8a10ca06f30d0bbc($fileIdentifier, $file); } return $loader; } } -function composerRequire1000482ab31b6ea30c0fe42bed510766($fileIdentifier, $file) +function composerRequire76f933238b0cbdfc8a10ca06f30d0bbc($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { require $file; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/composer/autoload_static.php new/vendor/composer/autoload_static.php --- old/vendor/composer/autoload_static.php 2018-02-12 22:57:57.119722174 +0100 +++ new/vendor/composer/autoload_static.php 2018-02-19 18:19:43.443949293 +0100 @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit1000482ab31b6ea30c0fe42bed510766 +class ComposerStaticInit76f933238b0cbdfc8a10ca06f30d0bbc { public static $files = array ( '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', @@ -189,9 +189,9 @@ public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit1000482ab31b6ea30c0fe42bed510766::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit1000482ab31b6ea30c0fe42bed510766::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit1000482ab31b6ea30c0fe42bed510766::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit76f933238b0cbdfc8a10ca06f30d0bbc::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit76f933238b0cbdfc8a10ca06f30d0bbc::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit76f933238b0cbdfc8a10ca06f30d0bbc::$classMap; }, null, ClassLoader::class); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/composer/installed.json new/vendor/composer/installed.json --- old/vendor/composer/installed.json 2018-02-12 22:57:56.495716106 +0100 +++ new/vendor/composer/installed.json 2018-02-19 18:19:42.435939770 +0100 @@ -708,17 +708,17 @@ }, { "name": "platformsh/client", - "version": "v0.14.1", - "version_normalized": "0.14.1.0", + "version": "v0.15.0", + "version_normalized": "0.15.0.0", "source": { "type": "git", "url": "https://github.com/platformsh/platformsh-client-php.git", - "reference": "b1c5ff8a0cd896a80aa7330a42d7be9e9ef0dd98" + "reference": "1ab0bd8d229dda78b4a545379fd107de4ead872c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/b1c5ff8a0cd896a80aa7330a42d7be9e9ef0dd98", - "reference": "b1c5ff8a0cd896a80aa7330a42d7be9e9ef0dd98", + "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/1ab0bd8d229dda78b4a545379fd107de4ead872c", + "reference": "1ab0bd8d229dda78b4a545379fd107de4ead872c", "shasum": "" }, "require": { @@ -731,7 +731,7 @@ "require-dev": { "phpunit/phpunit": "~4.5" }, - "time": "2018-01-19T10:05:52+00:00", + "time": "2018-02-12T10:31:29+00:00", "type": "library", "extra": { "patches": { @@ -998,17 +998,17 @@ }, { "name": "platformsh/console-form", - "version": "v0.0.15", - "version_normalized": "0.0.15.0", + "version": "v0.0.16", + "version_normalized": "0.0.16.0", "source": { "type": "git", "url": "https://github.com/platformsh/console-form.git", - "reference": "f8d6ec0d810e24e3a028bfffae905325289b8559" + "reference": "57931bde54bcc13ae0c784a71b41bcf32f1adeba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/platformsh/console-form/zipball/f8d6ec0d810e24e3a028bfffae905325289b8559", - "reference": "f8d6ec0d810e24e3a028bfffae905325289b8559", + "url": "https://api.github.com/repos/platformsh/console-form/zipball/57931bde54bcc13ae0c784a71b41bcf32f1adeba", + "reference": "57931bde54bcc13ae0c784a71b41bcf32f1adeba", "shasum": "" }, "require": { @@ -1018,7 +1018,7 @@ "require-dev": { "phpunit/phpunit": "^5.0" }, - "time": "2017-12-11T15:23:12+00:00", + "time": "2018-02-12T11:15:24+00:00", "type": "library", "installation-source": "dist", "autoload": { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/src/Model/Region.php new/vendor/platformsh/client/src/Model/Region.php --- old/vendor/platformsh/client/src/Model/Region.php 1970-01-01 01:00:00.000000000 +0100 +++ new/vendor/platformsh/client/src/Model/Region.php 2018-02-12 11:31:29.000000000 +0100 @@ -0,0 +1,63 @@ +<?php + +namespace Platformsh\Client\Model; + +use GuzzleHttp\ClientInterface; + +/** + * Represents a Platform.sh region. + * + * @property-read int $id + * @property-read string $label + * @property-read bool $available + * @property-read bool $private + * @property-read string $zone + * @property-read string $endpoint + */ +class Region extends Resource +{ + /** + * @inheritdoc + */ + protected function setData(array $data) + { + $data = isset($data['regions'][0]) ? $data['regions'][0] : $data; + $data['available'] = !empty($data['available']); + $data['private'] = !empty($data['private']); + $this->data = $data; + } + + /** + * @inheritdoc + */ + public static function wrapCollection(array $data, $baseUrl, ClientInterface $client) + { + $data = isset($data['regions']) ? $data['regions'] : []; + + return parent::wrapCollection($data, $baseUrl, $client); + } + + /** + * @inheritdoc + */ + public function operationAvailable($op) + { + if ($op === 'edit') { + return true; + } + + return parent::operationAvailable($op); + } + + /** + * @inheritdoc + */ + public function getLink($rel, $absolute = false) + { + if ($rel === '#edit') { + return $this->getUri($absolute); + } + + return parent::getLink($rel, $absolute); + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/src/PlatformClient.php new/vendor/platformsh/client/src/PlatformClient.php --- old/vendor/platformsh/client/src/PlatformClient.php 2018-01-19 11:05:52.000000000 +0100 +++ new/vendor/platformsh/client/src/PlatformClient.php 2018-02-12 11:31:29.000000000 +0100 @@ -7,6 +7,7 @@ use Platformsh\Client\Connection\ConnectorInterface; use Platformsh\Client\Exception\ApiResponseException; use Platformsh\Client\Model\Project; +use Platformsh\Client\Model\Region; use Platformsh\Client\Model\Result; use Platformsh\Client\Model\SshKey; use Platformsh\Client\Model\Subscription; @@ -224,13 +225,15 @@ /** * Create a new Platform.sh subscription. * - * @param string $region The region. See Subscription::$availableRegions. - * @param string $plan The plan. See Subscription::$availablePlans. - * @param string $title The project title. - * @param int $storage The storage of each environment, in MiB. - * @param int $environments The number of available environments. + * @param string $region The region ID. See getRegions(). + * @param string $plan The plan. See Subscription::$availablePlans. + * @param string $title The project title. + * @param int $storage The storage of each environment, in MiB. + * @param int $environments The number of available environments. * @param array $activationCallback An activation callback for the subscription. * + * @see PlatformClient::getRegions(). + * * @return Subscription */ public function createSubscription($region, $plan = 'development', $title = null, $storage = null, $environments = null, array $activationCallback = null) @@ -301,4 +304,14 @@ return $response->json(); } + + /** + * Get a list of available regions. + * + * @return Region[] + */ + public function getRegions() + { + return Region::getCollection($this->accountsEndpoint . 'regions', 0, [], $this->getConnector()->getClient()); + } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/console-form/src/Field/ArrayField.php new/vendor/platformsh/console-form/src/Field/ArrayField.php --- old/vendor/platformsh/console-form/src/Field/ArrayField.php 2017-12-11 16:23:12.000000000 +0100 +++ new/vendor/platformsh/console-form/src/Field/ArrayField.php 2018-02-12 12:15:24.000000000 +0100 @@ -11,14 +11,32 @@ /** * {@inheritdoc} */ - public function getAsQuestion() + public function normalize($value) { - $question = parent::getAsQuestion(); - $question->setNormalizer(function ($value) { - return is_array($value) ? $value : array_filter(preg_split('/[,;\n] */', $value), 'strlen'); - }); + // If the value is an array of only one element, it might be a + // comma-separated string provided to the command-line option. Extract + // the first element. + if (is_array($value) && count($value) === 1) { + $value = reset($value); + } - return $question; + // If the value is a string, split it into an array. + if (is_string($value)) { + $value = $this->split($value); + } + + return parent::normalize($value); + } + + /** + * Split a comma or whitespace-separated string into an array. + * + * @param string $str + * + * @return array + */ + private function split($str) { + return array_filter(preg_split('/[,\s]+/', $str), 'strlen'); } /** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/console-form/src/Field/OptionsField.php new/vendor/platformsh/console-form/src/Field/OptionsField.php --- old/vendor/platformsh/console-form/src/Field/OptionsField.php 2017-12-11 16:23:12.000000000 +0100 +++ new/vendor/platformsh/console-form/src/Field/OptionsField.php 2018-02-12 12:15:24.000000000 +0100 @@ -27,8 +27,13 @@ { parent::__construct($name, $config); $this->validators[] = function ($value) { - return $this->allowOther || in_array($value, $this->options, true) - ? true : "$value is not one of: " . implode(', ', $this->options); + if ($this->allowOther) { + return true; + } + $options = $this->isNumeric() ? $this->options : array_keys($this->options); + + return array_search($value, $options, true) !== false + ? true : "$value is not one of: " . implode(', ', $options); }; } @@ -63,17 +68,22 @@ */ protected function getChoiceQuestion() { - // Translate the default into an array key. - $defaultKey = $this->default !== null - ? array_search($this->default, $this->options, true) : $this->default; + $numeric = $this->isNumeric(); + $text = $this->getQuestionHeader(); + if ($numeric) { + $text .= "\nEnter a number to choose: "; + } $question = new ChoiceQuestion( - $this->getQuestionHeader() . "\nEnter a number to choose: ", + $text, $this->options, - $defaultKey !== false ? $defaultKey : null + $this->default ); $question->setPrompt($this->prompt); $question->setMaxAttempts($this->maxAttempts); + if (!$numeric) { + $question->setAutocompleterValues(array_keys($this->options)); + } return $question; } @@ -84,9 +94,11 @@ protected function getDescription() { $description = parent::getDescription(); - $optionsString = "'" . implode("', '", $this->options) . "'"; - if (strlen($optionsString) < 255) { - $description .= ' (' . $optionsString . ')'; + if (!empty($this->options)) { + $optionsString = "'" . implode("', '", $this->options) . "'"; + if (strlen($optionsString) < 255) { + $description .= ' (' . $optionsString . ')'; + } } return $description; @@ -102,4 +114,20 @@ $this->options = $callback($previousValues); } } + + /** + * Check if this is numeric, rather than associative. + * + * @return bool + */ + private function isNumeric() + { + foreach (array_keys($this->options) as $key) { + if (!is_int($key)) { + return false; + } + } + + return true; + } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/console-form/tests/FormTest.php new/vendor/platformsh/console-form/tests/FormTest.php --- old/vendor/platformsh/console-form/tests/FormTest.php 2017-12-11 16:23:12.000000000 +0100 +++ new/vendor/platformsh/console-form/tests/FormTest.php 2018-02-12 12:15:24.000000000 +0100 @@ -14,6 +14,7 @@ use Symfony\Component\Console\Helper\FormatterHelper; use Symfony\Component\Console\Helper\HelperSet; use Symfony\Component\Console\Helper\QuestionHelper; +use Symfony\Component\Console\Input\ArgvInput; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputDefinition; use Symfony\Component\Console\Output\NullOutput; @@ -288,6 +289,10 @@ 'allowOther' => true, 'optionName' => 'options-allow-other', ]), 'options_non_strict'); + $this->form->addField(new OptionsField('Associative options', [ + 'options' => ['option1' => 'Option 1', 'option2' => 'Option 2', 'option3' => 'Option 3'], + 'optionName' => 'options-assoc', + ]), 'options-assoc'); $this->form->configureInputDefinition($definition); $output = new NullOutput(); @@ -297,10 +302,15 @@ '--mail' => $this->validMail, '--options' => 'option1', '--options-allow-other' => 'optionO', + '--options-assoc' => 'option2', ], $definition); $input->setInteractive(false); $result = $this->form->resolveOptions($input, $output, $helper); - $validResult = $this->validResult + ['options' => 'option1', 'options_non_strict' => 'optionO']; + $validResult = $this->validResult + [ + 'options' => 'option1', + 'options_non_strict' => 'optionO', + 'options-assoc' => 'option2', + ]; $this->assertEquals($validResult, $result, 'Valid non-interactive option input'); // Test interactive input. @@ -309,9 +319,13 @@ '--mail' => $this->validMail, '--options-allow-other' => 'optionO', ], $definition); - $input->setStream($this->getInputStream(str_repeat("\n", $countFieldsBefore) . '1')); + $input->setStream($this->getInputStream(str_repeat("\n", $countFieldsBefore) . "1\noption2")); $result = $this->form->resolveOptions($input, $output, $helper); - $validResult = $this->validResult + ['options' => 'option2', 'options_non_strict' => 'optionO']; + $validResult = $this->validResult + [ + 'options' => 'option2', + 'options_non_strict' => 'optionO', + 'options-assoc' => 'option2', + ]; $this->assertEquals($validResult, $result, 'Valid interactive option input'); } @@ -375,6 +389,39 @@ $this->assertEquals($validResult, $result, 'Empty input passes'); } + public function testCommandLineCommaSeparatedArrayOptions() + { + $definition = new InputDefinition(); + $this->form->configureInputDefinition($definition); + + $validResult = $this->validResult; + $validResult['array'] = ['foo', 'bar', 'baz']; + + $input = new ArgvInput([ + 'commandName', + '--test', $this->validString, + '--mail', $this->validMail, + '--array', 'foo, bar,baz', + ], $definition); + $input->setInteractive(false); + $result = $this->form->resolveOptions($input, new NullOutput(), $this->getQuestionHelper()); + $this->assertEquals($validResult, $result, 'Array input with comma-separated values passes'); + + $validResult = $this->validResult; + $validResult['array'] = ['foo, bar', 'baz']; + + $input = new ArgvInput([ + 'commandName', + '--test', $this->validString, + '--mail', $this->validMail, + '--array', 'foo, bar', + '--array', 'baz', + ], $definition); + $input->setInteractive(false); + $result = $this->form->resolveOptions($input, new NullOutput(), $this->getQuestionHelper()); + $this->assertEquals($validResult, $result, 'Array input with array values passes'); + } + /** * @return QuestionHelper */
