Hello community, here is the log from the commit of package platformsh-cli for openSUSE:Factory checked in at 2019-01-10 15:23:35 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/platformsh-cli (Old) and /work/SRC/openSUSE:Factory/.platformsh-cli.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "platformsh-cli" Thu Jan 10 15:23:35 2019 rev:60 rq:664154 version:3.38.0 Changes: -------- --- /work/SRC/openSUSE:Factory/platformsh-cli/platformsh-cli.changes 2018-11-29 23:01:18.391439396 +0100 +++ /work/SRC/openSUSE:Factory/.platformsh-cli.new.28833/platformsh-cli.changes 2019-01-10 15:23:37.638312692 +0100 @@ -1,0 +2,49 @@ +Wed Jan 09 18:04:55 UTC 2019 - [email protected] + +- Update to version 3.38.0: + * Release v3.38.0 + * Fix addOption arguments in snapshot:restore + * Allow restoring snapshots to another environment (#735) + * Sort interactive project/environment choices alphabetically + * Update README.md [skip changelog] + * Deduplicate role option description [skip changelog] + * Separate user:add and user:update command help + * [environment:list] Define "created" and "updated" columns + * [environment:list] Fix "Name" column should always have been "Title" + * Also support environment titles of 0 + * Fix: environments with an empty name (e.g. '0') not being recognized + * [certificate:list] Add --pipe-domains option + * [certificate:list] Add --exclude-domain option + * [certificate:list] Add certs alias + * Remove interactivity check from installer (#765) + * [certificate:list] Define `domains` column + * [certificate:list] Filter on --no-expired by default; add --ignore-expiry option for previous behavior + * Fix inline documentation in user:list command + * Run tests in PHP 7.3 (Travis) (#764) + +------------------------------------------------------------------- +Fri Dec 28 23:29:16 UTC 2018 - [email protected] + +- Update to version 3.37.2: + * Release v3.37.2 + * [worker:list] Display project and environment name/ID + * [snapshot:list] Display project and environment name/ID + * [route:list] Display project name/ID + * [domain:list] Display project name/ID + * [activity:list] use api() method [skip changelog] + * [user:list] Display project name/ID + * Alias "python3" dependencies type to use pip + * Define "path" column in mount:list command + * Fix table CSV test + * Revert csv/tsv output to use LF instead of CRLF line breaks + * [activity:list] Better explanation of the selected environment/project + * Parse project URLs from the beta unified-UI (#761) + +------------------------------------------------------------------- +Thu Nov 29 13:53:32 UTC 2018 - [email protected] + +- Update to version 3.37.1: + * Release v3.37.1 + * [mount:size] Fix capacity calculation (should show % of total space, instead of % of "available") + +------------------------------------------------------------------- Old: ---- platformsh-cli-3.37.0.tar.xz New: ---- platformsh-cli-3.38.0.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ platformsh-cli.spec ++++++ --- /var/tmp/diff_new_pack.Wzr31p/_old 2019-01-10 15:23:38.154312159 +0100 +++ /var/tmp/diff_new_pack.Wzr31p/_new 2019-01-10 15:23:38.154312159 +0100 @@ -1,7 +1,7 @@ # # spec file for package platformsh-cli # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: platformsh-cli -Version: 3.37.0 +Version: 3.38.0 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.Wzr31p/_old 2019-01-10 15:23:38.186312126 +0100 +++ /var/tmp/diff_new_pack.Wzr31p/_new 2019-01-10 15:23:38.186312126 +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.37.0</param> + <param name="revision">refs/tags/v3.38.0</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.Wzr31p/_old 2019-01-10 15:23:38.202312109 +0100 +++ /var/tmp/diff_new_pack.Wzr31p/_new 2019-01-10 15:23:38.202312109 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">git://github.com/platformsh/platformsh-cli.git</param> - <param name="changesrevision">6ad5381f1888c5601a44c37b85ca2d00e17faf57</param> + <param name="changesrevision">89037ac97082af56f5346c0fc5dfeb3d8a2d0061</param> </service> </servicedata> ++++++ licenses.txt ++++++ --- /var/tmp/diff_new_pack.Wzr31p/_old 2019-01-10 15:23:38.242312068 +0100 +++ /var/tmp/diff_new_pack.Wzr31p/_new 2019-01-10 15:23:38.242312068 +0100 @@ -17,7 +17,7 @@ padraic/humbug_get_contents 1.1.2 BSD-3-Clause padraic/phar-updater v1.0.6 BSD-3-Clause paragonie/random_compat v2.0.17 MIT -platformsh/client v0.22.2 MIT +platformsh/client v0.23.0 MIT platformsh/console-form v0.0.23 MIT psr/container 1.0.0 MIT psr/log 1.1.0 MIT ++++++ platformsh-cli-3.37.0.tar.xz -> platformsh-cli-3.38.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/.travis.yml new/platformsh-cli-3.38.0/.travis.yml --- old/platformsh-cli-3.37.0/.travis.yml 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/.travis.yml 2019-01-09 15:57:31.000000000 +0100 @@ -8,7 +8,7 @@ include: - php: 5.6 env: TEST_SCRIPT=scripts/test/security.sh - - php: 7.2 + - php: 7.3 env: TEST_SCRIPT=scripts/test/security.sh - php: 5.6 @@ -22,10 +22,12 @@ env: TEST_SCRIPT=scripts/test/unit.sh - php: 7.2 env: TEST_SCRIPT=scripts/test/unit.sh + - php: 7.3 + env: TEST_SCRIPT=scripts/test/unit.sh - php: nightly env: TEST_SCRIPT=scripts/test/unit.sh - - php: 7.2 + - php: 7.3 env: TEST_SCRIPT=scripts/test/slow.sh allow_failures: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/README.md new/platformsh-cli-3.38.0/README.md --- old/platformsh-cli-3.37.0/README.md 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/README.md 2019-01-09 15:57:31.000000000 +0100 @@ -95,7 +95,7 @@ certificate:add Add an SSL certificate to the project certificate:delete Delete a certificate from the project certificate:get View a certificate - certificate:list (certificates) List project certificates + certificate:list (certificates, certs) List project certificates commit commit:get Show commit details commit:list (commits) List commits @@ -132,6 +132,7 @@ integration:get View details of an integration integration:list (integrations) View a list of project integration(s) integration:update Update an integration + integration:validate Validate an existing integration local local:build (build) Build the current project locally local:dir (dir) Find the local project root @@ -184,10 +185,11 @@ tunnel:list (tunnels) List SSH tunnels tunnel:open Open SSH tunnels to an app's relationships user - user:add (user:update) Add a user to the project, or set their role(s) + user:add Add a user to the project user:delete Delete a user from the project user:get View a user's role(s) user:list (users) List project users + user:update Update user role(s) on a project variable variable:create Create a variable variable:delete Delete a variable diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/composer.json new/platformsh-cli-3.38.0/composer.json --- old/platformsh-cli-3.37.0/composer.json 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/composer.json 2019-01-09 15:57:31.000000000 +0100 @@ -8,7 +8,7 @@ "guzzlehttp/guzzle": "^5.3", "guzzlehttp/ringphp": "^1.1", "platformsh/console-form": ">=0.0.22 <2.0", - "platformsh/client": ">=0.22.2 <2.0", + "platformsh/client": ">=0.23.0 <2.0", "symfony/console": "^3.0 >=3.2", "symfony/yaml": "^3.0 || ^2.6", "symfony/finder": "^3.0", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/composer.lock new/platformsh-cli-3.38.0/composer.lock --- old/platformsh-cli-3.37.0/composer.lock 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/composer.lock 2019-01-09 15:57:31.000000000 +0100 @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2b5dbc63521744801a54eb2cd2c5a14a", + "content-hash": "7316086542b599673424191e18406f6a", "packages": [ { "name": "cocur/slugify", @@ -712,16 +712,16 @@ }, { "name": "platformsh/client", - "version": "v0.22.2", + "version": "v0.23.0", "source": { "type": "git", "url": "https://github.com/platformsh/platformsh-client-php.git", - "reference": "e487f9fbb9f79b404dcfd19e633d13cade7bce6b" + "reference": "9b0fc3004d5abdc3cc54b0bea80f779e23660289" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/e487f9fbb9f79b404dcfd19e633d13cade7bce6b", - "reference": "e487f9fbb9f79b404dcfd19e633d13cade7bce6b", + "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/9b0fc3004d5abdc3cc54b0bea80f779e23660289", + "reference": "9b0fc3004d5abdc3cc54b0bea80f779e23660289", "shasum": "" }, "require": { @@ -757,7 +757,7 @@ } ], "description": "Platform.sh API client", - "time": "2018-10-24T20:17:25+00:00" + "time": "2019-01-09T14:36:49+00:00" }, { "name": "platformsh/console-form", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/config.yaml new/platformsh-cli-3.38.0/config.yaml --- old/platformsh-cli-3.37.0/config.yaml 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/config.yaml 2019-01-09 15:57:31.000000000 +0100 @@ -1,7 +1,7 @@ # Metadata about the CLI application itself. application: name: 'Platform.sh CLI' - version: '3.37.0' + version: '3.38.0' executable: 'platform' package_name: 'platformsh/cli' installer_url: 'https://platform.sh/cli/installer' @@ -104,6 +104,9 @@ git_domain: 'platform.sh' site_domains: ['platform.sh', 'platformsh.site'] + # Domain of a unified-UI instance (beta). + ui_domain: 'ui.platform.sh' + # Automatic updates. # This can be overridden in the user config file. updates: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/dist/installer.php new/platformsh-cli-3.38.0/dist/installer.php --- old/platformsh-cli-3.37.0/dist/installer.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/dist/installer.php 2019-01-09 15:57:31.000000000 +0100 @@ -222,10 +222,7 @@ output(PHP_EOL . ' Running self:install command...' . PHP_EOL); putenv('CLICOLOR_FORCE=' . (is_ansi() ? '1' : '0')); -$commandline = 'php ' . $pharPath . ' self:install'; -if (!is_interactive()) { - $commandline .= ' --yes'; -} +$commandline = 'php ' . $pharPath . ' self:install --yes'; $process = proc_open($commandline, [STDIN, STDOUT, STDERR], $pipes); $result = proc_close($process); @@ -311,25 +308,6 @@ } /** - * Returns whether the terminal is interactive. - * - * @return bool - */ -function is_interactive() -{ - global $argv; - if (!empty($argv) && array_intersect(['--no-interaction', '-y', '--yes'], $argv)) { - return false; - } - - if (function_exists('posix_isatty')) { - return posix_isatty(STDOUT) && posix_isatty(STDERR); - } - - return true; -} - -/** * Sets up the STDIN, STDOUT and STDERR constants. * * Due to a PHP bug, these constants are not available when the PHP script is diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/dist/manifest.json new/platformsh-cli-3.38.0/dist/manifest.json --- old/platformsh-cli-3.37.0/dist/manifest.json 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/dist/manifest.json 2019-01-09 15:57:31.000000000 +0100 @@ -1,10 +1,10 @@ [ { "name": "platform.phar", - "sha1": "99793bba2729e51a4ea425cbb069e9e0227d67b5", - "sha256": "6fcc456af03881579bdc67a53fcb7724f43e51c6723988a92f2a276d8323a9fb", - "url": "https://github.com/platformsh/platformsh-cli/releases/download/v3.37.0/platform.phar", - "version": "3.37.0", + "sha1": "5144fb0283e09583c7f5933324168194b6df4e61", + "sha256": "f6aa40652c031374338fdedc2b5fe45419477cb8d8c688639819f8cac11ddd13", + "url": "https://github.com/platformsh/platformsh-cli/releases/download/v3.38.0/platform.phar", + "version": "3.38.0", "php": { "min": "5.5.9" }, @@ -152,6 +152,16 @@ "notes": "New features:\n\n* Add --columns option for all tables (to filter and order table columns).\n* Add non-default \"disk\" and \"size\" columns to app:list command.\n* Add non-default \"updated_at\" column to domains:list command.\n* Add non-default \"host\" column to project:list command.\n* Allow loading more than 10 snapshots via --limit in snapshot:list command.\n\nOther changes:\n\n* Change CSV/TSV table output to make it cleaner. CSV/TSV cells will now only\n be enclosed in quote marks if necessary, conforming to RFC 4180.\n* Fail if password input cannot be hidden in auth:password-login command.\n* Set the remote only for new branches in environment:branch command.\n* Avoid wrapping dates in commit:list command.\n* Update list of allowed SSH key algorithms for ssh-key:add command.\n* Remove confirmation step in logout command.", "show from": "3.36.0", "hide from": "3.37.0" + }, + { + "notes": "* Revert csv/tsv table output to use LF instead of CRLF line breaks.\n* Display project and environment title/ID in the following commands:\n `activity:list` (`activities`), `domain:list` (`domains`),\n `route:list` (`routes`), `snapshot:list` (`snapshots`),\n `user:list` (`users`), `worker:list` (`workers`) \n* Local build: handle `python3` dependencies type (same as `python`).\n* Define the `path` column in the `mount:list` (`mounts`) command.\n* Parse project URLs from the beta unified-UI.", + "show from": "3.37.0", + "hide from": "3.37.2" + }, + { + "notes": "* Allow restoring snapshots to another environment in snapshot:restore command\n (with new --target and --branch-from options).\n* Sort interactive project/environment choices alphabetically.\n* Fix \"Name\"/\"name\" column should always have been \"Title\"/\"title\" in\n environment:list command.\n* Define \"created\" and \"updated\" columns in environment:list command.\n* Remove interactivity check from installer.\n* Fix: environments with an empty name (e.g. '0') not being recognized.\n* Fix documentation in user:list, user:add and user:update commands.\n* Various changes and new features in certificate:list command:\n - only show non-expired certificates by default\n - add --ignore-expiry option for the previous behavior\n - add --exclude-domain option to filter out certificates from the list\n - add --pipe-domains option to list domains covered by certificates\n - add \"certs\" alias\n - define \"domains\" column (for the --columns option)", + "show from": "3.37.0", + "hide from": "3.38.0" } ] } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Application.php new/platformsh-cli-3.38.0/src/Application.php --- old/platformsh-cli-3.37.0/src/Application.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Application.php 2019-01-09 15:57:31.000000000 +0100 @@ -194,6 +194,7 @@ $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(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/Activity/ActivityListCommand.php new/platformsh-cli-3.38.0/src/Command/Activity/ActivityListCommand.php --- old/platformsh-cli-3.37.0/src/Command/Activity/ActivityListCommand.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/Activity/ActivityListCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -96,19 +96,16 @@ if (!$table->formatIsMachineReadable()) { if ($environmentSpecific) { - $this->stdErr->writeln( - sprintf( - 'Activities for the environment <info>%s</info>:', - $apiResource->id - ) - ); + $this->stdErr->writeln(sprintf( + 'Activities on the project %s, environment %s:', + $this->api()->getProjectLabel($project), + $this->api()->getEnvironmentLabel($apiResource) + )); } else { - $this->stdErr->writeln( - sprintf( - 'Activities for the project <info>%s</info>:', - $this->api()->getProjectLabel($project) - ) - ); + $this->stdErr->writeln(sprintf( + 'Activities on the project %s:', + $this->api()->getProjectLabel($project) + )); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/Certificate/CertificateListCommand.php new/platformsh-cli-3.38.0/src/Command/Certificate/CertificateListCommand.php --- old/platformsh-cli-3.37.0/src/Command/Certificate/CertificateListCommand.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/Certificate/CertificateListCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -16,24 +16,34 @@ { $this ->setName('certificate:list') - ->setAliases(['certificates']) + ->setAliases(['certificates', 'certs']) ->setDescription('List project certificates'); $this->addOption('domain', null, InputOption::VALUE_REQUIRED, 'Filter by domain name (case-insensitive search)'); + $this->addOption('exclude-domain', null, InputOption::VALUE_REQUIRED, 'Exclude certificates, matching by domain name (case-insensitive search)'); $this->addOption('issuer', null, InputOption::VALUE_REQUIRED, 'Filter by issuer'); $this->addOption('only-auto', null, InputOption::VALUE_NONE, 'Show only auto-provisioned certificates'); $this->addOption('no-auto', null, InputOption::VALUE_NONE, 'Show only manually added certificates'); + $this->addOption('ignore-expiry', null, InputOption::VALUE_NONE, 'Show both expired and non-expired certificates'); $this->addOption('only-expired', null, InputOption::VALUE_NONE, 'Show only expired certificates'); - $this->addOption('no-expired', null, InputOption::VALUE_NONE, 'Show only non-expired certificates'); + $this->addOption('no-expired', null, InputOption::VALUE_NONE, 'Show only non-expired certificates (default)'); + $this->addOption('pipe-domains', null, InputOption::VALUE_NONE, 'Only return a list of domain names covered by the certificates'); PropertyFormatter::configureInput($this->getDefinition()); Table::configureInput($this->getDefinition()); $this->addProjectOption(); + $this->addExample('Output a list of domains covered by valid certificates', '--pipe-domains --no-expired'); } protected function execute(InputInterface $input, OutputInterface $output) { $this->validateInput($input); - $filterOptions = ['domain', 'issuer', 'only-auto', 'no-auto', 'only-expired', 'no-expired']; + // Set --no-expired by default, if --ignore-expiry and --only-expired + // are not supplied. + if (!$input->getOption('ignore-expiry') && !$input->getOption('only-expired')) { + $input->setOption('no-expired', true); + } + + $filterOptions = ['domain', 'exclude-domain', 'issuer', 'only-auto', 'no-auto', 'only-expired', 'no-expired']; $filters = array_filter(array_intersect_key($input->getOptions(), array_flip($filterOptions))); $project = $this->getSelectedProject(); @@ -42,11 +52,12 @@ $this->filterCerts($certs, $filters); - if (!empty($filters)) { + if (!empty($filters) && !$input->getOption('pipe-domains')) { $filtersUsed = '<comment>--' . implode('</comment>, <comment>--', array_keys($filters)) . '</comment>'; $this->stdErr->writeln(sprintf('Filters in use: %s', $filtersUsed)); + $this->stdErr->writeln(''); } if (empty($certs)) { @@ -55,17 +66,27 @@ return 0; } + if ($input->getOption('pipe-domains')) { + foreach ($certs as $cert) { + foreach ($cert->domains as $domain) { + $output->writeln($domain); + } + } + + return 0; + } + /** @var \Platformsh\Cli\Service\Table $table */ $table = $this->getService('table'); /** @var \Platformsh\Cli\Service\PropertyFormatter $propertyFormatter */ $propertyFormatter = $this->getService('property_formatter'); - $header = ['ID', 'Domain(s)', 'Created', 'Expires', 'Issuer']; + $header = ['ID', 'domains' => 'Domain(s)', 'Created', 'Expires', 'Issuer']; $rows = []; foreach ($certs as $cert) { $rows[] = [ $cert->id, - implode("\n", $cert->domains), + 'domains' => implode("\n", $cert->domains), $propertyFormatter->format($cert->created_at, 'created_at'), $propertyFormatter->format($cert->expires_at, 'expires_at'), $this->getCertificateIssuerByAlias($cert, 'commonName') ?: '', @@ -94,14 +115,16 @@ foreach ($filters as $filter => $value) { switch ($filter) { case 'domain': - $certs = array_filter($certs, function (Certificate $cert) use ($value) { + case 'exclude-domain': + $include = $filter === 'domain'; + $certs = array_filter($certs, function (Certificate $cert) use ($value, $include) { foreach ($cert->domains as $domain) { if (stripos($domain, $value) !== false) { - return true; + return $include; } } - return false; + return !$include; }); break; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/CommandBase.php new/platformsh-cli-3.38.0/src/Command/CommandBase.php --- old/platformsh-cli-3.37.0/src/Command/CommandBase.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/CommandBase.php 2019-01-09 15:57:31.000000000 +0100 @@ -759,7 +759,7 @@ ), OutputInterface::VERBOSITY_VERBOSE); } - if (!empty($environmentId)) { + if ($environmentId !== null) { $environment = $this->api()->getEnvironment($environmentId, $this->project, null, true); if (!$environment) { throw new ConsoleInvalidArgumentException('Specified environment not found: ' . $environmentId); @@ -865,10 +865,12 @@ throw new \BadMethodCallException('Not interactive: a project choice cannot be offered.'); } + // Build and sort a list of project options. $projectList = []; foreach ($projects as $project) { $projectList[$project->id] = $this->api()->getProjectLabel($project, false); } + asort($projectList, SORT_NATURAL | SORT_FLAG_CASE); /** @var \Platformsh\Cli\Service\QuestionHelper $questionHelper */ $questionHelper = $this->getService('question_helper'); @@ -897,6 +899,10 @@ $questionHelper = $this->getService('question_helper'); $default = $this->api()->getDefaultEnvironmentId($environments); + // Build and sort a list of options (environment IDs). + $ids = array_keys($environments); + sort($ids, SORT_NATURAL | SORT_FLAG_CASE); + $id = $questionHelper->askInput('Environment ID', $default, array_keys($environments), function ($value) use ($environments) { if (!isset($environments[$value])) { throw new \RuntimeException('Environment not found: ' . $value); @@ -968,8 +974,8 @@ // Select the environment. $envOptionName = 'environment'; - if ($input->hasArgument($this->envArgName) && $input->getArgument($this->envArgName)) { - if ($input->hasOption($envOptionName) && $input->getOption($envOptionName)) { + if ($input->hasArgument($this->envArgName) && $input->getArgument($this->envArgName) !== null) { + if ($input->hasOption($envOptionName) && $input->getOption($envOptionName) !== null) { throw new ConsoleInvalidArgumentException( sprintf( 'You cannot use both the <%s> argument and the --%s option', @@ -987,7 +993,9 @@ $this->selectEnvironment($argument, true, $selectDefaultEnv); } } elseif ($input->hasOption($envOptionName)) { - $environmentId = $input->getOption($envOptionName) ?: $environmentId; + if ($input->getOption($envOptionName) !== null) { + $environmentId = $input->getOption($envOptionName); + } $this->selectEnvironment($environmentId, !$envNotRequired, $selectDefaultEnv); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/Domain/DomainListCommand.php new/platformsh-cli-3.38.0/src/Command/Domain/DomainListCommand.php --- old/platformsh-cli-3.37.0/src/Command/Domain/DomainListCommand.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/Domain/DomainListCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -86,15 +86,23 @@ return 0; } - $this->stdErr->writeln("Your domains are: "); + if (!$table->formatIsMachineReadable()) { + $this->stdErr->writeln(sprintf( + 'Domains on the project %s:', + $this->api()->getProjectLabel($project) + )); + } + $table->render($rows, $header, $defaultColumns); - $this->stdErr->writeln(''); - $this->stdErr->writeln([ - 'To add a new domain, run: <info>' . $executable . ' domain:add [domain-name]</info>', - 'To view a domain, run: <info>' . $executable . ' domain:get [domain-name]</info>', - 'To delete a domain, run: <info>' . $executable . ' domain:delete [domain-name]</info>', - ]); + if (!$table->formatIsMachineReadable()) { + $this->stdErr->writeln(''); + $this->stdErr->writeln([ + 'To add a new domain, run: <info>' . $executable . ' domain:add [domain-name]</info>', + 'To view a domain, run: <info>' . $executable . ' domain:get [domain-name]</info>', + 'To delete a domain, run: <info>' . $executable . ' domain:delete [domain-name]</info>', + ]); + } return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/Environment/EnvironmentBranchCommand.php new/platformsh-cli-3.38.0/src/Command/Environment/EnvironmentBranchCommand.php --- old/platformsh-cli-3.37.0/src/Command/Environment/EnvironmentBranchCommand.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/Environment/EnvironmentBranchCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -47,7 +47,7 @@ $parentEnvironment = $this->getSelectedEnvironment(); $branchName = $input->getArgument('id'); - if (empty($branchName)) { + if ($branchName === null) { if ($input->isInteractive()) { // List environments. return $this->runOtherCommand( @@ -117,11 +117,11 @@ return 1; } - $title = $input->getOption('title') ?: $branchName; + $title = $input->getOption('title') !== null ? $input->getOption('title') : $branchName; $this->stdErr->writeln(sprintf( 'Creating a new environment %s, branched from %s', - $title && $title !== $branchName + strlen($title) > 0 && $title !== $branchName ? '<info>' . $title . '</info> (' . $branchName . ')' : '<info>' . $branchName . '</info>', $this->api()->getEnvironmentLabel($parentEnvironment) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/Environment/EnvironmentCheckoutCommand.php new/platformsh-cli-3.38.0/src/Command/Environment/EnvironmentCheckoutCommand.php --- old/platformsh-cli-3.37.0/src/Command/Environment/EnvironmentCheckoutCommand.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/Environment/EnvironmentCheckoutCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -36,10 +36,10 @@ } $branch = $input->getArgument('id'); - if (empty($branch)) { + if ($branch === null) { if ($input->isInteractive()) { $branch = $this->offerBranchChoice($project, $projectRoot); - if (empty($branch)) { + if ($branch === null) { return 1; } } else { @@ -115,7 +115,10 @@ } $environmentList = []; foreach ($environments as $id => $environment) { - if ($currentEnvironment && $id == $currentEnvironment->id) { + // The $id will be an integer for numeric environment names (as + // it was assigned to an array key), so it's cast back to a + // string for this comparison. + if ($currentEnvironment && (string) $id === $currentEnvironment->id) { continue; } $environmentList[$id] = $this->api()->getEnvironmentLabel($environment, false); @@ -146,7 +149,11 @@ // If there's more than one choice, present the user with a list. if (count($environmentList) > 1) { $chooseEnvironmentText = "Enter a number to check out another environment:"; - return $helper->choose($environmentList, $chooseEnvironmentText); + + // The environment ID will be an integer if it was numeric + // (because PHP does that with array keys), so it's cast back to + // a string here. + return (string) $helper->choose($environmentList, $chooseEnvironmentText); } // If there's only one choice, QuestionHelper::choose() does not diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/Environment/EnvironmentListCommand.php new/platformsh-cli-3.38.0/src/Command/Environment/EnvironmentListCommand.php --- old/platformsh-cli-3.37.0/src/Command/Environment/EnvironmentListCommand.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/Environment/EnvironmentListCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -18,6 +18,9 @@ protected $currentEnvironment; protected $mapping = []; + /** @var \Platformsh\Cli\Service\PropertyFormatter */ + protected $formatter; + /** * {@inheritdoc} */ @@ -107,6 +110,9 @@ $row[] = $this->formatEnvironmentStatus($environment->status); + $row[] = $this->formatter->format($environment->created_at, 'created_at'); + $row[] = $this->formatter->format($environment->updated_at, 'updated_at'); + $rows[] = $row; if (isset($this->children[$environment->id])) { $childRows = $this->buildEnvironmentRows( @@ -173,20 +179,24 @@ $this->children['master'] = []; } - $headers = ['ID', 'Name', 'Status']; + $headers = ['ID', 'Title', 'Status', 'Created', 'Updated']; + $defaultColumns = ['id', 'title', 'status']; /** @var \Platformsh\Cli\Service\Table $table */ $table = $this->getService('table'); + /** @var \Platformsh\Cli\Service\PropertyFormatter $formatter */ + $this->formatter = $this->getService('property_formatter'); + if ($table->formatIsMachineReadable()) { - $table->render($this->buildEnvironmentRows($tree, false, false), $headers); + $table->render($this->buildEnvironmentRows($tree, false, false), $headers, $defaultColumns); return; } $this->stdErr->writeln("Your environments are: "); - $table->render($this->buildEnvironmentRows($tree), $headers); + $table->render($this->buildEnvironmentRows($tree), $headers, $defaultColumns); if (!$this->currentEnvironment) { return; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/Mount/MountListCommand.php new/platformsh-cli-3.38.0/src/Command/Mount/MountListCommand.php --- old/platformsh-cli-3.37.0/src/Command/Mount/MountListCommand.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/Mount/MountListCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -51,12 +51,12 @@ return 0; } - $header = ['Mount path', 'Definition']; + $header = ['path' => 'Mount path', 'definition' => 'Definition']; $rows = []; /** @var \Platformsh\Cli\Service\PropertyFormatter $formatter */ $formatter = $this->getService('property_formatter'); foreach ($mounts as $path => $definition) { - $rows[] = [$path, $formatter->format($definition)]; + $rows[] = ['path' => $path, 'definition' => $formatter->format($definition)]; } /** @var \Platformsh\Cli\Service\Table $table */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/Mount/MountSizeCommand.php new/platformsh-cli-3.38.0/src/Command/Mount/MountSizeCommand.php --- old/platformsh-cli-3.37.0/src/Command/Mount/MountSizeCommand.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/Mount/MountSizeCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -203,15 +203,13 @@ $results[$filesystem]['mounts'][] = $mountPath; continue; } - $available = $this->getDfColumn($line, 'available'); - $used = $this->getDfColumn($line, 'used'); $results[$filesystem] = [ 'total' => $this->getDfColumn($line, 'total'), - 'used' => $used, - 'available' => $available, + 'used' => $this->getDfColumn($line, 'used'), + 'available' => $this->getDfColumn($line, 'available'), 'mounts' => [$mountPath], - 'percent_used' => $used / $available * 100, ]; + $results[$filesystem]['percent_used'] = $results[$filesystem]['used'] / $results[$filesystem]['total'] * 100; } return $results; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/Project/ProjectGetCommand.php new/platformsh-cli-3.38.0/src/Command/Project/ProjectGetCommand.php --- old/platformsh-cli-3.37.0/src/Command/Project/ProjectGetCommand.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/Project/ProjectGetCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -216,7 +216,7 @@ $result = $identifier->identify($projectId); $projectId = $result['projectId']; $host = $host ?: $result['host']; - $environmentId = $environmentId ?: $result['environmentId']; + $environmentId = $environmentId !== null ? $environmentId : $result['environmentId']; } $project = $this->selectProject($projectId, $host); @@ -245,7 +245,7 @@ } $this->projectRoot = $parent . '/' . basename($directory); - if (!$environmentId) { + if ($environmentId === null) { $environments = $this->api()->getEnvironments($project); $environmentId = isset($environments['master']) ? 'master' : key($environments); if (count($environments) > 1) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/Project/ProjectListCommand.php new/platformsh-cli-3.38.0/src/Command/Project/ProjectListCommand.php --- old/platformsh-cli-3.37.0/src/Command/Project/ProjectListCommand.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/Project/ProjectListCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -40,7 +40,7 @@ if ($host = $input->getOption('host')) { $filters['host'] = $host; } - if ($title = $input->getOption('title')) { + if (($title = $input->getOption('title')) !== null) { $filters['title'] = $title; } if ($input->getOption('my')) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/Route/RouteListCommand.php new/platformsh-cli-3.38.0/src/Command/Route/RouteListCommand.php --- old/platformsh-cli-3.37.0/src/Command/Route/RouteListCommand.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/Route/RouteListCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -53,7 +53,11 @@ } if (!$table->formatIsMachineReadable()) { - $this->stdErr->writeln("Routes for the environment <info>{$environment->id}</info>:"); + $this->stdErr->writeln(sprintf( + 'Routes on the project %s, environment %s:', + $this->api()->getProjectLabel($this->getSelectedProject()), + $this->api()->getEnvironmentLabel($environment) + )); } $table->render($rows, $header); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/Snapshot/SnapshotListCommand.php new/platformsh-cli-3.38.0/src/Command/Snapshot/SnapshotListCommand.php --- old/platformsh-cli-3.37.0/src/Command/Snapshot/SnapshotListCommand.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/Snapshot/SnapshotListCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -46,10 +46,6 @@ /** @var \Platformsh\Cli\Service\PropertyFormatter $formatter */ $formatter = $this->getService('property_formatter'); - if (!$table->formatIsMachineReadable()) { - $this->stdErr->writeln("Finding snapshots for the environment <info>{$environment->id}</info>"); - } - /** @var \Platformsh\Cli\Service\ActivityLoader $loader */ $loader = $this->getService('activity_loader'); $activities = $loader->load($environment, $input->getOption('limit'), 'environment.backup', $startsAt); @@ -71,6 +67,14 @@ ]; } + if (!$table->formatIsMachineReadable()) { + $this->stdErr->writeln(sprintf( + 'Snapshots on the project %s, environment %s:', + $this->api()->getProjectLabel($this->getSelectedProject()), + $this->api()->getEnvironmentLabel($environment) + )); + } + $table->render($rows, $headers); return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/Snapshot/SnapshotRestoreCommand.php new/platformsh-cli-3.38.0/src/Command/Snapshot/SnapshotRestoreCommand.php --- old/platformsh-cli-3.37.0/src/Command/Snapshot/SnapshotRestoreCommand.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/Snapshot/SnapshotRestoreCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -5,6 +5,7 @@ use Platformsh\Client\Model\Activity; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class SnapshotRestoreCommand extends CommandBase @@ -15,7 +16,9 @@ $this ->setName('snapshot:restore') ->setDescription('Restore an environment snapshot') - ->addArgument('snapshot', InputArgument::OPTIONAL, 'The name of the snapshot. Defaults to the most recent one'); + ->addArgument('snapshot', InputArgument::OPTIONAL, 'The name of the snapshot. Defaults to the most recent one') + ->addOption('target', null, InputOption::VALUE_REQUIRED, "The environment to restore to. Defaults to the snapshot's current environment") + ->addOption('branch-from', null, InputOption::VALUE_REQUIRED, 'If the --target does not yet exist, this specifies the parent of the new environment'); $this->addProjectOption() ->addEnvironmentOption() ->addWaitOptions(); @@ -72,19 +75,36 @@ return 1; } + // Validate the --branch-from option. + $branchFrom = $input->getOption('branch-from'); + if ($branchFrom !== null && !$this->api()->getEnvironment($branchFrom, $this->getSelectedProject())) { + $this->stdErr->writeln(sprintf('Environment not found (in --branch-from): <error>%s</error>', $branchFrom)); + + return 1; + } + + // Process the --target option. + $target = $input->getOption('target'); + $targetEnvironment = $target !== null + ? $this->api()->getEnvironment($target, $this->getSelectedProject()) + : $environment; + $targetLabel = $targetEnvironment + ? $this->api()->getEnvironmentLabel($targetEnvironment) + : '<info>' . $target . '</info>'; + /** @var \Platformsh\Cli\Service\QuestionHelper $questionHelper */ $questionHelper = $this->getService('question_helper'); $name = $selectedActivity['payload']['backup_name']; $date = date('c', strtotime($selectedActivity['created_at'])); if (!$questionHelper->confirm( - "Are you sure you want to restore the snapshot <comment>$name</comment> from <comment>$date</comment>?" + "Are you sure you want to restore the snapshot <comment>$name</comment> from <comment>$date</comment> to environment $targetLabel?" )) { return 1; } - $this->stdErr->writeln("Restoring snapshot <info>$name</info>"); + $this->stdErr->writeln("Restoring snapshot <info>$name</info> to $targetLabel"); - $activity = $selectedActivity->restore(); + $activity = $selectedActivity->restore($target, $branchFrom); if ($this->shouldWait($input)) { $this->stdErr->writeln('Waiting for the restore to complete...'); /** @var \Platformsh\Cli\Service\ActivityMonitor $activityMonitor */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/User/UserAddCommand.php new/platformsh-cli-3.38.0/src/Command/User/UserAddCommand.php --- old/platformsh-cli-3.37.0/src/Command/User/UserAddCommand.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/User/UserAddCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -20,16 +20,29 @@ { $this ->setName('user:add') - ->setAliases(['user:update']) - ->setDescription('Add a user to the project, or set their role(s)') - ->addArgument('email', InputArgument::OPTIONAL, "The user's email address") - ->addOption('role', 'r', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, "The user's project role ('admin' or 'viewer') or environment-specific role (e.g. 'master:contributor' or 'stage:viewer').\nThe character % can be used as a wildcard in the environment ID e.g. '%:viewer'.\nThe role can be abbreviated, e.g. 'master:c'."); + ->setDescription('Add a user to the project') + ->addArgument('email', InputArgument::OPTIONAL, "The user's email address"); + + $this->addRoleOption(); $this->addProjectOption(); $this->addWaitOptions(); + $this->addExample('Add Alice as a project admin', '[email protected] -r admin'); - $this->addExample('Make Bob an admin on the "develop" and "stage" environments', '[email protected] -r develop:a,stage:a'); - $this->addExample('Make Charlie a contributor on all existing environments', '[email protected] -r %:c'); - $this->addExample('Make Damien an admin on "master" and all (existing) environments starting with "pr-"', '[email protected] -r master:a -r pr-%:a'); + } + + /** + * Adds the --role (-r) option to the command. + */ + protected function addRoleOption() + { + $this->addOption( + 'role', + 'r', + InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, + "The user's project role ('admin' or 'viewer') or environment-specific role (e.g. 'master:contributor' or 'stage:viewer')." + . "\nThe character % can be used as a wildcard in the environment ID e.g. '%:viewer'." + . "\nThe role can be abbreviated, e.g. 'master:c'." + ); } protected function execute(InputInterface $input, OutputInterface $output) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/User/UserListCommand.php new/platformsh-cli-3.38.0/src/Command/User/UserListCommand.php --- old/platformsh-cli-3.37.0/src/Command/User/UserListCommand.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/User/UserListCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -44,13 +44,22 @@ ksort($rows); + if (!$table->formatIsMachineReadable()) { + $this->stdErr->writeln(sprintf( + 'Users on the project %s:', + $this->api()->getProjectLabel($project) + )); + } + $table->render(array_values($rows), ['email' => 'Email address', 'Name', 'role' => 'Project role', 'ID']); if (!$table->formatIsMachineReadable()) { $this->stdErr->writeln(''); $executable = $this->config()->get('application.executable'); + $this->stdErr->writeln("To add a new user to the project, run: <info>$executable user:add [email]</info>"); + $this->stdErr->writeln(''); $this->stdErr->writeln("To view a user's role(s), run: <info>$executable user:get [email]</info>"); - $this->stdErr->writeln("To change a user's role(s), run: <info>$executable user:add [email]</info>"); + $this->stdErr->writeln("To change a user's role(s), run: <info>$executable user:update [email]</info>"); } return 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/User/UserUpdateCommand.php new/platformsh-cli-3.38.0/src/Command/User/UserUpdateCommand.php --- old/platformsh-cli-3.37.0/src/Command/User/UserUpdateCommand.php 1970-01-01 01:00:00.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/User/UserUpdateCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -0,0 +1,27 @@ +<?php +namespace Platformsh\Cli\Command\User; + +use Symfony\Component\Console\Input\InputArgument; + +/** + * This command is the same as user:add, with different documentation. + */ +class UserUpdateCommand extends UserAddCommand +{ + + protected function configure() + { + $this + ->setName('user:update') + ->setDescription('Update user role(s) on a project') + ->addArgument('email', InputArgument::OPTIONAL, "The user's email address"); + + $this->addRoleOption(); + $this->addProjectOption(); + $this->addWaitOptions(); + + $this->addExample('Make Bob an admin on the "develop" and "stage" environments', '[email protected] -r develop:a,stage:a'); + $this->addExample('Make Charlie a contributor on all existing environments', '[email protected] -r %:c'); + $this->addExample('Make Damien an admin on "master" and all (existing) environments starting with "pr-"', '[email protected] -r master:a -r pr-%:a'); + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/WebCommand.php new/platformsh-cli-3.38.0/src/Command/WebCommand.php --- old/platformsh-cli-3.37.0/src/Command/WebCommand.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/WebCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -39,9 +39,9 @@ if ($this->hasSelectedProject()) { $url = $this->getSelectedProject()->getLink('#ui'); - if (!empty($environmentId)) { - // New (alpha) UI links lack the /environments path component. - if (strpos($url, 'https://ui.') === 0) { + if ($environmentId !== null) { + // Unified-UI links lack the /environments path component. + if ($this->config()->has('detection.ui_domain') && parse_url($url, PHP_URL_HOST) === $this->config()->get('detection.ui_domain')) { $url .= '/' . rawurlencode($environmentId); } else { $url .= '/environments/' . rawurlencode($environmentId); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Command/Worker/WorkerListCommand.php new/platformsh-cli-3.38.0/src/Command/Worker/WorkerListCommand.php --- old/platformsh-cli-3.37.0/src/Command/Worker/WorkerListCommand.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Command/Worker/WorkerListCommand.php 2019-01-09 15:57:31.000000000 +0100 @@ -49,6 +49,15 @@ /** @var \Platformsh\Cli\Service\Table $table */ $table = $this->getService('table'); + + if (!$table->formatIsMachineReadable()) { + $this->stdErr->writeln(sprintf( + 'Workers on the project <info>%s</info>, environment <info>%s</info>:', + $this->api()->getProjectLabel($this->getSelectedProject()), + $this->api()->getEnvironmentLabel($this->getSelectedEnvironment()) + )); + } + $table->render($rows, ['Name', 'Type', 'Commands']); return 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Local/DependencyInstaller.php new/platformsh-cli-3.38.0/src/Local/DependencyInstaller.php --- old/platformsh-cli-3.37.0/src/Local/DependencyInstaller.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Local/DependencyInstaller.php 2019-01-09 15:57:31.000000000 +0100 @@ -108,6 +108,7 @@ $stacks = [ 'nodejs' => new DependencyManager\Npm($this->shell), 'python' => new DependencyManager\Pip($this->shell), + 'python3' => new DependencyManager\Pip($this->shell), 'ruby' => new DependencyManager\Bundler($this->shell), 'php' => new DependencyManager\Composer($this->shell), ]; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Service/Api.php new/platformsh-cli-3.38.0/src/Service/Api.php --- old/platformsh-cli-3.37.0/src/Service/Api.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Service/Api.php 2019-01-09 15:57:31.000000000 +0100 @@ -623,9 +623,9 @@ public function getProjectLabel(Project $project, $tag = 'info') { $title = $project->title; - $pattern = $title ? '%2$s (%3$s)' : '%3$s'; + $pattern = strlen($title) > 0 ? '%2$s (%3$s)' : '%3$s'; if ($tag !== false) { - $pattern = $title ? '<%1$s>%2$s</%1$s> (%3$s)' : '<%1$s>%3$s</%1$s>'; + $pattern = strlen($title) > 0 ? '<%1$s>%2$s</%1$s> (%3$s)' : '<%1$s>%3$s</%1$s>'; } return sprintf($pattern, $tag, $title, $project->id); @@ -643,7 +643,7 @@ { $id = $environment->id; $title = $environment->title; - $use_title = $title && $title !== $id; + $use_title = strlen($title) > 0 && $title !== $id; $pattern = $use_title ? '%2$s (%3$s)' : '%3$s'; if ($tag !== false) { $pattern = $use_title ? '<%1$s>%2$s</%1$s> (%3$s)' : '<%1$s>%3$s</%1$s>'; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Service/Identifier.php new/platformsh-cli-3.38.0/src/Service/Identifier.php --- old/platformsh-cli-3.37.0/src/Service/Identifier.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Service/Identifier.php 2019-01-09 15:57:31.000000000 +0100 @@ -89,13 +89,8 @@ $site_domains_pattern = '(' . implode('|', array_map('preg_quote', $this->config->get('detection.site_domains'))) . ')'; $site_pattern = '/\-\w+\.[a-z]{2}(\-[0-9])?\.' . $site_domains_pattern . '$/'; - if (strpos($path, '/projects/') !== false || strpos($fragment, '/projects/') !== false) { - $result['host'] = $host; - $result['projectId'] = basename(preg_replace('#/projects(/\w+)/?.*$#', '$1', $url)); - if (preg_match('#/environments(/[^/]+)/?.*$#', $url, $matches)) { - $result['environmentId'] = rawurldecode(basename($matches[1])); - } - } elseif (preg_match($site_pattern, $host)) { + + if (preg_match($site_pattern, $host)) { list($env_project_app,) = explode('.', $host, 2); if (($tripleDashPos = strrpos($env_project_app, '---')) !== false) { $env_project_app = substr($env_project_app, $tripleDashPos + 3); @@ -110,6 +105,29 @@ $result['projectId'] = substr($env_project, $dashPos + 1); $result['environmentId'] = substr($env_project, 0, $dashPos); } + + return $result; + } + + if (strpos($path, '/projects/') !== false || strpos($fragment, '/projects/') !== false) { + $result['host'] = $host; + $result['projectId'] = basename(preg_replace('#/projects(/\w+)/?.*$#', '$1', $url)); + if (preg_match('#/environments(/[^/]+)/?.*$#', $url, $matches)) { + $result['environmentId'] = rawurldecode(basename($matches[1])); + } + + return $result; + } + + if ($this->config->has('detection.ui_domain') + && $host === $this->config->get('detection.ui_domain') + && preg_match('#^/[a-z0-9-]+/([a-z0-9-]+)(/([^/]+))?#', $path, $matches)) { + $result['projectId'] = $matches[1]; + if (isset($matches[3])) { + $result['environmentId'] = rawurldecode($matches[3]); + } + + return $result; } return $result; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Service/QuestionHelper.php new/platformsh-cli-3.38.0/src/Service/QuestionHelper.php --- old/platformsh-cli-3.37.0/src/Service/QuestionHelper.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Service/QuestionHelper.php 2019-01-09 15:57:31.000000000 +0100 @@ -85,12 +85,12 @@ return key($items); } $itemList = array_values($items); - $defaultKey = $default !== null ? array_search($default, $itemList) : null; + $defaultKey = $default !== null ? array_search($default, $itemList, true) : null; $question = new ChoiceQuestion($text, $itemList, $defaultKey); $question->setMaxAttempts(5); $choice = $this->ask($this->input, $this->output, $question); - $choiceKey = array_search($choice, $items); + $choiceKey = array_search($choice, $items, true); if ($choiceKey === false) { throw new \RuntimeException("Invalid value: $choice"); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/src/Service/Table.php new/platformsh-cli-3.38.0/src/Service/Table.php --- old/platformsh-cli-3.37.0/src/Service/Table.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/src/Service/Table.php 2019-01-09 15:57:31.000000000 +0100 @@ -223,7 +223,11 @@ if (!empty($header)) { array_unshift($rows, $header); } - $this->output->write((new Csv($delimiter))->format($rows)); + // RFC 4180 (the closest thing to a CSV standard) asks for CRLF line + // breaks, but these do not play nicely with POSIX shells whose + // default internal field separator (IFS) does not account for CR. So + // the line break character is forced as LF. + $this->output->write((new Csv($delimiter, "\n"))->format($rows)); } /** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/tests/Service/IdentifierTest.php new/platformsh-cli-3.38.0/tests/Service/IdentifierTest.php --- old/platformsh-cli-3.37.0/tests/Service/IdentifierTest.php 1970-01-01 01:00:00.000000000 +0100 +++ new/platformsh-cli-3.38.0/tests/Service/IdentifierTest.php 2019-01-09 15:57:31.000000000 +0100 @@ -0,0 +1,100 @@ +<?php + +namespace Platformsh\Cli\Tests; + +use Platformsh\Cli\Service\Identifier; + +class IdentifierTest extends \PHPUnit_Framework_TestCase +{ + + public function testIdentify() + { + $identifier = new Identifier(); + + $url = 'https://master-4jkbdba6zde2i.eu-2.platformsh.site'; + $expected = [ + 'projectId' => '4jkbdba6zde2i', + 'environmentId' => 'master', + 'host' => null, + 'appId' => null, + ]; + $this->assertEquals($expected, $identifier->identify($url)); + + $url = 'https://master-4jkbdba6zde2i--foo.eu-2.platformsh.site'; + $expected = [ + 'projectId' => '4jkbdba6zde2i', + 'environmentId' => 'master', + 'host' => null, + 'appId' => 'foo', + ]; + $this->assertEquals($expected, $identifier->identify($url)); + + $url = 'https://www---master-4jkbdba6zde2i.eu-2.platformsh.site'; + $expected = [ + 'projectId' => '4jkbdba6zde2i', + 'environmentId' => 'master', + 'host' => null, + 'appId' => null, + ]; + $this->assertEquals($expected, $identifier->identify($url)); + + $url = 'https://eu-2.platform.sh/projects/4jkbdba6zde2i'; + $expected = [ + 'projectId' => '4jkbdba6zde2i', + 'environmentId' => null, + 'host' => 'eu-2.platform.sh', + 'appId' => null, + ]; + $this->assertEquals($expected, $identifier->identify($url)); + + $url = 'https://eu-2.platform.sh/projects/4jkbdba6zde2i/environments/bar'; + $expected = [ + 'projectId' => '4jkbdba6zde2i', + 'environmentId' => 'bar', + 'host' => 'eu-2.platform.sh', + 'appId' => null, + ]; + $this->assertEquals($expected, $identifier->identify($url)); + + $url = 'https://ui.platform.sh/foo/4jkbdba6zde2i'; + $expected = [ + 'projectId' => '4jkbdba6zde2i', + 'environmentId' => null, + 'host' => null, + 'appId' => null, + ]; + $this->assertEquals($expected, $identifier->identify($url)); + + $url = 'https://ui.platform.sh/foo/4jkbdba6zde2i/bar'; + $expected = [ + 'projectId' => '4jkbdba6zde2i', + 'environmentId' => 'bar', + 'host' => null, + 'appId' => null, + ]; + $this->assertEquals($expected, $identifier->identify($url)); + } + + public function testIdentifyWithEnvironmentIdOf0() + { + $identifier = new Identifier(); + + $url = 'https://eu-2.platform.sh/projects/4jkbdba6zde2i/environments/0'; + $expected = [ + 'projectId' => '4jkbdba6zde2i', + 'environmentId' => '0', + 'host' => 'eu-2.platform.sh', + 'appId' => null, + ]; + $this->assertEquals($expected, $identifier->identify($url)); + + $url = 'https://ui.platform.sh/foo/4jkbdba6zde2i/0'; + $expected = [ + 'projectId' => '4jkbdba6zde2i', + 'environmentId' => '0', + 'host' => null, + 'appId' => null, + ]; + $this->assertEquals($expected, $identifier->identify($url)); + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.37.0/tests/Service/TableServiceTest.php new/platformsh-cli-3.38.0/tests/Service/TableServiceTest.php --- old/platformsh-cli-3.37.0/tests/Service/TableServiceTest.php 2018-11-28 10:48:36.000000000 +0100 +++ new/platformsh-cli-3.38.0/tests/Service/TableServiceTest.php 2019-01-09 15:57:31.000000000 +0100 @@ -29,7 +29,7 @@ ['foo', 1, 2, 3], ['bar', 4, 5, 6], ]; - $expected = (new Csv())->format([ + $expected = (new Csv(',', "\n"))->format([ ['Value 2', 'Name'], ['2', 'foo'], ['5', 'bar'], ++++++ 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-11-29 00:56:03.022636751 +0100 +++ new/vendor/autoload.php 2019-01-09 19:05:00.765710176 +0100 @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit5a63cef765f5d3c7c18e50d3aff43b1c::getLoader(); +return ComposerAutoloaderInit434b3fb8d6425b9c0fdd81e20c14d3f7::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-11-29 00:56:03.022636751 +0100 +++ new/vendor/composer/autoload_real.php 2019-01-09 19:05:00.765710176 +0100 @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit5a63cef765f5d3c7c18e50d3aff43b1c +class ComposerAutoloaderInit434b3fb8d6425b9c0fdd81e20c14d3f7 { private static $loader; @@ -19,15 +19,15 @@ return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit5a63cef765f5d3c7c18e50d3aff43b1c', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit434b3fb8d6425b9c0fdd81e20c14d3f7', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit5a63cef765f5d3c7c18e50d3aff43b1c', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit434b3fb8d6425b9c0fdd81e20c14d3f7', '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\ComposerStaticInit5a63cef765f5d3c7c18e50d3aff43b1c::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit434b3fb8d6425b9c0fdd81e20c14d3f7::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\ComposerStaticInit5a63cef765f5d3c7c18e50d3aff43b1c::$files; + $includeFiles = Composer\Autoload\ComposerStaticInit434b3fb8d6425b9c0fdd81e20c14d3f7::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire5a63cef765f5d3c7c18e50d3aff43b1c($fileIdentifier, $file); + composerRequire434b3fb8d6425b9c0fdd81e20c14d3f7($fileIdentifier, $file); } return $loader; } } -function composerRequire5a63cef765f5d3c7c18e50d3aff43b1c($fileIdentifier, $file) +function composerRequire434b3fb8d6425b9c0fdd81e20c14d3f7($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-11-29 00:56:03.022636751 +0100 +++ new/vendor/composer/autoload_static.php 2019-01-09 19:05:00.765710176 +0100 @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit5a63cef765f5d3c7c18e50d3aff43b1c +class ComposerStaticInit434b3fb8d6425b9c0fdd81e20c14d3f7 { public static $files = array ( '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', @@ -201,9 +201,9 @@ public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit5a63cef765f5d3c7c18e50d3aff43b1c::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit5a63cef765f5d3c7c18e50d3aff43b1c::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit5a63cef765f5d3c7c18e50d3aff43b1c::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit434b3fb8d6425b9c0fdd81e20c14d3f7::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit434b3fb8d6425b9c0fdd81e20c14d3f7::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit434b3fb8d6425b9c0fdd81e20c14d3f7::$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-11-29 00:56:02.630633386 +0100 +++ new/vendor/composer/installed.json 2019-01-09 19:05:00.345706414 +0100 @@ -731,17 +731,17 @@ }, { "name": "platformsh/client", - "version": "v0.22.2", - "version_normalized": "0.22.2.0", + "version": "v0.23.0", + "version_normalized": "0.23.0.0", "source": { "type": "git", "url": "https://github.com/platformsh/platformsh-client-php.git", - "reference": "e487f9fbb9f79b404dcfd19e633d13cade7bce6b" + "reference": "9b0fc3004d5abdc3cc54b0bea80f779e23660289" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/e487f9fbb9f79b404dcfd19e633d13cade7bce6b", - "reference": "e487f9fbb9f79b404dcfd19e633d13cade7bce6b", + "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/9b0fc3004d5abdc3cc54b0bea80f779e23660289", + "reference": "9b0fc3004d5abdc3cc54b0bea80f779e23660289", "shasum": "" }, "require": { @@ -754,7 +754,7 @@ "require-dev": { "phpunit/phpunit": "~4.5" }, - "time": "2018-10-24T20:17:25+00:00", + "time": "2019-01-09T14:36:49+00:00", "type": "library", "extra": { "patches": { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/src/Model/Activity.php new/vendor/platformsh/client/src/Model/Activity.php --- old/vendor/platformsh/client/src/Model/Activity.php 2018-10-24 22:17:25.000000000 +0200 +++ new/vendor/platformsh/client/src/Model/Activity.php 2019-01-09 15:36:49.000000000 +0100 @@ -104,9 +104,19 @@ /** * Restore the backup associated with this activity. * + * @param string|null $target The name of the target environment to + * which the backup should be restored (this + * could be the name of an existing + * environment, or a new environment). Leave + * this null to restore to the backup's + * original environment. + * @param string|null $branchFrom If a new environment will be created + * (depending on $target), this specifies + * the name of the parent branch. + * * @return Activity */ - public function restore() + public function restore($target = null, $branchFrom = null) { if ($this->getProperty('type') !== 'environment.backup') { throw new \BadMethodCallException('Cannot restore activity (wrong type)'); @@ -115,7 +125,15 @@ throw new \BadMethodCallException('Cannot restore backup (not complete)'); } - return $this->runLongOperation('restore'); + $options = []; + if ($target !== null) { + $options['environment_name'] = $target; + } + if ($branchFrom !== null) { + $options['branch_from'] = $branchFrom; + } + + return $this->runLongOperation('restore', 'post', $options); } /** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/src/Session/Storage/File.php new/vendor/platformsh/client/src/Session/Storage/File.php --- old/vendor/platformsh/client/src/Session/Storage/File.php 2018-10-24 22:17:25.000000000 +0200 +++ new/vendor/platformsh/client/src/Session/Storage/File.php 2019-01-09 15:36:49.000000000 +0100 @@ -13,16 +13,62 @@ protected $directory; /** - * @param string $directory A directory where session files will be saved - * (default: ~/.platformsh/.session) + * @param string|null $directory + * A writable directory where session files will be saved. Leave null + * to use the default. */ public function __construct($directory = null) { - $this->directory = $directory ?: $this->getHomeDirectory() . '/.platformsh/.session'; + $this->directory = $directory ?: $this->getDefaultDirectory(); } /** - * @throws \Exception + * Get the default directory for session files. + * + * @return string + */ + protected function getDefaultDirectory() + { + // Default to ~/.platformsh/.session, but if it's not writable, fall + // back to the temporary directory. + $default = $this->getHomeDirectory() . '/.platformsh/.session'; + if ($this->canWrite($default)) { + return $default; + } + $temp = sys_get_temp_dir() . '/.platformsh-client/.session'; + if ($this->canWrite($temp)) { + return $temp; + } + + throw new \RuntimeException('Unable to find a writable session storage directory'); + } + + /** + * Tests whether a file path is writable (even if it doesn't exist). + * + * @param string $path + * + * @return bool + */ + protected function canWrite($path) + { + if (is_writable($path)) { + return true; + } + + $current = $path; + while (!file_exists($current) && ($parent = dirname($current)) && $parent !== $current) { + if (is_writable($parent)) { + return true; + } + $current = $parent; + } + + return false; + } + + /** + * Finds the user's home directory. * * @return string */ @@ -33,7 +79,7 @@ $home = $userProfile; } if (!$home || !is_dir($home)) { - throw new \Exception('Could not determine home directory'); + throw new \RuntimeException('Could not determine home directory'); } return $home;
