Hello community,

here is the log from the commit of package platformsh-cli for openSUSE:Factory 
checked in at 2017-05-03 15:57:06
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/platformsh-cli (Old)
 and      /work/SRC/openSUSE:Factory/.platformsh-cli.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "platformsh-cli"

Wed May  3 15:57:06 2017 rev:9 rq:492384 version:3.15.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/platformsh-cli/platformsh-cli.changes    
2017-04-28 09:13:56.784641352 +0200
+++ /work/SRC/openSUSE:Factory/.platformsh-cli.new/platformsh-cli.changes       
2017-05-03 15:57:07.808734039 +0200
@@ -1,0 +2,26 @@
+Mon May 01 23:05:14 UTC 2017 - [email protected]
+
+- Update to version 3.15.3:
+  * Fix wrong array keys in certificate:add
+  * Trigger patch in platformsh/client package to actually apply
+  * Document PLATFORMSH_CLI_TOKEN variable, with a warning
+  * Do not check for updates immediately after install
+  * Since we have the filename, the Phar can run directly
+  * No need to write to user config for updates check
+  * Release v3.15.3
+
+-------------------------------------------------------------------
+Mon May 01 16:30:03 UTC 2017 - [email protected]
+
+- Update to version 3.15.2:
+  * Explain that auto-provisioned certificates can't be deleted
+  * Show issuer in certificate:list
+  * Allow partial match on ID in certificate:delete
+  * Use RequestTty only for certain commands, when stdin is a tty
+  * Add --raw option to sql command
+  * SSH commands need to show errors
+  * Downgrade Process, avoiding apparent segfault
+  * Ensure running another command doesn't wipe necessary service data
+  * Release v3.15.2
+
+-------------------------------------------------------------------

Old:
----
  platformsh-cli-3.15.1.tar.xz

New:
----
  platformsh-cli-3.15.3.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ platformsh-cli.spec ++++++
--- /var/tmp/diff_new_pack.FvdPk2/_old  2017-05-03 15:57:08.728604177 +0200
+++ /var/tmp/diff_new_pack.FvdPk2/_new  2017-05-03 15:57:08.732603612 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           platformsh-cli
-Version:        3.15.1
+Version:        3.15.3
 Release:        0
 Summary:        The unified tool for managing your Platform.sh services from 
the command line.
 # See licenses.txt for dependency licenses.

++++++ _service ++++++
--- /var/tmp/diff_new_pack.FvdPk2/_old  2017-05-03 15:57:08.776597401 +0200
+++ /var/tmp/diff_new_pack.FvdPk2/_new  2017-05-03 15:57:08.776597401 +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.15.1</param>
+    <param name="revision">refs/tags/v3.15.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.FvdPk2/_old  2017-05-03 15:57:08.796594578 +0200
+++ /var/tmp/diff_new_pack.FvdPk2/_new  2017-05-03 15:57:08.796594578 +0200
@@ -1,6 +1,6 @@
 <servicedata>
   <service name="tar_scm">
     <param name="url">git://github.com/platformsh/platformsh-cli.git</param>
-    <param 
name="changesrevision">75e6ca004b80b07475892f2feb89e1cda8a17c36</param>
+    <param 
name="changesrevision">3fff2c671e63c504259be508cdc4d2771862d051</param>
   </service>
 </servicedata>

++++++ licenses.txt ++++++
--- /var/tmp/diff_new_pack.FvdPk2/_old  2017-05-03 15:57:08.860585544 +0200
+++ /var/tmp/diff_new_pack.FvdPk2/_new  2017-05-03 15:57:08.864584980 +0200
@@ -28,5 +28,5 @@
 symfony/filesystem                  v3.2.7   MIT           
 symfony/finder                      v3.2.7   MIT           
 symfony/polyfill-mbstring           v1.3.0   MIT           
-symfony/process                     v3.2.7   MIT           
+symfony/process                     v3.2.4   MIT           
 symfony/yaml                        v3.2.7   MIT           

