Hello community, here is the log from the commit of package platformsh-cli for openSUSE:Factory checked in at 2018-10-15 09:43:18 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/platformsh-cli (Old) and /work/SRC/openSUSE:Factory/.platformsh-cli.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "platformsh-cli" Mon Oct 15 09:43:18 2018 rev:57 rq:641749 version:3.35.3 Changes: -------- --- /work/SRC/openSUSE:Factory/platformsh-cli/platformsh-cli.changes 2018-10-08 17:47:09.258351615 +0200 +++ /work/SRC/openSUSE:Factory/.platformsh-cli.new/platformsh-cli.changes 2018-10-15 09:43:37.763359041 +0200 @@ -1,0 +2,8 @@ +Fri Oct 12 19:17:51 UTC 2018 - jimmy@boombatower.com + +- Update to version 3.35.3: + * Release v3.35.3 + * Revoke this session's tokens pro-actively on logout + * multi: ignore blank lines in the project ID list + +------------------------------------------------------------------- Old: ---- platformsh-cli-3.35.2.tar.xz New: ---- platformsh-cli-3.35.3.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ platformsh-cli.spec ++++++ --- /var/tmp/diff_new_pack.3uXV3w/_old 2018-10-15 09:43:39.003357649 +0200 +++ /var/tmp/diff_new_pack.3uXV3w/_new 2018-10-15 09:43:39.007357645 +0200 @@ -17,7 +17,7 @@ Name: platformsh-cli -Version: 3.35.2 +Version: 3.35.3 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.3uXV3w/_old 2018-10-15 09:43:39.031357617 +0200 +++ /var/tmp/diff_new_pack.3uXV3w/_new 2018-10-15 09:43:39.031357617 +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.35.2</param> + <param name="revision">refs/tags/v3.35.3</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.3uXV3w/_old 2018-10-15 09:43:39.047357600 +0200 +++ /var/tmp/diff_new_pack.3uXV3w/_new 2018-10-15 09:43:39.051357595 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">git://github.com/platformsh/platformsh-cli.git</param> - <param name="changesrevision">f524af6368289fa17c9c8d6c088c260e46b3ec4a</param> + <param name="changesrevision">83849efa1ad6d69c845e84c233785913bb1938bb</param> </service> </servicedata> ++++++ licenses.txt ++++++ --- /var/tmp/diff_new_pack.3uXV3w/_old 2018-10-15 09:43:39.087357554 +0200 +++ /var/tmp/diff_new_pack.3uXV3w/_new 2018-10-15 09:43:39.087357554 +0200 @@ -17,7 +17,7 @@ padraic/humbug_get_contents 1.1.2 BSD-3-Clause padraic/phar-updater v1.0.5 BSD-3-Clause paragonie/random_compat v2.0.11 MIT -platformsh/client v0.19.2 MIT +platformsh/client v0.20.2 MIT platformsh/console-form v0.0.23 MIT psr/container 1.0.0 MIT psr/log 1.0.2 MIT ++++++ platformsh-cli-3.35.2.tar.xz -> platformsh-cli-3.35.3.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.35.2/composer.json new/platformsh-cli-3.35.3/composer.json --- old/platformsh-cli-3.35.2/composer.json 2018-10-05 11:21:50.000000000 +0200 +++ new/platformsh-cli-3.35.3/composer.json 2018-10-12 18:32:40.000000000 +0200 @@ -8,7 +8,7 @@ "guzzlehttp/guzzle": "^5.3", "guzzlehttp/ringphp": "^1.1", "platformsh/console-form": ">=0.0.22 <2.0", - "platformsh/client": ">=0.19.2 <2.0", + "platformsh/client": ">=0.20.2 <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.35.2/composer.lock new/platformsh-cli-3.35.3/composer.lock --- old/platformsh-cli-3.35.2/composer.lock 2018-10-05 11:21:50.000000000 +0200 +++ new/platformsh-cli-3.35.3/composer.lock 2018-10-12 18:32:40.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": "9cda4be36a91eb4c3047272134b31a98", + "content-hash": "683a401d37c922ba8fd60e6a691587f7", "packages": [ { "name": "cocur/slugify", @@ -711,16 +711,16 @@ }, { "name": "platformsh/client", - "version": "v0.19.2", + "version": "v0.20.2", "source": { "type": "git", "url": "https://github.com/platformsh/platformsh-client-php.git", - "reference": "678f057067174c3b2c6716168bc86060a3f10097" + "reference": "220947685624464455d8ae3022c418ae832ce85e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/678f05...", - "reference": "678f057067174c3b2c6716168bc86060a3f10097", + "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/220947...", + "reference": "220947685624464455d8ae3022c418ae832ce85e", "shasum": "" }, "require": { @@ -756,7 +756,7 @@ } ], "description": "Platform.sh API client", - "time": "2018-08-23T09:40:35+00:00" + "time": "2018-10-12T16:21:31+00:00" }, { "name": "platformsh/console-form", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.35.2/config.yaml new/platformsh-cli-3.35.3/config.yaml --- old/platformsh-cli-3.35.2/config.yaml 2018-10-05 11:21:50.000000000 +0200 +++ new/platformsh-cli-3.35.3/config.yaml 2018-10-12 18:32:40.000000000 +0200 @@ -1,7 +1,7 @@ # Metadata about the CLI application itself. application: name: 'Platform.sh CLI' - version: '3.35.2' + version: '3.35.3' executable: 'platform' package_name: 'platformsh/cli' installer_url: 'https://platform.sh/cli/installer' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.35.2/dist/manifest.json new/platformsh-cli-3.35.3/dist/manifest.json --- old/platformsh-cli-3.35.2/dist/manifest.json 2018-10-05 11:21:50.000000000 +0200 +++ new/platformsh-cli-3.35.3/dist/manifest.json 2018-10-12 18:32:40.000000000 +0200 @@ -1,10 +1,10 @@ [ { "name": "platform.phar", - "sha1": "8479397a644be78557d8ca58a0dbeb0e7b5ffc08", - "sha256": "1f7b9aec2af20ea0a0931b2c6b8d89d45c9de1c51fd3c071eb07f760ea284006", - "url": "https://github.com/platformsh/platformsh-cli/releases/download/v3.35.2/platf...", - "version": "3.35.2", + "sha1": "5d6b774f6123893f2f6bf39c43ab3575bcac1048", + "sha256": "c8df4ae595fa0311a36ebbbb795d559a8524fe61e1a711702877899abf18dfec", + "url": "https://github.com/platformsh/platformsh-cli/releases/download/v3.35.3/platf...", + "version": "3.35.3", "php": { "min": "5.5.9" }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.35.2/src/Command/MultiCommand.php new/platformsh-cli-3.35.3/src/Command/MultiCommand.php --- old/platformsh-cli-3.35.2/src/Command/MultiCommand.php 2018-10-05 11:21:50.000000000 +0200 +++ new/platformsh-cli-3.35.3/src/Command/MultiCommand.php 2018-10-12 18:32:40.000000000 +0200 @@ -242,7 +242,7 @@ */ private function splitProjectList($list) { - return array_unique(preg_split('/[,\s]+/', $list) ?: []); + return array_filter(array_unique(preg_split('/[,\s]+/', $list) ?: [])); } /** ++++++ platformsh-cli-vendor.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/autoload.php new/vendor/autoload.php --- old/vendor/autoload.php 2018-10-05 18:34:22.517671139 +0200 +++ new/vendor/autoload.php 2018-10-12 21:17:55.123509060 +0200 @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit0dff82c60c70d8471aa3cff70381581f::getLoader(); +return ComposerAutoloaderInitc45f5bdff98953bc26396bfd59ba098e::getLoader(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/composer/autoload_real.php new/vendor/composer/autoload_real.php --- old/vendor/composer/autoload_real.php 2018-10-05 18:34:22.517671139 +0200 +++ new/vendor/composer/autoload_real.php 2018-10-12 21:17:55.123509060 +0200 @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit0dff82c60c70d8471aa3cff70381581f +class ComposerAutoloaderInitc45f5bdff98953bc26396bfd59ba098e { private static $loader; @@ -19,15 +19,15 @@ return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit0dff82c60c70d8471aa3cff70381581f', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInitc45f5bdff98953bc26396bfd59ba098e', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit0dff82c60c70d8471aa3cff70381581f', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInitc45f5bdff98953bc26396bfd59ba098e', '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\ComposerStaticInit0dff82c60c70d8471aa3cff70381581f::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInitc45f5bdff98953bc26396bfd59ba098e::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -48,19 +48,19 @@ $loader->register(true); if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit0dff82c60c70d8471aa3cff70381581f::$files; + $includeFiles = Composer\Autoload\ComposerStaticInitc45f5bdff98953bc26396bfd59ba098e::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire0dff82c60c70d8471aa3cff70381581f($fileIdentifier, $file); + composerRequirec45f5bdff98953bc26396bfd59ba098e($fileIdentifier, $file); } return $loader; } } -function composerRequire0dff82c60c70d8471aa3cff70381581f($fileIdentifier, $file) +function composerRequirec45f5bdff98953bc26396bfd59ba098e($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { require $file; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/composer/autoload_static.php new/vendor/composer/autoload_static.php --- old/vendor/composer/autoload_static.php 2018-10-05 18:34:22.517671139 +0200 +++ new/vendor/composer/autoload_static.php 2018-10-12 21:17:55.123509060 +0200 @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit0dff82c60c70d8471aa3cff70381581f +class ComposerStaticInitc45f5bdff98953bc26396bfd59ba098e { public static $files = array ( '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', @@ -195,9 +195,9 @@ public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit0dff82c60c70d8471aa3cff70381581f::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit0dff82c60c70d8471aa3cff70381581f::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit0dff82c60c70d8471aa3cff70381581f::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInitc45f5bdff98953bc26396bfd59ba098e::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitc45f5bdff98953bc26396bfd59ba098e::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInitc45f5bdff98953bc26396bfd59ba098e::$classMap; }, null, ClassLoader::class); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/composer/installed.json new/vendor/composer/installed.json --- old/vendor/composer/installed.json 2018-10-05 18:34:22.093667157 +0200 +++ new/vendor/composer/installed.json 2018-10-12 21:17:54.571504046 +0200 @@ -730,17 +730,17 @@ }, { "name": "platformsh/client", - "version": "v0.19.2", - "version_normalized": "0.19.2.0", + "version": "v0.20.2", + "version_normalized": "0.20.2.0", "source": { "type": "git", "url": "https://github.com/platformsh/platformsh-client-php.git", - "reference": "678f057067174c3b2c6716168bc86060a3f10097" + "reference": "220947685624464455d8ae3022c418ae832ce85e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/678f05...", - "reference": "678f057067174c3b2c6716168bc86060a3f10097", + "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/220947...", + "reference": "220947685624464455d8ae3022c418ae832ce85e", "shasum": "" }, "require": { @@ -753,7 +753,7 @@ "require-dev": { "phpunit/phpunit": "~4.5" }, - "time": "2018-08-23T09:40:35+00:00", + "time": "2018-10-12T16:21:31+00:00", "type": "library", "extra": { "patches": { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/src/Connection/Connector.php new/vendor/platformsh/client/src/Connection/Connector.php --- old/vendor/platformsh/client/src/Connection/Connector.php 2018-08-23 11:40:35.000000000 +0200 +++ new/vendor/platformsh/client/src/Connection/Connector.php 2018-10-12 18:21:31.000000000 +0200 @@ -9,7 +9,9 @@ use GuzzleHttp\ClientInterface; use GuzzleHttp\Collection; use GuzzleHttp\Event\CompleteEvent; +use GuzzleHttp\Exception\BadResponseException; use GuzzleHttp\Subscriber\Cache\CacheSubscriber; +use GuzzleHttp\Url; use Platformsh\Client\OAuth2\ApiToken; use Platformsh\Client\OAuth2\PasswordCredentialsWithTfa; use Platformsh\Client\Session\Session; @@ -64,6 +66,7 @@ 'verify' => true, 'user_agent' => "Platform.sh-Client-PHP/$version (+$url)", 'cache' => false, + 'revoke_url' => '/oauth2/revoke', 'token_url' => '/oauth2/token', 'proxy' => null, 'api_token' => null, @@ -90,8 +93,40 @@ public function logOut() { $this->loggedOut = true; - $this->session->clear(); - $this->session->save(); + + try { + $this->revokeTokens(); + } catch (BadResponseException $e) { + // Retry the request once. + if ($e->getResponse() && $e->getResponse()->getStatusCode() < 500) { + $this->revokeTokens(); + } + } finally { + $this->session->clear(); + $this->session->save(); + } + } + + /** + * Revokes the access and refresh tokens saved in the session. + */ + private function revokeTokens() + { + $revocations = array_filter([ + 'refresh_token' => $this->session->get('refreshToken'), + 'access_token' => $this->session->get('accessToken'), + ]); + $url = Url::fromString($this->config['accounts']) + ->combine($this->config['revoke_url']) + ->__toString(); + foreach ($revocations as $type => $token) { + $this->getClient()->post($url, [ + 'body' => [ + 'token' => $token, + 'token_type_hint' => $type, + ], + ]); + } } public function __destruct() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/src/DataStructure/ReadOnlyStructureTrait.php new/vendor/platformsh/client/src/DataStructure/ReadOnlyStructureTrait.php --- old/vendor/platformsh/client/src/DataStructure/ReadOnlyStructureTrait.php 2018-08-23 11:40:35.000000000 +0200 +++ new/vendor/platformsh/client/src/DataStructure/ReadOnlyStructureTrait.php 2018-10-12 18:21:31.000000000 +0200 @@ -2,15 +2,33 @@ namespace Platformsh\Client\DataStructure; +/** + * Apply this trait to a class to get read-only properties, with magic getters. + * + * The properties can be documented (with their expected types) in the class's + * docblock, via "@property-read" annotations. Types are not enforced. + */ trait ReadOnlyStructureTrait { private $data = []; + /** + * Private constructor. Instantiate this object using self::fromData(). + * + * @param array $data + */ private function __construct(array $data) { $this->data = $data; } + /** + * Magic getter. + * + * @param string $name + * + * @return mixed + */ public function __get($name) { $this->checkExists($name); @@ -18,12 +36,28 @@ return $this->data[$name]; } + /** + * Magic setter. + * + * @param string $name + * @param mixed $value + * + * @throws \InvalidArgumentException if the property is not found + * @throws \BadMethodCallException if the property is found + */ public function __set($name, $value) { $this->checkExists($name); throw new \BadMethodCallException('Property not writable: ' . $name); } + /** + * Check if a property exists. + * + * @param string $property + * + * @throws \InvalidArgumentException if the property is not found + */ private function checkExists($property) { if (!array_key_exists($property, $this->data)) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/src/Model/Backup.php new/vendor/platformsh/client/src/Model/Backup.php --- old/vendor/platformsh/client/src/Model/Backup.php 1970-01-01 01:00:00.000000000 +0100 +++ new/vendor/platformsh/client/src/Model/Backup.php 2018-10-12 18:21:31.000000000 +0200 @@ -0,0 +1,22 @@ +policies = $policies; + $this->manualCount = $manualCount; + } + + /** + * Instantiates a backup configuration object from config data. + * + * @param array $data + * + * @return static + */ + public static function fromData(array $data) + { + $policies = []; + foreach (isset($data['schedule']) ? $data['schedule'] : [] as $policyData) { + $policies[] = new Policy($policyData['interval'], $policyData['count']); + } + + return new static($policies, isset($data['manual_count']) ? $data['manual_count'] : 1); + } + + /** + * Get the configured number of manual backups to keep. + * + * @return int + */ + public function getManualCount() + { + return $this->manualCount; + } + + /** + * Get a list of backup retention policies. + * + * @return \Platformsh\Client\Model\Backups\Policy[] + */ + public function getPolicies() + { + return $this->policies; + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/src/Model/Backups/Policy.php new/vendor/platformsh/client/src/Model/Backups/Policy.php --- old/vendor/platformsh/client/src/Model/Backups/Policy.php 1970-01-01 01:00:00.000000000 +0100 +++ new/vendor/platformsh/client/src/Model/Backups/Policy.php 2018-10-12 18:21:31.000000000 +0200 @@ -0,0 +1,55 @@ +interval = $interval; + $this->count = $count; + } + + /** + * Get the configured interval. + * + * @return string|int + */ + public function getInterval() + { + return $this->interval; + } + + /** + * Get the configured number of backups to keep. + * + * @return int + */ + public function getCount() + { + return $this->count; + } + + /** + * Get the configured interval, in seconds. + * + * @return int + */ + public function getIntervalAsSeconds() + { + return (new Duration($this->interval))->getSeconds(); + } +} 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 2018-08-23 11:40:35.000000000 +0200 +++ new/vendor/platformsh/client/src/Model/Environment.php 2018-10-12 18:21:31.000000000 +0200 @@ -5,8 +5,11 @@ use Cocur\Slugify\Slugify; use Platformsh\Client\Exception\EnvironmentStateException; use Platformsh\Client\Exception\OperationUnavailableException; +use Platformsh\Client\Model\Backups\BackupConfig; +use Platformsh\Client\Model\Backups\Policy; use Platformsh\Client\Model\Deployment\EnvironmentDeployment; use Platformsh\Client\Model\Git\Commit; +use Platformsh\Client\Model\Type\Duration; /** * A Platform.sh environment. @@ -48,6 +51,9 @@ * 'is_enabled' (bool), 'addresses' (array), and 'basic_auth' (array). * @property-read bool $is_main * Whether the environment is the main, production one. + * @property-read array $backups + * The backup configuration. It's recommended to use getBackupConfig() instead + * of using this array directly. */ class Environment extends Resource { @@ -552,4 +558,53 @@ { return $this->runLongOperation('redeploy'); } + + /** + * Get a list of environment backups. + * + * @param int $limit + * Limit the number of backups to return. + * + * @return Backup[] + */ + public function getBackups($limit = 0) + { + return Backup::getCollection($this->getUri() . '/backups', $limit, [], $this->client); + } + + /** + * Get the scheduled backup configuration for this environment. + * + * @return BackupConfig + */ + public function getBackupConfig() + { + // In legacy versions the 'backups' key might not exist on the + // environment. + return BackupConfig::fromData($this->getProperty('backups', false) ?: []); + } + + /** + * Add a scheduled backup policy. + * + * @param \Platformsh\Client\Model\Backups\Policy $policy + * + * @return \Platformsh\Client\Model\Result + */ + public function addBackupPolicy(Policy $policy) + { + $backups = isset($this->data['backups']) ? $this->data['backups'] : []; + $backups['schedule'][] = [ + 'interval' => $policy->getInterval(), + 'count' => $policy->getCount(), + ]; + $backups += ['manual_count' => 3]; + + // Sort the backup schedule, by interval. + usort($backups['schedule'], function (array $a, array $b) { + return (new Duration($a['interval']))->compare(new Duration($b['interval'])); + }); + + return $this->update(['backups' => $backups]); + } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/src/Model/Region.php new/vendor/platformsh/client/src/Model/Region.php --- old/vendor/platformsh/client/src/Model/Region.php 2018-08-23 11:40:35.000000000 +0200 +++ new/vendor/platformsh/client/src/Model/Region.php 2018-10-12 18:21:31.000000000 +0200 @@ -40,13 +40,13 @@ /** * @inheritdoc */ - public function operationAvailable($op, $refreshDuringCheck = false) + protected function isOperationAvailable($op) { if ($op === 'edit') { return true; } - return parent::operationAvailable($op, $refreshDuringCheck); + return parent::isOperationAvailable($op); } /** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/src/Model/Resource.php new/vendor/platformsh/client/src/Model/Resource.php --- old/vendor/platformsh/client/src/Model/Resource.php 2018-08-23 11:40:35.000000000 +0200 +++ new/vendor/platformsh/client/src/Model/Resource.php 2018-10-12 18:21:31.000000000 +0200 @@ -556,7 +556,7 @@ * * @return bool */ - private function isOperationAvailable($op) + protected function isOperationAvailable($op) { return isset($this->data['_links']["#$op"]['href']); } 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 2018-08-23 11:40:35.000000000 +0200 +++ new/vendor/platformsh/client/src/Model/Subscription.php 2018-10-12 18:21:31.000000000 +0200 @@ -30,7 +30,7 @@ const STATUS_ACTIVE = 'active'; const STATUS_REQUESTED = 'requested'; const STATUS_PROVISIONING = 'provisioning'; - const STATUS_FAILED = 'provisioning Failure'; + const STATUS_FAILED = 'provisioning failure'; const STATUS_SUSPENDED = 'suspended'; const STATUS_DELETED = 'deleted'; @@ -115,7 +115,8 @@ * * This could be one of Subscription::STATUS_ACTIVE, * Subscription::STATUS_REQUESTED, Subscription::STATUS_PROVISIONING, - * Subscription::STATUS_SUSPENDED, or Subscription::STATUS_DELETED. + * Subscription::STATUS_FAILED, Subscription::STATUS_SUSPENDED, + * or Subscription::STATUS_DELETED. * * @return string */ @@ -171,13 +172,13 @@ /** * @inheritdoc */ - public function operationAvailable($op, $refreshDuringCheck = false) + protected function isOperationAvailable($op) { if ($op === 'edit') { return true; } - return parent::operationAvailable($op, $refreshDuringCheck); + return parent::isOperationAvailable($op); } /** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/src/Model/Type/Duration.php new/vendor/platformsh/client/src/Model/Type/Duration.php --- old/vendor/platformsh/client/src/Model/Type/Duration.php 1970-01-01 01:00:00.000000000 +0100 +++ new/vendor/platformsh/client/src/Model/Type/Duration.php 2018-10-12 18:21:31.000000000 +0200 @@ -0,0 +1,114 @@ +seconds = self::stringToSeconds((string) $duration); + } + + /** + * Returns the duration as a number of seconds. + * + * @return int|float + */ + public function getSeconds() + { + return $this->seconds; + } + + /** + * Returns the duration as a string. + * + * @return string + */ + public function __toString() + { + foreach (array_reverse(self::suffixes()) as $suffix => $unit) { + if ($this->seconds % $unit === 0) { + return sprintf('%s%s', $this->seconds / $unit, $suffix); + } + } + + return (string) $this->seconds; + } + + /** + * List valid date/time suffixes. + * + * @todo define in the static variable declaration in PHP 5.6+, or in a private constant in PHP 7.1+ + * + * @return array An array whose keys are suffixes and whose values are + * durations in seconds. + */ + public static function suffixes() + { + if (isset(self::$suffixes)) { + return self::$suffixes; + } + + return self::$suffixes = [ + 's' => 1, + 'm' => 60, + 'h' => 60 * 60, + 'd' => 24 * 60 * 60, + 'w' => 7 * 24 * 60 * 60, + 'M' => 30 * 24 * 60 * 60, + 'y' => 365 * 24 * 60 * 60, + ]; + } + + /** + * Converts a duration string to seconds. + * + * @param string $duration + * + * @return int|float + */ + private static function stringToSeconds($duration) + { + if (isset(self::suffixes()[substr($duration, -1)])) { + $amount = substr($duration, 0, strlen($duration) - 1); + $unit = self::suffixes()[substr($duration, -1)]; + } else { + $unit = 1; + $amount = $duration; + } + + if (!is_numeric($amount)) { + throw new \InvalidArgumentException('Invalid duration: ' . $duration); + } + + return $unit * $amount; + } + + /** + * Compares the current Duration object to another one. + * + * @param \Platformsh\Client\Model\Type\Duration $other + * + * @return int + * 0 if the durations are equal, 1 if the current duration is greater, + * and -1 if the $other duration is greater. + */ + public function compare(Duration $other) + { + $a = $this->getSeconds(); + $b = $other->getSeconds(); + + // In a future version (PHP 7+) this can be replaced with $a <=> $b. + return $a > $b ? 1 : ($b > $a ? -1 : 0); + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/tests/Model/Type/DurationTest.php new/vendor/platformsh/client/tests/Model/Type/DurationTest.php --- old/vendor/platformsh/client/tests/Model/Type/DurationTest.php 1970-01-01 01:00:00.000000000 +0100 +++ new/vendor/platformsh/client/tests/Model/Type/DurationTest.php 2018-10-12 18:21:31.000000000 +0200 @@ -0,0 +1,74 @@ + 60, + '60' => 60, + '2m' => 120, + 120 => 120, + '10m' => 600, + '20m' => 1200, + '1h' => 3600, + '3600.5' => 3600.5, + '120m' => 7200, + '2h' => 7200, + '10d' => 864000, + '1M' => 2592000, + '10w' => 6048000, + '0.5y' => 15768000, + '1y' => 31536000, + ]; + $actual = []; + foreach (array_keys($expected) as $string) { + $actual[$string] = (new Duration($string))->getSeconds(); + } + $this->assertEquals($expected, $actual); + } + + public function testSecondsToString() + { + $expected = [ + 1 => '1s', + '1.5' => '1.5s', + 60 => '1m', + 61 => '61s', + 120 => '2m', + 1800 => '30m', + 3600 => '1h', + 36000 => '10h', + 86400 => '1d', + ]; + $actual = []; + foreach (array_keys($expected) as $seconds) { + $actual[$seconds] = (new Duration($seconds))->__toString(); + } + $this->assertEquals($expected, $actual); + } + + public function testCompare() + { + $expected = [ + ['1s', '1m', -1], + ['1h', '1m', 1], + ['1h', '60m', 0], + ['1d', '86400s', 0], + ]; + $actual = []; + foreach ($expected as $key => $expectation) { + list($a, $b) = $expectation; + $actual[$key] = [ + $a, $b, (new Duration($a))->compare(new Duration($b)) + ]; + } + $this->assertEquals($expected, $actual); + } + +}