Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package platformsh-cli for openSUSE:Factory checked in at 2021-06-27 18:59:17 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/platformsh-cli (Old) and /work/SRC/openSUSE:Factory/.platformsh-cli.new.2625 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "platformsh-cli" Sun Jun 27 18:59:17 2021 rev:111 rq:902552 version:3.67.2 Changes: -------- --- /work/SRC/openSUSE:Factory/platformsh-cli/platformsh-cli.changes 2021-03-18 22:54:56.575530989 +0100 +++ /work/SRC/openSUSE:Factory/.platformsh-cli.new.2625/platformsh-cli.changes 2021-06-27 19:00:38.696399259 +0200 @@ -1,0 +2,46 @@ +Sat Jun 26 20:16:36 UTC 2021 - ji...@boombatower.com + +- Update to version 3.67.2: + * Release v3.67.2 + * Fix: user:add command was silently doing nothing during non-interactive use + * Pass --fail to curl utility commands (#1049) + * Release v3.67.1 + * Fix environment type not found when --type not specified in push command + * Release v3.67.0 + * Support build-time environment-level variables (#1051) + * Support new /users/me API in auth:info command + * Release v3.66.4 + * Fall back to old /me API if there is no proxy URL configured + * Fix user:update to avoid recalculating environment access changes while they are made + * Mention the type in the environment label + * Add a --type option to the push command + * Add --type option to the branch command + * Translate validation errors in the env:info command + * Allow the env type to be modified in the env:info command + * Add the type in the environment:list (env) command + * Direct the user to Console in the web command (#1062) + * Release v3.66.3 + * Fix filename of arm64 Keychain credential helper + * Release v3.66.2 + * Update docker-credential-helpers; add Keychain support for Mac M1 (#1060) + * Add a workaround for the default branch title in new projects (#1061) + * Do not require an env when the branch command is used without arguments + * Use the /users/me API if enabled + * Fix edge case bug (#1057) + * Release v3.66.1 + * Bump paragonie/random_compat from 2.0.19 to 2.0.20 (#1050) + * Unhide the subscription:info command (#1052) + * Exclude lost+found directory to avoid permission error in mount:size command (#1056) + * Swap --access order in httpaccess example (fixes #1053) + * SSH diagnostics: avoid recommending ssh-cert:load if it is not enabled + * Set the default_branch to "main" by default for new projects (#1046) + * Add a link to help on the --type option for the activity:list command (#1048) + * Bump phpseclib/phpseclib from 2.0.29 to 2.0.31 in /vendor-bin/box (#1047) + * Document PLATFORMSH_CLI_DEFAULT_TIMEOUT in the README + * Release v3.66.0 + * Bump drush/drush from 8.4.6 to 8.4.8 (#1045) + * Use http scheme for SOLR service tunnel URL (#1034) + * Add --default-branch option to the project:create command (#1042) + * Make the default timeout configurable through an env var + +------------------------------------------------------------------- Old: ---- platformsh-cli-3.65.4.tar.xz New: ---- platformsh-cli-3.67.2.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ platformsh-cli.spec ++++++ --- /var/tmp/diff_new_pack.YgmYph/_old 2021-06-27 19:00:39.416400205 +0200 +++ /var/tmp/diff_new_pack.YgmYph/_new 2021-06-27 19:00:39.420400211 +0200 @@ -17,7 +17,7 @@ Name: platformsh-cli -Version: 3.65.4 +Version: 3.67.2 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.YgmYph/_old 2021-06-27 19:00:39.464400268 +0200 +++ /var/tmp/diff_new_pack.YgmYph/_new 2021-06-27 19:00:39.468400274 +0200 @@ -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.65.4</param> + <param name="revision">refs/tags/v3.67.2</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.YgmYph/_old 2021-06-27 19:00:39.496400311 +0200 +++ /var/tmp/diff_new_pack.YgmYph/_new 2021-06-27 19:00:39.496400311 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">git://github.com/platformsh/platformsh-cli.git</param> - <param name="changesrevision">32237d959e71aaffe552bff29680b02558779779</param> + <param name="changesrevision">7fbaa00f32d22cad94b544bbe818abde14d46680</param> </service> </servicedata> ++++++ licenses.txt ++++++ --- /var/tmp/diff_new_pack.YgmYph/_old 2021-06-27 19:00:39.536400363 +0200 +++ /var/tmp/diff_new_pack.YgmYph/_new 2021-06-27 19:00:39.536400363 +0200 @@ -14,10 +14,10 @@ guzzlehttp/streams 3.0.0 MIT padraic/humbug_get_contents 1.1.2 BSD-3-Clause padraic/phar-updater v1.0.6 BSD-3-Clause -paragonie/random_compat v2.0.19 MIT +paragonie/random_compat v2.0.20 MIT pjcdawkins/guzzle-oauth2-plugin v2.3.1 MIT -platformsh/client 0.42.0 MIT -platformsh/console-form v0.0.24 MIT +platformsh/client 0.45.0 MIT +platformsh/console-form v0.0.25 MIT psr/container 1.0.0 MIT psr/log 1.1.3 MIT react/promise v2.8.0 MIT ++++++ platformsh-cli-3.65.4.tar.xz -> platformsh-cli-3.67.2.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/README.md new/platformsh-cli-3.67.2/README.md --- old/platformsh-cli-3.65.4/README.md 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/README.md 2021-06-18 13:15:31.000000000 +0200 @@ -91,6 +91,7 @@ multi Execute a command on multiple projects web Open the Web UI activity + activity:cancel Cancel an activity activity:get View detailed information on a single activity activity:list (activities, act) Get a list of activities for an environment or project activity:log Display the log for an activity @@ -128,7 +129,7 @@ environment:activate Activate an environment environment:branch (branch) Branch an environment environment:checkout (checkout) Check out an environment - environment:delete Delete an environment + environment:delete (environment:deactivate) Delete an environment environment:drush (drush) Run a drush command on the remote environment environment:http-access (httpaccess) Update HTTP access settings for an environment environment:info Read or set properties for an environment @@ -139,6 +140,7 @@ environment:push (push) Push code to an environment environment:redeploy (redeploy) Redeploy an environment environment:relationships (relationships) Show an environment's relationships + environment:scp (scp) Copy files to and from current environment using scp environment:ssh (ssh) SSH to the current environment environment:synchronize (sync) Synchronize an environment's code and/or data from its parent environment:url (url) Get the public URLs of an environment @@ -191,6 +193,8 @@ ssh-key:add Add a new SSH key ssh-key:delete Delete an SSH key ssh-key:list (ssh-keys) Get a list of SSH keys in your account +subscription + subscription:info Read or modify subscription properties tunnel tunnel:close Close SSH tunnels tunnel:info View relationship info for SSH tunnels @@ -260,6 +264,7 @@ Other customization is available via environment variables: * `PLATFORMSH_CLI_DEBUG`: set to 1 to enable cURL debugging. _Warning_: this will print all request information in the terminal, including sensitive access tokens. +* `PLATFORMSH_CLI_DEFAULT_TIMEOUT`: the timeout (in seconds) for most individual API requests. The default is 30. * `PLATFORMSH_CLI_DISABLE_CACHE`: set to 1 to disable caching * `PLATFORMSH_CLI_HOME`: override the home directory (inside which the .platformsh directory is stored) * `PLATFORMSH_CLI_NO_COLOR`: set to 1 to disable colors in output diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/composer.json new/platformsh-cli-3.67.2/composer.json --- old/platformsh-cli-3.65.4/composer.json 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/composer.json 2021-06-18 13:15:31.000000000 +0200 @@ -7,8 +7,8 @@ "doctrine/cache": "~1.5", "guzzlehttp/guzzle": "^5.3", "guzzlehttp/ringphp": "^1.1", - "platformsh/console-form": ">=0.0.24 <2.0", - "platformsh/client": ">=0.42.0 <2.0", + "platformsh/console-form": ">=0.0.25 <2.0", + "platformsh/client": ">=0.45.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.65.4/composer.lock new/platformsh-cli-3.67.2/composer.lock --- old/platformsh-cli-3.65.4/composer.lock 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/composer.lock 2021-06-18 13:15:31.000000000 +0200 @@ -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": "67fc026a6a17fa007f3fc47b5b3a907a", + "content-hash": "c7a4dbff5ce2fa320fc3aa4ba5cafb63", "packages": [ { "name": "cocur/slugify", @@ -628,16 +628,16 @@ }, { "name": "paragonie/random_compat", - "version": "v2.0.19", + "version": "v2.0.20", "source": { "type": "git", "url": "https://github.com/paragonie/random_compat.git", - "reference": "446fc9faa5c2a9ddf65eb7121c0af7e857295241" + "reference": "0f1f60250fccffeaf5dda91eea1c018aed1adc2a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/446fc9faa5c2a9ddf65eb7121c0af7e857295241", - "reference": "446fc9faa5c2a9ddf65eb7121c0af7e857295241", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/0f1f60250fccffeaf5dda91eea1c018aed1adc2a", + "reference": "0f1f60250fccffeaf5dda91eea1c018aed1adc2a", "shasum": "" }, "require": { @@ -678,7 +678,7 @@ "issues": "https://github.com/paragonie/random_compat/issues", "source": "https://github.com/paragonie/random_compat" }, - "time": "2020-10-15T10:06:57+00:00" + "time": "2021-04-17T09:33:01+00:00" }, { "name": "pjcdawkins/guzzle-oauth2-plugin", @@ -730,16 +730,16 @@ }, { "name": "platformsh/client", - "version": "0.42.0", + "version": "0.45.0", "source": { "type": "git", "url": "https://github.com/platformsh/platformsh-client-php.git", - "reference": "d87cc67684a56fa1c03e520669b03d25539d631c" + "reference": "4dcff942a5b0c0f39d524b5f2af56a0c4333e6fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/d87cc67684a56fa1c03e520669b03d25539d631c", - "reference": "d87cc67684a56fa1c03e520669b03d25539d631c", + "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/4dcff942a5b0c0f39d524b5f2af56a0c4333e6fe", + "reference": "4dcff942a5b0c0f39d524b5f2af56a0c4333e6fe", "shasum": "" }, "require": { @@ -771,22 +771,22 @@ "description": "Platform.sh API client", "support": { "issues": "https://github.com/platformsh/platformsh-client-php/issues", - "source": "https://github.com/platformsh/platformsh-client-php/tree/0.42.0" + "source": "https://github.com/platformsh/platformsh-client-php/tree/0.45.0" }, - "time": "2021-02-26T21:49:53+00:00" + "time": "2021-06-14T08:13:20+00:00" }, { "name": "platformsh/console-form", - "version": "v0.0.24", + "version": "v0.0.25", "source": { "type": "git", "url": "https://github.com/platformsh/console-form.git", - "reference": "4dc5f0990399633b6a39ca13752080ea4f62f716" + "reference": "9b1a93e5e27aa1c1614ac14102a55162f69732ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/platformsh/console-form/zipball/4dc5f0990399633b6a39ca13752080ea4f62f716", - "reference": "4dc5f0990399633b6a39ca13752080ea4f62f716", + "url": "https://api.github.com/repos/platformsh/console-form/zipball/9b1a93e5e27aa1c1614ac14102a55162f69732ae", + "reference": "9b1a93e5e27aa1c1614ac14102a55162f69732ae", "shasum": "" }, "require": { @@ -814,9 +814,9 @@ "description": "A lightweight Symfony Console form system.", "support": { "issues": "https://github.com/platformsh/console-form/issues", - "source": "https://github.com/platformsh/console-form/tree/v0.0.24" + "source": "https://github.com/platformsh/console-form/tree/v0.0.25" }, - "time": "2019-07-12T11:29:37+00:00" + "time": "2021-06-16T16:02:08+00:00" }, { "name": "psr/container", @@ -2258,16 +2258,16 @@ }, { "name": "drush/drush", - "version": "8.4.6", + "version": "8.4.8", "source": { "type": "git", "url": "https://github.com/drush-ops/drush.git", - "reference": "4e48e11d7fe858eebe6c2fad71650c977d3f8900" + "reference": "b377b1896e344085d06bdbf671a465950a164d1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drush-ops/drush/zipball/4e48e11d7fe858eebe6c2fad71650c977d3f8900", - "reference": "4e48e11d7fe858eebe6c2fad71650c977d3f8900", + "url": "https://api.github.com/repos/drush-ops/drush/zipball/b377b1896e344085d06bdbf671a465950a164d1e", + "reference": "b377b1896e344085d06bdbf671a465950a164d1e", "shasum": "" }, "require": { @@ -2372,7 +2372,7 @@ "forum": "http://drupal.stackexchange.com/questions/tagged/drush", "irc": "irc://irc.freenode.org/drush", "issues": "https://github.com/drush-ops/drush/issues", - "source": "https://github.com/drush-ops/drush/tree/8.4.6" + "source": "https://github.com/drush-ops/drush/tree/8.4.8" }, "funding": [ { @@ -2380,7 +2380,7 @@ "type": "github" } ], - "time": "2021-02-01T15:34:47+00:00" + "time": "2021-03-22T15:27:55+00:00" }, { "name": "nikic/php-parser", @@ -3132,16 +3132,16 @@ }, { "name": "psy/psysh", - "version": "v0.10.6", + "version": "v0.10.7", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "6f990c19f91729de8b31e639d6e204ea59f19cf3" + "reference": "a395af46999a12006213c0c8346c9445eb31640c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/6f990c19f91729de8b31e639d6e204ea59f19cf3", - "reference": "6f990c19f91729de8b31e639d6e204ea59f19cf3", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/a395af46999a12006213c0c8346c9445eb31640c", + "reference": "a395af46999a12006213c0c8346c9445eb31640c", "shasum": "" }, "require": { @@ -3202,9 +3202,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.10.6" + "source": "https://github.com/bobthecow/psysh/tree/v0.10.7" }, - "time": "2021-01-18T15:53:43+00:00" + "time": "2021-03-14T02:14:56+00:00" }, { "name": "sebastian/comparator", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/config.yaml new/platformsh-cli-3.67.2/config.yaml --- old/platformsh-cli-3.65.4/config.yaml 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/config.yaml 2021-06-18 13:15:31.000000000 +0200 @@ -92,6 +92,7 @@ console_url: 'https://console.platform.sh' pricing_url: 'https://platform.sh/pricing' api_token_help_url: 'https://docs.platform.sh/gettingstarted/cli/api-tokens.html' + activity_type_list_url: 'https://docs.platform.sh/integrations/activity/reference.html#type' available_regions: - eu-2.platform.sh - us-3.platform.sh @@ -111,6 +112,7 @@ users_ttl: 600 # The default timeout for API requests, in seconds. + # Overridden by {application.env_prefix}DEFAULT_TIMEOUT env var. default_timeout: 30 # Disable the docker-credential-helpers credential storage. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/dist/manifest.json new/platformsh-cli-3.67.2/dist/manifest.json --- old/platformsh-cli-3.65.4/dist/manifest.json 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/dist/manifest.json 2021-06-18 13:15:31.000000000 +0200 @@ -17,10 +17,10 @@ }, { "name": "platform.phar", - "sha1": "b651add00ccb2125209413ef7d7f8881a0ad53ff", - "sha256": "1676a299a726f38f01e277398de8270aa8a060628a9ec8a52e7d4e9cd691aa8c", - "url": "https://github.com/platformsh/platformsh-cli/releases/download/v3.65.4/platform.phar", - "version": "3.65.4", + "sha1": "4a8b85e3f45fffd15791e233dc57e9ab23c08f74", + "sha256": "cd282ba2ab969c04eaed034b2ec771ab518a38d006947984a72660d130ccfe83", + "url": "https://github.com/platformsh/platformsh-cli/releases/download/v3.67.2/platform.phar", + "version": "3.67.2", "php": { "min": "5.5.9" }, @@ -314,6 +314,16 @@ "notes": "New features:\n\n* Add --format=plain option for table commands. This produces TSV-like output, \n but with no quoting or escaping, to make most output easier to process with \n basic command-line tools such as cut and grep. Literal tabs and newlines are \n replaced by a space.\n\nOther changes:\n\n* Rename the backup --unsafe option to --live\n (This tones down the warning level on making such a backup)\n* Remove the restriction on deleting the main environment\n* Remove us-2 from available region examples", "show from": "3.64.0", "hide from": "3.65.0" + }, + { + "notes": "* Use the 'http://' scheme instead of 'solr://' for Solr service URLs.\n* Add a --default-branch option to the project:create command.\n* Make the default API request timeout configurable through an env var.\n PLATFORMSH_CLI_DEFAULT_TIMEOUT will override the default of 30 (seconds).", + "show from": "3.65.0", + "hide from": "3.66.0" + }, + { + "notes": "New features (which depend on the upcoming API version 12):\n\n* Support build-time environment-level variables.\n* Some support for environment types (see note below):\n - Add the type in the `environment:list` (`env`) command.\n - Mention the type in the environment label.\n - Add a `--type` option to the `push` command.\n - Add a `--type` option to the `branch` command.\n - Allow the type to be modified in the `env:info` command.\n\n> Note: user commands (such as `user:add` and `user:update`) do not yet support\nenvironment types. They will in a future version. The API is backwards\ncompatible: if your project supports environment types, and you change a user's\nrole on an environment, it will change their role on all environments of that\ntype.\n\nOther changes:\n\n* Support new `/users/me` API in the `auth:info` command.\n* Fix `user:update` to avoid recalculating environment access changes while they are made.", + "show from": "3.66.0", + "hide from": "3.67.0" } ] } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/Activity/ActivityListCommand.php new/platformsh-cli-3.67.2/src/Command/Activity/ActivityListCommand.php --- old/platformsh-cli-3.65.4/src/Command/Activity/ActivityListCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/Activity/ActivityListCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -19,9 +19,16 @@ { $this ->setName('activity:list') - ->setAliases(['activities', 'act']) - ->addOption('type', null, InputOption::VALUE_REQUIRED, 'Filter activities by type') - ->addOption('limit', null, InputOption::VALUE_REQUIRED, 'Limit the number of results displayed', 10) + ->setAliases(['activities', 'act']); + + // Add the --type option, with a link to help if configured. + $typeDescription = 'Filter activities by type'; + if ($this->config()->has('service.activity_type_list_url')) { + $typeDescription .= "\nFor a list of types see: " . $this->config()->get('service.activity_type_list_url'); + } + $this->addOption('type', null, InputOption::VALUE_REQUIRED, $typeDescription); + + $this->addOption('limit', null, InputOption::VALUE_REQUIRED, 'Limit the number of results displayed', 10) ->addOption('start', null, InputOption::VALUE_REQUIRED, 'Only activities created before this date will be listed') ->addOption('state', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Filter activities by state: in_progress, pending, complete, or cancelled') ->addOption('result', null, InputOption::VALUE_REQUIRED, 'Filter activities by result: success or failure') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/Auth/AuthInfoCommand.php new/platformsh-cli-3.67.2/src/Command/Auth/AuthInfoCommand.php --- old/platformsh-cli-3.65.4/src/Command/Auth/AuthInfoCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/Auth/AuthInfoCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -24,10 +24,32 @@ protected function execute(InputInterface $input, OutputInterface $output) { - $info = $this->api()->getMyAccount((bool) $input->getOption('refresh')); /** @var \Platformsh\Cli\Service\PropertyFormatter $formatter */ $formatter = $this->getService('property_formatter'); - $propertiesToDisplay = ['id', 'uuid', 'display_name', 'username', 'mail', 'has_key']; + + if ($this->api()->authApiEnabled()) { + $info = $this->api()->getUser()->getProperties(); + } else { + // Backwards compatibility. + $account = $this->api()->getMyAccount((bool) $input->getOption('refresh')); + $info = [ + 'id' => $account['id'], + 'first_name' => '', + 'last_name' => '', + 'email' => $account['mail'], + 'username' => $account['username'], + ]; + if (isset($account['display_name'])) { + $parts = \explode(' ', $account['display_name'], 2); + if (count($parts) === 2) { + list($info['first_name'], $info['last_name']) = $parts; + } else { + $info['last_name'] = $account['display_name']; + } + } + } + + $propertiesToDisplay = ['id', 'first_name', 'last_name', 'username', 'email', 'mfa_enabled']; $info = array_intersect_key($info, array_flip($propertiesToDisplay)); $property = $input->getArgument('property'); @@ -46,14 +68,25 @@ if ($property) { if (!isset($info[$property])) { - throw new InvalidArgumentException('Property not found: ' . $property); + // Backwards compatibility. + if ($property === 'display_name' && isset($info['first_name'], $info['last_name'])) { + $this->stdErr->writeln('<options=reverse>Deprecated:</> the "display_name" property has been replaced by "first_name" and "last_name".'); + $info[$property] = \sprintf('%s %s', $info['first_name'], $info['last_name']); + } elseif ($property === 'mail' && isset($info['email'])) { + $this->stdErr->writeln('<options=reverse>Deprecated:</> the "mail" property is now named "email".'); + $info[$property] = $info['email']; + } elseif ($property === 'uuid' && isset($info['id'])) { + $this->stdErr->writeln('<options=reverse>Deprecated:</> the "uuid" property is now named "id".'); + $info[$property] = $info['id']; + } else { + throw new InvalidArgumentException('Property not found: ' . $property); + } } $output->writeln($formatter->format($info[$property], $property)); return 0; } - unset($info['uuid']); $values = []; $header = []; foreach ($propertiesToDisplay as $property) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/Auth/BrowserLoginCommand.php new/platformsh-cli-3.67.2/src/Command/Auth/BrowserLoginCommand.php --- old/platformsh-cli-3.65.4/src/Command/Auth/BrowserLoginCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/Auth/BrowserLoginCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -69,12 +69,22 @@ $api = $this->api(); try { $api->inLoginCheck = true; - $account = $api->getMyAccount(true); - $this->stdErr->writeln(sprintf('You are already logged in as <info>%s</info> (%s).', - $account['username'], - $account['mail'] - )); + if ($api->authApiEnabled()) { + $user = $api->getUser(null, true); + $this->stdErr->writeln(\sprintf( + 'You are already logged in as <info>%s</info> (<info>%s</info>)', + $user->username, + $user->email + )); + } else { + $accountInfo = $api->getMyAccount(true); + $this->stdErr->writeln(\sprintf( + 'You are already logged in as <info>%s</info> (<info>%s</info>).', + $accountInfo['username'], + $accountInfo['mail'] + )); + } if ($input->isInteractive()) { /** @var \Platformsh\Cli\Service\QuestionHelper $questionHelper */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/Backup/BackupCreateCommand.php new/platformsh-cli-3.67.2/src/Command/Backup/BackupCreateCommand.php --- old/platformsh-cli-3.65.4/src/Command/Backup/BackupCreateCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/Backup/BackupCreateCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -50,7 +50,7 @@ $this->stdErr->writeln('The environment is not active.'); } else { try { - $access = $selectedEnvironment->getUser($this->api()->getMyAccount()['id']); + $access = $selectedEnvironment->getUser($this->api()->getMyUserId()); if ($access->role !== 'admin') { $this->stdErr->writeln('You must be an administrator to create a backup.'); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/CommandBase.php new/platformsh-cli-3.67.2/src/Command/CommandBase.php --- old/platformsh-cli-3.65.4/src/Command/CommandBase.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/CommandBase.php 2021-06-18 13:15:31.000000000 +0200 @@ -1733,12 +1733,21 @@ if ($newline) { $this->stdErr->writeln(''); } - $accountInfo = $api->getMyAccount(); - $this->stdErr->writeln(sprintf( - 'You are logged in as <info>%s</info> (<info>%s</info>)', - $accountInfo['username'], - $accountInfo['mail'] - )); + if ($api->authApiEnabled()) { + $user = $api->getUser(); + $this->stdErr->writeln(\sprintf( + 'You are logged in as <info>%s</info> (<info>%s</info>)', + $user->username, + $user->email + )); + } else { + $accountInfo = $api->getMyAccount(); + $this->stdErr->writeln(\sprintf( + 'You are logged in as <info>%s</info> (<info>%s</info>)', + $accountInfo['username'], + $accountInfo['mail'] + )); + } } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/Db/DbSizeCommand.php new/platformsh-cli-3.67.2/src/Command/Db/DbSizeCommand.php --- old/platformsh-cli-3.65.4/src/Command/Db/DbSizeCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/Db/DbSizeCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -321,7 +321,7 @@ */ private function mysqlTablesInNeedOfOptimizing() { /*, data_free, data_length, ((data_free+1)/(data_length+1))*100 as wasted_space_percentage*/ - return 'SELECT TABLE_SCHEMA, TABLE_NAME FROM information_schema.tables WHERE ENGINE = "InnoDB" AND ((data_free+1)/(data_length+1))*100 >= '.self::WASTED_SPACE_WARNING_THRESHOLD.' ORDER BY data_free DESC LIMIT 10'; + return 'SELECT TABLE_SCHEMA, TABLE_NAME FROM information_schema.tables WHERE ENGINE = "InnoDB" AND TABLE_TYPE="BASE TABLE" AND ((data_free+1)/(data_length+1))*100 >= '.self::WASTED_SPACE_WARNING_THRESHOLD.' ORDER BY data_free DESC LIMIT 10'; } /** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/Environment/EnvironmentBranchCommand.php new/platformsh-cli-3.67.2/src/Command/Environment/EnvironmentBranchCommand.php --- old/platformsh-cli-3.65.4/src/Command/Environment/EnvironmentBranchCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/Environment/EnvironmentBranchCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -20,6 +20,7 @@ ->addArgument('id', InputArgument::OPTIONAL, 'The ID (branch name) of the new environment') ->addArgument('parent', InputArgument::OPTIONAL, 'The parent of the new environment') ->addOption('title', null, InputOption::VALUE_REQUIRED, 'The title of the new environment') + ->addOption('type', null, InputOption::VALUE_REQUIRED, 'The type of the new environment') ->addOption( 'force', null, @@ -42,11 +43,10 @@ protected function execute(InputInterface $input, OutputInterface $output) { $this->envArgName = 'parent'; - $this->validateInput($input); + $branchName = $input->getArgument('id'); + $this->validateInput($input, $branchName === null); $selectedProject = $this->getSelectedProject(); - $parentEnvironment = $this->getSelectedEnvironment(); - $branchName = $input->getArgument('id'); if ($branchName === null) { if ($input->isInteractive()) { // List environments. @@ -60,6 +60,8 @@ return 1; } + $parentEnvironment = $this->getSelectedEnvironment(); + if ($branchName === $parentEnvironment->id) { $this->stdErr->writeln('Already on <comment>' . $branchName . '</comment>'); @@ -119,15 +121,27 @@ $title = $input->getOption('title') !== null ? $input->getOption('title') : $branchName; + $newLabel = strlen($title) > 0 && $title !== $branchName + ? '<info>' . $title . '</info> (' . $branchName . ')' + : '<info>' . $branchName . '</info>'; + + $type = $input->getOption('type'); + if ($type !== null) { + $newLabel .= ' (type: <info>' . $type . '</info>)'; + } + $this->stdErr->writeln(sprintf( 'Creating a new environment %s, branched from %s', - strlen($title) > 0 && $title !== $branchName - ? '<info>' . $title . '</info> (' . $branchName . ')' - : '<info>' . $branchName . '</info>', + $newLabel, $this->api()->getEnvironmentLabel($parentEnvironment) )); - $activity = $parentEnvironment->branch($title, $branchName, !$input->getOption('no-clone-parent')); + $activity = $parentEnvironment->branch( + $title, + $branchName, + !$input->getOption('no-clone-parent'), + $type + ); // Clear the environments cache, as branching has started. $this->api()->clearEnvironmentsCache($selectedProject->id); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/Environment/EnvironmentHttpAccessCommand.php new/platformsh-cli-3.67.2/src/Command/Environment/EnvironmentHttpAccessCommand.php --- old/platformsh-cli-3.65.4/src/Command/Environment/EnvironmentHttpAccessCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/Environment/EnvironmentHttpAccessCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -39,7 +39,7 @@ ->addEnvironmentOption() ->addWaitOptions(); $this->addExample('Require a username and password', '--auth myname:mypassword'); - $this->addExample('Restrict access to only one IP address', '--access deny:any --access allow:69.208.1.192'); + $this->addExample('Restrict access to only one IP address', '--access allow:69.208.1.192 --access deny:any'); $this->addExample('Remove the password requirement, keeping IP restrictions', '--auth 0'); $this->addExample('Disable all HTTP access control', '--enabled 0'); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/Environment/EnvironmentInfoCommand.php new/platformsh-cli-3.67.2/src/Command/Environment/EnvironmentInfoCommand.php --- old/platformsh-cli-3.65.4/src/Command/Environment/EnvironmentInfoCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/Environment/EnvironmentInfoCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -1,6 +1,7 @@ <?php namespace Platformsh\Cli\Command\Environment; +use GuzzleHttp\Exception\BadResponseException; use Platformsh\Cli\Command\CommandBase; use Platformsh\Cli\Console\AdaptiveTableCell; use Platformsh\Cli\Service\Table; @@ -133,7 +134,19 @@ return 0; } - $result = $environment->update([$property => $value]); + try { + $result = $environment->update([$property => $value]); + } catch (BadResponseException $e) { + // Translate validation error messages. + if (($response = $e->getResponse()) && $response->getStatusCode() === 400 && ($body = $response->getBody())) { + $detail = \json_decode((string) $body, true); + if (\is_array($detail) && !empty($detail['detail'][$property])) { + $this->stdErr->writeln("Invalid value for <error>$property</error>: " . $detail['detail'][$property]); + return 1; + } + } + throw $e; + } $this->stdErr->writeln(sprintf( 'Property <info>%s</info> set to: %s', $property, @@ -169,6 +182,7 @@ 'parent' => 'string', 'title' => 'string', 'restrict_robots' => 'boolean', + 'type' => 'string', ]; return isset($writableProperties[$property]) ? $writableProperties[$property] : false; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/Environment/EnvironmentListCommand.php new/platformsh-cli-3.67.2/src/Command/Environment/EnvironmentListCommand.php --- old/platformsh-cli-3.65.4/src/Command/Environment/EnvironmentListCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/Environment/EnvironmentListCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -6,11 +6,13 @@ use Platformsh\Cli\Console\ProgressMessage; use Platformsh\Cli\Service\Table; use Platformsh\Client\Model\Environment; +use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface; +use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -class EnvironmentListCommand extends CommandBase +class EnvironmentListCommand extends CommandBase implements CompletionAwareInterface { protected $children = []; @@ -35,7 +37,8 @@ ->addOption('pipe', null, InputOption::VALUE_NONE, 'Output a simple list of environment IDs.') ->addOption('refresh', null, InputOption::VALUE_REQUIRED, 'Whether to refresh the list.', 1) ->addOption('sort', null, InputOption::VALUE_REQUIRED, 'A property to sort by', 'title') - ->addOption('reverse', null, InputOption::VALUE_NONE, 'Sort in reverse (descending) order'); + ->addOption('reverse', null, InputOption::VALUE_NONE, 'Sort in reverse (descending) order') + ->addOption('type', null, InputOption::VALUE_REQUIRED|InputOption::VALUE_IS_ARRAY, 'Filter the list by environment type(s)'); Table::configureInput($this->getDefinition()); $this->addProjectOption(); } @@ -112,6 +115,7 @@ } $row[] = $this->formatEnvironmentStatus($environment->status); + $row[] = $environment->getProperty('type', false) ?: ''; $row[] = $this->formatter->format($environment->created_at, 'created_at'); $row[] = $this->formatter->format($environment->updated_at, 'updated_at'); @@ -143,13 +147,36 @@ $progress = new ProgressMessage($output); $progress->showIfOutputDecorated('Loading environments...'); - $environments = $this->api()->getEnvironments($this->getSelectedProject(), $refresh ? true : null); + $project = $this->getSelectedProject(); + $environments = $this->api()->getEnvironments($project, $refresh ? true : null); + + $progress->done(); + + // Determine whether environment types are supported. + $supportsTypes = $project->operationAvailable('environment-types'); + if (!$supportsTypes) { + $first = reset($environments); + if ($first && $first->hasProperty('type')) { + $supportsTypes = true; + } + } + // Filter the list of environments. + $filters = []; if ($input->getOption('no-inactive')) { - $environments = array_filter($environments, function ($environment) { - return $environment->status !== 'inactive'; - }); + $filters['no-inactive'] = true; + } + if ($types = $input->getOption('type')) { + if (!$supportsTypes) { + $this->stdErr->writeln('<options=reverse>Warning:</> environment types are not yet supported on this project.'); + } + if (count($types) === 1) { + // Split comma- or whitespace-separated values. + $types = preg_split('/[\s,]+/', reset($types)); + } + $filters['type'] = $types; } + $this->filterEnvironments($environments, $filters); if ($input->getOption('sort')) { $this->api()->sortResources($environments, $input->getOption('sort')); @@ -158,12 +185,26 @@ $environments = array_reverse($environments, true); } - $progress->done(); - if ($input->getOption('pipe')) { $output->writeln(array_keys($environments)); - return; + return 0; + } + + // Display a message if no environments are found. + if (empty($environments)) { + if (!empty($filters)) { + $filtersUsed = '<comment>--' + . implode('</comment>, <comment>--', array_keys($filters)) + . '</comment>'; + $this->stdErr->writeln('No environments found (filters in use: ' . $filtersUsed . ').'); + } else { + $this->stdErr->writeln( + 'No environments found.' + ); + } + + return 0; } $project = $this->getSelectedProject(); @@ -180,9 +221,13 @@ $tree = $this->buildEnvironmentTree($environments); - $headers = ['ID', 'machine_name' => 'Machine name', 'Title', 'Status', 'Created', 'Updated']; + $headers = ['ID', 'machine_name' => 'Machine name', 'Title', 'Status', 'Type', 'Created', 'Updated']; $defaultColumns = ['id', 'title', 'status']; + if ($supportsTypes) { + $defaultColumns[] = 'type'; + } + /** @var \Platformsh\Cli\Service\Table $table */ $table = $this->getService('table'); @@ -191,8 +236,7 @@ if ($table->formatIsMachineReadable()) { $table->render($this->buildEnvironmentRows($tree, false, false), $headers, $defaultColumns); - - return; + return 0; } $this->stdErr->writeln("Your environments are: "); @@ -200,7 +244,7 @@ $table->render($this->buildEnvironmentRows($tree), $headers, $defaultColumns); if (!$this->currentEnvironment) { - return; + return 0; } $this->stdErr->writeln("<info>*</info> - Indicates the current environment\n"); @@ -242,6 +286,8 @@ 'Sync the current environment by running <info>' . $executable . ' environment:synchronize</info>' ); } + + return 0; } /** @@ -257,4 +303,47 @@ return ucfirst($status); } + + /** + * Filter the list of environments. + * + * @param Environment[] &$environments + * @param mixed[string] $filters + */ + protected function filterEnvironments(array &$environments, array $filters) + { + if (!empty($filters['no-inactive'])) { + $environments = array_filter($environments, function ($environment) { + return $environment->status !== 'inactive'; + }); + } + if (!empty($filters['type'])) { + $environments = array_filter($environments, function ($environment) use ($filters) { + return !$environment->hasProperty('type') || \in_array($environment->getProperty('type'), $filters['type']); + }); + } + } + + /** + * {@inheritDoc} + */ + public function completeOptionValues($optionName, CompletionContext $context) + { + if ($optionName === 'type') { + // @todo fetch types from the project if known? not necessary until custom types are available + return ['development', 'staging', 'production']; + } + if ($optionName === 'sort') { + return ['id', 'title', 'status', 'name', 'machine_name', 'parent', 'created_at', 'updated_at']; + } + return []; + } + + /** + * {@inheritDoc} + */ + public function completeArgumentValues($argumentName, CompletionContext $context) + { + return []; + } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/Environment/EnvironmentPushCommand.php new/platformsh-cli-3.67.2/src/Command/Environment/EnvironmentPushCommand.php --- old/platformsh-cli-3.65.4/src/Command/Environment/EnvironmentPushCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/Environment/EnvironmentPushCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -1,6 +1,7 @@ <?php namespace Platformsh\Cli\Command\Environment; +use GuzzleHttp\Exception\BadResponseException; use Platformsh\Cli\Command\CommandBase; use Platformsh\Cli\Exception\ProcessFailedException; use Platformsh\Cli\Exception\RootNotFoundException; @@ -29,7 +30,8 @@ ->addOption('set-upstream', 'u', InputOption::VALUE_NONE, 'Set the target environment as the upstream for the source branch') ->addOption('activate', null, InputOption::VALUE_NONE, 'Activate the environment before pushing') ->addOption('branch', null, InputOption::VALUE_NONE, 'DEPRECATED: alias of --activate') - ->addOption('parent', null, InputOption::VALUE_REQUIRED, 'Set a new environment parent (only used with --activate or --branch)'); + ->addOption('parent', null, InputOption::VALUE_REQUIRED, 'Set the new environment parent (only used with --activate or --branch)') + ->addOption('type', null, InputOption::VALUE_REQUIRED, 'Set the environment type (only used with --activate or --branch)'); $this->addWaitOptions(); $this->addProjectOption() ->addEnvironmentOption(); @@ -123,10 +125,19 @@ // If activating, determine what the environment's parent should be. $parentId = $input->getOption('parent') ?: $this->findTargetParent($project, $targetEnvironment ?: null); + // Determine the environment type. + $type = $input->getOption('type'); + if ($type !== null && !$project->getEnvironmentType($type)) { + $this->stdErr->writeln('Environment type not found: <error>' . $type . '</error>'); + return 1; + } elseif ($type === null && $input->isInteractive()) { + $type = $this->askEnvironmentType($project); + } + // Activate the target environment. The deployment activity // will queue up behind whatever other activities are created // here. - $activities = $this->activateTarget($target, $parentId, $project); + $activities = $this->activateTarget($target, $parentId, $project, $type); if ($activities === false) { return 1; } @@ -207,10 +218,11 @@ * @param string $target * @param string $parentId * @param Project $project + * @param string|null $type * * @return false|array A list of activities, or false on failure. */ - private function activateTarget($target, $parentId, Project $project) { + private function activateTarget($target, $parentId, Project $project, $type) { $parentEnvironment = $this->api()->getEnvironment($parentId, $project); if (!$parentEnvironment) { throw new \RuntimeException("Parent environment not found: $parentId"); @@ -219,10 +231,17 @@ $targetEnvironment = $this->api()->getEnvironment($target, $project); if ($targetEnvironment) { $activities = []; + $updates = []; if ($targetEnvironment->parent !== $parentId) { + $updates['parent'] = $parentId; + } + if ($type !== null && $targetEnvironment->hasProperty('type') && $targetEnvironment->getProperty('type') !== $type) { + $updates['type'] = $type; + } + if (!empty($updates)) { $activities = array_merge( $activities, - $targetEnvironment->update(['parent' => $parentId])->getActivities() + $targetEnvironment->update($updates)->getActivities() ); } $activities[] = $targetEnvironment->activate(); @@ -251,10 +270,11 @@ return false; } - $activity = $parentEnvironment->branch($target, $target); + $activity = $parentEnvironment->branch($target, $target, true, $type); $this->stdErr->writeln(sprintf( - 'Branched <info>%s</info> from parent %s', + 'Branched <info>%s</info>%s from parent %s', $target, + $type !== null ? ' (type: ' . $type . ')' : '', $this->api()->getEnvironmentLabel($parentEnvironment) )); $this->debug(sprintf('Branch activity ID / state: %s / %s', $activity->id, $activity->state)); @@ -265,6 +285,36 @@ } /** + * Asks the user for the environment type. + * + * @param Project $project + * + * @return string|null + */ + private function askEnvironmentType(Project $project) { + try { + $types = $project->getEnvironmentTypes(); + } catch (BadResponseException $e) { + if ($e->getResponse() && $e->getResponse()->getStatusCode() === 404) { + $this->debug('Cannot list environment types. The project probably does not yet support them.'); + return null; + } + throw $e; + } + $defaultId = null; + $ids = []; + foreach ($types as $type) { + if ($type->id === 'development') { + $defaultId = $type->id; + } + $ids[] = $type->id; + } + $questionHelper = $this->getService('question_helper'); + + return $questionHelper->askInput('Environment type', $defaultId, $ids); + } + + /** * Determines the parent of the target environment (for activate / branch). * * @param Project $project diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/Mount/MountSizeCommand.php new/platformsh-cli-3.67.2/src/Command/Mount/MountSizeCommand.php --- old/platformsh-cli-3.65.4/src/Command/Mount/MountSizeCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/Mount/MountSizeCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -98,7 +98,8 @@ $commands[] = 'cd "$' . $appDirVar . '"'; foreach ($mountPaths as $mountPath) { - $commands[] = 'du --block-size=1 -s ' . escapeshellarg($mountPath); + // The lost+found directory is excluded as it won't be readable. + $commands[] = 'du --block-size=1 --exclude=lost+found -s ' . escapeshellarg($mountPath); } $command = 'set -e; ' . implode('; ', $commands); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/Project/ProjectCreateCommand.php new/platformsh-cli-3.67.2/src/Command/Project/ProjectCreateCommand.php --- old/platformsh-cli-3.65.4/src/Command/Project/ProjectCreateCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/Project/ProjectCreateCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -7,6 +7,7 @@ use Platformsh\Cli\Command\CommandBase; use Platformsh\Cli\Console\Bot; use Platformsh\Cli\Exception\ProjectNotFoundException; +use Platformsh\Client\Model\Subscription\SubscriptionOptions; use Platformsh\ConsoleForm\Field\Field; use Platformsh\ConsoleForm\Field\OptionsField; use Platformsh\ConsoleForm\Form; @@ -128,13 +129,14 @@ } $subscription = $this->api()->getClient() - ->createSubscription( - $options['region'], - $options['plan'], - $options['title'], - $options['storage'] * 1024, - $options['environments'] - ); + ->createSubscription(SubscriptionOptions::fromArray([ + 'project_title' => $options['title'], + 'project_region' => $options['region'], + 'default_branch' => $options['default_branch'], + 'plan' => $options['plan'], + 'storage' => $options['storage'] * 1024, + 'environments' => $options['environments'], + ])); $this->api()->clearProjectsCache(); @@ -205,7 +207,25 @@ $this->stdErr->writeln(" URL: <info>{$subscription->project_ui}</info>"); $project = $this->api()->getProject($subscription->project_id); - $this->stdErr->writeln(" Git URL: <info>{$project->getGitUrl()}</info>"); + if ($project !== false) { + $this->stdErr->writeln(" Git URL: <info>{$project->getGitUrl()}</info>"); + + // Temporary workaround for the default environment's title. + /** @todo remove this from API version 12 */ + if ($project->default_branch !== 'master') { + try { + $env = $project->getEnvironment($project->default_branch); + if ($env->title === 'Master') { + $prev = $env->title; + $new = $project->default_branch; + $this->debug(\sprintf('Updating the title of environment %s from %s to %s', $env->id, $prev, $new)); + $env->update(['title' => $new]); + } + } catch (\Exception $e) { + $this->debug('Error: ' . $e->getMessage()); + } + } + } if ($setRemote && $gitRoot !== false && $project !== false) { $this->stdErr->writeln(''); @@ -329,6 +349,11 @@ return is_numeric($value) && $value > 0 && $value < 1024; }, ]), + 'default_branch' => new Field('Default branch', [ + 'description' => 'The default Git branch name for the project (the production environment)', + 'required' => false, + 'default' => 'main', + ]), ]; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/Project/ProjectDeleteCommand.php new/platformsh-cli-3.67.2/src/Command/Project/ProjectDeleteCommand.php --- old/platformsh-cli-3.65.4/src/Command/Project/ProjectDeleteCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/Project/ProjectDeleteCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -73,7 +73,7 @@ } catch (ClientException $e) { $response = $e->getResponse(); if ($response !== null && $response->getStatusCode() === 403) { - if ($project->owner !== $this->api()->getMyAccount()['id']) { + if ($project->owner !== $this->api()->getMyUserId()) { $this->stdErr->writeln("Only the project's owner can delete it."); return 1; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/Project/ProjectListCommand.php new/platformsh-cli-3.67.2/src/Command/Project/ProjectListCommand.php --- old/platformsh-cli-3.65.4/src/Command/Project/ProjectListCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/Project/ProjectListCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -158,7 +158,7 @@ break; case 'my': - $ownerId = $this->api()->getMyAccount()['id']; + $ownerId = $this->api()->getMyUserId(); $projects = array_filter($projects, function (Project $project) use ($ownerId) { return $project->owner === $ownerId; }); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/Session/SessionSwitchCommand.php new/platformsh-cli-3.67.2/src/Command/Session/SessionSwitchCommand.php --- old/platformsh-cli-3.65.4/src/Command/Session/SessionSwitchCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/Session/SessionSwitchCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -92,12 +92,21 @@ private function showAccountInfo() { if ($this->api()->isLoggedIn()) { - $info = $this->api()->getMyAccount(); - $this->stdErr->writeln(sprintf( - "\nUsername: <info>%s</info>\nEmail address: <info>%s</info>", - $info['username'], - $info['mail'] - )); + if ($this->api()->authApiEnabled()) { + $user = $this->api()->getUser(); + $this->stdErr->writeln(sprintf( + "\nUsername: <info>%s</info>\nEmail address: <info>%s</info>", + $user->username, + $user->email + )); + } else { + $info = $this->api()->getMyAccount(); + $this->stdErr->writeln(sprintf( + "\nUsername: <info>%s</info>\nEmail address: <info>%s</info>", + $info['username'], + $info['mail'] + )); + } return; } $this->stdErr->writeln(sprintf("\nTo log in, run: <info>%s login</info>", $this->config()->get('application.executable'))); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/SshCert/SshCertInfoCommand.php new/platformsh-cli-3.67.2/src/Command/SshCert/SshCertInfoCommand.php --- old/platformsh-cli-3.65.4/src/Command/SshCert/SshCertInfoCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/SshCert/SshCertInfoCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -64,6 +64,6 @@ } private function isValid(Certificate $cert) { - return !$cert->hasExpired(0) && $cert->metadata()->getKeyId() === $this->api()->getMyAccount()['id']; + return !$cert->hasExpired(0) && $cert->metadata()->getKeyId() === $this->api()->getMyUserId(); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/SshCert/SshCertLoadCommand.php new/platformsh-cli-3.67.2/src/Command/SshCert/SshCertLoadCommand.php --- old/platformsh-cli-3.65.4/src/Command/SshCert/SshCertLoadCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/SshCert/SshCertLoadCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -36,7 +36,7 @@ && !$input->getOption('new') && !$input->getOption('new-key') && !$sshCert->hasExpired() - && $sshCert->metadata()->getKeyId() === $this->api()->getMyAccount()['id']) { + && $sshCert->metadata()->getKeyId() === $this->api()->getMyUserId()) { $this->stdErr->writeln('A valid SSH certificate exists'); $this->displayCertificate($sshCert); $refresh = false; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/SshKey/SshKeyAddCommand.php new/platformsh-cli-3.67.2/src/Command/SshKey/SshKeyAddCommand.php --- old/platformsh-cli-3.65.4/src/Command/SshKey/SshKeyAddCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/SshKey/SshKeyAddCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -29,11 +29,15 @@ $sshDir = $this->config()->getHomeDirectory() . DIRECTORY_SEPARATOR . '.ssh'; - $account = $this->api()->getMyAccount(); + if ($this->api()->authApiEnabled()) { + $email = $this->api()->getUser()->email; + } else { + $email = $this->api()->getMyAccount()['mail']; + } $this->stdErr->writeln(sprintf( "Adding an SSH key to your %s account (<info>%s</info>)\n", $this->config()->get('service.name'), - $account['mail'] + $email )); $publicKeyPath = $input->getArgument('path'); @@ -165,10 +169,12 @@ private function askNewKeyPath(QuestionHelper $questionHelper) { $basename = 'id_rsa-' . $this->config()->get('service.slug'); - $accountInfo = $this->api()->getMyAccount(); - if (!empty($accountInfo['username'])) { - $basename .= '-' . $accountInfo['username']; + if ($this->api()->authApiEnabled()) { + $username = $this->api()->getUser()->username; + } else { + $username = $this->api()->getMyAccount()['username']; } + $basename .= '-' . $username; $sshDir = $this->config()->getHomeDirectory() . DIRECTORY_SEPARATOR . '.ssh'; for ($i = 2; \file_exists($sshDir . DIRECTORY_SEPARATOR . $basename); $i++) { $basename .= $i; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/SubscriptionInfoCommand.php new/platformsh-cli-3.67.2/src/Command/SubscriptionInfoCommand.php --- old/platformsh-cli-3.65.4/src/Command/SubscriptionInfoCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/SubscriptionInfoCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -13,8 +13,6 @@ class SubscriptionInfoCommand extends CommandBase { - protected $hiddenInList = true; - /** @var \Platformsh\Cli\Service\PropertyFormatter|null */ protected $formatter; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/User/UserAddCommand.php new/platformsh-cli-3.67.2/src/Command/User/UserAddCommand.php --- old/platformsh-cli-3.65.4/src/Command/User/UserAddCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/User/UserAddCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -171,24 +171,26 @@ } // Build a list of the changes that are going to be made. - $changes = []; + $changesText = []; if ($existingProjectAccess) { if ($existingProjectAccess->role !== $desiredProjectRole) { - $changes[] = sprintf('Project role: <error>%s</error> -> <info>%s</info>', $existingProjectAccess->role, $desiredProjectRole); + $changesText[] = sprintf('Project role: <error>%s</error> -> <info>%s</info>', $existingProjectAccess->role, $desiredProjectRole); } } else { - $changes[] = sprintf('Project role: <info>%s</info>', $desiredProjectRole); + $changesText[] = sprintf('Project role: <info>%s</info>', $desiredProjectRole); } + $environmentChanges = []; if ($desiredProjectRole !== ProjectAccess::ROLE_ADMIN) { foreach ($this->api()->getEnvironments($project) as $id => $environment) { $new = isset($desiredEnvironmentRoles[$id]) ? $desiredEnvironmentRoles[$id] : 'none'; if ($existingEnvironmentRoles) { $existing = isset($existingEnvironmentRoles[$id]) ? $existingEnvironmentRoles[$id] : 'none'; if ($existing !== $new) { - $changes[] = sprintf(' Role on <info>%s</info>: <error>%s</error> -> <info>%s</info>', $id, $existing, $new); + $changesText[] = sprintf(' Role on <info>%s</info>: <error>%s</error> -> <info>%s</info>', $id, $existing, $new); + $environmentChanges[$id] = $new; } } elseif ($new !== 'none') { - $changes[] = sprintf(' Role on <info>%s</info>: <info>%s</info>', $id, $new); + $changesText[] = sprintf(' Role on <info>%s</info>: <info>%s</info>', $id, $new); } } } @@ -230,7 +232,7 @@ } // Exit early if there are no changes to make. - if (empty($changes)) { + if (empty($changesText)) { if ($provideProjectForm || $provideEnvironmentForm) { $this->stdErr->writeln(''); $this->stdErr->writeln('There are no changes to make.'); @@ -250,7 +252,7 @@ } else { $this->stdErr->writeln(sprintf('Adding the user <info>%s</info> to %s:', $email, $this->api()->getProjectLabel($project))); } - foreach ($changes as $change) { + foreach ($changesText as $change) { $this->stdErr->writeln(' ' . $change); } $this->stdErr->writeln(''); @@ -313,8 +315,12 @@ // Make the desired changes at the environment level. if ($desiredProjectRole !== ProjectAccess::ROLE_ADMIN) { - foreach ($this->api()->getEnvironments($project) as $environmentId => $environment) { - $role = isset($desiredEnvironmentRoles[$environmentId]) ? $desiredEnvironmentRoles[$environmentId] : 'none'; + foreach ($environmentChanges as $environmentId => $role) { + $environment = $this->api()->getEnvironment($environmentId, $project); + if (!$environment) { + $this->stdErr->writeln('Environment not found: <comment>' . $environmentId . '</comment>'); + continue; + } $access = $environment->getUser($userId); if ($role === 'none') { if ($access) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/User/UserDeleteCommand.php new/platformsh-cli-3.67.2/src/Command/User/UserDeleteCommand.php --- old/platformsh-cli-3.65.4/src/Command/User/UserDeleteCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/User/UserDeleteCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -63,8 +63,7 @@ // If the user was deleting themselves from the project, then invalidate // the projects cache. - $myUserId = $this->api()->getMyAccount()['id']; - if ($myUserId === $selectedUser->id) { + if ($this->api()->getMyUserId() === $selectedUser->id) { $this->api()->clearProjectsCache(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/Variable/VariableCommandBase.php new/platformsh-cli-3.67.2/src/Command/Variable/VariableCommandBase.php --- old/platformsh-cli-3.65.4/src/Command/Variable/VariableCommandBase.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/Variable/VariableCommandBase.php 2021-06-18 13:15:31.000000000 +0200 @@ -235,17 +235,17 @@ ]); $fields['visible_build'] = new BooleanField('Visible at build time', [ 'optionName' => 'visible-build', - 'conditions' => [ - 'level' => self::LEVEL_PROJECT, - ], 'description' => 'Whether the variable should be visible at build time', 'questionLine' => 'Should the variable be available at build time?', + 'defaultCallback' => function (array $values) { + // Variables that are visible at build-time will affect the + // build cache, so it is good to minimise the number of them. + // This defaults to true for project-level variables, false otherwise. + return isset($values['level']) && $values['level'] === self::LEVEL_PROJECT; + }, ]); $fields['visible_runtime'] = new BooleanField('Visible at runtime', [ 'optionName' => 'visible-runtime', - 'conditions' => [ - 'level' => self::LEVEL_PROJECT, - ], 'description' => 'Whether the variable should be visible at runtime', 'questionLine' => 'Should the variable be available at runtime?', ]); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/Variable/VariableCreateCommand.php new/platformsh-cli-3.67.2/src/Command/Variable/VariableCreateCommand.php --- old/platformsh-cli-3.65.4/src/Command/Variable/VariableCreateCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/Variable/VariableCreateCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -113,6 +113,16 @@ switch ($level) { case 'environment': + // Unset visible_build and visible_runtime if they are already the API's defaults. + // This is to provide backwards compatibility with older API versions. + // @todo remove when API version 12 is everywhere + if (isset($values['visible_build']) && $values['visible_build'] === false) { + unset($values['visible_build']); + } + if (isset($values['visible_runtime']) && $values['visible_runtime'] === true) { + unset($values['visible_runtime']); + } + $environment = $this->getSelectedEnvironment(); if ($environment->getVariable($values['name'])) { $this->stdErr->writeln(sprintf( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Command/WebCommand.php new/platformsh-cli-3.67.2/src/Command/WebCommand.php --- old/platformsh-cli-3.65.4/src/Command/WebCommand.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Command/WebCommand.php 2021-06-18 13:15:31.000000000 +0200 @@ -38,7 +38,8 @@ } if ($this->hasSelectedProject()) { - $url = $this->getSelectedProject()->getLink('#ui'); + $subscription = $this->api()->getClient()->getSubscription($this->getSelectedProject()->getSubscriptionId()); + $url = $subscription->project_ui; if ($environmentId !== null) { // Console links lack the /environments path component. if ($this->config()->has('detection.console_domain') && parse_url($url, PHP_URL_HOST) === $this->config()->get('detection.console_domain')) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/CredentialHelper/Manager.php new/platformsh-cli-3.67.2/src/CredentialHelper/Manager.php --- old/platformsh-cli-3.65.4/src/CredentialHelper/Manager.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/CredentialHelper/Manager.php 2021-06-18 13:15:31.000000000 +0200 @@ -246,19 +246,24 @@ private function getHelpers() { return [ 'wincred' => [ - 'url' => 'https://github.com/docker/docker-credential-helpers/releases/download/v0.6.3/docker-credential-wincred-v0.6.3-amd64.zip', + 'url' => 'https://github.com/docker/docker-credential-helpers/releases/download/v0.6.4/docker-credential-wincred-v0.6.4-amd64.zip', 'filename' => 'docker-credential-wincred.exe', - 'sha256' => 'df73f7e58ec229c4250c6f13e5d39846602d18b65b0a3ec84009f5492123e5ba', + 'sha256' => 'a4e7885d3d469b2e3c92ab72c729e35df94ed1952bc8090272107fef0652e474', ], 'secretservice' => [ - 'url' => 'https://github.com/docker/docker-credential-helpers/releases/download/v0.6.3/docker-credential-secretservice-v0.6.3-amd64.tar.gz', + 'url' => 'https://github.com/docker/docker-credential-helpers/releases/download/v0.6.4/docker-credential-secretservice-v0.6.4-amd64.tar.gz', 'filename' => 'docker-credential-secretservice', - 'sha256' => 'f1c7e07c41b432e0d9d784090d59f6e10fe783856afaa58a79fefd425e030aae', + 'sha256' => '1bddcc1da7ea4d6f50d8e21ba3f0d2ae518c04d90553f543e683af62e9c7c9a8', ], 'osxkeychain' => [ - 'url' => 'https://github.com/docker/docker-credential-helpers/releases/download/v0.6.3/docker-credential-osxkeychain-v0.6.3-amd64.tar.gz', + 'url' => 'https://github.com/docker/docker-credential-helpers/releases/download/v0.6.4/docker-credential-osxkeychain-v0.6.4-amd64.tar.gz', 'filename' => 'docker-credential-osxkeychain', - 'sha256' => '5ff307ef63cafb244f19fe639b7f8d89c12753b0bb6d038c92c74614909e38fe', + 'sha256' => '76c4088359bbbcd25b8d0ff8436086742b6184aba6380ae57d39e5513f723b74', + ], + 'osxkeychain-arm64' => [ + 'url' => 'https://github.com/docker/docker-credential-helpers/releases/download/v0.6.4/docker-credential-osxkeychain-v0.6.4-arm64.tar.gz', + 'filename' => 'docker-credential-osxkeychain', + 'sha256' => '902e8237747aac0eca61efa1875e65aa8552b7c95fc406cf0d2aef733dda41de', ], ]; } @@ -269,19 +274,24 @@ * @return array */ private function getHelper() { - // The system architectures must be one supported by the packages. - if (!in_array(php_uname('m'), ['x86_64', 'amd64', 'AMD64'])) { - throw new \RuntimeException('Unable to find a credentials helper for this system architecture'); - } + $arch = php_uname('m'); $helpers = $this->getHelpers(); - if (OsUtil::isWindows()) { - return $helpers['wincred']; + if (OsUtil::isOsX()) { + if ($arch === 'arm64') { + return $helpers['osxkeychain-arm64']; + } elseif (\in_array($arch, ['x86_64', 'amd64', 'AMD64'])) { + return $helpers['osxkeychain']; + } } - if (OsUtil::isOsX()) { - return $helpers['osxkeychain']; + if (!in_array($arch, ['x86_64', 'amd64', 'AMD64'])) { + throw new \RuntimeException('Unable to find a credentials helper for this system architecture'); + } + + if (OsUtil::isWindows()) { + return $helpers['wincred']; } if (OsUtil::isLinux()) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Service/Api.php new/platformsh-cli-3.67.2/src/Service/Api.php --- old/platformsh-cli-3.65.4/src/Service/Api.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Service/Api.php 2021-06-18 13:15:31.000000000 +0200 @@ -721,6 +721,8 @@ * * @param bool $reset * + * @deprecated use getUser() if the Auth API (the config key api.auth) is enabled + * * @return array * An array containing at least 'username', 'id', 'mail', and * 'display_name'. @@ -737,6 +739,29 @@ } /** + * Returns the ID of the current user. + * + * @return string + */ + public function getMyUserId($reset = false) + { + if ($this->authApiEnabled()) { + return $this->getUser(null, $reset)->id; + } + return $this->getMyAccount($reset)['id']; + } + + /** + * Determines if the Auth API can be used, e.g. the getUser() method. + * + * @return bool + */ + public function authApiEnabled() + { + return $this->config->getWithDefault('api.auth', false) && $this->config->getWithDefault('api.base_url', ''); + } + + /** * Get the logged-in user's SSH keys. * * @param bool $reset @@ -785,8 +810,9 @@ /** * Get user information. * - * This is from the /users API which deals with basic authentication - * related data. + * This is from the /users API which deals with basic authentication-related data. + * + * @see Api::authApiEnabled() * * @param string|null $id * The user ID. Defaults to the current user. @@ -799,8 +825,12 @@ if (!$this->config->getWithDefault('api.auth', false)) { throw new \BadMethodCallException('api.auth must be enabled for this method'); } - $id = $id ?: $this->getMyAccount()['id']; // @todo achieve this more efficiently - $cacheKey = 'user:' . $id; + if ($id) { + $cacheKey = 'user:' . $id; + } else { + $id = 'me'; + $cacheKey = sprintf('%s:me', $this->config->getSessionId()); + } if ($reset || !($data = $this->cache->fetch($cacheKey))) { $user = $this->getClient()->getUser($id); if (!$user) { @@ -983,13 +1013,18 @@ { $id = $environment->id; $title = $environment->title; + $type = $environment->getProperty('type', false); $use_title = strlen($title) > 0 && $title !== $id; + $use_type = $type !== null && $type !== $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>'; } + if ($use_type) { + $pattern .= $tag !== false ? ' (type: <%1$s>%4$s</%1$s>)' : ' (type: %4$s)'; + } - return sprintf($pattern, $tag, $title, $id); + return sprintf($pattern, $tag, $title, $id, $type); } /** @@ -1045,7 +1080,7 @@ // If there is no token, or it has expired, make an API request, which // automatically obtains a token and saves it to the session. if (!$token || $expires < time()) { - $this->getMyAccount(true); + $this->getMyUserId(true); if (!$token = $session->get('accessToken')) { throw new \RuntimeException('No access token found'); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Service/Config.php new/platformsh-cli-3.67.2/src/Service/Config.php --- old/platformsh-cli-3.65.4/src/Service/Config.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Service/Config.php 2021-06-18 13:15:31.000000000 +0200 @@ -318,6 +318,7 @@ 'SKIP_SSL' => 'api.skip_ssl', 'ACCOUNTS_API' => 'api.accounts_api_url', 'API_URL' => 'api.base_url', + 'DEFAULT_TIMEOUT' => 'api.default_timeout', 'OAUTH2_AUTH_URL' => 'api.oauth2_auth_url', 'OAUTH2_CLIENT_ID' => 'api.oauth2_client_id', 'OAUTH2_TOKEN_URL' => 'api.oauth2_token_url', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Service/CurlCli.php new/platformsh-cli-3.67.2/src/Service/CurlCli.php --- old/platformsh-cli-3.65.4/src/Service/CurlCli.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Service/CurlCli.php 2021-06-18 13:15:31.000000000 +0200 @@ -92,6 +92,8 @@ $commandline .= ' --silent --show-error'; } + $commandline .= ' --fail'; + $stdErr->writeln(sprintf('Running command: <info>%s</info>', str_replace($token, '[token]', $commandline)), OutputInterface::VERBOSITY_VERBOSE); $process = proc_open($commandline, [STDIN, STDOUT, STDERR], $pipes); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Service/Relationships.php new/platformsh-cli-3.67.2/src/Service/Relationships.php --- old/platformsh-cli-3.65.4/src/Service/Relationships.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Service/Relationships.php 2021-06-18 13:15:31.000000000 +0200 @@ -343,6 +343,10 @@ $parts['query'] = (new Query($parts['query']))->__toString(); } + if (isset($parts['scheme']) && $parts['scheme'] === 'solr') { + $parts['scheme'] = 'http'; + } + return \GuzzleHttp\Url::buildUrl($parts); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/src/Service/SshDiagnostics.php new/platformsh-cli-3.67.2/src/Service/SshDiagnostics.php --- old/platformsh-cli-3.65.4/src/Service/SshDiagnostics.php 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/src/Service/SshDiagnostics.php 2021-06-18 13:15:31.000000000 +0200 @@ -176,7 +176,7 @@ $this->stdErr->writeln('The SSH connection failed because access requires MFA (multi-factor authentication).'); - if (!$this->config->getWithDefault('api.auth', false)) { + if (!$this->api->authApiEnabled()) { if ($this->config->has('api.mfa_setup_url')) { $this->stdErr->writeln(\sprintf( 'Ensure that MFA is enabled on your account. Set it up at: <comment>%s</comment>', @@ -221,18 +221,19 @@ if ($this->keyAuthenticationFailed($failedProcess) && !$this->sshKey->hasLocalKey()) { $this->stdErr->writeln(''); $this->stdErr->writeln('The SSH connection failed.'); - if (!$this->certifier->isAutoLoadEnabled() && !$this->certifier->getExistingCertificate()) { + if (!$this->certifier->isAutoLoadEnabled() && !$this->certifier->getExistingCertificate() && $this->config->isCommandEnabled('ssh-cert:load')) { $this->stdErr->writeln(\sprintf( 'You may need to create an SSH certificate, by running: <comment>%s ssh-cert:load</comment>', $executable )); return; } - $this->stdErr->writeln(\sprintf( - 'You may need to add an SSH key, by running: <comment>%s ssh-key:add</comment>', - $executable - )); - return; + if ($this->config->isCommandEnabled('ssh-key:add')) { + $this->stdErr->writeln(\sprintf( + 'You may need to add an SSH key, by running: <comment>%s ssh-key:add</comment>', + $executable + )); + } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.65.4/vendor-bin/box/composer.lock new/platformsh-cli-3.67.2/vendor-bin/box/composer.lock --- old/platformsh-cli-3.65.4/vendor-bin/box/composer.lock 2021-03-17 14:44:30.000000000 +0100 +++ new/platformsh-cli-3.67.2/vendor-bin/box/composer.lock 2021-06-18 13:15:31.000000000 +0200 @@ -2155,24 +2155,24 @@ }, { "name": "paragonie/constant_time_encoding", - "version": "v2.3.0", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/paragonie/constant_time_encoding.git", - "reference": "47a1cedd2e4d52688eb8c96469c05ebc8fd28fa2" + "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/47a1cedd2e4d52688eb8c96469c05ebc8fd28fa2", - "reference": "47a1cedd2e4d52688eb8c96469c05ebc8fd28fa2", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c", + "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c", "shasum": "" }, "require": { "php": "^7|^8" }, "require-dev": { - "phpunit/phpunit": "^6|^7", - "vimeo/psalm": "^1|^2|^3" + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" }, "type": "library", "autoload": { @@ -2218,7 +2218,7 @@ "issues": "https://github.com/paragonie/constant_time_encoding/issues", "source": "https://github.com/paragonie/constant_time_encoding" }, - "time": "2019-11-06T19:20:29+00:00" + "time": "2020-12-06T15:14:20+00:00" }, { "name": "paragonie/pharaoh", @@ -2583,16 +2583,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "2.0.29", + "version": "2.0.31", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "497856a8d997f640b4a516062f84228a772a48a8" + "reference": "233a920cb38636a43b18d428f9a8db1f0a1a08f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/497856a8d997f640b4a516062f84228a772a48a8", - "reference": "497856a8d997f640b4a516062f84228a772a48a8", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/233a920cb38636a43b18d428f9a8db1f0a1a08f4", + "reference": "233a920cb38636a43b18d428f9a8db1f0a1a08f4", "shasum": "" }, "require": { @@ -2600,7 +2600,7 @@ }, "require-dev": { "phing/phing": "~2.7", - "phpunit/phpunit": "^4.8.35|^5.7|^6.0", + "phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4", "squizlabs/php_codesniffer": "~2.0" }, "suggest": { @@ -2672,7 +2672,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/2.0" + "source": "https://github.com/phpseclib/phpseclib/tree/2.0.31" }, "funding": [ { @@ -2688,7 +2688,7 @@ "type": "tidelift" } ], - "time": "2020-09-08T04:24:43+00:00" + "time": "2021-04-06T13:56:45+00:00" }, { "name": "psr/container", ++++++ 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 2021-03-18 01:22:39.614163325 +0100 +++ new/vendor/autoload.php 2021-06-26 22:16:39.852724928 +0200 @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit411ad3dc1f6912bfbe3e42f2ebc6e05b::getLoader(); +return ComposerAutoloaderInitdc9c93b81c54d5fbcad86934d6174224::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 2021-03-18 01:22:39.614163325 +0100 +++ new/vendor/composer/autoload_real.php 2021-06-26 22:16:39.852724928 +0200 @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit411ad3dc1f6912bfbe3e42f2ebc6e05b +class ComposerAutoloaderInitdc9c93b81c54d5fbcad86934d6174224 { private static $loader; @@ -22,15 +22,15 @@ return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit411ad3dc1f6912bfbe3e42f2ebc6e05b', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInitdc9c93b81c54d5fbcad86934d6174224', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit411ad3dc1f6912bfbe3e42f2ebc6e05b', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInitdc9c93b81c54d5fbcad86934d6174224', '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\ComposerStaticInit411ad3dc1f6912bfbe3e42f2ebc6e05b::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInitdc9c93b81c54d5fbcad86934d6174224::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -51,19 +51,19 @@ $loader->register(true); if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit411ad3dc1f6912bfbe3e42f2ebc6e05b::$files; + $includeFiles = Composer\Autoload\ComposerStaticInitdc9c93b81c54d5fbcad86934d6174224::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire411ad3dc1f6912bfbe3e42f2ebc6e05b($fileIdentifier, $file); + composerRequiredc9c93b81c54d5fbcad86934d6174224($fileIdentifier, $file); } return $loader; } } -function composerRequire411ad3dc1f6912bfbe3e42f2ebc6e05b($fileIdentifier, $file) +function composerRequiredc9c93b81c54d5fbcad86934d6174224($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 2021-03-18 01:22:39.614163325 +0100 +++ new/vendor/composer/autoload_static.php 2021-06-26 22:16:39.852724928 +0200 @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit411ad3dc1f6912bfbe3e42f2ebc6e05b +class ComposerStaticInitdc9c93b81c54d5fbcad86934d6174224 { public static $files = array ( '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', @@ -193,9 +193,9 @@ public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit411ad3dc1f6912bfbe3e42f2ebc6e05b::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit411ad3dc1f6912bfbe3e42f2ebc6e05b::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit411ad3dc1f6912bfbe3e42f2ebc6e05b::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInitdc9c93b81c54d5fbcad86934d6174224::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitdc9c93b81c54d5fbcad86934d6174224::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInitdc9c93b81c54d5fbcad86934d6174224::$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 2021-03-18 01:22:39.114158645 +0100 +++ new/vendor/composer/installed.json 2021-06-26 22:16:39.408725560 +0200 @@ -641,17 +641,17 @@ }, { "name": "paragonie/random_compat", - "version": "v2.0.19", - "version_normalized": "2.0.19.0", + "version": "v2.0.20", + "version_normalized": "2.0.20.0", "source": { "type": "git", "url": "https://github.com/paragonie/random_compat.git", - "reference": "446fc9faa5c2a9ddf65eb7121c0af7e857295241" + "reference": "0f1f60250fccffeaf5dda91eea1c018aed1adc2a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/446fc9faa5c2a9ddf65eb7121c0af7e857295241", - "reference": "446fc9faa5c2a9ddf65eb7121c0af7e857295241", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/0f1f60250fccffeaf5dda91eea1c018aed1adc2a", + "reference": "0f1f60250fccffeaf5dda91eea1c018aed1adc2a", "shasum": "" }, "require": { @@ -663,7 +663,7 @@ "suggest": { "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." }, - "time": "2020-10-15T10:06:57+00:00", + "time": "2021-04-17T09:33:01+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -747,17 +747,17 @@ }, { "name": "platformsh/client", - "version": "0.42.0", - "version_normalized": "0.42.0.0", + "version": "0.45.0", + "version_normalized": "0.45.0.0", "source": { "type": "git", "url": "https://github.com/platformsh/platformsh-client-php.git", - "reference": "d87cc67684a56fa1c03e520669b03d25539d631c" + "reference": "4dcff942a5b0c0f39d524b5f2af56a0c4333e6fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/d87cc67684a56fa1c03e520669b03d25539d631c", - "reference": "d87cc67684a56fa1c03e520669b03d25539d631c", + "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/4dcff942a5b0c0f39d524b5f2af56a0c4333e6fe", + "reference": "4dcff942a5b0c0f39d524b5f2af56a0c4333e6fe", "shasum": "" }, "require": { @@ -771,7 +771,7 @@ "require-dev": { "phpunit/phpunit": "~4.5" }, - "time": "2021-02-26T21:49:53+00:00", + "time": "2021-06-14T08:13:20+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -791,22 +791,22 @@ "description": "Platform.sh API client", "support": { "issues": "https://github.com/platformsh/platformsh-client-php/issues", - "source": "https://github.com/platformsh/platformsh-client-php/tree/0.42.0" + "source": "https://github.com/platformsh/platformsh-client-php/tree/0.45.0" } }, { "name": "platformsh/console-form", - "version": "v0.0.24", - "version_normalized": "0.0.24.0", + "version": "v0.0.25", + "version_normalized": "0.0.25.0", "source": { "type": "git", "url": "https://github.com/platformsh/console-form.git", - "reference": "4dc5f0990399633b6a39ca13752080ea4f62f716" + "reference": "9b1a93e5e27aa1c1614ac14102a55162f69732ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/platformsh/console-form/zipball/4dc5f0990399633b6a39ca13752080ea4f62f716", - "reference": "4dc5f0990399633b6a39ca13752080ea4f62f716", + "url": "https://api.github.com/repos/platformsh/console-form/zipball/9b1a93e5e27aa1c1614ac14102a55162f69732ae", + "reference": "9b1a93e5e27aa1c1614ac14102a55162f69732ae", "shasum": "" }, "require": { @@ -816,7 +816,7 @@ "require-dev": { "phpunit/phpunit": "^5.0" }, - "time": "2019-07-12T11:29:37+00:00", + "time": "2021-06-16T16:02:08+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -836,7 +836,7 @@ "description": "A lightweight Symfony Console form system.", "support": { "issues": "https://github.com/platformsh/console-form/issues", - "source": "https://github.com/platformsh/console-form/tree/v0.0.24" + "source": "https://github.com/platformsh/console-form/tree/v0.0.25" } }, { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/paragonie/random_compat/.github/workflows/ci.yml new/vendor/paragonie/random_compat/.github/workflows/ci.yml --- old/vendor/paragonie/random_compat/.github/workflows/ci.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/vendor/paragonie/random_compat/.github/workflows/ci.yml 2021-04-17 11:33:01.000000000 +0200 @@ -0,0 +1,102 @@ +name: CI + +on: [push] + +jobs: + old: + name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + operating-system: ['ubuntu-16.04'] + php-versions: ['5.3', '5.4', '5.5', '5.6', '7.0'] + phpunit-versions: ['7.5.20'] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, intl + ini-values: post_max_size=256M, max_execution_time=180 + tools: psalm, phpunit:${{ matrix.phpunit-versions }} + + - name: Install dependencies + run: composer self-update --1; composer install + + - name: PHPUnit tests + uses: php-actions/phpunit@v2 + with: + memory_limit: 256M + + moderate: + name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + operating-system: ['ubuntu-latest'] + php-versions: ['7.1', '7.2', '7.3'] + phpunit-versions: ['latest'] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, intl, sodium + ini-values: post_max_size=256M, max_execution_time=180 + tools: psalm, phpunit:${{ matrix.phpunit-versions }} + + - name: Install dependencies + run: composer install + + - name: Modernize dependencies + run: composer require --dev "phpunit/phpunit:>=4" + + - name: PHPUnit tests + uses: php-actions/phpunit@v2 + timeout-minutes: 30 + with: + memory_limit: 256M + + modern: + name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + operating-system: ['ubuntu-latest'] + php-versions: ['7.4', '8.0'] + phpunit-versions: ['latest'] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, intl, sodium + ini-values: post_max_size=256M, max_execution_time=180 + tools: psalm, phpunit:${{ matrix.phpunit-versions }} + + - name: Install dependencies + run: composer install + + - name: Modernize dependencies + run: composer require --dev "phpunit/phpunit:>=4" + + - name: PHPUnit tests + uses: php-actions/phpunit@v2 + timeout-minutes: 30 + with: + memory_limit: 256M + + - name: Install Psalm + run: rm composer.lock && composer require --dev vimeo/psalm:^4 + + - name: Static Analysis + run: vendor/bin/psalm diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/paragonie/random_compat/lib/random.php new/vendor/paragonie/random_compat/lib/random.php --- old/vendor/paragonie/random_compat/lib/random.php 2020-10-15 12:06:57.000000000 +0200 +++ new/vendor/paragonie/random_compat/lib/random.php 2021-04-17 11:33:01.000000000 +0200 @@ -54,9 +54,9 @@ $RandomCompatDIR = dirname(__FILE__); -require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'byte_safe_strings.php'; -require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'cast_to_int.php'; -require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'error_polyfill.php'; +require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'byte_safe_strings.php'; +require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'cast_to_int.php'; +require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'error_polyfill.php'; if (!is_callable('random_bytes')) { /** @@ -76,9 +76,9 @@ if (extension_loaded('libsodium')) { // See random_bytes_libsodium.php if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) { - require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_libsodium.php'; + require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_libsodium.php'; } elseif (method_exists('Sodium', 'randombytes_buf')) { - require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_libsodium_legacy.php'; + require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_libsodium_legacy.php'; } } @@ -117,7 +117,7 @@ // place, that is not helpful to us here. // See random_bytes_dev_urandom.php - require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_dev_urandom.php'; + require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_dev_urandom.php'; } // Unset variables after use $RandomCompat_basedir = null; @@ -159,7 +159,7 @@ extension_loaded('mcrypt') ) { // See random_bytes_mcrypt.php - require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_mcrypt.php'; + require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_mcrypt.php'; } $RandomCompatUrandom = null; @@ -182,9 +182,10 @@ if (!in_array('com', $RandomCompat_disabled_classes)) { try { $RandomCompatCOMtest = new COM('CAPICOM.Utilities.1'); + /** @psalm-suppress TypeDoesNotContainType */ if (method_exists($RandomCompatCOMtest, 'GetRandom')) { // See random_bytes_com_dotnet.php - require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_com_dotnet.php'; + require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_com_dotnet.php'; } } catch (com_exception $e) { // Don't try to use it. @@ -219,7 +220,7 @@ } if (!is_callable('random_int')) { - require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_int.php'; + require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_int.php'; } $RandomCompatDIR = null; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/paragonie/random_compat/phpunit-autoload.php new/vendor/paragonie/random_compat/phpunit-autoload.php --- old/vendor/paragonie/random_compat/phpunit-autoload.php 2020-10-15 12:06:57.000000000 +0200 +++ new/vendor/paragonie/random_compat/phpunit-autoload.php 1970-01-01 01:00:00.000000000 +0100 @@ -1,14 +0,0 @@ -<?php - -require_once __DIR__ . '/psalm-autoload.php'; - -/** - * This is necessary for PHPUnit on PHP >= 5.3 - * - * Class PHPUnit_Framework_TestCase - */ -if (PHP_VERSION_ID >= 50300) { - if (!class_exists('PHPUnit_Framework_TestCase')) { - require_once __DIR__ . '/other/phpunit-shim.php'; - } -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/src/Model/Environment.php new/vendor/platformsh/client/src/Model/Environment.php --- old/vendor/platformsh/client/src/Model/Environment.php 2021-02-26 22:49:53.000000000 +0100 +++ new/vendor/platformsh/client/src/Model/Environment.php 2021-06-14 10:13:20.000000000 +0200 @@ -232,24 +232,35 @@ } /** - * Branch (create a new environment). + * Branches an environment (creates a new environment as a child of the current one). + * + * The new environment's code will be the same as the parent environment. + * Some other settings are typically inherited, such as variables. + * Data is cloned from the parent environment (if $cloneParent is left as + * true), including all data from services and file mounts. * * @param string $title The title of the new environment. - * @param string $id The ID of the new environment. This will be the Git - * branch name. Leave blank to generate automatically - * from the title. + * @param string|null $id The ID of the new environment. This will be the Git + * branch name. Leave empty to generate automatically + * from the title (not recommended). * @param bool $cloneParent Whether to clone data from the parent * environment while branching. + * @param string|null $type The environment type, e.g. 'staging' or 'development'. + * Leave this empty to use the default type for new + * environments ('development' at the time of writing). * * @return Activity */ - public function branch($title, $id = null, $cloneParent = true) + public function branch($title, $id = null, $cloneParent = true, $type = null) { $id = $id ?: $this->sanitizeId($title); $body = ['name' => $id, 'title' => $title]; if (!$cloneParent) { $body['clone_parent'] = false; } + if ($type !== null) { + $body['type'] = $type; + } return $this->runLongOperation('branch', 'post', $body); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/src/Model/EnvironmentType.php new/vendor/platformsh/client/src/Model/EnvironmentType.php --- old/vendor/platformsh/client/src/Model/EnvironmentType.php 1970-01-01 01:00:00.000000000 +0100 +++ new/vendor/platformsh/client/src/Model/EnvironmentType.php 2021-06-14 10:13:20.000000000 +0200 @@ -0,0 +1,9 @@ +<?php + +namespace Platformsh\Client\Model; + +/** + * @property-read string $id + * @property-read array $attributes + */ +class EnvironmentType extends Resource {} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/src/Model/Project.php new/vendor/platformsh/client/src/Model/Project.php --- old/vendor/platformsh/client/src/Model/Project.php 2021-02-26 22:49:53.000000000 +0100 +++ new/vendor/platformsh/client/src/Model/Project.php 2021-06-14 10:13:20.000000000 +0200 @@ -242,6 +242,28 @@ } /** + * Get a list of environment types for the project. + * + * @return EnvironmentType[] + */ + public function getEnvironmentTypes() + { + return EnvironmentType::getCollection($this->getLink('environment-types'), 0, [], $this->client); + } + + /** + * Get an environment type. + * + * @param string $id + * + * @return EnvironmentType|false + */ + public function getEnvironmentType($id) + { + return EnvironmentType::get($id, $this->getLink('environment-types'), $this->client); + } + + /** * Get a list of domains for the project. * * @param int $limit diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/src/Model/Subscription/SubscriptionOptions.php new/vendor/platformsh/client/src/Model/Subscription/SubscriptionOptions.php --- old/vendor/platformsh/client/src/Model/Subscription/SubscriptionOptions.php 1970-01-01 01:00:00.000000000 +0100 +++ new/vendor/platformsh/client/src/Model/Subscription/SubscriptionOptions.php 2021-06-14 10:13:20.000000000 +0200 @@ -0,0 +1,53 @@ +<?php + +namespace Platformsh\Client\Model\Subscription; + +final class SubscriptionOptions { + /** @var string|NULL */ + private $project_region; + /** @var string|NULL */ + private $project_title; + /** @var string|NULL */ + private $default_branch; + /** @var string|NULL */ + private $options_url; + /** @var string|NULL */ + private $plan; + /** @var int|NULL */ + private $environments; + /** @var int|NULL */ + private $storage; + /** @var string|NULL */ + private $owner; + /** @var array|NULL */ + private $activation_callback; + + /** + * @param array $options + * + * @return SubscriptionOptions + */ + public static function fromArray(array $options) + { + $obj = new self(); + foreach ($options as $key => $value) { + if (\property_exists($obj, $key)) { + $obj->$key = $value; + } else { + throw new \InvalidArgumentException('Unknown property: ' . $key); + } + } + return $obj; + } + + /** @return array */ + public function toArray() { + $arr = []; + foreach ($this as $key => $value) { + if ($value !== null) { + $arr[$key] = $value; + } + } + return $arr; + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/src/Model/Subscription.php new/vendor/platformsh/client/src/Model/Subscription.php --- old/vendor/platformsh/client/src/Model/Subscription.php 2021-02-26 22:49:53.000000000 +0100 +++ new/vendor/platformsh/client/src/Model/Subscription.php 2021-06-14 10:13:20.000000000 +0200 @@ -24,8 +24,22 @@ class Subscription extends Resource { + /** + * @deprecated + * @see \Platformsh\Client\PlatformClient::getPlans() + * + * @var string[] + */ public static $availablePlans = ['development', 'standard', 'medium', 'large']; + + /** + * @deprecated + * @see \Platformsh\Client\PlatformClient::getRegions() + * + * @var string[] + */ public static $availableRegions = ['eu.platform.sh', 'us.platform.sh']; + protected static $required = ['project_region']; const STATUS_ACTIVE = 'active'; 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 2021-02-26 22:49:53.000000000 +0100 +++ new/vendor/platformsh/client/src/PlatformClient.php 2021-06-14 10:13:20.000000000 +0200 @@ -15,6 +15,7 @@ use Platformsh\Client\Model\SetupOptions; use Platformsh\Client\Model\SshKey; use Platformsh\Client\Model\Subscription; +use Platformsh\Client\Model\Subscription\SubscriptionOptions; use Platformsh\Client\Model\User; class PlatformClient @@ -271,36 +272,50 @@ /** * Create a new Platform.sh subscription. * - * @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. - * @param string $catalog The catalog item url. See getCatalog(). - * - * @see PlatformClient::getCatalog() - * @see PlatformClient::getRegions() - * @see Subscription::wait() + * @param SubscriptionOptions|string $options + * Subscription request options, which override the other arguments. + * If a string is passed, it will be used as the region ID (deprecated). See getRegions(). + * @param string $plan The plan. See getPlans(). @deprecated + * @param string $title The project title. @deprecated + * @param int $storage The storage of each environment, in MiB. @deprecated + * @param int $environments The number of available environments. @deprecated + * @param array $activation_callback An activation callback for the subscription. @deprecated + * @param string $options_url The catalog options URL. See getCatalog(). @deprecated * * @return Subscription * A subscription, representing a project. Use Subscription::wait() or * similar code to wait for the subscription's project to be provisioned * and activated. + * + * @see PlatformClient::getCatalog() + * @see PlatformClient::getRegions() + * @see Subscription::wait() + * + * @noinspection PhpTooManyParametersInspection */ - public function createSubscription($region, $plan = 'development', $title = null, $storage = null, $environments = null, array $activationCallback = null, $catalog = null) + public function createSubscription($options, $plan = null, $title = null, $storage = null, $environments = null, array $activation_callback = null, $options_url = null) { - $url = $this->apiUrl() . '/subscriptions'; - $values = $this->cleanRequest([ - 'project_region' => $region, - 'plan' => $plan, - 'project_title' => $title, - 'storage' => $storage, - 'environments' => $environments, - 'activation_callback' => $activationCallback, - 'options_url' => $catalog, - ]); + if ($options instanceof SubscriptionOptions) { + $values = $options->toArray(); + } elseif (\is_string($options)) { + \trigger_error('The previous arguments list has been replaced by a single SubscriptionOptions argument', E_USER_DEPRECATED); + if ($plan === null) { + // Backwards-compatible default. + $plan = 'development'; + } + $values = $this->cleanRequest([ + 'project_region' => $options, + 'plan' => $plan, + 'project_title' => $title, + 'storage' => $storage, + 'environments' => $environments, + 'activation_callback' => $activation_callback, + 'options_url' => $options_url, + ]); + } else { + throw new \InvalidArgumentException('The first argument must be a SubscriptionOptions object or a string'); + } return Subscription::create($values, $url, $this->connector->getClient()); } @@ -456,7 +471,7 @@ throw new \RuntimeException('No API URL configured'); } if ($id === null) { - $id = $this->getAccountInfo()['id']; + $id = 'me'; } return User::get($id, $this->connector->getApiUrl() . '/users', $this->connector->getClient()); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/console-form/src/Field/BooleanField.php new/vendor/platformsh/console-form/src/Field/BooleanField.php --- old/vendor/platformsh/console-form/src/Field/BooleanField.php 2019-07-12 13:29:37.000000000 +0200 +++ new/vendor/platformsh/console-form/src/Field/BooleanField.php 2021-06-16 18:02:08.000000000 +0200 @@ -6,9 +6,19 @@ class BooleanField extends Field { - public $default = true; - /** + * @{inheritdoc} + */ + public function __construct($name, array $config = []) + { + parent::__construct($name, $config); + // The default is true, unless a callback is set. + if (!isset($this->defaultCallback) && !isset($this->default)) { + $this->default = true; + } + } + + /** * {@inheritdoc} */ protected function getQuestionText() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/console-form/src/Field/Field.php new/vendor/platformsh/console-form/src/Field/Field.php --- old/vendor/platformsh/console-form/src/Field/Field.php 2019-07-12 13:29:37.000000000 +0200 +++ new/vendor/platformsh/console-form/src/Field/Field.php 2021-06-16 18:02:08.000000000 +0200 @@ -85,6 +85,15 @@ protected $default; /** + * The field's original default value (unaffected by the defaultCallback) used internally. + * + * @internal + * + * @var mixed|null + */ + protected $originalDefault; + + /** * The prompt. * * @var string @@ -199,6 +208,10 @@ $this->normalizers[] = $value; break; + case 'default': + $this->default = $this->originalDefault = $value; + break; + default: if (!property_exists($this, $key)) { throw new \InvalidArgumentException("Unrecognized config key: $key"); @@ -456,7 +469,7 @@ if ($this->isEmpty($value)) { return null; } - if ($input->getParameterOption('--' . $optionName) === false && $value === $this->default) { + if ($input->getParameterOption('--' . $optionName) === false && $value === $this->originalDefault) { return null; }