++++++ platformsh-cli-3.15.1.tar.xz -> platformsh-cli-3.15.3.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.15.1/README.md 
new/platformsh-cli-3.15.3/README.md
--- old/platformsh-cli-3.15.1/README.md 2017-04-26 16:54:54.000000000 +0200
+++ new/platformsh-cli-3.15.3/README.md 2017-05-02 00:40:27.000000000 +0200
@@ -185,6 +185,7 @@
 ```yaml
 api:
   # A path (relative or absolute) to a file containing an API token.
+  # The file should be stored with minimal permissions.
   # Run 'platform logout --all' if you change this value.
   token_file: null
 
@@ -208,6 +209,7 @@
 * `PLATFORMSH_CLI_DEBUG`: set to 1 to enable cURL debugging
 * `PLATFORMSH_CLI_DISABLE_CACHE`: set to 1 to disable caching
 * `PLATFORMSH_CLI_SESSION_ID`: change user session (default 'default')
+* `PLATFORMSH_CLI_TOKEN`: an API token. _Warning_: storing a secret in an 
environment variable can be insecure. It is usually preferable to use 
`config.yaml` as above.
 * `PLATFORMSH_CLI_UPDATES_CHECK`: set to 0 to disable the automatic updates 
check
 * `http_proxy` or `https_proxy`: specify a proxy for connecting to Platform.sh
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.15.1/composer.json 
new/platformsh-cli-3.15.3/composer.json
--- old/platformsh-cli-3.15.1/composer.json     2017-04-26 16:54:54.000000000 
+0200
+++ new/platformsh-cli-3.15.3/composer.json     2017-05-02 00:40:27.000000000 
+0200
@@ -13,7 +13,7 @@
         "symfony/yaml": "^3.0 || ^2.6",
         "symfony/finder": "^3.0",
         "symfony/filesystem": "^3.0",
-        "symfony/process": "^3.0 !=3.2.5 !=3.2.6",
+        "symfony/process": "^3.0 !=3.2.5 !=3.2.6 !=3.2.7",
         "stecman/symfony-console-completion": "~0.7",
         "symfony/event-dispatcher": "^3.0",
         "padraic/phar-updater": "^1.0",
@@ -49,5 +49,10 @@
     ],
     "bin": [
         "bin/platform"
-    ]
+    ],
+    "extra": {
+        "patches": {
+            "commerceguys/guzzle-oauth2-plugin": {}
+        }
+    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.15.1/composer.lock 
new/platformsh-cli-3.15.3/composer.lock
--- old/platformsh-cli-3.15.1/composer.lock     2017-04-26 16:54:54.000000000 
+0200
+++ new/platformsh-cli-3.15.3/composer.lock     2017-05-02 00:40:27.000000000 
+0200
@@ -4,7 +4,7 @@
         "Read more about it at 
https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file";,
         "This file is @generated automatically"
     ],
-    "content-hash": "45c0dda3a1b95ceb517677403cf37592",
+    "content-hash": "c3322283a273a90a18178d15f6e44acc",
     "packages": [
         {
             "name": "cocur/slugify",
@@ -91,6 +91,11 @@
                 "phpunit/phpunit": "~4.5"
             },
             "type": "library",
+            "extra": {
+                "patches_applied": {
+                    "Make it possible to get the access token without 
triggering a refresh": 
"https://github.com/pjcdawkins/guzzle-oauth2-plugin/commit/d2d720015813185d1ad4fa12884cab9bac6a8b25.patch";
+                }
+            },
             "autoload": {
                 "psr-4": {
                     "CommerceGuys\\Guzzle\\Oauth2\\": "src"
@@ -1269,16 +1274,16 @@
         },
         {
             "name": "symfony/process",
-            "version": "v3.2.7",
+            "version": "v3.2.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/process.git";,
-                "reference": "57fdaa55827ae14d617550ebe71a820f0a5e2282"
+                "reference": "0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/symfony/process/zipball/57fdaa55827ae14d617550ebe71a820f0a5e2282";,
-                "reference": "57fdaa55827ae14d617550ebe71a820f0a5e2282",
+                "url": 
"https://api.github.com/repos/symfony/process/zipball/0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856";,
+                "reference": "0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856",
                 "shasum": ""
             },
             "require": {
@@ -1314,7 +1319,7 @@
             ],
             "description": "Symfony Process Component",
             "homepage": "https://symfony.com";,
-            "time": "2017-03-27T18:07:02+00:00"
+            "time": "2017-02-16T14:07:22+00:00"
         },
         {
             "name": "symfony/yaml",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.15.1/config.yaml 
new/platformsh-cli-3.15.3/config.yaml
--- old/platformsh-cli-3.15.1/config.yaml       2017-04-26 16:54:54.000000000 
+0200
+++ new/platformsh-cli-3.15.3/config.yaml       2017-05-02 00:40:27.000000000 
+0200
@@ -1,7 +1,7 @@
 # Metadata about the CLI application itself.
 application:
   name: 'Platform.sh CLI'
-  version: '3.15.1'
+  version: '3.15.3'
   executable: 'platform'
   phar: 'platform.phar'
   package_name: 'platformsh/cli'
@@ -74,7 +74,7 @@
 # Automatic updates.
 # This can be overridden in the user config file.
 updates:
-  last_checked: null
+  last_checked: ~
   check_interval: 86400
 
   # Overridden by {application.env_prefix}UPDATES_CHECK env var.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.15.1/src/Command/Certificate/CertificateAddCommand.php 
new/platformsh-cli-3.15.3/src/Command/Certificate/CertificateAddCommand.php
--- old/platformsh-cli-3.15.1/src/Command/Certificate/CertificateAddCommand.php 
2017-04-26 16:54:54.000000000 +0200
+++ new/platformsh-cli-3.15.3/src/Command/Certificate/CertificateAddCommand.php 
2017-05-02 00:40:27.000000000 +0200
@@ -35,9 +35,9 @@
             return 1;
         }
 
-        list($certificate, $key, $chain) = (new 
SslUtil())->validate($certPath, $keyPath, $chainPaths);
+        $options = (new SslUtil())->validate($certPath, $keyPath, $chainPaths);
 
-        $result = $project->addCertificate($certificate, $key, $chain);
+        $result = $project->addCertificate($options['certificate'], 
$options['key'], $options['chain']);
 
         if (!$input->getOption('no-wait')) {
             /** @var \Platformsh\Cli\Service\ActivityMonitor $activityMonitor 
*/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.15.1/src/Command/Certificate/CertificateDeleteCommand.php 
new/platformsh-cli-3.15.3/src/Command/Certificate/CertificateDeleteCommand.php
--- 
old/platformsh-cli-3.15.1/src/Command/Certificate/CertificateDeleteCommand.php  
    2017-04-26 16:54:54.000000000 +0200
+++ 
new/platformsh-cli-3.15.3/src/Command/Certificate/CertificateDeleteCommand.php  
    2017-05-02 00:40:27.000000000 +0200
@@ -1,6 +1,7 @@
 <?php
 namespace Platformsh\Cli\Command\Certificate;
 
+use GuzzleHttp\Exception\BadResponseException;
 use Platformsh\Cli\Command\CommandBase;
 use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
@@ -16,7 +17,7 @@
         $this
             ->setName('certificate:delete')
             ->setDescription('Delete a certificate from the project')
-            ->addArgument('id', InputArgument::REQUIRED, 'The full certificate 
ID');
+            ->addArgument('id', InputArgument::REQUIRED, 'The certificate ID 
(or the start of it)');
         $this->addProjectOption();
     }
 
@@ -32,8 +33,12 @@
 
         $certificate = $project->getCertificate($id);
         if (!$certificate) {
-            $this->stdErr->writeln(sprintf('Certificate not found: 
<error>%s</error>', $id));
-            return 1;
+            try {
+                $certificate = $this->api()->matchPartialId($id, 
$project->getCertificates(), 'Certificate');
+            } catch (\InvalidArgumentException $e) {
+                $this->stdErr->writeln($e->getMessage());
+                return 1;
+            }
         }
 
         /** @var \Platformsh\Cli\Service\QuestionHelper $questionHelper */
@@ -42,7 +47,16 @@
             return 1;
         }
 
-        $result = $certificate->delete();
+        try {
+            $result = $certificate->delete();
+        } catch (BadResponseException $e) {
+            if (($response = $e->getResponse()) && $response->getStatusCode() 
=== 403 && $certificate->is_provisioned) {
+                $this->stdErr->writeln(sprintf('The certificate 
<error>%s</error> is automatically provisioned; it cannot be deleted.', 
$certificate->id));
+                return 1;
+            }
+
+            throw $e;
+        }
 
         $this->stdErr->writeln(sprintf('The certificate <info>%s</info> has 
been deleted.', $certificate->id));
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.15.1/src/Command/Certificate/CertificateGetCommand.php 
new/platformsh-cli-3.15.3/src/Command/Certificate/CertificateGetCommand.php
--- old/platformsh-cli-3.15.1/src/Command/Certificate/CertificateGetCommand.php 
2017-04-26 16:54:54.000000000 +0200
+++ new/platformsh-cli-3.15.3/src/Command/Certificate/CertificateGetCommand.php 
2017-05-02 00:40:27.000000000 +0200
@@ -30,10 +30,10 @@
         $id = $input->getArgument('id');
         $cert = $project->getCertificate($id);
         if (!$cert) {
-            $cert = $this->matchCertificateId($id, 
$project->getCertificates());
-            if (!$cert) {
-                $this->stdErr->writeln(sprintf('Certificate not found: %s', 
$id));
-
+            try {
+                $cert = $this->api()->matchPartialId($id, 
$project->getCertificates(), 'Certificate');
+            } catch (\InvalidArgumentException $e) {
+                $this->stdErr->writeln($e->getMessage());
                 return 1;
             }
         }
@@ -45,23 +45,4 @@
 
         return 0;
     }
-
-    /**
-     * @param string                                 $id
-     * @param \Platformsh\Client\Model\Certificate[] $certs
-     *
-     * @return \Platformsh\Client\Model\Certificate|null
-     */
-    protected function matchCertificateId($id, array $certs)
-    {
-        if (strlen($id) > 5) {
-            foreach ($certs as $candidate) {
-                if (strpos($candidate->id, $id) === 0) {
-                    return $candidate;
-                }
-            }
-        }
-
-        return null;
-    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.15.1/src/Command/Certificate/CertificateListCommand.php 
new/platformsh-cli-3.15.3/src/Command/Certificate/CertificateListCommand.php
--- 
old/platformsh-cli-3.15.1/src/Command/Certificate/CertificateListCommand.php    
    2017-04-26 16:54:54.000000000 +0200
+++ 
new/platformsh-cli-3.15.3/src/Command/Certificate/CertificateListCommand.php    
    2017-05-02 00:40:27.000000000 +0200
@@ -58,7 +58,7 @@
         /** @var \Platformsh\Cli\Service\PropertyFormatter $propertyFormatter 
*/
         $propertyFormatter = $this->getService('property_formatter');
 
-        $header = ['ID', 'Domain(s)', 'Created', 'Expires'];
+        $header = ['ID', 'Domain(s)', 'Created', 'Expires', 'Issuer'];
         $rows = [];
         foreach ($certs as $cert) {
             $rows[] = [
@@ -66,6 +66,7 @@
                 implode("\n", $cert->domains),
                 $propertyFormatter->format($cert->created_at, 'created_at'),
                 $propertyFormatter->format($cert->expires_at, 'expires_at'),
+                $this->getCertificateIssuerByAlias($cert, 'commonName') ?: '',
             ];
         }
 
@@ -128,4 +129,20 @@
             }
         }
     }
+
+    /**
+     * @param \Platformsh\Client\Model\Certificate $cert
+     * @param string                               $alias
+     *
+     * @return string|bool
+     */
+    protected function getCertificateIssuerByAlias(Certificate $cert, $alias) {
+        foreach ($cert->issuer as $issuer) {
+            if (isset($issuer['alias'], $issuer['value']) && $issuer['alias'] 
=== $alias) {
+                return $issuer['value'];
+            }
+        }
+
+        return false;
+    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.15.1/src/Command/CommandBase.php 
new/platformsh-cli-3.15.3/src/Command/CommandBase.php
--- old/platformsh-cli-3.15.1/src/Command/CommandBase.php       2017-04-26 
16:54:54.000000000 +0200
+++ new/platformsh-cli-3.15.3/src/Command/CommandBase.php       2017-05-02 
00:40:27.000000000 +0200
@@ -13,6 +13,7 @@
 use Symfony\Component\Config\FileLocator;
 use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Exception\InvalidArgumentException as 
ConsoleInvalidArgumentException;
+use Symfony\Component\Console\Input\ArgvInput;
 use Symfony\Component\Console\Input\ArrayInput;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
@@ -222,37 +223,46 @@
 
     /**
      * Check for updates.
-     *
-     * @param bool $reset
      */
-    protected function checkUpdates($reset = false)
+    protected function checkUpdates()
     {
-        if (!$reset && self::$checkedUpdates) {
+        // Avoid checking more than once in this process.
+        if (self::$checkedUpdates) {
             return;
         }
         self::$checkedUpdates = true;
 
-        // Check that this instance of the CLI was installed as a Phar.
-        if (!extension_loaded('Phar') || !\Phar::running(false)) {
+        // Check that the Phar extension is available.
+        if (!extension_loaded('Phar')) {
             return;
         }
 
-        $timestamp = time();
-        $config = $this->config();
+        // Get the filename of the Phar, or stop if this instance of the CLI is
+        // not a Phar.
+        $pharFilename = \Phar::running(false);
+        if (!$pharFilename) {
+            return;
+        }
 
+        // Check if updates are configured.
+        $config = $this->config();
         if (!$config->get('updates.check')) {
             return;
-        } elseif (!$reset
-            && $config->get('updates.last_checked') > $timestamp - 
$config->get('updates.check_interval')) {
+        }
+
+        // Determine an embargo time, after which updates can be checked.
+        $timestamp = time();
+        $embargoTime = $timestamp - $config->get('updates.check_interval');
+
+        // Stop if updates were last checked after the embargo time.
+        if ($config->has('updates.last_checked') && 
$config->get('updates.last_checked') > $embargoTime) {
             return;
         }
 
-        $config->writeUserConfig([
-            'updates' => [
-                'check' => true,
-                'last_checked' => $timestamp,
-            ],
-        ]);
+        // Stop if the Phar was updated after the embargo time.
+        if (filemtime($pharFilename) > $embargoTime) {
+            return;
+        }
 
         // Ensure classes are auto-loaded if they may be needed after the
         // update.
@@ -284,14 +294,17 @@
             $exitCode = 0;
             list($currentMajorVersion,) = explode('.', $currentVersion, 2);
             list($newMajorVersion,) = explode('.', $newVersion, 2);
-            if ($newMajorVersion === $currentMajorVersion && 
isset($GLOBALS['argv'])) {
-                $originalCommand = implode(' ', array_map('escapeshellarg', 
$GLOBALS['argv']));
+            if ($newMajorVersion === $currentMajorVersion
+                && isset($this->input)
+                && $this->input instanceof ArgvInput
+                && is_executable($pharFilename)) {
+                $originalCommand = $this->input->__toString();
                 $questionText = "\n"
                     . 'Original command: <info>' . $originalCommand . '</info>'
                     . "\n\n" . 'Continue?';
                 if ($questionHelper->confirm($questionText)) {
                     $this->stdErr->writeln('');
-                    $exitCode = $shell->executeSimple($originalCommand);
+                    $exitCode = 
$shell->executeSimple(escapeshellarg($pharFilename) . ' ' . $originalCommand);
                 }
             }
             exit($exitCode);
@@ -921,12 +934,19 @@
 
         $this->debug('Running command: ' . $name);
 
-        $this->container()->reset();
+        // Give the other command an entirely new service container, because 
the
+        // "input" and "output" parameters, and all their dependents, need to
+        // change.
+        $container = self::$container;
+        self::$container = null;
 
         $application->setCurrentCommand($command);
         $result = $command->run($cmdInput, $output ?: $this->output);
         $application->setCurrentCommand($this);
 
+        // Restore the old service container.
+        self::$container = $container;
+
         return $result;
     }
 
@@ -1079,4 +1099,14 @@
 
         return $this->synopsis[$key];
     }
+
+    /**
+     * @param resource|int $descriptor
+     *
+     * @return bool
+     */
+    protected function isTerminal($descriptor)
+    {
+        return !function_exists('posix_isatty') || posix_isatty($descriptor);
+    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.15.1/src/Command/Db/DbSqlCommand.php 
new/platformsh-cli-3.15.3/src/Command/Db/DbSqlCommand.php
--- old/platformsh-cli-3.15.1/src/Command/Db/DbSqlCommand.php   2017-04-26 
16:54:54.000000000 +0200
+++ new/platformsh-cli-3.15.3/src/Command/Db/DbSqlCommand.php   2017-05-02 
00:40:27.000000000 +0200
@@ -7,6 +7,7 @@
 use Symfony\Component\Console\Exception\InvalidArgumentException;
 use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
 
 class DbSqlCommand extends CommandBase
@@ -17,7 +18,8 @@
         $this->setName('db:sql')
             ->setAliases(['sql'])
             ->setDescription('Run SQL on the remote database')
-            ->addArgument('query', InputArgument::OPTIONAL, 'An SQL statement 
to execute');
+            ->addArgument('query', InputArgument::OPTIONAL, 'An SQL statement 
to execute')
+            ->addOption('raw', null, InputOption::VALUE_NONE, 'Produce raw, 
non-tabular output');
         $this->addProjectOption()->addEnvironmentOption()->addAppOption();
         Relationships::configureInput($this->getDefinition());
         Ssh::configureInput($this->getDefinition());
@@ -44,27 +46,38 @@
             return 1;
         }
 
+        $query = $input->getArgument('query');
+
         switch ($database['scheme']) {
             case 'pgsql':
                 $sqlCommand = 'psql ' . 
$relationships->getSqlCommandArgs('psql', $database);
-                $queryOption = ' -c ';
+                if ($query) {
+                    if ($input->getOption('raw')) {
+                        $sqlCommand .= ' -t';
+                    }
+                    $sqlCommand .= ' -c ' . escapeshellarg($query);
+                }
                 break;
 
             default:
                 $sqlCommand = 'mysql --no-auto-rehash ' . 
$relationships->getSqlCommandArgs('mysql', $database);
-                $queryOption = ' --execute ';
+                if ($query) {
+                    if ($input->getOption('raw')) {
+                        $sqlCommand .= ' --batch --raw';
+                    }
+                    $sqlCommand .= ' --execute ' . escapeshellarg($query);
+                }
                 break;
         }
 
-        $query = $input->getArgument('query');
-        if ($query) {
-            $sqlCommand .= $queryOption . escapeshellarg($query);
-        }
-
         /** @var \Platformsh\Cli\Service\Ssh $ssh */
         $ssh = $this->getService('ssh');
 
-        $sshCommand = $ssh->getSshCommand();
+        $sshOptions = [];
+        if ($this->isTerminal(STDIN)) {
+            $sshOptions['RequestTty'] = 'yes';
+        }
+        $sshCommand = $ssh->getSshCommand($sshOptions);
         $sshCommand .= ' ' . escapeshellarg($sshUrl)
             . ' ' . escapeshellarg($sqlCommand);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.15.1/src/Command/Environment/EnvironmentPushCommand.php 
new/platformsh-cli-3.15.3/src/Command/Environment/EnvironmentPushCommand.php
--- 
old/platformsh-cli-3.15.1/src/Command/Environment/EnvironmentPushCommand.php    
    2017-04-26 16:54:54.000000000 +0200
+++ 
new/platformsh-cli-3.15.3/src/Command/Environment/EnvironmentPushCommand.php    
    2017-05-02 00:40:27.000000000 +0200
@@ -145,7 +145,7 @@
         $extraSshOptions = [];
         $env = [];
         if ($input->getOption('no-wait')) {
-            $extraSshOptions[] = 'SendEnv PLATFORMSH_PUSH_NO_WAIT';
+            $extraSshOptions['SendEnv'] = 'PLATFORMSH_PUSH_NO_WAIT';
             $env['PLATFORMSH_PUSH_NO_WAIT'] = '1';
         }
         $git->setSshCommand($ssh->getSshCommand($extraSshOptions));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.15.1/src/Command/Environment/EnvironmentSshCommand.php 
new/platformsh-cli-3.15.3/src/Command/Environment/EnvironmentSshCommand.php
--- old/platformsh-cli-3.15.1/src/Command/Environment/EnvironmentSshCommand.php 
2017-04-26 16:54:54.000000000 +0200
+++ new/platformsh-cli-3.15.3/src/Command/Environment/EnvironmentSshCommand.php 
2017-05-02 00:40:27.000000000 +0200
@@ -50,7 +50,12 @@
 
         /** @var \Platformsh\Cli\Service\Ssh $ssh */
         $ssh = $this->getService('ssh');
-        $command = $ssh->getSshCommand() . ' ' . escapeshellarg($sshUrl);
+        $sshOptions = [];
+        if ($this->isTerminal(STDIN)) {
+            $sshOptions['RequestTty'] = 'yes';
+        }
+        $command = $ssh->getSshCommand($sshOptions);
+        $command .= ' ' . escapeshellarg($sshUrl);
         if ($remoteCommand) {
             $command .= ' ' . escapeshellarg($remoteCommand);
         }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.15.1/src/Command/Self/SelfUpdateCommand.php 
new/platformsh-cli-3.15.3/src/Command/Self/SelfUpdateCommand.php
--- old/platformsh-cli-3.15.1/src/Command/Self/SelfUpdateCommand.php    
2017-04-26 16:54:54.000000000 +0200
+++ new/platformsh-cli-3.15.3/src/Command/Self/SelfUpdateCommand.php    
2017-05-02 00:40:27.000000000 +0200
@@ -47,7 +47,7 @@
     /**
      * {@inheritdoc}
      */
-    protected function checkUpdates($reset = false)
+    protected function checkUpdates()
     {
         // Don't check for updates automatically when running self-update.
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.15.1/src/Service/Api.php 
new/platformsh-cli-3.15.3/src/Service/Api.php
--- old/platformsh-cli-3.15.1/src/Service/Api.php       2017-04-26 
16:54:54.000000000 +0200
+++ new/platformsh-cli-3.15.3/src/Service/Api.php       2017-05-02 
00:40:27.000000000 +0200
@@ -39,7 +39,7 @@
     protected $apiTokenType = 'exchange';
 
     /** @var PlatformClient */
-    protected $client;
+    protected static $client;
 
     /** @var Environment[] */
     protected static $environmentsCache = [];
@@ -83,13 +83,15 @@
                 $this->apiToken = $this->config->get('api.token');
                 $this->apiTokenType = 'exchange';
                 $this->sessionId = 'api-token';
-            } elseif ($this->config->has('api.access_token_file')) {
+            } elseif ($this->config->has('api.access_token_file') || 
$this->config->has('api.access_token')) {
                 // Permanent, personal access token (deprecated) - an OAuth 2.0
                 // bearer token which is used directly in API requests.
-                $this->apiToken = 
$this->loadTokenFromFile($this->config->get('api.access_token_file'));
-                $this->apiTokenType = 'access';
-            } elseif ($this->config->has('api.access_token')) {
-                $this->apiToken = $this->config->get('api.access_token');
+                @trigger_error('This type of API token (a permanent access 
token) is deprecated. Please generate a new API token when possible.', 
E_USER_DEPRECATED);
+                if ($this->config->has('api.access_token_file')) {
+                    $this->apiToken = 
$this->loadTokenFromFile($this->config->get('api.access_token_file'));
+                } else {
+                    $this->apiToken = $this->config->get('api.access_token');
+                }
                 $this->apiTokenType = 'access';
             }
         }
@@ -154,7 +156,7 @@
      */
     public function getClient($autoLogin = true)
     {
-        if (!isset($this->client)) {
+        if (!isset(self::$client)) {
             $connectorOptions = [];
             $connectorOptions['accounts'] = 
$this->config->get('api.accounts_api_url');
             $connectorOptions['verify'] = !$this->config->get('api.skip_ssl');
@@ -186,14 +188,14 @@
             $session->setId('cli-' . $this->sessionId);
             $session->setStorage(new File($this->config->getUserConfigDir() . 
'/.session'));
 
-            $this->client = new PlatformClient($connector);
+            self::$client = new PlatformClient($connector);
 
             if ($autoLogin && !$connector->isLoggedIn()) {
                 $this->dispatcher->dispatch('login_required');
             }
         }
 
-        return $this->client;
+        return self::$client;
     }
 
     /**
@@ -558,4 +560,37 @@
 
         return sprintf($pattern, $tag, $title, $project->id);
     }
+
+    /**
+     * Get a resource, matching on the beginning of the ID.
+     *
+     * @param string        $id
+     * @param ApiResource[] $resources
+     * @param string        $name
+     *
+     * @return ApiResource
+     *   The resource, if one (and only one) is matched.
+     */
+    public function matchPartialId($id, array $resources, $name = 'Resource')
+    {
+        $matched = array_filter($resources, function (ApiResource $resource) 
use ($id) {
+            return strpos($resource->getProperty('id'), $id) === 0;
+        });
+
+        if (count($matched) > 1) {
+            $matchedIds = array_map(function (ApiResource $resource) {
+                return $resource->id;
+            }, $matched);
+            throw new \InvalidArgumentException(sprintf(
+                'The partial ID "<error>%s</error>" is ambiguous; it matches 
the following %s IDs: %s',
+                $id,
+                strtolower($name),
+                "\n  " . implode("\n  ", $matchedIds)
+            ));
+        } elseif (count($matched) === 0) {
+            throw new \InvalidArgumentException(sprintf('%s not found: 
"<error>%s</error>"', $name, $id));
+        }
+
+        return reset($matched);
+    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.15.1/src/Service/Config.php 
new/platformsh-cli-3.15.3/src/Service/Config.php
--- old/platformsh-cli-3.15.1/src/Service/Config.php    2017-04-26 
16:54:54.000000000 +0200
+++ new/platformsh-cli-3.15.3/src/Service/Config.php    2017-05-02 
00:40:27.000000000 +0200
@@ -142,32 +142,6 @@
         return $this->userConfig;
     }
 
-    /**
-     * Update user configuration.
-     *
-     * @param array $config
-     */
-    public function writeUserConfig(array $config)
-    {
-        $dir = $this->getUserConfigDir();
-        if (!is_dir($dir) && !mkdir($dir, 0700, true)) {
-            trigger_error('Failed to create user config directory: ' . $dir, 
E_USER_WARNING);
-        }
-        $existingConfig = $this->getUserConfig();
-        $config = array_replace_recursive($existingConfig, $config);
-        $configFile = $dir . '/config.yaml';
-        $new = !file_exists($configFile);
-        if (file_put_contents($configFile, Yaml::dump($config, 10)) === false) 
{
-            trigger_error('Failed to write user config to: ' . $configFile, 
E_USER_WARNING);
-        }
-        // If the config file was newly created, then chmod to be r/w only by
-        // the user.
-        if ($new) {
-            chmod($configFile, 0600);
-        }
-        $this->userConfig = $config;
-    }
-
     protected function applyUserConfigOverrides()
     {
         // A whitelist of allowed overrides.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.15.1/src/Service/Ssh.php 
new/platformsh-cli-3.15.3/src/Service/Ssh.php
--- old/platformsh-cli-3.15.1/src/Service/Ssh.php       2017-04-26 
16:54:54.000000000 +0200
+++ new/platformsh-cli-3.15.3/src/Service/Ssh.php       2017-05-02 
00:40:27.000000000 +0200
@@ -38,17 +38,9 @@
         $options = array_merge($this->getSshOptions(), $extraOptions);
 
         $args = [];
-        if ($this->output->isDebug()) {
-            $args[] = '-vv';
-        } elseif ($this->output->isVeryVerbose()) {
-            $args[] = '-v';
-        } elseif ($this->output->isQuiet()) {
-            $args[] = '-q';
-        }
-
-        foreach ($options as $option) {
+        foreach ($options as $name => $value) {
             $args[] = '-o';
-            $args[] = $option;
+            $args[] = $name . ' ' . $value;
         }
 
         return $args;
@@ -63,19 +55,23 @@
     {
         $options = [];
 
-        $options[] = 'SendEnv TERM';
+        $options['SendEnv'] = 'TERM';
 
         if ($this->input->hasOption('identity-file') && 
$this->input->getOption('identity-file')) {
             $file = $this->input->getOption('identity-file');
             if (!file_exists($file)) {
                 throw new \InvalidArgumentException('Identity file not found: 
' . $file);
             }
-            $options[] = 'IdentitiesOnly yes';
-            $options[] = 'IdentityFile ' . $file;
+            $options['IdentitiesOnly'] = 'yes';
+            $options['IdentityFile'] = $file;
         }
 
-        if ($this->output->isDecorated()) {
-            $options[] = 'RequestTty yes';
+        if ($this->output->isDebug()) {
+            $options['LogLevel'] = 'DEBUG';
+        } elseif ($this->output->isVeryVerbose()) {
+            $options['LogLevel'] = 'VERBOSE';
+        } elseif ($this->output->isQuiet()) {
+            $options['LogLevel'] = 'QUIET';
         }
 
         return $options;

++++++ 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     2017-04-26 18:40:07.063327027 +0200
+++ new/vendor/autoload.php     2017-05-02 01:05:16.417576043 +0200
@@ -4,4 +4,4 @@
 
 require_once __DIR__ . '/composer/autoload_real.php';
 
-return ComposerAutoloaderInitb0c98a3a98d513ba273f445467f7f7fe::getLoader();
+return ComposerAutoloaderInit89af1a5db1fd8f018f647d41d92d023b::getLoader();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/commerceguys/guzzle-oauth2-plugin/PATCHES.txt 
new/vendor/commerceguys/guzzle-oauth2-plugin/PATCHES.txt
--- old/vendor/commerceguys/guzzle-oauth2-plugin/PATCHES.txt    1970-01-01 
01:00:00.000000000 +0100
+++ new/vendor/commerceguys/guzzle-oauth2-plugin/PATCHES.txt    2017-05-02 
01:05:15.569568170 +0200
@@ -0,0 +1,7 @@
+This file was automatically generated by Composer Patches 
(https://github.com/cweagans/composer-patches)
+Patches applied to this directory:
+
+Make it possible to get the access token without triggering a refresh
+Source: 
https://github.com/pjcdawkins/guzzle-oauth2-plugin/commit/d2d720015813185d1ad4fa12884cab9bac6a8b25.patch
+
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/commerceguys/guzzle-oauth2-plugin/src/Oauth2Subscriber.php 
new/vendor/commerceguys/guzzle-oauth2-plugin/src/Oauth2Subscriber.php
--- old/vendor/commerceguys/guzzle-oauth2-plugin/src/Oauth2Subscriber.php       
2015-12-13 00:27:25.000000000 +0100
+++ new/vendor/commerceguys/guzzle-oauth2-plugin/src/Oauth2Subscriber.php       
2017-05-02 01:05:15.569568170 +0200
@@ -110,16 +110,18 @@
     /**
      * Get the access token.
      *
+     * @param bool $refresh Whether to refresh the token, if possible.
+     *
      * @return AccessToken|null Oauth2 access token
      */
-    public function getAccessToken()
+    public function getAccessToken($refresh = true)
     {
         if ($this->accessToken && $this->accessToken->isExpired()) {
             // The access token has expired.
             $this->accessToken = null;
         }
 
-        if (null === $this->accessToken) {
+        if (null === $this->accessToken && $refresh) {
             // Try to acquire a new access token from the server.
             $this->accessToken = $this->acquireAccessToken();
             if ($this->accessToken) {
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       2017-04-26 18:40:07.063327027 
+0200
+++ new/vendor/composer/autoload_real.php       2017-05-02 01:05:16.417576043 
+0200
@@ -2,7 +2,7 @@
 
 // autoload_real.php @generated by Composer
 
-class ComposerAutoloaderInitb0c98a3a98d513ba273f445467f7f7fe
+class ComposerAutoloaderInit89af1a5db1fd8f018f647d41d92d023b
 {
     private static $loader;
 
@@ -19,15 +19,15 @@
             return self::$loader;
         }
 
-        
spl_autoload_register(array('ComposerAutoloaderInitb0c98a3a98d513ba273f445467f7f7fe',
 'loadClassLoader'), true, true);
+        
spl_autoload_register(array('ComposerAutoloaderInit89af1a5db1fd8f018f647d41d92d023b',
 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
-        
spl_autoload_unregister(array('ComposerAutoloaderInitb0c98a3a98d513ba273f445467f7f7fe',
 'loadClassLoader'));
+        
spl_autoload_unregister(array('ComposerAutoloaderInit89af1a5db1fd8f018f647d41d92d023b',
 '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\ComposerStaticInitb0c98a3a98d513ba273f445467f7f7fe::getInitializer($loader));
+            
call_user_func(\Composer\Autoload\ComposerStaticInit89af1a5db1fd8f018f647d41d92d023b::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\ComposerStaticInitb0c98a3a98d513ba273f445467f7f7fe::$files;
+            $includeFiles = 
Composer\Autoload\ComposerStaticInit89af1a5db1fd8f018f647d41d92d023b::$files;
         } else {
             $includeFiles = require __DIR__ . '/autoload_files.php';
         }
         foreach ($includeFiles as $fileIdentifier => $file) {
-            composerRequireb0c98a3a98d513ba273f445467f7f7fe($fileIdentifier, 
$file);
+            composerRequire89af1a5db1fd8f018f647d41d92d023b($fileIdentifier, 
$file);
         }
 
         return $loader;
     }
 }
 
-function composerRequireb0c98a3a98d513ba273f445467f7f7fe($fileIdentifier, 
$file)
+function composerRequire89af1a5db1fd8f018f647d41d92d023b($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     2017-04-26 18:40:07.063327027 
+0200
+++ new/vendor/composer/autoload_static.php     2017-05-02 01:05:16.417576043 
+0200
@@ -4,7 +4,7 @@
 
 namespace Composer\Autoload;
 
-class ComposerStaticInitb0c98a3a98d513ba273f445467f7f7fe
+class ComposerStaticInit89af1a5db1fd8f018f647d41d92d023b
 {
     public static $files = array (
         '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . 
'/symfony/polyfill-mbstring/bootstrap.php',
@@ -183,9 +183,9 @@
     public static function getInitializer(ClassLoader $loader)
     {
         return \Closure::bind(function () use ($loader) {
-            $loader->prefixLengthsPsr4 = 
ComposerStaticInitb0c98a3a98d513ba273f445467f7f7fe::$prefixLengthsPsr4;
-            $loader->prefixDirsPsr4 = 
ComposerStaticInitb0c98a3a98d513ba273f445467f7f7fe::$prefixDirsPsr4;
-            $loader->classMap = 
ComposerStaticInitb0c98a3a98d513ba273f445467f7f7fe::$classMap;
+            $loader->prefixLengthsPsr4 = 
ComposerStaticInit89af1a5db1fd8f018f647d41d92d023b::$prefixLengthsPsr4;
+            $loader->prefixDirsPsr4 = 
ComposerStaticInit89af1a5db1fd8f018f647d41d92d023b::$prefixDirsPsr4;
+            $loader->classMap = 
ComposerStaticInit89af1a5db1fd8f018f647d41d92d023b::$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  2017-04-26 18:40:05.951316552 +0200
+++ new/vendor/composer/installed.json  2017-05-02 01:05:15.813570436 +0200
@@ -561,6 +561,11 @@
         },
         "time": "2015-12-12T23:27:25+00:00",
         "type": "library",
+        "extra": {
+            "patches_applied": {
+                "Make it possible to get the access token without triggering a 
refresh": 
"https://github.com/pjcdawkins/guzzle-oauth2-plugin/commit/d2d720015813185d1ad4fa12884cab9bac6a8b25.patch";
+            }
+        },
         "installation-source": "dist",
         "autoload": {
             "psr-4": {
@@ -1310,23 +1315,23 @@
     },
     {
         "name": "symfony/process",
-        "version": "v3.2.7",
-        "version_normalized": "3.2.7.0",
+        "version": "v3.2.4",
+        "version_normalized": "3.2.4.0",
         "source": {
             "type": "git",
             "url": "https://github.com/symfony/process.git";,
-            "reference": "57fdaa55827ae14d617550ebe71a820f0a5e2282"
+            "reference": "0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856"
         },
         "dist": {
             "type": "zip",
-            "url": 
"https://api.github.com/repos/symfony/process/zipball/57fdaa55827ae14d617550ebe71a820f0a5e2282";,
-            "reference": "57fdaa55827ae14d617550ebe71a820f0a5e2282",
+            "url": 
"https://api.github.com/repos/symfony/process/zipball/0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856";,
+            "reference": "0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856",
             "shasum": ""
         },
         "require": {
             "php": ">=5.5.9"
         },
-        "time": "2017-03-27T18:07:02+00:00",
+        "time": "2017-02-16T14:07:22+00:00",
         "type": "library",
         "extra": {
             "branch-alias": {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/symfony/process/Process.php 
new/vendor/symfony/process/Process.php
--- old/vendor/symfony/process/Process.php      2017-03-27 20:07:02.000000000 
+0200
+++ new/vendor/symfony/process/Process.php      2017-02-16 15:07:22.000000000 
+0100
@@ -169,6 +169,7 @@
         $this->setTimeout($timeout);
         $this->useFileHandles = '\\' === DIRECTORY_SEPARATOR;
         $this->pty = false;
+        $this->enhanceWindowsCompatibility = true;
         $this->enhanceSigchildCompatibility = '\\' !== DIRECTORY_SEPARATOR && 
$this->isSigchildEnabled();
         $this->options = array_replace(array('suppress_errors' => true, 
'binary_pipes' => true), $options);
     }
@@ -265,25 +266,24 @@
         $this->callback = $this->buildCallback($callback);
         $this->hasCallback = null !== $callback;
         $descriptors = $this->getDescriptors();
-        $inheritEnv = $this->inheritEnv;
 
         $commandline = $this->commandline;
+        $envline = '';
 
-        $env = $this->env;
-        $envBackup = array();
-        if (null !== $env && $inheritEnv) {
+        if (null !== $this->env && $this->inheritEnv) {
             if ('\\' === DIRECTORY_SEPARATOR && 
!empty($this->options['bypass_shell']) && !$this->enhanceWindowsCompatibility) {
                 throw new LogicException('The "bypass_shell" option must be 
false to inherit environment variables while enhanced Windows compatibility is 
off');
             }
-
-            foreach ($env as $k => $v) {
-                $envBackup[$k] = getenv($k);
-                putenv(false === $v || null === $v ? $k : "$k=$v");
+            $env = '\\' === DIRECTORY_SEPARATOR ? '(SET %s)&&' : 'export %s;';
+            foreach ($this->env as $k => $v) {
+                $envline .= sprintf($env, 
ProcessUtils::escapeArgument("$k=$v"));
             }
             $env = null;
+        } else {
+            $env = $this->env;
         }
         if ('\\' === DIRECTORY_SEPARATOR && 
$this->enhanceWindowsCompatibility) {
-            $commandline = 'cmd /V:ON /E:ON /D /C "('.$commandline.')';
+            $commandline = 'cmd /V:ON /E:ON /D /C 
"('.$envline.$commandline.')';
             foreach ($this->processPipes->getFiles() as $offset => $filename) {
                 $commandline .= ' 
'.$offset.'>'.ProcessUtils::escapeArgument($filename);
             }
@@ -297,20 +297,18 @@
             $descriptors[3] = array('pipe', 'w');
 
             // See 
https://unix.stackexchange.com/questions/71205/background-process-pipe-input
-            $commandline = '{ ('.$this->commandline.') <&3 3<&- 3>/dev/null & 
} 3<&0;';
+            $commandline = $envline.'{ ('.$this->commandline.') <&3 3<&- 
3>/dev/null & } 3<&0;';
             $commandline .= 'pid=$!; echo $pid >&3; wait $pid; code=$?; echo 
$code >&3; exit $code';
 
             // Workaround for the bug, when PTS functionality is enabled.
             // @see : https://bugs.php.net/69442
             $ptsWorkaround = fopen(__FILE__, 'r');
+        } elseif ('' !== $envline) {
+            $commandline = $envline.$commandline;
         }
 
         $this->process = proc_open($commandline, $descriptors, 
$this->processPipes->pipes, $this->cwd, $env, $this->options);
 
-        foreach ($envBackup as $k => $v) {
-            putenv(false === $v ? $k : "$k=$v");
-        }
-
         if (!is_resource($this->process)) {
             throw new RuntimeException('Unable to launch a new process.');
         }
@@ -379,7 +377,7 @@
         if (null !== $callback) {
             if (!$this->processPipes->haveReadSupport()) {
                 $this->stop(0);
-                throw new \LogicException('Pass the callback to the 
Process::start method or enableOutput to use a callback with Process::wait');
+                throw new \LogicException('Pass the callback to the 
Process:start method or enableOutput to use a callback with Process::wait');
             }
             $this->callback = $this->buildCallback($callback);
         }
@@ -1106,7 +1104,10 @@
             return !is_array($value);
         });
 
-        $this->env = $env;
+        $this->env = array();
+        foreach ($env as $key => $value) {
+            $this->env[$key] = (string) $value;
+        }
 
         return $this;
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/symfony/process/Tests/ExecutableFinderTest.php 
new/vendor/symfony/process/Tests/ExecutableFinderTest.php
--- old/vendor/symfony/process/Tests/ExecutableFinderTest.php   2017-03-27 
20:07:02.000000000 +0200
+++ new/vendor/symfony/process/Tests/ExecutableFinderTest.php   2017-02-16 
15:07:22.000000000 +0100
@@ -11,13 +11,12 @@
 
 namespace Symfony\Component\Process\Tests;
 
-use PHPUnit\Framework\TestCase;
 use Symfony\Component\Process\ExecutableFinder;
 
 /**
  * @author Chris Smith <[email protected]>
  */
-class ExecutableFinderTest extends TestCase
+class ExecutableFinderTest extends \PHPUnit_Framework_TestCase
 {
     private $path;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/symfony/process/Tests/PhpExecutableFinderTest.php 
new/vendor/symfony/process/Tests/PhpExecutableFinderTest.php
--- old/vendor/symfony/process/Tests/PhpExecutableFinderTest.php        
2017-03-27 20:07:02.000000000 +0200
+++ new/vendor/symfony/process/Tests/PhpExecutableFinderTest.php        
2017-02-16 15:07:22.000000000 +0100
@@ -11,13 +11,12 @@
 
 namespace Symfony\Component\Process\Tests;
 
-use PHPUnit\Framework\TestCase;
 use Symfony\Component\Process\PhpExecutableFinder;
 
 /**
  * @author Robert Schönthal <[email protected]>
  */
-class PhpExecutableFinderTest extends TestCase
+class PhpExecutableFinderTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * tests find() with the constant PHP_BINARY.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/symfony/process/Tests/PhpProcessTest.php 
new/vendor/symfony/process/Tests/PhpProcessTest.php
--- old/vendor/symfony/process/Tests/PhpProcessTest.php 2017-03-27 
20:07:02.000000000 +0200
+++ new/vendor/symfony/process/Tests/PhpProcessTest.php 2017-02-16 
15:07:22.000000000 +0100
@@ -11,11 +11,10 @@
 
 namespace Symfony\Component\Process\Tests;
 
-use PHPUnit\Framework\TestCase;
 use Symfony\Component\Process\PhpExecutableFinder;
 use Symfony\Component\Process\PhpProcess;
 
-class PhpProcessTest extends TestCase
+class PhpProcessTest extends \PHPUnit_Framework_TestCase
 {
     public function testNonBlockingWorks()
     {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/symfony/process/Tests/ProcessBuilderTest.php 
new/vendor/symfony/process/Tests/ProcessBuilderTest.php
--- old/vendor/symfony/process/Tests/ProcessBuilderTest.php     2017-03-27 
20:07:02.000000000 +0200
+++ new/vendor/symfony/process/Tests/ProcessBuilderTest.php     2017-02-16 
15:07:22.000000000 +0100
@@ -11,10 +11,9 @@
 
 namespace Symfony\Component\Process\Tests;
 
-use PHPUnit\Framework\TestCase;
 use Symfony\Component\Process\ProcessBuilder;
 
-class ProcessBuilderTest extends TestCase
+class ProcessBuilderTest extends \PHPUnit_Framework_TestCase
 {
     public function testInheritEnvironmentVars()
     {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/symfony/process/Tests/ProcessFailedExceptionTest.php 
new/vendor/symfony/process/Tests/ProcessFailedExceptionTest.php
--- old/vendor/symfony/process/Tests/ProcessFailedExceptionTest.php     
2017-03-27 20:07:02.000000000 +0200
+++ new/vendor/symfony/process/Tests/ProcessFailedExceptionTest.php     
2017-02-16 15:07:22.000000000 +0100
@@ -11,13 +11,12 @@
 
 namespace Symfony\Component\Process\Tests;
 
-use PHPUnit\Framework\TestCase;
 use Symfony\Component\Process\Exception\ProcessFailedException;
 
 /**
  * @author Sebastian Marek <[email protected]>
  */
-class ProcessFailedExceptionTest extends TestCase
+class ProcessFailedExceptionTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * tests ProcessFailedException throws exception if the process was 
successful.
@@ -29,7 +28,7 @@
             ->method('isSuccessful')
             ->will($this->returnValue(true));
 
-        $this->{method_exists($this, $_ = 'expectException') ? $_ : 
'setExpectedException'}(
+        $this->setExpectedException(
             '\InvalidArgumentException',
             'Expected a failed process, but the given process was successful.'
         );
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/symfony/process/Tests/ProcessTest.php 
new/vendor/symfony/process/Tests/ProcessTest.php
--- old/vendor/symfony/process/Tests/ProcessTest.php    2017-03-27 
20:07:02.000000000 +0200
+++ new/vendor/symfony/process/Tests/ProcessTest.php    2017-02-16 
15:07:22.000000000 +0100
@@ -11,7 +11,6 @@
 
 namespace Symfony\Component\Process\Tests;
 
-use PHPUnit\Framework\TestCase;
 use Symfony\Component\Process\Exception\LogicException;
 use Symfony\Component\Process\Exception\ProcessTimedOutException;
 use Symfony\Component\Process\Exception\RuntimeException;
@@ -23,7 +22,7 @@
 /**
  * @author Robert Schönthal <[email protected]>
  */
-class ProcessTest extends TestCase
+class ProcessTest extends \PHPUnit_Framework_TestCase
 {
     private static $phpBin;
     private static $process;
@@ -944,14 +943,7 @@
     public function testMethodsThatNeedARunningProcess($method)
     {
         $process = $this->getProcess('foo');
-
-        if (method_exists($this, 'expectException')) {
-            
$this->expectException('Symfony\Component\Process\Exception\LogicException');
-            $this->expectExceptionMessage(sprintf('Process must be started 
before calling %s.', $method));
-        } else {
-            
$this->setExpectedException('Symfony\Component\Process\Exception\LogicException',
 sprintf('Process must be started before calling %s.', $method));
-        }
-
+        
$this->setExpectedException('Symfony\Component\Process\Exception\LogicException',
 sprintf('Process must be started before calling %s.', $method));
         $process->{$method}();
     }
 
@@ -1391,32 +1383,6 @@
         $this->assertSame('456', $p2->getOutput());
     }
 
-    public function testSetBadEnv()
-    {
-        $process = $this->getProcess('echo hello');
-        $process->setEnv(array('bad%%' => '123'));
-        $process->inheritEnvironmentVariables(true);
-
-        $process->run();
-
-        $this->assertSame('hello'.PHP_EOL, $process->getOutput());
-        $this->assertSame('', $process->getErrorOutput());
-    }
-
-    public function testEnvBackupDoesNotDeleteExistingVars()
-    {
-        putenv('existing_var=foo');
-        $process = $this->getProcess('php -r "echo 
getenv(\'new_test_var\');"');
-        $process->setEnv(array('existing_var' => 'bar', 'new_test_var' => 
'foo'));
-        $process->inheritEnvironmentVariables();
-
-        $process->run();
-
-        $this->assertSame('foo', $process->getOutput());
-        $this->assertSame('foo', getenv('existing_var'));
-        $this->assertFalse(getenv('new_test_var'));
-    }
-
     public function testInheritEnvEnabled()
     {
         $process = $this->getProcess(self::$phpBin.' -r '.escapeshellarg('echo 
serialize($_SERVER);'), null, array('BAR' => 'BAZ'));
@@ -1493,12 +1459,7 @@
             if (!$expectException) {
                 $this->markTestSkipped('PHP is compiled with 
--enable-sigchild.');
             } elseif (self::$notEnhancedSigchild) {
-                if (method_exists($this, 'expectException')) {
-                    
$this->expectException('Symfony\Component\Process\Exception\RuntimeException');
-                    $this->expectExceptionMessage('This PHP has been compiled 
with --enable-sigchild.');
-                } else {
-                    
$this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException',
 'This PHP has been compiled with --enable-sigchild.');
-                }
+                
$this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException',
 'This PHP has been compiled with --enable-sigchild.');
             }
         }
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/symfony/process/Tests/ProcessUtilsTest.php 
new/vendor/symfony/process/Tests/ProcessUtilsTest.php
--- old/vendor/symfony/process/Tests/ProcessUtilsTest.php       2017-03-27 
20:07:02.000000000 +0200
+++ new/vendor/symfony/process/Tests/ProcessUtilsTest.php       2017-02-16 
15:07:22.000000000 +0100
@@ -11,10 +11,9 @@
 
 namespace Symfony\Component\Process\Tests;
 
-use PHPUnit\Framework\TestCase;
 use Symfony\Component\Process\ProcessUtils;
 
-class ProcessUtilsTest extends TestCase
+class ProcessUtilsTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * @dataProvider dataArguments


Reply via email to