Hello community, here is the log from the commit of package platformsh-cli for openSUSE:Factory checked in at 2019-08-19 21:38:56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/platformsh-cli (Old) and /work/SRC/openSUSE:Factory/.platformsh-cli.new.22127 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "platformsh-cli" Mon Aug 19 21:38:56 2019 rev:78 rq:724191 version:3.46.0 Changes: -------- --- /work/SRC/openSUSE:Factory/platformsh-cli/platformsh-cli.changes 2019-07-28 10:22:34.784568003 +0200 +++ /work/SRC/openSUSE:Factory/.platformsh-cli.new.22127/platformsh-cli.changes 2019-08-19 21:39:02.136322428 +0200 @@ -1,0 +2,24 @@ +Fri Aug 16 21:35:00 UTC 2019 - [email protected] + +- Update to version 3.46.0: + * Release v3.46.0 + * Add bitbucket_server integration support (#833) + * Test building and installing on Travis (#834) + * Tiny fix to account for other shell types before detecting ZSH + * self:install: use --shell-type when finding a config file + * Document new installer options + * Add --shell-type option to installer + * Add --manifest option to installer + * Provide installer on dev builds + * Add color to self:install command + * Installer output improvements + * Installer: require curl, openssl and pcre + * Add --charset option to the db:dump command (#832) + * Rsync cleanup [skip changelog] + * Fix findTargetParent() argument in push command + * Add --branch option to push command (#827) + * Rename "Capacity" to "% Used" in mount:size command (#828) + * Installer: remove unnecessary mbstring check + * Enable compression in project:curl command + +------------------------------------------------------------------- Old: ---- platformsh-cli-3.45.0.tar.xz New: ---- platformsh-cli-3.46.0.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ platformsh-cli.spec ++++++ --- /var/tmp/diff_new_pack.LGPq6j/_old 2019-08-19 21:39:03.184321769 +0200 +++ /var/tmp/diff_new_pack.LGPq6j/_new 2019-08-19 21:39:03.184321769 +0200 @@ -17,7 +17,7 @@ Name: platformsh-cli -Version: 3.45.0 +Version: 3.46.0 Release: 0 Summary: Tool for managing Platform.sh services from the command line # See licenses.txt for dependency licenses. ++++++ _service ++++++ --- /var/tmp/diff_new_pack.LGPq6j/_old 2019-08-19 21:39:03.208321754 +0200 +++ /var/tmp/diff_new_pack.LGPq6j/_new 2019-08-19 21:39:03.208321754 +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.45.0</param> + <param name="revision">refs/tags/v3.46.0</param> <param name="url">git://github.com/platformsh/platformsh-cli.git</param> <param name="scm">git</param> <param name="changesgenerate">enable</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.LGPq6j/_old 2019-08-19 21:39:03.220321747 +0200 +++ /var/tmp/diff_new_pack.LGPq6j/_new 2019-08-19 21:39:03.220321747 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">git://github.com/platformsh/platformsh-cli.git</param> - <param name="changesrevision">13bfd296b0a6d6fed21b5ca285cd387d149e6df5</param> + <param name="changesrevision">92b7081944733f136f28e0340b6cbd2761aa5e8e</param> </service> </servicedata> ++++++ licenses.txt ++++++ --- /var/tmp/diff_new_pack.LGPq6j/_old 2019-08-19 21:39:03.248321729 +0200 +++ /var/tmp/diff_new_pack.LGPq6j/_new 2019-08-19 21:39:03.252321726 +0200 @@ -16,7 +16,7 @@ padraic/phar-updater v1.0.6 BSD-3-Clause paragonie/random_compat v2.0.18 MIT pjcdawkins/guzzle-oauth2-plugin v2.2.0 MIT -platformsh/client v0.28.1 MIT +platformsh/client v0.29.0 MIT platformsh/console-form v0.0.23 MIT psr/container 1.0.0 MIT psr/log 1.1.0 MIT ++++++ platformsh-cli-3.45.0.tar.xz -> platformsh-cli-3.46.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/.platform.app.yaml new/platformsh-cli-3.46.0/.platform.app.yaml --- old/platformsh-cli-3.45.0/.platform.app.yaml 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/.platform.app.yaml 2019-08-16 18:40:08.000000000 +0200 @@ -20,6 +20,18 @@ EOF mv dist/dev-build-index.php web/index.php + mv dist/installer.php web/installer + export sha256="$(sha256sum web/platform.phar | cut -f1 -d' ')" + cat <<EOF > web/manifest.json + [ + { + "version": "$version", + "sha256": "$sha256", + "name": "platform.phar", + "url": "platform.phar" + } + ] + EOF web: locations: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/.travis.yml new/platformsh-cli-3.46.0/.travis.yml --- old/platformsh-cli-3.45.0/.travis.yml 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/.travis.yml 2019-08-16 18:40:08.000000000 +0200 @@ -28,6 +28,9 @@ env: TEST_SCRIPT=scripts/test/unit.sh - php: 7.3 + env: TEST_SCRIPT=scripts/test/build-and-install.sh + + - php: 7.3 env: TEST_SCRIPT=scripts/test/slow.sh allow_failures: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/composer.json new/platformsh-cli-3.46.0/composer.json --- old/platformsh-cli-3.45.0/composer.json 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/composer.json 2019-08-16 18:40:08.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.28.1 <2.0", + "platformsh/client": ">=0.29.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.45.0/composer.lock new/platformsh-cli-3.46.0/composer.lock --- old/platformsh-cli-3.45.0/composer.lock 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/composer.lock 2019-08-16 18:40:08.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": "3b15e017599176f45d3e1b9094dc9a81", + "content-hash": "f14ac5a3055dd7a7e98e56f409a266ab", "packages": [ { "name": "cocur/slugify", @@ -663,16 +663,16 @@ }, { "name": "platformsh/client", - "version": "v0.28.1", + "version": "v0.29.0", "source": { "type": "git", "url": "https://github.com/platformsh/platformsh-client-php.git", - "reference": "01bbf0289adad03102179412f710fdc7527fab60" + "reference": "d6362961c9c956cbc4115351c29fdf5ef612c9f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/01bbf0289adad03102179412f710fdc7527fab60", - "reference": "01bbf0289adad03102179412f710fdc7527fab60", + "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/d6362961c9c956cbc4115351c29fdf5ef612c9f6", + "reference": "d6362961c9c956cbc4115351c29fdf5ef612c9f6", "shasum": "" }, "require": { @@ -702,7 +702,7 @@ } ], "description": "Platform.sh API client", - "time": "2019-07-25T12:06:41+00:00" + "time": "2019-08-08T12:03:20+00:00" }, { "name": "platformsh/console-form", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/dist/dev-build-index.php new/platformsh-cli-3.46.0/dist/dev-build-index.php --- old/platformsh-cli-3.45.0/dist/dev-build-index.php 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/dist/dev-build-index.php 2019-08-16 18:40:08.000000000 +0200 @@ -37,6 +37,13 @@ $sourceLinkSpecific = false; } +$baseUrl = 'https://' . $_SERVER['HTTP_HOST']; +$installScript = sprintf( + 'curl -sfS %s | php -- --dev --manifest %s', + escapeshellarg($baseUrl . '/installer'), + escapeshellarg($baseUrl . '/manifest.json'), +); + ?> <!DOCTYPE html> <html lang="en"> @@ -124,6 +131,12 @@ Source: <a href="<?= htmlspecialchars($sourceLinkSpecific) ?>"><?= htmlspecialchars($sourceLinkSpecific) ?></a> </p> <?php endif; ?> + <?php if ($installScript): ?> + <p> + Install with:<br/> + <code><?= htmlspecialchars($installScript) ?></code> + </p> + <?php endif; ?> </body> </html> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/dist/installer.php new/platformsh-cli-3.46.0/dist/installer.php --- old/platformsh-cli-3.45.0/dist/installer.php 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/dist/installer.php 2019-08-16 18:40:08.000000000 +0200 @@ -17,8 +17,10 @@ * --alpha, --beta, --dev Install an unstable version. * --no-ansi Disable ANSI (no colors). * --ansi Enable ANSI (e.g. for colors). - * --min Min version to install. - * --max Max version to install (not recommended). + * --min VERSION Min version to install. + * --max VERSION Max version to install (not recommended). + * --manifest URL A manifest JSON file URL (use for testing). + * --shell-type TYPE The shell type for autocompletion (bash or zsh). * * This file's syntax must support PHP 5.5.9 or higher. * It must not include any other files. @@ -53,18 +55,29 @@ private $argv; public function __construct(array $args = []) { - $this->manifestUrl = getenv('PLATFORMSH_CLI_MANIFEST_URL') ?: 'https://platform.sh/cli/manifest.json'; + $this->argv = !empty($args) ? $args : $GLOBALS['argv']; + + if (getenv('PLATFORMSH_CLI_MANIFEST_URL') !== false) { + $this->manifestUrl = getenv('PLATFORMSH_CLI_MANIFEST_URL'); + } elseif ($manifestOption = $this->getOption('manifest')) { + $this->manifestUrl = $manifestOption; + } else { + $this->manifestUrl = 'https://platform.sh/cli/manifest.json'; + } $this->configDir = '.platformsh'; $this->executable = 'platform'; $this->cliName = 'Platform.sh CLI'; $this->pharName = $this->executable . '.phar'; - $this->argv = !empty($args) ? $args : $GLOBALS['argv']; } /** * Runs the install itself. */ public function run() { + error_reporting(E_ALL); + ini_set('log_errors', 0); + ini_set('display_errors', 1); + $this->output($this->cliName . " installer", 'heading'); // Run environment checks. @@ -105,18 +118,18 @@ ); $required_extensions = [ - 'mbstring', + 'curl', 'openssl', 'pcre', ]; foreach ($required_extensions as $extension) { $this->check( 'The "' . $extension . '" PHP extension is installed.', - 'Warning: the "' . $extension . '" PHP extension will be needed.', + 'The "' . $extension . '" PHP extension is required.', function () use ($extension) { return extension_loaded($extension); }, - false + true ); } @@ -175,17 +188,115 @@ // The necessary checks have passed. Start downloading the right version. $this->output(PHP_EOL . 'Download', 'heading'); - $this->output(' Finding the latest version...'); - $manifest = file_get_contents($this->manifestUrl); - if ($manifest === false) { - $this->output(' Failed to download manifest file: ' . $this->manifestUrl, 'error'); - exit(1); + $latest = $this->performTask('Finding the latest version', function () { + return $this->findLatestVersion($this->manifestUrl); + }); + + $this->performTask('Downloading version ' . $latest['version'], function () use ($latest) { + $url = $latest['url']; + + // A relative download URL is treated as relative to the manifest URL. + if (strpos($url, '//') === false && strpos($this->manifestUrl, '//') !== false) { + $removePath = parse_url($this->manifestUrl, PHP_URL_PATH); + $url = str_replace($removePath, '/' . ltrim($url, '/'), $this->manifestUrl); + } + + if (!file_put_contents($this->pharName, file_get_contents($url))) { + return TaskResult::failure('The download failed'); + } + + return TaskResult::success(); + }); + + $pharPath = realpath($this->pharName) ?: $this->pharName; + + $this->performTask('Checking file integrity', function () use ($latest, $pharPath) { + if ($latest['sha256'] !== hash_file('sha256', $pharPath)) { + unlink($pharPath); + + return TaskResult::failure('The download was incomplete, or the file is corrupted'); + } + + return TaskResult::success(); + }); + + $this->performTask('Checking that the file is a valid Phar', function () use ($pharPath) { + try { + new \Phar($pharPath); + } catch (\Exception $e) { + return TaskResult::failure( + 'The file is not a valid Phar archive' . "\n" . $e->getMessage() + ); + } + + return TaskResult::success(); + }); + + $this->output(PHP_EOL . 'Install', 'heading'); + + $this->performTask('Making the Phar executable', function () use ($pharPath) { + if (!chmod($pharPath, 0755)) { + return TaskResult::failure('Failed to make the Phar executable'); + } + + return TaskResult::success(); + }); + + if ($homeDir = $this->getHomeDirectory()) { + $pharPath = $this->performTask('Moving the Phar to your home directory', function () use ($pharPath, $homeDir) { + $binDir = $homeDir . '/' . $this->configDir . '/bin'; + if (!is_dir($binDir) && !mkdir($binDir, 0700, true)) { + return TaskResult::failure('Failed to create directory: ' . $binDir); + } + + $destination = $binDir . '/' . $this->executable; + if (!rename($pharPath, $destination)) { + return TaskResult::failure('Failed to move the Phar to: ' . $destination); + } + + return TaskResult::success($destination); + }); + $this->output(' Executable location: ' . $pharPath); } + $this->output(PHP_EOL . 'Running self:install command...' . PHP_EOL); + $result = $this->selfInstall($pharPath); + + exit($result); + } + + /** + * Runs the 'self:install' command. + * + * @param string $pharPath The path of the Phar executable. + * + * @return int The command's exit code. + */ + private function selfInstall($pharPath) { + $command = 'php ' . escapeshellarg($pharPath) . ' self:install --yes'; + if ($shellType = $this->getOption('shell-type')) { + $command .= ' --shell-type ' . escapeshellarg($shellType); + } + putenv('CLICOLOR_FORCE=' . ($this->terminalSupportsAnsi() ? '1' : '0')); + + return $this->runCommand($command); + } + + /** + * Finds the latest version to download from the manifest. + * + * @param string $manifestUrl + * + * @return TaskResult + */ + private function findLatestVersion($manifestUrl) { + $manifest = file_get_contents($manifestUrl); + if ($manifest === false) { + return TaskResult::failure('Failed to download manifest file: ' . $manifestUrl); + } $manifest = json_decode($manifest, true); if ($manifest === null) { - $this->output(' Failed to decode manifest file: ' . $this->manifestUrl, 'error'); - exit(1); + return TaskResult::failure('Failed to decode manifest file: ' . $manifestUrl); } $allowedSuffixes = ['stable']; @@ -198,67 +309,38 @@ $resolver = new VersionResolver(); $versions = $resolver->findInstallableVersions($manifest, $phpVersion, $allowedSuffixes); if (empty($versions)) { - $this->output(' ' . $resolver->explainNoInstallableVersions($manifest, $phpVersion, $allowedSuffixes), 'error'); - exit(1); + return TaskResult::failure($resolver->explainNoInstallableVersions($manifest, $phpVersion, $allowedSuffixes)); } try { $latest = $resolver->findLatestVersion($versions, $this->getOption('min'), $this->getOption('max')); } catch (\Exception $e) { - $this->output(' ' . $e->getMessage(), 'error'); - exit(1); - } - - $this->output(" Downloading version {$latest['version']}..."); - if (!file_put_contents($this->pharName, file_get_contents($latest['url']))) { - $this->output(' The download failed.', 'error'); - } - - $pharPath = realpath($this->pharName) ?: $this->pharName; - - $this->output(' Checking file integrity...'); - if ($latest['sha256'] !== hash_file('sha256', $pharPath)) { - unlink($pharPath); - $this->output(' The download was corrupted.', 'error'); - exit(1); + return TaskResult::failure($e->getMessage()); } - $this->output(' Checking that the file is a valid Phar (PHP Archive)...'); - - try { - new \Phar($pharPath); - } catch (\Exception $e) { - $this->output(' The file is not a valid Phar archive.', 'error'); - $this->output(' ' . $e->getMessage(), 'error'); - exit(1); - } - - $this->output(PHP_EOL . 'Install', 'heading'); - - $this->output(' Making the Phar executable...'); - if (!chmod($pharPath, 0755)) { - $this->output(' Failed to make the Phar executable: ' . $pharPath, 'warning'); - } + return TaskResult::success($latest); + } - if ($homeDir = $this->getHomeDirectory()) { - $this->output(' Moving the Phar to your home directory...'); - $binDir = $homeDir . '/' . $this->configDir . '/bin'; - if (!is_dir($binDir) && !mkdir($binDir, 0700, true)) { - $this->output(' Failed to create directory: ' . $binDir, 'error'); - } - elseif (!rename($pharPath, $binDir . '/' . $this->executable)) { - $this->output(' Failed to move the Phar to: ' . $binDir . '/' . $this->executable, 'error'); - } - else { - $pharPath = $binDir . '/' . $this->executable; - $this->output(' Successfully moved the Phar to: ' . $pharPath); + /** + * @param string $summaryText Description of the task. + * @param callable $task A function that returns a TaskResult. + * @param string $indent Whether to indent the summary & errors. + * + * @return mixed The result of the task, if any. + */ + private function performTask($summaryText, $task, $indent = ' ') { + $this->output($indent . $summaryText . '...', null, false); + /** @var TaskResult $result */ + $result = $task(); + if (!$result->isSuccess()) { + $this->output(''); + if ($message = $result->getMessage()) { + $this->output('Error: ' . $message, 'error'); } + exit(1); } + $this->output(' done', 'success'); - $this->output(PHP_EOL . ' Running self:install command...' . PHP_EOL); - putenv('CLICOLOR_FORCE=' . ($this->terminalSupportsAnsi() ? '1' : '0')); - $result = $this->runCommand('php ' . $pharPath . ' self:install --yes'); - - exit($result); + return $result->getData(); } /** @@ -302,12 +384,12 @@ if ($condition()) { $this->output(' [*] ' . $success, 'success'); } + elseif (!$exit) { + $this->output(' [!] ' . $failure, 'warning'); + } else { - $this->output(' [ ] ' . $failure, $exit ? 'error' : 'warning'); - - if ($exit) { - exit(1); - } + $this->output(' [X] ' . $failure, 'error'); + exit(1); } } @@ -430,6 +512,38 @@ } } +class TaskResult { + private $success = false; + private $message = ''; + private $data; + + private function __construct($success, $message = '', $data = null) { + $this->success = $success; + $this->message = $message; + $this->data = $data; + } + + public static function success($data = null) { + return new self(true, '', $data); + } + + public static function failure($errorMessage) { + return new self(false, $errorMessage); + } + + public function isSuccess() { + return $this->success; + } + + public function getMessage() { + return $this->message; + } + + public function getData() { + return $this->data; + } +} + class VersionResolver { /** * Finds the latest installable version in the manifest. @@ -449,7 +563,7 @@ } if ($dashPos = strpos($version['version'], '-')) { $suffix = substr($version['version'], $dashPos + 1); - if (!in_array($suffix, $allowedSuffixes)) { + if (!in_array($suffix, $allowedSuffixes) && !in_array('dev', $allowedSuffixes)) { continue; } } @@ -478,7 +592,7 @@ } if ($dashPos = strpos($version['version'], '-')) { $suffix = substr($version['version'], $dashPos + 1); - if (!in_array($suffix, $allowedSuffixes)) { + if (!in_array($suffix, $allowedSuffixes) && !in_array('dev', $allowedSuffixes)) { $reasons[] = sprintf('Version %s has the suffix -%s, not allowed', $name, $suffix); continue; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/dist/manifest.json new/platformsh-cli-3.46.0/dist/manifest.json --- old/platformsh-cli-3.45.0/dist/manifest.json 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/dist/manifest.json 2019-08-16 18:40:08.000000000 +0200 @@ -17,10 +17,10 @@ }, { "name": "platform.phar", - "sha1": "d325f44a66e8187bf27fcb5d60f6565d0d9aee5c", - "sha256": "5056bf2b35968c157d9f93b667fe621b3339e0531c0fb54be63b3ef53d6e0756", - "url": "https://github.com/platformsh/platformsh-cli/releases/download/v3.45.0/platform.phar", - "version": "3.45.0", + "sha1": "ce43c8117ddd3f7cd54a763e7cf2d642d68386a7", + "sha256": "bd5b2f68f68e469d57c19ed036e082fd131fe69d17e8e716979ac1a2bafb26ca", + "url": "https://github.com/platformsh/platformsh-cli/releases/download/v3.46.0/platform.phar", + "version": "3.46.0", "php": { "min": "5.5.9" }, @@ -213,6 +213,11 @@ "notes": "New features:\n\n* Add --all (-a) option to mount:download command. This lets you download files\n from all of an application's mounts.\n* Enable gzip encoding in all API requests, if the zlib PHP extension is\n available. This should result in a performance improvement, particularly for\n slow connections or API responses containing a lot of data (e.g. the\n activity:list or environment:list commands).\n\nOther changes:\n\n* In mount:upload, convert OS X filename characters using rsync's `--iconv`.\n* Small bug fix for commit and repo commands: do not fetch an empty commit\n hash (after stripping commit parents notation).\n* Installer: fix check for git on Windows.", "show from": "3.44.0", "hide from": "3.45.0" + }, + { + "notes": "New features:\n\n* Add --charset option to the db:dump command.\n Specifying the character set is recommended for any database dump.\n If your application database is in MySQL's utf8mb4, for example, use:\n platform db:dump --charset utf8mb4\n* Add --branch option to the 'push' command.\n This allows a new environment to be created as an active branch from a\n specified parent - thus inheriting settings from that parent - rather than\n setting the parent later.\n* Add bitbucket_server integration support.\n\nOther changes:\n\n* Installer:\n - Add --shell-type option to specify 'bash' or 'zsh' to the installer, for\n example:\n curl -sfS https://platform.sh/cli/installer | php -- --shell-type bash\n - Add --manifest option to use a test or development manifest file.\n - Require the curl, openssl and pcre PHP extensions (and stop requiring\n mbstring).\n - The --dev option will now allow any version string.\n* Rename \"Capacity\" to \"% Used\" in mount:size command.\n Also makes column machine names consistent with the db:size command.", + "show from": "3.45.0", + "hide from": "3.46.0" } ] } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/scripts/test/build-and-install.sh new/platformsh-cli-3.46.0/scripts/test/build-and-install.sh --- old/platformsh-cli-3.45.0/scripts/test/build-and-install.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/platformsh-cli-3.46.0/scripts/test/build-and-install.sh 2019-08-16 18:40:08.000000000 +0200 @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Tests building and installing a test version of the CLI. +# This must be run from the repository root. + +export version=test + +# Ensure Composer dependencies including Box. +if [ ! -d vendor ]; then + composer install +fi +if [ ! -d vendor-bin/box/vendor ]; then + composer bin all install +fi + +function cleanup { + rm tmp-platform.phar + rm tmp-manifest.json +} +trap cleanup EXIT + +# Build the CLI. +./bin/platform self:build --no-composer-rebuild --yes --replace-version "$version" --output tmp-platform.phar + +# Create a manifest file. +export sha256="$(shasum -a 256 tmp-platform.phar | cut -f1 -d' ')" +cat <<EOF > tmp-manifest.json +[ + { + "version": "$version", + "sha256": "$sha256", + "name": "platform.phar", + "url": "tmp-platform.phar" + } +] +EOF + +# Run the installer. +cat ./dist/installer.php | php -- --manifest ./tmp-manifest.json --dev diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/scripts/test/installer.sh new/platformsh-cli-3.46.0/scripts/test/installer.sh --- old/platformsh-cli-3.45.0/scripts/test/installer.sh 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/scripts/test/installer.sh 2019-08-16 18:40:08.000000000 +0200 @@ -2,5 +2,4 @@ # Tests the CLI installer. # This must be run from the repository root. -export PLATFORMSH_CLI_MANIFEST_URL=./dist/manifest.json -cat ./dist/installer.php | php +cat ./dist/installer.php | php -- --manifest ./dist/manifest.json diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/src/Command/Db/DbDumpCommand.php new/platformsh-cli-3.46.0/src/Command/Db/DbDumpCommand.php --- old/platformsh-cli-3.45.0/src/Command/Db/DbDumpCommand.php 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/src/Command/Db/DbDumpCommand.php 2019-08-16 18:40:08.000000000 +0200 @@ -26,7 +26,8 @@ ->addOption('stdout', 'o', InputOption::VALUE_NONE, 'Output to STDOUT instead of a file') ->addOption('table', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Table(s) to include') ->addOption('exclude-table', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Table(s) to exclude') - ->addOption('schema-only', null, InputOption::VALUE_NONE, 'Dump only schemas, no data'); + ->addOption('schema-only', null, InputOption::VALUE_NONE, 'Dump only schemas, no data') + ->addOption('charset', null, InputOption::VALUE_REQUIRED, 'The character set encoding for the dump'); $this->addProjectOption()->addEnvironmentOption()->addAppOption(); Relationships::configureInput($this->getDefinition()); Ssh::configureInput($this->getDefinition()); @@ -193,6 +194,9 @@ foreach ($excludedTables as $table) { $dumpCommand .= ' ' . OsUtil::escapePosixShellArg('--exclude-table=' . $table); } + if ($input->getOption('charset') !== null) { + $dumpCommand .= ' ' . OsUtil::escapePosixShellArg('--encoding=' . $input->getOption('charset')); + } if ($output->isVeryVerbose()) { $dumpCommand .= ' --verbose'; } @@ -216,6 +220,9 @@ if (!empty($service->configuration['properties']['max_allowed_packet'])) { $dumpCommand .= ' --max_allowed_packet=' . $service->configuration['properties']['max_allowed_packet'] . 'MB'; } + if ($input->getOption('charset') !== null) { + $dumpCommand .= ' ' . OsUtil::escapePosixShellArg('--default-character-set=' . $input->getOption('charset')); + } if ($output->isVeryVerbose()) { $dumpCommand .= ' --verbose'; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/src/Command/Db/DbSizeCommand.php new/platformsh-cli-3.46.0/src/Command/Db/DbSizeCommand.php --- old/platformsh-cli-3.45.0/src/Command/Db/DbSizeCommand.php 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/src/Command/Db/DbSizeCommand.php 2019-08-16 18:40:08.000000000 +0200 @@ -76,7 +76,7 @@ $machineReadable = $table->formatIsMachineReadable(); $showInBytes = $input->getOption('bytes') || $machineReadable; - $columns = ['max' => 'Allocated disk', 'used' => 'Estimated usage', 'percent_used' => 'Percentage used']; + $columns = ['max' => 'Allocated disk', 'used' => 'Estimated usage', 'percent_used' => '% used']; $values = [ 'max' => $showInBytes ? $allocatedDisk : Helper::formatMemory($allocatedDisk), 'used' => $showInBytes ? $estimatedUsage : Helper::formatMemory($estimatedUsage), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/src/Command/Environment/EnvironmentPushCommand.php new/platformsh-cli-3.46.0/src/Command/Environment/EnvironmentPushCommand.php --- old/platformsh-cli-3.45.0/src/Command/Environment/EnvironmentPushCommand.php 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/src/Command/Environment/EnvironmentPushCommand.php 2019-08-16 18:40:08.000000000 +0200 @@ -5,6 +5,8 @@ use Platformsh\Cli\Exception\RootNotFoundException; use Platformsh\Cli\Service\Ssh; use Platformsh\Client\Exception\EnvironmentStateException; +use Platformsh\Client\Model\Environment; +use Platformsh\Client\Model\Project; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -24,8 +26,9 @@ ->addOption('force', 'f', InputOption::VALUE_NONE, 'Allow non-fast-forward updates') ->addOption('force-with-lease', null, InputOption::VALUE_NONE, 'Allow non-fast-forward updates, if the remote-tracking branch is up to date') ->addOption('set-upstream', 'u', InputOption::VALUE_NONE, 'Set the target environment as the upstream for the source branch') + ->addOption('branch', null, InputOption::VALUE_NONE, 'Create the environment as a branch') ->addOption('activate', null, InputOption::VALUE_NONE, 'Activate the environment after pushing') - ->addOption('parent', null, InputOption::VALUE_REQUIRED, 'Set a new environment parent (only used with --activate)'); + ->addOption('parent', null, InputOption::VALUE_REQUIRED, 'Set a new environment parent (only used with --activate or --branch)'); $this->addWaitOptions(); $this->addProjectOption() ->addEnvironmentOption(); @@ -100,10 +103,20 @@ )); $activate = false; + $createAsBranch = false; $parentId = null; if ($target !== 'master') { + // Determine whether to create the environment as a branch. + if (!$targetEnvironment) { + $createAsBranch = $input->getOption('branch') + || ($input->isInteractive() && $questionHelper->confirm(sprintf( + 'Create <info>%s</info> as an active branch?', + $target + ))); + } + // Determine whether to activate the environment after pushing. - if (!$targetEnvironment || $targetEnvironment->status === 'inactive') { + if ($targetEnvironment && $targetEnvironment->status === 'inactive') { $activate = $input->getOption('activate') || ($input->isInteractive() && $questionHelper->confirm(sprintf( 'Activate <info>%s</info> after pushing?', @@ -112,14 +125,37 @@ } // If activating, determine what the environment's parent should be. - if ($activate) { - $parentId = $input->getOption('parent'); - if (!$parentId) { - $autoCompleterValues = array_keys($this->api()->getEnvironments($project)); - $parentId = $autoCompleterValues === ['master'] - ? 'master' - : $questionHelper->askInput('Parent environment', 'master', $autoCompleterValues); + if ($activate || $createAsBranch) { + $parentId = $input->getOption('parent') ?: $this->findTargetParent($project, $targetEnvironment ?: null); + } + + if ($createAsBranch) { + $parentEnvironment = $this->api()->getEnvironment($parentId, $project); + if (!$parentEnvironment) { + throw new \RuntimeException("Parent environment not found: $parentId"); + } + if (!$parentEnvironment->operationAvailable('branch', true)) { + $this->stdErr->writeln(sprintf( + 'Operation not available: the environment %s cannot be branched.', + $this->api()->getEnvironmentLabel($parentEnvironment, 'error') + )); + + if ($parentEnvironment->is_dirty) { + $this->stdErr->writeln('An activity is currently pending or in progress on the environment.'); + } elseif (!$parentEnvironment->isActive()) { + $this->stdErr->writeln('The environment is not active.'); + } + + return 1; } + + $activity = $parentEnvironment->branch($target, $target); + $this->stdErr->writeln(sprintf( + 'Branched <info>%s</info> from parent %s', + $target, + $this->api()->getEnvironmentLabel($parentEnvironment) + )); + $this->debug(sprintf('Branch activity ID / state: %s / %s', $activity->id, $activity->state)); } } @@ -184,4 +220,29 @@ return 0; } + + /** + * Determines the parent of the target environment (for activate / branch). + * + * @param Project $project + * @param Environment|null $targetEnvironment + * + * @return string The parent environment ID. + */ + private function findTargetParent(Project $project, Environment $targetEnvironment = null) { + $environments = $this->api()->getEnvironments($project); + if ($targetEnvironment && $targetEnvironment->parent) { + $defaultId = $targetEnvironment->parent; + } elseif ($this->hasSelectedEnvironment()) { + $defaultId = $this->getSelectedEnvironment()->id; + } else { + $defaultId = $this->api()->getDefaultEnvironmentId($environments); + } + if (array_keys($environments) === [$defaultId]) { + return $defaultId; + } + $questionHelper = $this->getService('question_helper'); + + return $questionHelper->askInput('Parent environment', $defaultId, array_keys($environments)); + } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/src/Command/Integration/IntegrationAddCommand.php new/platformsh-cli-3.46.0/src/Command/Integration/IntegrationAddCommand.php --- old/platformsh-cli-3.45.0/src/Command/Integration/IntegrationAddCommand.php 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/src/Command/Integration/IntegrationAddCommand.php 2019-08-16 18:40:08.000000000 +0200 @@ -54,8 +54,10 @@ } } + $values = $this->postProcessValues($values); + // Confirm this action for Git source integrations. - if (isset($values['type']) && in_array($values['type'], ['github', 'gitlab', 'bitbucket'])) { + if (isset($values['type']) && in_array($values['type'], ['github', 'gitlab', 'bitbucket', 'bitbucket_server'])) { $this->stdErr->writeln( "<comment>Warning:</comment> adding a '" . $values['type'] . "' integration will automatically synchronize code from the external Git repository." . "\nThis means it can overwrite all the code in your project.\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/src/Command/Integration/IntegrationCommandBase.php new/platformsh-cli-3.46.0/src/Command/Integration/IntegrationCommandBase.php --- old/platformsh-cli-3.45.0/src/Command/Integration/IntegrationCommandBase.php 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/src/Command/Integration/IntegrationCommandBase.php 2019-08-16 18:40:08.000000000 +0200 @@ -35,6 +35,37 @@ } /** + * Performs extra logic on values after the form is complete. + * + * @param array $values + * @param Integration|null $integration + * + * @return array + */ + protected function postProcessValues(array $values, Integration $integration = null) + { + // Find the integration type. + $type = isset($values['type']) + ? $values['type'] + : ($integration !== null ? $integration->type : null); + + // Process Bitbucket Server values. + if ($type === 'bitbucket_server') { + // Translate base_url into url. + if (isset($values['base_url'])) { + $values['url'] = $values['base_url']; + unset($values['base_url']); + } + // Split bitbucket_server "repository" into project/repository. + if (isset($values['repository']) && strpos($values['repository'], '/', 1) !== false) { + list($values['project'], $values['repository']) = explode('/', $values['repository'], 2); + } + } + + return $values; + } + + /** * @return Field[] */ private function getFields() @@ -46,6 +77,7 @@ 'questionLine' => '', 'options' => [ 'bitbucket', + 'bitbucket_server', 'github', 'gitlab', 'hipchat', @@ -55,14 +87,28 @@ 'health.slack', ], ]), + 'base_url' => new UrlField('Base URL', [ + 'conditions' => ['type' => [ + 'gitlab', + 'bitbucket_server', + ]], + 'description' => 'The base URL of the server installation', + ]), + 'username' => new Field('Username', [ + 'conditions' => ['type' => [ + 'bitbucket_server', + ]], + 'description' => 'The Bitbucket Server username', + ]), 'token' => new Field('Token', [ 'conditions' => ['type' => [ 'github', 'gitlab', 'hipchat', 'health.slack', + 'bitbucket_server', ]], - 'description' => 'An OAuth token for the integration', + 'description' => 'An access token for the integration', ]), 'key' => new Field('OAuth consumer key', [ 'optionName' => 'key', @@ -80,18 +126,12 @@ 'description' => 'A Bitbucket OAuth consumer secret', 'valueKeys' => ['app_credentials', 'secret'], ]), - 'base_url' => new UrlField('Base URL', [ - 'conditions' => ['type' => [ - 'gitlab', - ]], - 'description' => 'The base URL of the GitLab installation', - ]), 'project' => new Field('Project', [ - 'optionName' => 'gitlab-project', + 'optionName' => 'server-project', 'conditions' => ['type' => [ 'gitlab', ]], - 'description' => 'The GitLab project (e.g. \'namespace/repo\')', + 'description' => 'The project (e.g. \'namespace/repo\')', 'validator' => function ($string) { return strpos($string, '/', 1) !== false; }, @@ -99,10 +139,11 @@ 'repository' => new Field('Repository', [ 'conditions' => ['type' => [ 'bitbucket', + 'bitbucket_server', 'github', ]], - 'description' => 'The repository to track (e.g. \'user/repo\')', - 'questionLine' => 'The repository (e.g. \'user/repo\')', + 'description' => 'The repository to track (e.g. \'foo/bar\')', + 'questionLine' => 'The repository (e.g. \'foo/bar\')', 'validator' => function ($string) { return substr_count($string, '/', 1) === 1; }, @@ -124,6 +165,7 @@ 'build_pull_requests' => new BooleanField('Build pull requests', [ 'conditions' => ['type' => [ 'bitbucket', + 'bitbucket_server', 'github', ]], 'description' => 'Build every pull request as an environment', @@ -154,6 +196,7 @@ 'conditions' => [ 'type' => [ 'github', + 'bitbucket_server', ], 'build_pull_requests' => true, ], @@ -173,6 +216,7 @@ 'fetch_branches' => new BooleanField('Fetch branches', [ 'conditions' => ['type' => [ 'bitbucket', + 'bitbucket_server', 'github', 'gitlab', ]], @@ -182,6 +226,7 @@ 'conditions' => [ 'type' => [ 'bitbucket', + 'bitbucket_server', 'github', 'gitlab', ], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/src/Command/Integration/IntegrationListCommand.php new/platformsh-cli-3.46.0/src/Command/Integration/IntegrationListCommand.php --- old/platformsh-cli-3.45.0/src/Command/Integration/IntegrationListCommand.php 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/src/Command/Integration/IntegrationListCommand.php 2019-08-16 18:40:08.000000000 +0200 @@ -78,6 +78,14 @@ } break; + case 'bitbucket_server': + $summary = sprintf('Project: %s', $details['project']); + $summary .= "\n" . sprintf('Base URL: %s', $details['url']); + if ($integration->hasLink('#hook')) { + $summary .= "\n" . sprintf('Hook URL: %s', $integration->getLink('#hook')); + } + break; + case 'gitlab': $summary = sprintf('Project: %s', $details['project']); $summary .= "\n" . sprintf('Base URL: %s', $details['base_url']); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/src/Command/Integration/IntegrationUpdateCommand.php new/platformsh-cli-3.46.0/src/Command/Integration/IntegrationUpdateCommand.php --- old/platformsh-cli-3.45.0/src/Command/Integration/IntegrationUpdateCommand.php 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/src/Command/Integration/IntegrationUpdateCommand.php 2019-08-16 18:40:08.000000000 +0200 @@ -57,6 +57,8 @@ } } + $this->postProcessValues($newValues, $integration); + // Merge current values with new values, accounting for nested arrays. foreach ($integration->getProperties() as $key => $currentValue) { if (isset($newValues[$key])) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/src/Command/Mount/MountSizeCommand.php new/platformsh-cli-3.46.0/src/Command/Mount/MountSizeCommand.php --- old/platformsh-cli-3.45.0/src/Command/Mount/MountSizeCommand.php 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/src/Command/Mount/MountSizeCommand.php 2019-08-16 18:40:08.000000000 +0200 @@ -107,32 +107,38 @@ // Build a table of results: one line per mount, one (multi-line) row // per filesystem. - $header = ['Mount(s)', 'Size(s)', 'Disk', 'Used', 'Available', 'Capacity']; + $header = [ + 'mounts' => 'Mount(s)', + 'sizes' => 'Size(s)', + 'max' => 'Disk', + 'used' => 'Used', + 'available' => 'Available', + 'percent_used' => '% Used', + ]; $rows = []; $showInBytes = $input->getOption('bytes'); foreach ($volumeInfo as $info) { $row = []; - $row[] = implode("\n", $info['mounts']); + $row['mounts'] = implode("\n", $info['mounts']); $mountUsage = []; foreach ($info['mounts'] as $mountPath) { $mountUsage[] = $mountSizes[$mountPath]; } if ($showInBytes) { - $row[] = implode("\n", $mountUsage); - $row[] = $info['total']; - $row[] = $info['used']; - $row[] = $info['available']; + $row['sizes'] = implode("\n", $mountUsage); + $row['max'] = $info['total']; + $row['used'] = $info['used']; + $row['available'] = $info['available']; } else { - $row[] = implode("\n", array_map([Helper::class, 'formatMemory'], $mountUsage)); - $row[] = Helper::formatMemory($info['total']); - $row[] = Helper::formatMemory($info['used']); - $row[] = Helper::formatMemory($info['available']); + $row['sizes'] = implode("\n", array_map([Helper::class, 'formatMemory'], $mountUsage)); + $row['max'] = Helper::formatMemory($info['total']); + $row['used'] = Helper::formatMemory($info['used']); + $row['available'] = Helper::formatMemory($info['available']); } - $row[] = round($info['percent_used'], 1) . '%'; + $row['percent_used'] = round($info['percent_used'], 1) . '%'; $rows[] = $row; } - /** @var \Platformsh\Cli\Service\Table $table */ $table = $this->getService('table'); $table->render($rows, $header); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/src/Command/Project/ProjectCurlCommand.php new/platformsh-cli-3.46.0/src/Command/Project/ProjectCurlCommand.php --- old/platformsh-cli-3.45.0/src/Command/Project/ProjectCurlCommand.php 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/src/Command/Project/ProjectCurlCommand.php 2019-08-16 18:40:08.000000000 +0200 @@ -21,6 +21,7 @@ ->addOption('data', 'd', InputOption::VALUE_REQUIRED, 'Data to send') ->addOption('include', 'i', InputOption::VALUE_NONE, 'Include headers in the output') ->addOption('head', 'I', InputOption::VALUE_NONE, 'Fetch headers only') + ->addOption('disable-compression', null, InputOption::VALUE_NONE, 'Do not use the curl --compressed flag') ->addOption('header', 'H', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Extra header(s)'); $this->addProjectOption(); $this->addExample('Change the project title', '-X PATCH -d \'{"title": "New title"}\''); @@ -64,6 +65,10 @@ $commandline .= ' --data ' . escapeshellarg($data); } + if (!$input->getOption('disable-compression')) { + $commandline .= ' --compressed'; + } + foreach ($input->getOption('header') as $header) { $commandline .= ' --header ' . escapeshellarg($header); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/src/Command/Self/SelfInstallCommand.php new/platformsh-cli-3.46.0/src/Command/Self/SelfInstallCommand.php --- old/platformsh-cli-3.45.0/src/Command/Self/SelfInstallCommand.php 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/src/Command/Self/SelfInstallCommand.php 2019-08-16 18:40:08.000000000 +0200 @@ -51,36 +51,42 @@ // We can't do anything without these files, so exit. return 1; } - $this->stdErr->writeln(' done'); + $this->stdErr->writeln(' <info>done</info>'); $this->stdErr->writeln(''); + $shellType = $input->getOption('shell-type'); + if ($shellType === null && getenv('SHELL') !== false) { + $shellType = str_replace('.exe', '', basename(getenv('SHELL'))); + $this->debug('Detected shell type: ' . $shellType); + } + $this->stdErr->write('Setting up autocompletion...'); try { $args = [ '--generate-hook' => true, '--program' => $this->config()->get('application.executable'), ]; - if ($input->getOption('shell-type')) { - $args['--shell-type'] = $input->getOption('shell-type'); + if ($shellType) { + $args['--shell-type'] = $shellType; } $buffer = new BufferedOutput(); $exitCode = $this->runOtherCommand('_completion', $args, $buffer); if ($exitCode === 0 && ($autoCompleteHook = $buffer->fetch())) { $fs->dumpFile($configDir . '/autocompletion.sh', $autoCompleteHook); - $this->stdErr->writeln(' done'); + $this->stdErr->writeln(' <info>done</info>'); } } catch (\Exception $e) { // If stdout is not a terminal, then we tried but // autocompletion probably isn't needed at all, as we are in the // context of some kind of automated build. So ignore the error. if (!$this->isTerminal(STDOUT)) { - $this->stdErr->writeln(' skipped'); + $this->stdErr->writeln(' <info>skipped</info>'); } // Otherwise, print the error and continue. The user probably // wants to know what went wrong, but autocompletion is still not // essential. else { - $this->stdErr->writeln(' failed'); + $this->stdErr->writeln(' <comment>failed</comment>'); $this->stdErr->writeln($this->indentAndWrap($e->getMessage())); } } @@ -104,7 +110,7 @@ $this->debug(sprintf('Shell config file specified via %s', $shellConfigOverrideVar)); $shellConfigFile = $shellConfigOverride; } else { - $shellConfigFile = $this->findShellConfigFile(); + $shellConfigFile = $this->findShellConfigFile($shellType); } $currentShellConfig = ''; @@ -222,7 +228,7 @@ } if (!file_put_contents($shellConfigFile, $newShellConfig)) { - $this->stdErr->writeln(sprintf('Failed to write to configuration file: %s', $shellConfigFile)); + $this->stdErr->writeln(sprintf('Failed to write to configuration file: <error>%s</error>', $shellConfigFile)); return 1; } @@ -331,10 +337,12 @@ /** * Finds a shell configuration file for the user. * + * @param string|null $shellType The shell type. + * * @return string|false * The absolute path to a shell config file, or false on failure. */ - protected function findShellConfigFile() + protected function findShellConfigFile($shellType) { // Special handling for the .environment file on Platform.sh environments. $envPrefix = $this->config()->get('service.env_prefix'); @@ -344,12 +352,6 @@ return getenv($envPrefix . 'APP_DIR') . '/.environment'; } - $shell = null; - if (getenv('SHELL') !== false) { - $shell = basename(getenv('SHELL')); - $this->debug('Detected shell: ' . $shell); - } - $candidates = [ '.bashrc', '.bash_profile', @@ -363,7 +365,7 @@ ]; } - if ($shell === 'zsh' || getenv('ZSH')) { + if ($shellType === 'zsh' || (empty($shellType) && getenv('ZSH'))) { array_unshift($candidates, '.zshrc'); array_unshift($candidates, '.zprofile'); } @@ -380,7 +382,7 @@ // If none of the files exist (yet), and we are on Bash, and the home // directory is writable, then use ~/.bashrc or ~/.bash_profile on // OS X. - if (is_writable($homeDir) && $shell === 'bash') { + if (is_writable($homeDir) && $shellType === 'bash') { if (OsUtil::isOsX()) { $this->debug('OS X: defaulting to ~/.bash_profile'); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.45.0/src/Service/Rsync.php new/platformsh-cli-3.46.0/src/Service/Rsync.php --- old/platformsh-cli-3.45.0/src/Service/Rsync.php 2019-07-25 14:45:39.000000000 +0200 +++ new/platformsh-cli-3.46.0/src/Service/Rsync.php 2019-08-16 18:40:08.000000000 +0200 @@ -42,38 +42,42 @@ * Syncs files from a local to a remote location. * * @param string $sshUrl - * @param string $localPath - * @param string $remotePath + * @param string $localDir + * @param string $remoteDir * @param array $options */ - public function syncUp($sshUrl, $localPath, $remotePath, array $options = []) + public function syncUp($sshUrl, $localDir, $remoteDir, array $options = []) { - $this->doSync($sshUrl, $remotePath, $localPath, true, $options); + // Ensure a trailing slash on the "from" path, to copy the directory's + // contents rather than the directory itself. + $from = rtrim($localDir, '/') . '/'; + $to = sprintf('%s:%s', $sshUrl, $remoteDir); + $this->doSync($from, $to, $options); } /** * Syncs files from a remote to a local location. * * @param string $sshUrl - * @param string $remotePath - * @param string $localPath + * @param string $remoteDir + * @param string $localDir * @param array $options */ - public function syncDown($sshUrl, $remotePath, $localPath, array $options = []) + public function syncDown($sshUrl, $remoteDir, $localDir, array $options = []) { - $this->doSync($sshUrl, $remotePath, $localPath, false, $options); + $from = sprintf('%s:%s/', $sshUrl, $remoteDir); + $to = $localDir; + $this->doSync($from, $to, $options); } /** * Runs rsync. * - * @param string $sshUrl - * @param string $remotePath - * @param string $localPath - * @param bool $up + * @param string $from + * @param string $to * @param array $options */ - private function doSync($sshUrl, $remotePath, $localPath, $up, array $options = []) + private function doSync($from, $to, array $options = []) { $params = ['rsync', '--archive', '--compress', '--human-readable']; @@ -83,13 +87,8 @@ $params[] = '-v'; } - if ($up) { - $params[] = rtrim($localPath, '/') . '/'; - $params[] = sprintf('%s:%s', $sshUrl, $remotePath); - } else { - $params[] = sprintf('%s:%s/', $sshUrl, $remotePath); - $params[] = $localPath; - } + $params[] = $from; + $params[] = $to; if (!empty($options['convert-mac-filenames'])) { $params[] = '--iconv=utf-8-mac,utf-8'; ++++++ 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 2019-07-26 22:44:12.344120655 +0200 +++ new/vendor/autoload.php 2019-08-16 23:35:03.157555973 +0200 @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInite7cf5b1805bce3b2279ae358e5d9e864::getLoader(); +return ComposerAutoloaderInita5e1e69967a31c49125500f6ed3d919d::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 2019-07-26 22:44:12.344120655 +0200 +++ new/vendor/composer/autoload_real.php 2019-08-16 23:35:03.157555973 +0200 @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInite7cf5b1805bce3b2279ae358e5d9e864 +class ComposerAutoloaderInita5e1e69967a31c49125500f6ed3d919d { private static $loader; @@ -19,15 +19,15 @@ return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInite7cf5b1805bce3b2279ae358e5d9e864', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInita5e1e69967a31c49125500f6ed3d919d', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInite7cf5b1805bce3b2279ae358e5d9e864', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInita5e1e69967a31c49125500f6ed3d919d', '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\ComposerStaticInite7cf5b1805bce3b2279ae358e5d9e864::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInita5e1e69967a31c49125500f6ed3d919d::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\ComposerStaticInite7cf5b1805bce3b2279ae358e5d9e864::$files; + $includeFiles = Composer\Autoload\ComposerStaticInita5e1e69967a31c49125500f6ed3d919d::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequiree7cf5b1805bce3b2279ae358e5d9e864($fileIdentifier, $file); + composerRequirea5e1e69967a31c49125500f6ed3d919d($fileIdentifier, $file); } return $loader; } } -function composerRequiree7cf5b1805bce3b2279ae358e5d9e864($fileIdentifier, $file) +function composerRequirea5e1e69967a31c49125500f6ed3d919d($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 2019-07-26 22:44:12.344120655 +0200 +++ new/vendor/composer/autoload_static.php 2019-08-16 23:35:03.157555973 +0200 @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInite7cf5b1805bce3b2279ae358e5d9e864 +class ComposerStaticInita5e1e69967a31c49125500f6ed3d919d { 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 = ComposerStaticInite7cf5b1805bce3b2279ae358e5d9e864::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInite7cf5b1805bce3b2279ae358e5d9e864::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInite7cf5b1805bce3b2279ae358e5d9e864::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInita5e1e69967a31c49125500f6ed3d919d::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInita5e1e69967a31c49125500f6ed3d919d::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInita5e1e69967a31c49125500f6ed3d919d::$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 2019-07-26 22:44:11.940117048 +0200 +++ new/vendor/composer/installed.json 2019-08-16 23:35:02.709551910 +0200 @@ -680,17 +680,17 @@ }, { "name": "platformsh/client", - "version": "v0.28.1", - "version_normalized": "0.28.1.0", + "version": "v0.29.0", + "version_normalized": "0.29.0.0", "source": { "type": "git", "url": "https://github.com/platformsh/platformsh-client-php.git", - "reference": "01bbf0289adad03102179412f710fdc7527fab60" + "reference": "d6362961c9c956cbc4115351c29fdf5ef612c9f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/01bbf0289adad03102179412f710fdc7527fab60", - "reference": "01bbf0289adad03102179412f710fdc7527fab60", + "url": "https://api.github.com/repos/platformsh/platformsh-client-php/zipball/d6362961c9c956cbc4115351c29fdf5ef612c9f6", + "reference": "d6362961c9c956cbc4115351c29fdf5ef612c9f6", "shasum": "" }, "require": { @@ -704,7 +704,7 @@ "require-dev": { "phpunit/phpunit": "~4.5" }, - "time": "2019-07-25T12:06:41+00:00", + "time": "2019-08-08T12:03:20+00:00", "type": "library", "installation-source": "dist", "autoload": { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/platformsh/client/src/Model/Integration.php new/vendor/platformsh/client/src/Model/Integration.php --- old/vendor/platformsh/client/src/Model/Integration.php 2019-07-25 14:06:41.000000000 +0200 +++ new/vendor/platformsh/client/src/Model/Integration.php 2019-08-08 14:03:20.000000000 +0200 @@ -19,6 +19,7 @@ /** @var array */ protected static $types = [ 'bitbucket', + 'bitbucket_server', 'hipchat', 'github', 'gitlab',
