Hello community,

here is the log from the commit of package platformsh-cli for openSUSE:Factory 
checked in at 2018-01-20 11:28:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/platformsh-cli (Old)
 and      /work/SRC/openSUSE:Factory/.platformsh-cli.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "platformsh-cli"

Sat Jan 20 11:28:07 2018 rev:31 rq:567751 version:3.27.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/platformsh-cli/platformsh-cli.changes    
2017-12-29 18:52:44.949195921 +0100
+++ /work/SRC/openSUSE:Factory/.platformsh-cli.new/platformsh-cli.changes       
2018-01-20 11:28:12.684166580 +0100
@@ -1,0 +2,25 @@
+Fri Jan 19 15:44:58 UTC 2018 - [email protected]
+
+- Update to version 3.27.0:
+  * Release v3.27.0
+  * Print changelog in self:build
+  * Allow override of application.login_method in user config
+  * Set --build-pull-requests-post-merge false by default (GitHub integrations)
+  * Respect --no-wait in environment:init, and clear environment cache
+  * Allow custom scheme in browser login
+  * Fix browser login boolean mistake..
+  * Explain failed deletion
+  * Delegate project:delete access to the API
+  * Link directly to latest release
+  * auth:browser-login: always display URL in case the default browser did not 
work
+  * Support colors via CLICOLOR_FORCE in final section of installer
+  * Use browser login by default (#672)
+  * Move disabled_commands under application in config.yaml
+  * Add help in auth:browser-login and auth:login explaining alternatives
+  * Better Windows description
+  * Update README.md
+  * Update to Symfony 3.4.2
+  * Browser login: markup improvements
+  * Update CHANGELOG.md for v3.26.1
+
+-------------------------------------------------------------------

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

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

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

Other differences:
------------------
++++++ platformsh-cli.spec ++++++
--- /var/tmp/diff_new_pack.318D9s/_old  2018-01-20 11:28:13.444131037 +0100
+++ /var/tmp/diff_new_pack.318D9s/_new  2018-01-20 11:28:13.444131037 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package platformsh-cli
 #
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           platformsh-cli
-Version:        3.26.1
+Version:        3.27.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.318D9s/_old  2018-01-20 11:28:13.468129916 +0100
+++ /var/tmp/diff_new_pack.318D9s/_new  2018-01-20 11:28:13.468129916 +0100
@@ -2,7 +2,7 @@
   <service name="tar_scm" mode="disabled">
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(.*)</param>
-    <param name="revision">refs/tags/v3.26.1</param>
+    <param name="revision">refs/tags/v3.27.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.318D9s/_old  2018-01-20 11:28:13.492128793 +0100
+++ /var/tmp/diff_new_pack.318D9s/_new  2018-01-20 11:28:13.492128793 +0100
@@ -1,6 +1,6 @@
 <servicedata>
   <service name="tar_scm">
     <param name="url">git://github.com/platformsh/platformsh-cli.git</param>
-    <param 
name="changesrevision">739e783bffc5ce6c2b401ebf495e0397135596cf</param>
+    <param 
name="changesrevision">14f78ca17089deff54abed0e3d3e379788ce8aa6</param>
   </service>
 </servicedata>

++++++ licenses.txt ++++++
--- /var/tmp/diff_new_pack.318D9s/_old  2018-01-20 11:28:13.532126922 +0100
+++ /var/tmp/diff_new_pack.318D9s/_new  2018-01-20 11:28:13.532126922 +0100
@@ -22,13 +22,13 @@
 psr/log                             1.0.2    MIT           
 react/promise                       v2.5.1   MIT           
 stecman/symfony-console-completion  0.7.0    MIT           
-symfony/config                      v3.4.1   MIT           
-symfony/console                     v3.4.1   MIT           
-symfony/debug                       v3.4.1   MIT           
-symfony/dependency-injection        v3.4.1   MIT           
-symfony/event-dispatcher            v3.4.1   MIT           
-symfony/filesystem                  v3.4.1   MIT           
-symfony/finder                      v3.4.1   MIT           
+symfony/config                      v3.4.2   MIT           
+symfony/console                     v3.4.2   MIT           
+symfony/debug                       v3.4.2   MIT           
+symfony/dependency-injection        v3.4.2   MIT           
+symfony/event-dispatcher            v3.4.2   MIT           
+symfony/filesystem                  v3.4.2   MIT           
+symfony/finder                      v3.4.2   MIT           
 symfony/polyfill-mbstring           v1.6.0   MIT           
-symfony/process                     v3.4.1   MIT           
-symfony/yaml                        v3.4.1   MIT           
+symfony/process                     v3.4.2   MIT           
+symfony/yaml                        v3.4.2   MIT           

++++++ platformsh-cli-3.26.1.tar.xz -> platformsh-cli-3.27.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.26.1/CHANGELOG.md 
new/platformsh-cli-3.27.0/CHANGELOG.md
--- old/platformsh-cli-3.26.1/CHANGELOG.md      2017-12-28 12:27:23.000000000 
+0100
+++ new/platformsh-cli-3.27.0/CHANGELOG.md      2018-01-18 18:53:58.000000000 
+0100
@@ -4,6 +4,15 @@
 
 More readable, curated release notes can be found at: 
https://github.com/platformsh/platformsh-cli/releases
 
+## [v3.27.0](https://github.com/platformsh/platformsh-cli/tree/v3.27.0) 
(2018-01-18)
+[Full 
Changelog](https://github.com/platformsh/platformsh-cli/compare/v3.26.1...v3.27.0)
+
+* Use browser login by default (the old login method is available as 
`auth:password-login`).
+* Set `--build-pull-requests-post-merge` to false by default (GitHub 
integrations).
+* Respect `--no-wait` in `environment:init`, and clear the environment cache 
afterwards.
+* In the `project:delete` command, leave access control to the API.
+* Support disabling or enabling colorized output via the CLICOLOR_FORCE 
environment variable.
+
 ## [v3.26.1](https://github.com/platformsh/platformsh-cli/tree/v3.26.1) 
(2017-12-28)
 [Full 
Changelog](https://github.com/platformsh/platformsh-cli/compare/v3.26.0...v3.26.1)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.26.1/README.md 
new/platformsh-cli-3.27.0/README.md
--- old/platformsh-cli-3.26.1/README.md 2017-12-28 12:27:23.000000000 +0100
+++ new/platformsh-cli-3.27.0/README.md 2018-01-18 18:53:58.000000000 +0100
@@ -9,7 +9,7 @@
 * Git
 * A Bash-like shell:
   * On OS X or Linux/Unix: SH, Bash, Dash or ZSH - usually the built-in shell 
will work.
-  * On Windows: [Bash on 
Ubuntu](https://msdn.microsoft.com/en-gb/commandline/wsl/about) on Windows 
(recommended), or a Bash-compatible shell such as [Git 
Bash](https://git-for-windows.github.io/), Cygwin, or MinGW.
+  * On Windows: [Windows Subsystem for 
Linux](https://msdn.microsoft.com/en-gb/commandline/wsl/about) (recommended), 
or another Bash-compatible shell such as [Git 
Bash](https://git-for-windows.github.io/), Cygwin, or MinGW.
 * For building locally, your project's dependencies, e.g.
   * [Composer](https://getcomposer.org/) (for many PHP projects)
   * [Drush](https://github.com/drush-ops/drush) (for Drupal projects)
@@ -25,9 +25,8 @@
 
 ### Installing manually
 
-1. Download the latest stable package from the
-  [Releases page](https://github.com/platformsh/platformsh-cli/releases)
-  (look for the latest `platform.phar` file).
+1. Download the `platform.phar` file from the
+  [latest 
release](https://github.com/platformsh/platformsh-cli/releases/latest).
 
 2. Rename the file to `platform`, ensure it is executable, and move it into a
   directory in your PATH (use `echo $PATH` to see your options).
@@ -64,9 +63,8 @@
   --quiet          -q Do not output any message
   --verbose        -v|vv|vvv Increase the verbosity of messages
   --version        -V Display this application version
-  --yes            -y Answer "yes" to all prompts
+  --yes            -y Answer "yes" to all prompts; disable interaction
   --no             -n Answer "no" to all prompts
-  --shell          -s Launch the shell
 
 Available commands:
   clear-cache (clearcache, cc)              Clear the CLI cache
@@ -80,10 +78,10 @@
   activity:log                              Display the log for an activity
 app
   app:config-get                            View the configuration of an app
-  app:list (apps)                           Get a list of all apps in the 
local repository
+  app:list (apps)                           List apps in the project
 auth
   auth:info                                 Display your account information
-  auth:login (login)                        Log in to Platform.sh
+  auth:login (login)                        Log in to Platform.sh using a 
username and password
   auth:logout (logout)                      Log out of Platform.sh
 certificate
   certificate:add                           Add an SSL certificate to the 
project
@@ -112,7 +110,7 @@
   environment:logs (log)                    Read an environment's logs
   environment:merge (merge)                 Merge an environment
   environment:push (push)                   Push code to an environment
-  environment:relationships (relationships)   Show an environment's 
relationships
+  environment:relationships (relationships) Show an environment's relationships
   environment:ssh (ssh)                     SSH to the current environment
   environment:synchronize (sync)            Synchronize an environment's code 
and/or data from its parent
   environment:url (url)                     Get the public URLs of an 
environment
@@ -137,13 +135,13 @@
   project:list (projects)                   Get a list of all active projects
   project:set-remote                        Set the remote project for the 
current Git repository
   project:variable:delete                   Delete a variable from a project
-  project:variable:get (project-variables, pvget)   View variable(s) for a 
project
+  project:variable:get (project-variables, pvget) View variable(s) for a 
project
   project:variable:set (pvset)              Set a variable for a project
 repo
   repo:cat                                  Read a file in the project 
repository
   repo:ls                                   List files in the project 
repository
 route
-  route:get                                 View a route
+  route:get                                 View a resolved route
   route:list (routes)                       List all routes for an environment
 self
   self:install                              Install or update CLI 
configuration files
@@ -219,6 +217,7 @@
 * `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
+* `CLICOLOR_FORCE`: set to 1 or 0 to force colorized output on or off, 
respectively
 * `http_proxy` or `https_proxy`: specify a proxy for connecting to Platform.sh
 
 ## Contributing
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.26.1/composer.lock 
new/platformsh-cli-3.27.0/composer.lock
--- old/platformsh-cli-3.26.1/composer.lock     2017-12-28 12:27:23.000000000 
+0100
+++ new/platformsh-cli-3.27.0/composer.lock     2018-01-18 18:53:58.000000000 
+0100
@@ -917,16 +917,16 @@
         },
         {
             "name": "symfony/config",
-            "version": "v3.4.1",
+            "version": "v3.4.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/config.git";,
-                "reference": "1de51a6c76359897ab32c309934b93d036bccb60"
+                "reference": "e57211b88aa889fefac1cb36866db04100b0f21c"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/symfony/config/zipball/1de51a6c76359897ab32c309934b93d036bccb60";,
-                "reference": "1de51a6c76359897ab32c309934b93d036bccb60",
+                "url": 
"https://api.github.com/repos/symfony/config/zipball/e57211b88aa889fefac1cb36866db04100b0f21c";,
+                "reference": "e57211b88aa889fefac1cb36866db04100b0f21c",
                 "shasum": ""
             },
             "require": {
@@ -975,20 +975,20 @@
             ],
             "description": "Symfony Config Component",
             "homepage": "https://symfony.com";,
-            "time": "2017-11-19T20:09:36+00:00"
+            "time": "2017-12-14T19:40:10+00:00"
         },
         {
             "name": "symfony/console",
-            "version": "v3.4.1",
+            "version": "v3.4.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/console.git";,
-                "reference": "2cdef78de8f54f68ff16a857e710e7302b47d4c7"
+                "reference": "9f21adfb92a9315b73ae2ed43138988ee4913d4e"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/symfony/console/zipball/2cdef78de8f54f68ff16a857e710e7302b47d4c7";,
-                "reference": "2cdef78de8f54f68ff16a857e710e7302b47d4c7",
+                "url": 
"https://api.github.com/repos/symfony/console/zipball/9f21adfb92a9315b73ae2ed43138988ee4913d4e";,
+                "reference": "9f21adfb92a9315b73ae2ed43138988ee4913d4e",
                 "shasum": ""
             },
             "require": {
@@ -1044,20 +1044,20 @@
             ],
             "description": "Symfony Console Component",
             "homepage": "https://symfony.com";,
-            "time": "2017-12-02T18:20:11+00:00"
+            "time": "2017-12-14T19:40:10+00:00"
         },
         {
             "name": "symfony/debug",
-            "version": "v3.4.1",
+            "version": "v3.4.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/debug.git";,
-                "reference": "fb2001e5d85f95d8b6ab94ae3be5d2672df128fd"
+                "reference": "543deab3ffff94402440b326fc94153bae2dfa7a"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/symfony/debug/zipball/fb2001e5d85f95d8b6ab94ae3be5d2672df128fd";,
-                "reference": "fb2001e5d85f95d8b6ab94ae3be5d2672df128fd",
+                "url": 
"https://api.github.com/repos/symfony/debug/zipball/543deab3ffff94402440b326fc94153bae2dfa7a";,
+                "reference": "543deab3ffff94402440b326fc94153bae2dfa7a",
                 "shasum": ""
             },
             "require": {
@@ -1100,20 +1100,20 @@
             ],
             "description": "Symfony Debug Component",
             "homepage": "https://symfony.com";,
-            "time": "2017-11-21T09:01:46+00:00"
+            "time": "2017-12-12T08:27:14+00:00"
         },
         {
             "name": "symfony/dependency-injection",
-            "version": "v3.4.1",
+            "version": "v3.4.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/dependency-injection.git";,
-                "reference": "27810742895ad89e706ba5028e4f8fe425792b50"
+                "reference": "5f81907ea43bfa971ac2c7fbac593ebe7cd7d333"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/symfony/dependency-injection/zipball/27810742895ad89e706ba5028e4f8fe425792b50";,
-                "reference": "27810742895ad89e706ba5028e4f8fe425792b50",
+                "url": 
"https://api.github.com/repos/symfony/dependency-injection/zipball/5f81907ea43bfa971ac2c7fbac593ebe7cd7d333";,
+                "reference": "5f81907ea43bfa971ac2c7fbac593ebe7cd7d333",
                 "shasum": ""
             },
             "require": {
@@ -1121,7 +1121,7 @@
                 "psr/container": "^1.0"
             },
             "conflict": {
-                "symfony/config": "<3.3.1",
+                "symfony/config": "<3.3.7",
                 "symfony/finder": "<3.3",
                 "symfony/proxy-manager-bridge": "<3.4",
                 "symfony/yaml": "<3.4"
@@ -1171,20 +1171,20 @@
             ],
             "description": "Symfony DependencyInjection Component",
             "homepage": "https://symfony.com";,
-            "time": "2017-12-04T19:20:32+00:00"
+            "time": "2017-12-14T19:40:10+00:00"
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v3.4.1",
+            "version": "v3.4.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher.git";,
-                "reference": "ca20b8f9ef149f40ff656d52965f240d85f7a8e4"
+                "reference": "b869cbf8a15ca6261689de2c28a7d7f2d0706835"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/symfony/event-dispatcher/zipball/ca20b8f9ef149f40ff656d52965f240d85f7a8e4";,
-                "reference": "ca20b8f9ef149f40ff656d52965f240d85f7a8e4",
+                "url": 
"https://api.github.com/repos/symfony/event-dispatcher/zipball/b869cbf8a15ca6261689de2c28a7d7f2d0706835";,
+                "reference": "b869cbf8a15ca6261689de2c28a7d7f2d0706835",
                 "shasum": ""
             },
             "require": {
@@ -1234,20 +1234,20 @@
             ],
             "description": "Symfony EventDispatcher Component",
             "homepage": "https://symfony.com";,
-            "time": "2017-11-09T14:14:31+00:00"
+            "time": "2017-12-14T19:40:10+00:00"
         },
         {
             "name": "symfony/filesystem",
-            "version": "v3.4.1",
+            "version": "v3.4.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/filesystem.git";,
-                "reference": "de56eee71e0a128d8c54ccc1909cdefd574bad0f"
+                "reference": "25b135bea251829e3db6a77d773643408b575ed4"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/symfony/filesystem/zipball/de56eee71e0a128d8c54ccc1909cdefd574bad0f";,
-                "reference": "de56eee71e0a128d8c54ccc1909cdefd574bad0f",
+                "url": 
"https://api.github.com/repos/symfony/filesystem/zipball/25b135bea251829e3db6a77d773643408b575ed4";,
+                "reference": "25b135bea251829e3db6a77d773643408b575ed4",
                 "shasum": ""
             },
             "require": {
@@ -1283,11 +1283,11 @@
             ],
             "description": "Symfony Filesystem Component",
             "homepage": "https://symfony.com";,
-            "time": "2017-11-19T18:59:05+00:00"
+            "time": "2017-12-14T19:40:10+00:00"
         },
         {
             "name": "symfony/finder",
-            "version": "v3.4.1",
+            "version": "v3.4.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/finder.git";,
@@ -1395,16 +1395,16 @@
         },
         {
             "name": "symfony/process",
-            "version": "v3.4.1",
+            "version": "v3.4.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/process.git";,
-                "reference": "db25e810fd5e124085e3777257d0cf4ae533d0ea"
+                "reference": "bb3ef65d493a6d57297cad6c560ee04e2a8f5098"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/symfony/process/zipball/db25e810fd5e124085e3777257d0cf4ae533d0ea";,
-                "reference": "db25e810fd5e124085e3777257d0cf4ae533d0ea",
+                "url": 
"https://api.github.com/repos/symfony/process/zipball/bb3ef65d493a6d57297cad6c560ee04e2a8f5098";,
+                "reference": "bb3ef65d493a6d57297cad6c560ee04e2a8f5098",
                 "shasum": ""
             },
             "require": {
@@ -1440,20 +1440,20 @@
             ],
             "description": "Symfony Process Component",
             "homepage": "https://symfony.com";,
-            "time": "2017-11-22T12:18:49+00:00"
+            "time": "2017-12-14T19:40:10+00:00"
         },
         {
             "name": "symfony/yaml",
-            "version": "v3.4.1",
+            "version": "v3.4.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git";,
-                "reference": "f6a99b95b338799645fe9f7880d7d4ca1bf79cc1"
+                "reference": "afe0cd38486505c9703707707d91450cfc1bd536"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/symfony/yaml/zipball/f6a99b95b338799645fe9f7880d7d4ca1bf79cc1";,
-                "reference": "f6a99b95b338799645fe9f7880d7d4ca1bf79cc1",
+                "url": 
"https://api.github.com/repos/symfony/yaml/zipball/afe0cd38486505c9703707707d91450cfc1bd536";,
+                "reference": "afe0cd38486505c9703707707d91450cfc1bd536",
                 "shasum": ""
             },
             "require": {
@@ -1498,7 +1498,7 @@
             ],
             "description": "Symfony Yaml Component",
             "homepage": "https://symfony.com";,
-            "time": "2017-12-04T18:15:22+00:00"
+            "time": "2017-12-11T20:38:23+00:00"
         }
     ],
     "packages-dev": [
@@ -1888,16 +1888,16 @@
         },
         {
             "name": "nikic/php-parser",
-            "version": "v3.1.2",
+            "version": "v3.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nikic/PHP-Parser.git";,
-                "reference": "08131e7ff29de6bb9f12275c7d35df71f25f4d89"
+                "reference": "579f4ce846734a1cf55d6a531d00ca07a43e3cda"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/nikic/PHP-Parser/zipball/08131e7ff29de6bb9f12275c7d35df71f25f4d89";,
-                "reference": "08131e7ff29de6bb9f12275c7d35df71f25f4d89",
+                "url": 
"https://api.github.com/repos/nikic/PHP-Parser/zipball/579f4ce846734a1cf55d6a531d00ca07a43e3cda";,
+                "reference": "579f4ce846734a1cf55d6a531d00ca07a43e3cda",
                 "shasum": ""
             },
             "require": {
@@ -1935,7 +1935,7 @@
                 "parser",
                 "php"
             ],
-            "time": "2017-11-04T11:48:34+00:00"
+            "time": "2017-12-26T14:43:21+00:00"
         },
         {
             "name": "pear/console_table",
@@ -2482,16 +2482,16 @@
         },
         {
             "name": "psy/psysh",
-            "version": "v0.8.15",
+            "version": "v0.8.17",
             "source": {
                 "type": "git",
                 "url": "https://github.com/bobthecow/psysh.git";,
-                "reference": "b1d289c2cb03a2f8249912c53e96ced38f879926"
+                "reference": "5069b70e8c4ea492c2b5939b6eddc78bfe41cfec"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/bobthecow/psysh/zipball/b1d289c2cb03a2f8249912c53e96ced38f879926";,
-                "reference": "b1d289c2cb03a2f8249912c53e96ced38f879926",
+                "url": 
"https://api.github.com/repos/bobthecow/psysh/zipball/5069b70e8c4ea492c2b5939b6eddc78bfe41cfec";,
+                "reference": "5069b70e8c4ea492c2b5939b6eddc78bfe41cfec",
                 "shasum": ""
             },
             "require": {
@@ -2499,14 +2499,13 @@
                 "jakub-onderka/php-console-highlighter": "0.3.*",
                 "nikic/php-parser": "~1.3|~2.0|~3.0",
                 "php": ">=5.3.9",
-                "symfony/console": "~2.3.10|^2.4.2|~3.0",
-                "symfony/var-dumper": "~2.7|~3.0"
+                "symfony/console": "~2.3.10|^2.4.2|~3.0|~4.0",
+                "symfony/var-dumper": "~2.7|~3.0|~4.0"
             },
             "require-dev": {
-                "friendsofphp/php-cs-fixer": "~1.11",
                 "hoa/console": "~3.16|~1.14",
                 "phpunit/phpunit": "^4.8.35|^5.4.3",
-                "symfony/finder": "~2.1|~3.0"
+                "symfony/finder": "~2.1|~3.0|~4.0"
             },
             "suggest": {
                 "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot 
happier :)",
@@ -2551,7 +2550,7 @@
                 "interactive",
                 "shell"
             ],
-            "time": "2017-11-16T14:29:51+00:00"
+            "time": "2017-12-28T16:14:16+00:00"
         },
         {
             "name": "sebastian/comparator",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.26.1/config.yaml 
new/platformsh-cli-3.27.0/config.yaml
--- old/platformsh-cli-3.26.1/config.yaml       2017-12-28 12:27:23.000000000 
+0100
+++ new/platformsh-cli-3.27.0/config.yaml       2018-01-18 18:53:58.000000000 
+0100
@@ -1,7 +1,7 @@
 # Metadata about the CLI application itself.
 application:
   name: 'Platform.sh CLI'
-  version: '3.26.1'
+  version: '3.27.0'
   executable: 'platform'
   package_name: 'platformsh/cli'
   installer_url: 'https://platform.sh/cli/installer'
@@ -11,8 +11,11 @@
   env_prefix: 'PLATFORMSH_CLI_'
   tmp_sub_dir: 'platformsh-cli-tmp'
 
-# Disabled commands.
-disabled_commands: []
+  # The default login method: either 'browser' or 'password'.
+  login_method: browser
+
+  # Disabled commands.
+  disabled_commands: []
 
 # Configuration for working with projects locally.
 local:
@@ -41,6 +44,7 @@
   accounts_url: 'https://accounts.platform.sh'
   pricing_url: 'https://platform.sh/pricing'
   default_from_address: '[email protected]'
+  api_token_help_url: 
'https://docs.platform.sh/gettingstarted/cli/api-tokens.html'
   available_regions:
     - eu.platform.sh
     - us.platform.sh
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.26.1/dist/installer.php 
new/platformsh-cli-3.27.0/dist/installer.php
--- old/platformsh-cli-3.26.1/dist/installer.php        2017-12-28 
12:27:23.000000000 +0100
+++ new/platformsh-cli-3.27.0/dist/installer.php        2018-01-18 
18:53:58.000000000 +0100
@@ -218,6 +218,7 @@
 }
 
 output(PHP_EOL . '  Running self:install command...');
+putenv('CLICOLOR_FORCE=' . is_ansi() ? '1' : '0');
 exec('php ' . $pharPath . ' self:install --yes 2>&1', $output, $return_var);
 output(preg_replace('/^/m', '  ', implode(PHP_EOL, $output)));
 if ($return_var === 0) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.26.1/dist/manifest.json 
new/platformsh-cli-3.27.0/dist/manifest.json
--- old/platformsh-cli-3.26.1/dist/manifest.json        2017-12-28 
12:27:23.000000000 +0100
+++ new/platformsh-cli-3.27.0/dist/manifest.json        2018-01-18 
18:53:58.000000000 +0100
@@ -1,10 +1,10 @@
 [
     {
         "name": "platform.phar",
-        "sha1": "ea31c25ce3078e00075fe798c597ef11595fc6a1",
-        "sha256": 
"4d76e1c9921f98cba69c836de8879000ea58d843c08988af8a7407f53edab19b",
-        "url": 
"https://github.com/platformsh/platformsh-cli/releases/download/v3.26.1/platform.phar";,
-        "version": "3.26.1",
+        "sha1": "152b7c59d9b7594d94a7d772e51a335502ccd5c0",
+        "sha256": 
"8df70df88de443e3375c42276263c12aeb1f8e6426c21c77f3ddf63e1e867334",
+        "url": 
"https://github.com/platformsh/platformsh-cli/releases/download/v3.27.0/platform.phar";,
+        "version": "3.27.0",
         "php": {
             "min": "5.5.9"
         },
@@ -92,6 +92,11 @@
                 "notes": "New features:\n* Support remote 
projects/environments in app:list command.\n* Add worker:list (workers) 
command.\n* Use \"deployments\" HTTP API (instead of SSH) in app:config 
command.\n* Auto-ensure webhooks on GitHub and GitLab integrations, where 
possible.\n\nOther changes:\n* Skip updates check if the Phar file is not 
writable.\n* Remove different coloration for local commands in `list` (there 
are so few listed).\n* Recommend --no-wait if snapshot:create is run in a 
non-TTY.\n* Suggest project:set-remote in RootNotFoundException.\n* Fix 
environment:drush (drush) command to use configured document root, or 
PLATFORM_DOCUMENT_ROOT where available.\n* Be stricter about when to use $_ENV, 
when getting parent variables for PHP <7.1.",
                 "show from": "3.25.0",
                 "hide from": "3.26.0"
+            },
+            {
+                "notes": "* Use browser login by default (the old login method 
is available as `auth:password-login`).\n* Set 
`--build-pull-requests-post-merge` to false by default (GitHub 
integrations).\n* Respect `--no-wait` in `environment:init`, and clear the 
environment cache afterwards.\n* In the `project:delete` command, leave access 
control to the API.\n* Support disabling or enabling colorized output via the 
CLICOLOR_FORCE environment variable.",
+                "show from": "3.26.1",
+                "hide from": "3.27.0"
             }
         ]
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.26.1/resources/oauth-listener/index.php 
new/platformsh-cli-3.27.0/resources/oauth-listener/index.php
--- old/platformsh-cli-3.26.1/resources/oauth-listener/index.php        
2017-12-28 12:27:23.000000000 +0100
+++ new/platformsh-cli-3.27.0/resources/oauth-listener/index.php        
2018-01-18 18:53:58.000000000 +0100
@@ -116,9 +116,13 @@
 
     public function __construct()
     {
+        // Set default title and headers.
         $appName = getenv('CLI_OAUTH_APP_NAME') ?: 'CLI';
         $this->title = htmlspecialchars($appName) . ': Authentication 
(temporary URL)';
-        $this->headers = ['Cache-Control' => 'no-cache'];
+        $this->headers = [
+            'Cache-Control' => 'no-cache',
+            'Content-Type' => 'text/html; charset=utf-8',
+        ];
     }
 }
 
@@ -135,7 +139,6 @@
 <!DOCTYPE html>
 <html>
 <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     <meta charset="utf-8">
     <title><?php echo $response->title; ?></title>
     <style>
@@ -151,27 +154,23 @@
 
         body {
             margin: 3em;
+            text-align: center;
         }
 
         img {
             display: block;
-            width: 100px;
-            height: 100px;
-            margin: 0 auto;
-        }
-
-        div {
-            margin: 10px;
-            text-align: center;
+            margin: 10px auto;
         }
     </style>
 </head>
 <body>
-<div>
     <img
         
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkAQMAAABKLAcXAAAABlBMVEUAAADg4ODy8Xj7AAAAAXRSTlMAQObYZgAAAB5JREFUOMtj+I8EPozyRnlU4w1NMJhCcDT+hm2MAQAJBMb6YxK/8wAAAABJRU5ErkJggg=="
-        alt="">
+        alt=""
+        width="100"
+        height="100">
+
     <?php echo $response->content; ?>
-</div>
+
 </body>
 </html>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.26.1/src/Application.php 
new/platformsh-cli-3.27.0/src/Application.php
--- old/platformsh-cli-3.26.1/src/Application.php       2017-12-28 
12:27:23.000000000 +0100
+++ new/platformsh-cli-3.27.0/src/Application.php       2018-01-18 
18:53:58.000000000 +0100
@@ -95,7 +95,7 @@
         $commands[] = new Command\Auth\AuthInfoCommand();
         $commands[] = new Command\Auth\AuthTokenCommand();
         $commands[] = new Command\Auth\LogoutCommand();
-        $commands[] = new Command\Auth\LoginCommand();
+        $commands[] = new Command\Auth\PasswordLoginCommand();
         $commands[] = new Command\Auth\BrowserLoginCommand();
         $commands[] = new Command\Certificate\CertificateAddCommand();
         $commands[] = new Command\Certificate\CertificateDeleteCommand();
@@ -221,6 +221,15 @@
             $input->setInteractive(false);
         }
 
+        // Allow the CLICOLOR_FORCE environment variable to override whether
+        // colors are used in the output.
+        /* @see StreamOutput::hasColorSupport() */
+        if (getenv('CLICOLOR_FORCE') === '0') {
+            $output->setDecorated(false);
+        } elseif (getenv('CLICOLOR_FORCE') === '1') {
+            $output->setDecorated(true);
+        }
+
         parent::configureIO($input, $output);
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.26.1/src/Command/Auth/BrowserLoginCommand.php 
new/platformsh-cli-3.27.0/src/Command/Auth/BrowserLoginCommand.php
--- old/platformsh-cli-3.26.1/src/Command/Auth/BrowserLoginCommand.php  
2017-12-28 12:27:23.000000000 +0100
+++ new/platformsh-cli-3.27.0/src/Command/Auth/BrowserLoginCommand.php  
2018-01-18 18:53:58.000000000 +0100
@@ -7,8 +7,6 @@
 use Platformsh\Cli\Service\Filesystem;
 use Platformsh\Cli\Service\Url;
 use Platformsh\Cli\Util\PortUtil;
-use Symfony\Component\Console\Exception\RuntimeException;
-use Symfony\Component\Console\Input\ArrayInput;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
@@ -19,31 +17,39 @@
     protected function configure()
     {
         $service = $this->config()->get('service.name');
+        $applicationName = $this->config()->get('application.name');
+        $executable = $this->config()->get('application.executable');
 
         $this->setName('auth:browser-login');
-
-        // The command with the "login" alias will be invoked automatically 
when
-        // needed (in interactive mode).
-        if ($this->config()->isExperimentEnabled('browser_login')) {
+        if ($this->config()->get('application.login_method') === 'browser') {
             $this->setAliases(['login']);
-        } else {
-            $this->hiddenInList = true;
         }
 
         $this->setDescription('Log in to ' . $service . ' via a browser')
             ->addOption('force', 'f', InputOption::VALUE_NONE, 'Log in again, 
even if already logged in');
         Url::configureInput($this->getDefinition());
+
+        $help = 'Use this command to log in to the ' . $applicationName . ' 
using a browser.'
+            . "\n\nAlternatively, to log in with a username and password in 
the terminal, use:\n    <info>"
+            . $executable . ' auth:password-login</info>';
+        if ($aHelp = $this->getApiTokenHelp()) {
+            $help .= "\n\n" . $aHelp;
+        }
+        $this->setHelp($help);
     }
 
     protected function execute(InputInterface $input, OutputInterface $output)
     {
-        // Disable the API token for this command.
         if ($this->api()->hasApiToken()) {
-            throw new \Exception('Cannot log in: an API token is set');
+            $this->stdErr->writeln('Cannot log in: an API token is set');
+            return 1;
         }
-        // Login can only happen during interactive use.
         if (!$input->isInteractive()) {
-            throw new RuntimeException('Non-interactive login not supported');
+            $this->stdErr->writeln('Non-interactive login is not supported.');
+            if ($aHelp = $this->getApiTokenHelp('comment')) {
+                $this->stdErr->writeln("\n" . $aHelp);
+            }
+            return 1;
         }
         $connector = $this->api()->getClient(false)->getConnector();
         if (!$input->getOption('force') && $connector->isLoggedIn()) {
@@ -51,15 +57,6 @@
             return 0;
         }
 
-        // If being run from another command, prompt.
-        if ($input instanceof ArrayInput) {
-            /** @var \Platformsh\Cli\Service\QuestionHelper $questionHelper */
-            $questionHelper = $this->getService('question_helper');
-            if (!$questionHelper->confirm("Authentication is required.\nLog in 
via a browser?")) {
-                return 1;
-            }
-        }
-
         // Set up the local PHP web server, which will serve an OAuth2 redirect
         // and wait for the response.
         // Firstly, find an address. The port needs to be within a known range,
@@ -81,12 +78,15 @@
         }
         chmod($codeFile, 0600);
 
-        // Find the authorization URL from the api.accounts_api_url.
+        // Find the authorization and token URLs.
         $apiUrl = $this->config()->get('api.accounts_api_url');
         $authHost = parse_url($apiUrl, PHP_URL_HOST);
+        $authScheme = parse_url($apiUrl, PHP_URL_SCHEME) ?: 'https';
         if (!$authHost) {
             throw new \RuntimeException('Failed to get API host.');
         }
+        $authUrl = $authScheme . '://' . $authHost . '/oauth2/authorize';
+        $tokenUrl = $authScheme . '://' . $authHost . '/oauth2/token';
 
         // Start the local server.
         $process = new Process([
@@ -100,7 +100,7 @@
         $process->setEnv([
             'CLI_OAUTH_APP_NAME' => $this->config()->get('application.name'),
             'CLI_OAUTH_STATE' => $this->getRandomState(),
-            'CLI_OAUTH_AUTH_URL' => 'https://' . $authHost . 
'/oauth2/authorize',
+            'CLI_OAUTH_AUTH_URL' => $authUrl,
             'CLI_OAUTH_CLIENT_ID' => 
$this->config()->get('api.oauth2_client_id'),
             'CLI_OAUTH_FILE' => $codeFile,
         ]);
@@ -123,10 +123,16 @@
         /** @var \Platformsh\Cli\Service\Url $urlService */
         $urlService = $this->getService('url');
         if ($urlService->openUrl($localUrl, false)) {
+            $this->stdErr->writeln(sprintf('Opened URL: <info>%s</info>', 
$localUrl));
             $this->stdErr->writeln('Please use the browser to log in.');
         } else {
-            $this->stdErr->writeln('Open the following URL and log in:');
-            $this->stdErr->writeln($localUrl);
+            $this->stdErr->writeln('Please open the following URL in a browser 
and log in:');
+            $this->stdErr->writeln('<info>' . $localUrl . '</info>');
+            $this->stdErr->writeln('');
+            $this->stdErr->writeln(sprintf(
+                'For help, quit this process (e.g. with Ctrl+C), and run: 
<info>%s help login</info>',
+                $this->config()->get('application.executable')
+            ));
         }
 
         // Wait for the file to be filled with an OAuth2 authorization code.
@@ -158,7 +164,7 @@
 
         // Using the authorization code, request an access token.
         $this->stdErr->writeln('Login information received. Verifying...');
-        $token = $this->getAccessToken($code, $localUrl, $authHost);
+        $token = $this->getAccessToken($code, $localUrl, $tokenUrl);
 
         // Finalize login: clear the cache and save the new credentials.
         /** @var \Doctrine\Common\Cache\CacheProvider $cache */
@@ -212,16 +218,18 @@
     }
 
     /**
+     * Exchange the authorization code for an access token.
+     *
      * @param string $authCode
      * @param string $redirectUri
-     * @param string $authHost
+     * @param string $tokenUrl
      *
      * @return array
      */
-    private function getAccessToken($authCode, $redirectUri, $authHost)
+    private function getAccessToken($authCode, $redirectUri, $tokenUrl)
     {
         return (new Client())->post(
-            'https://' . $authHost . '/oauth2/token',
+            $tokenUrl,
             [
                 'json' => [
                     'grant_type' => 'authorization_code',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.26.1/src/Command/Auth/LoginCommand.php 
new/platformsh-cli-3.27.0/src/Command/Auth/LoginCommand.php
--- old/platformsh-cli-3.26.1/src/Command/Auth/LoginCommand.php 2017-12-28 
12:27:23.000000000 +0100
+++ new/platformsh-cli-3.27.0/src/Command/Auth/LoginCommand.php 1970-01-01 
01:00:00.000000000 +0100
@@ -1,171 +0,0 @@
-<?php
-namespace Platformsh\Cli\Command\Auth;
-
-use GuzzleHttp\Exception\BadResponseException;
-use Platformsh\Cli\Command\CommandBase;
-use Symfony\Component\Console\Exception\RuntimeException;
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Question\Question;
-
-class LoginCommand extends CommandBase
-{
-
-    protected function configure()
-    {
-        $service = $this->config()->get('service.name');
-        $accountsUrl = $this->config()->get('service.accounts_url');
-
-        $this->setName('auth:login');
-
-        if (!$this->config()->isExperimentEnabled('browser_login')) {
-            $this->setAliases(['login']);
-        }
-
-        $this->setDescription('Log in to ' . $service . ' using a username and 
password');
-        $help = 'Use this command to log in to your ' . $service . ' account.'
-            . "\n\nYou can create an account at:\n    <info>" . $accountsUrl . 
'</info>'
-            . "\n\nIf you have an account, but you do not already have a 
password, you can set one here:\n    <info>"
-            . $accountsUrl . '/user/password</info>';
-        $this->setHelp($help);
-    }
-
-    protected function execute(InputInterface $input, OutputInterface $output)
-    {
-        // Disable the API token for this command.
-        if ($this->api()->hasApiToken()) {
-            throw new \Exception('Cannot log in: an API token is set');
-        }
-        // Login can only happen during interactive use.
-        if (!$input->isInteractive()) {
-            throw new RuntimeException('Non-interactive login not supported');
-        }
-
-        $this->stdErr->writeln(
-            'Please log in using your <info>' . 
$this->config()->get('service.name') . '</info> account.'
-        );
-        $this->stdErr->writeln('');
-        $this->configureAccount($input, $this->stdErr);
-
-        /** @var \Doctrine\Common\Cache\CacheProvider $cache */
-        $cache = $this->getService('cache');
-        $cache->flushAll();
-
-        $info = $this->api()->getClient(false)->getAccountInfo();
-        if (isset($info['username'], $info['mail'])) {
-            $this->stdErr->writeln('');
-            $this->stdErr->writeln(sprintf(
-                'You are logged in as <info>%s</info> (%s).',
-                $info['username'],
-                $info['mail']
-            ));
-        }
-    }
-
-    protected function configureAccount(InputInterface $input, OutputInterface 
$output)
-    {
-        /** @var \Platformsh\Cli\Service\QuestionHelper $questionHelper */
-        $questionHelper = $this->getService('question_helper');
-
-        $question = new Question('Your email address or username: ');
-        $question->setValidator([$this, 'validateUsernameOrEmail']);
-        $question->setMaxAttempts(5);
-        $email = $questionHelper->ask($input, $output, $question);
-
-        $question = new Question('Your password: ');
-        $question->setValidator(
-            function ($answer) {
-                if (trim($answer) == '') {
-                    throw new \RuntimeException('The password cannot be 
empty');
-                }
-
-                return $answer;
-            }
-        );
-        $question->setHidden(true);
-        $question->setMaxAttempts(5);
-        $password = $questionHelper->ask($input, $output, $question);
-
-        try {
-            $this->api()->getClient(false)
-                ->getConnector()
-                ->logIn($email, $password, true);
-        } catch (BadResponseException $e) {
-            // If a two-factor authentication challenge is received, then ask
-            // the user for their TOTP code, and then retry logging in.
-            if ($e->getResponse()->getHeader('X-Drupal-TFA')) {
-                $question = new Question("Your application verification code: 
");
-                $question->setValidator(function ($answer) use ($email, 
$password) {
-                    if (trim($answer) == '') {
-                        throw new \RuntimeException("The code cannot be 
empty.");
-                    }
-                    try {
-                        $this->api()->getClient(false)
-                            ->getConnector()
-                            ->logIn($email, $password, true, $answer);
-                    } catch (BadResponseException $e) {
-                        // If there is a two-factor authentication error, show
-                        // the error description that the server provides.
-                        //
-                        // A RuntimeException here causes the user to be asked
-                        // again for their TOTP code.
-                        if ($e->getResponse()->getHeader('X-Drupal-TFA')) {
-                            $json = $e->getResponse()->json();
-                            throw new 
\RuntimeException($json['error_description']);
-                        } else {
-                            throw $e;
-                        }
-                    }
-
-                    return $answer;
-                });
-                $question->setMaxAttempts(5);
-                $output->writeln("\nTwo-factor authentication is required.");
-                $questionHelper->ask($input, $output, $question);
-            } elseif ($e->getResponse()->getStatusCode() === 401) {
-                $output->writeln([
-                    '',
-                    '<error>Login failed. Please check your 
credentials.</error>',
-                    '',
-                    "Forgot your password? Or don't have a password yet? 
Visit:",
-                    '  <comment>' . 
$this->config()->get('service.accounts_url') . '/user/password</comment>',
-                    '',
-                ]);
-                $this->configureAccount($input, $output);
-            } else {
-                throw $e;
-            }
-        }
-    }
-
-    /**
-     * Validation callback for the username or email address.
-     *
-     * @param string $username
-     *
-     * @return string
-     */
-    public function validateUsernameOrEmail($username)
-    {
-        $username = trim($username);
-        if (!strlen($username) || (!filter_var($username, 
FILTER_VALIDATE_EMAIL) && !$this->validateUsername($username))) {
-            throw new \RuntimeException(
-                'Please enter a valid email address or username.'
-            );
-        }
-
-        return $username;
-    }
-
-    /**
-     * Validate a username.
-     *
-     * @param string $username
-     *
-     * @return bool
-     */
-    protected function validateUsername($username)
-    {
-        return preg_match('/^[a-z0-9][a-z0-9-]{0,30}[a-z0-9]$/', $username) 
=== 1;
-    }
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.26.1/src/Command/Auth/PasswordLoginCommand.php 
new/platformsh-cli-3.27.0/src/Command/Auth/PasswordLoginCommand.php
--- old/platformsh-cli-3.26.1/src/Command/Auth/PasswordLoginCommand.php 
1970-01-01 01:00:00.000000000 +0100
+++ new/platformsh-cli-3.27.0/src/Command/Auth/PasswordLoginCommand.php 
2018-01-18 18:53:58.000000000 +0100
@@ -0,0 +1,180 @@
+<?php
+namespace Platformsh\Cli\Command\Auth;
+
+use GuzzleHttp\Exception\BadResponseException;
+use Platformsh\Cli\Command\CommandBase;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Question\Question;
+
+class PasswordLoginCommand extends CommandBase
+{
+
+    protected function configure()
+    {
+        $service = $this->config()->get('service.name');
+        $accountsUrl = $this->config()->get('service.accounts_url');
+        $executable = $this->config()->get('application.executable');
+
+        $this->setName('auth:password-login');
+        if ($this->config()->get('application.login_method') === 'password') {
+            $this->setAliases(['login']);
+        }
+
+        $this->setHiddenAliases(['auth:login']);
+        $this->setDescription('Log in to ' . $service . ' using a username and 
password');
+
+        $help = 'Use this command to log in to your ' . $service . ' account 
in the terminal.'
+            . "\n\nYou can create an account at:\n    <info>" . $accountsUrl . 
'</info>'
+            . "\n\nIf you have an account, but you do not already have a 
password, you can set one here:\n    <info>"
+            . $accountsUrl . '/user/password</info>'
+            . "\n\nAlternatively, to log in to the CLI with a browser, run:\n  
  <info>"
+            . $executable . ' auth:browser-login</info>';
+        if ($aHelp = $this->getApiTokenHelp()) {
+            $help .= "\n\n" . $aHelp;
+        }
+        $this->setHelp($help);
+    }
+
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        if ($this->api()->hasApiToken()) {
+            $this->stdErr->writeln('Cannot log in: an API token is set');
+            return 1;
+        }
+        if (!$input->isInteractive()) {
+            $this->stdErr->writeln('Non-interactive login is not supported.');
+            if ($aHelp = $this->getApiTokenHelp('comment')) {
+                $this->stdErr->writeln("\n" . $aHelp);
+            }
+            return 1;
+        }
+
+        $this->stdErr->writeln(
+            'Please log in using your <info>' . 
$this->config()->get('service.name') . '</info> account.'
+        );
+        $this->stdErr->writeln('');
+        $this->configureAccount($input, $this->stdErr);
+
+        /** @var \Doctrine\Common\Cache\CacheProvider $cache */
+        $cache = $this->getService('cache');
+        $cache->flushAll();
+
+        $info = $this->api()->getClient(false)->getAccountInfo();
+        if (isset($info['username'], $info['mail'])) {
+            $this->stdErr->writeln('');
+            $this->stdErr->writeln(sprintf(
+                'You are logged in as <info>%s</info> (%s).',
+                $info['username'],
+                $info['mail']
+            ));
+        }
+    }
+
+    protected function configureAccount(InputInterface $input, OutputInterface 
$output)
+    {
+        /** @var \Platformsh\Cli\Service\QuestionHelper $questionHelper */
+        $questionHelper = $this->getService('question_helper');
+
+        $question = new Question('Your email address or username: ');
+        $question->setValidator([$this, 'validateUsernameOrEmail']);
+        $question->setMaxAttempts(5);
+        $email = $questionHelper->ask($input, $output, $question);
+
+        $question = new Question('Your password: ');
+        $question->setValidator(
+            function ($answer) {
+                if (trim($answer) == '') {
+                    throw new \RuntimeException('The password cannot be 
empty');
+                }
+
+                return $answer;
+            }
+        );
+        $question->setHidden(true);
+        $question->setMaxAttempts(5);
+        $password = $questionHelper->ask($input, $output, $question);
+
+        try {
+            $this->api()->getClient(false)
+                ->getConnector()
+                ->logIn($email, $password, true);
+        } catch (BadResponseException $e) {
+            // If a two-factor authentication challenge is received, then ask
+            // the user for their TOTP code, and then retry logging in.
+            if ($e->getResponse()->getHeader('X-Drupal-TFA')) {
+                $question = new Question("Your application verification code: 
");
+                $question->setValidator(function ($answer) use ($email, 
$password) {
+                    if (trim($answer) == '') {
+                        throw new \RuntimeException("The code cannot be 
empty.");
+                    }
+                    try {
+                        $this->api()->getClient(false)
+                            ->getConnector()
+                            ->logIn($email, $password, true, $answer);
+                    } catch (BadResponseException $e) {
+                        // If there is a two-factor authentication error, show
+                        // the error description that the server provides.
+                        //
+                        // A RuntimeException here causes the user to be asked
+                        // again for their TOTP code.
+                        if ($e->getResponse()->getHeader('X-Drupal-TFA')) {
+                            $json = $e->getResponse()->json();
+                            throw new 
\RuntimeException($json['error_description']);
+                        } else {
+                            throw $e;
+                        }
+                    }
+
+                    return $answer;
+                });
+                $question->setMaxAttempts(5);
+                $output->writeln("\nTwo-factor authentication is required.");
+                $questionHelper->ask($input, $output, $question);
+            } elseif ($e->getResponse()->getStatusCode() === 401) {
+                $output->writeln([
+                    '',
+                    '<error>Login failed. Please check your 
credentials.</error>',
+                    '',
+                    "Forgot your password? Or don't have a password yet? 
Visit:",
+                    '  <comment>' . 
$this->config()->get('service.accounts_url') . '/user/password</comment>',
+                    '',
+                ]);
+                $this->configureAccount($input, $output);
+            } else {
+                throw $e;
+            }
+        }
+    }
+
+    /**
+     * Validation callback for the username or email address.
+     *
+     * @param string $username
+     *
+     * @return string
+     */
+    public function validateUsernameOrEmail($username)
+    {
+        $username = trim($username);
+        if (!strlen($username) || (!filter_var($username, 
FILTER_VALIDATE_EMAIL) && !$this->validateUsername($username))) {
+            throw new \RuntimeException(
+                'Please enter a valid email address or username.'
+            );
+        }
+
+        return $username;
+    }
+
+    /**
+     * Validate a username.
+     *
+     * @param string $username
+     *
+     * @return bool
+     */
+    protected function validateUsername($username)
+    {
+        return preg_match('/^[a-z0-9][a-z0-9-]{0,30}[a-z0-9]$/', $username) 
=== 1;
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.26.1/src/Command/CommandBase.php 
new/platformsh-cli-3.27.0/src/Command/CommandBase.php
--- old/platformsh-cli-3.26.1/src/Command/CommandBase.php       2017-12-28 
12:27:23.000000000 +0100
+++ new/platformsh-cli-3.27.0/src/Command/CommandBase.php       2018-01-18 
18:53:58.000000000 +0100
@@ -324,14 +324,29 @@
      */
     public function login()
     {
+        $success = false;
         if ($this->output && $this->input && $this->input->isInteractive()) {
-            $exitCode = $this->runOtherCommand('login');
-            $this->stdErr->writeln('');
-            if ($exitCode === 0) {
-                return;
+            $method = $this->config()->get('application.login_method');
+            if ($method === 'browser') {
+                /** @var \Platformsh\Cli\Service\QuestionHelper 
$questionHelper */
+                $questionHelper = $this->getService('question_helper');
+                $urlService = $this->getService('url');
+                if ($urlService->canOpenUrls()
+                    && $questionHelper->confirm("Authentication is 
required.\nLog in via a browser?")) {
+                    $this->stdErr->writeln('');
+                    $exitCode = $this->runOtherCommand('auth:browser-login');
+                    $this->stdErr->writeln('');
+                    $success = $exitCode === 0;
+                }
+            } elseif ($method === 'password') {
+                $exitCode = $this->runOtherCommand('auth:password-login');
+                $this->stdErr->writeln('');
+                $success = $exitCode === 0;
             }
         }
-        throw new LoginRequiredException();
+        if (!$success) {
+            throw new LoginRequiredException();
+        }
     }
 
     /**
@@ -1145,7 +1160,24 @@
      */
     public function isEnabled()
     {
-        return !$this->config()->has('disabled_commands')
-            || !in_array($this->getName(), 
$this->config()->get('disabled_commands'));
+        return !$this->config()->has('application.disabled_commands')
+            || !in_array($this->getName(), 
$this->config()->get('application.disabled_commands'));
+    }
+
+    /**
+     * Get help on how to use API tokens.
+     *
+     * @param string $tag
+     *
+     * @return string|null
+     */
+    protected function getApiTokenHelp($tag = 'info')
+    {
+        if ($this->config()->has('service.api_token_help_url')) {
+            return "To authenticate non-interactively using an API token, 
see:\n    <$tag>"
+                . $this->config()->get('service.api_token_help_url') . 
"</$tag>";
+        }
+
+        return null;
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.26.1/src/Command/Environment/EnvironmentInitCommand.php 
new/platformsh-cli-3.27.0/src/Command/Environment/EnvironmentInitCommand.php
--- 
old/platformsh-cli-3.26.1/src/Command/Environment/EnvironmentInitCommand.php    
    2017-12-28 12:27:23.000000000 +0100
+++ 
new/platformsh-cli-3.27.0/src/Command/Environment/EnvironmentInitCommand.php    
    2018-01-18 18:53:58.000000000 +0100
@@ -56,9 +56,13 @@
             throw $e;
         }
 
-        /** @var \Platformsh\Cli\Service\ActivityMonitor $activityMonitor */
-        $activityMonitor = $this->getService('activity_monitor');
-        $activityMonitor->waitAndLog($activity);
+        $this->api()->clearEnvironmentsCache($environment->project);
+
+        if (!$input->getOption('no-wait')) {
+            /** @var \Platformsh\Cli\Service\ActivityMonitor $activityMonitor 
*/
+            $activityMonitor = $this->getService('activity_monitor');
+            $activityMonitor->waitAndLog($activity);
+        }
 
         return 0;
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.26.1/src/Command/Integration/IntegrationCommandBase.php 
new/platformsh-cli-3.27.0/src/Command/Integration/IntegrationCommandBase.php
--- 
old/platformsh-cli-3.26.1/src/Command/Integration/IntegrationCommandBase.php    
    2017-12-28 12:27:23.000000000 +0100
+++ 
new/platformsh-cli-3.27.0/src/Command/Integration/IntegrationCommandBase.php    
    2018-01-18 18:53:58.000000000 +0100
@@ -112,6 +112,7 @@
                 ],
                 'build_pull_requests' => true,
               ],
+              'default' => false,
               'description' => 'GitHub: build pull requests based on their 
post-merge state',
               'questionLine' => 'Build pull requests based on their post-merge 
state',
             ]),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.26.1/src/Command/Project/ProjectDeleteCommand.php 
new/platformsh-cli-3.27.0/src/Command/Project/ProjectDeleteCommand.php
--- old/platformsh-cli-3.26.1/src/Command/Project/ProjectDeleteCommand.php      
2017-12-28 12:27:23.000000000 +0100
+++ new/platformsh-cli-3.27.0/src/Command/Project/ProjectDeleteCommand.php      
2018-01-18 18:53:58.000000000 +0100
@@ -1,6 +1,7 @@
 <?php
 namespace Platformsh\Cli\Command\Project;
 
+use GuzzleHttp\Exception\ClientException;
 use Platformsh\Cli\Command\CommandBase;
 use Symfony\Component\Console\Exception\InvalidArgumentException as 
ConsoleInvalidArgumentException;
 use Symfony\Component\Console\Input\InputArgument;
@@ -24,11 +25,6 @@
         $this->validateInput($input);
         $project = $this->getSelectedProject();
 
-        if ($this->api()->getMyAccount()['uuid'] !== $project->owner) {
-            $this->stdErr->writeln("Only the project's owner can delete it.");
-            return 1;
-        }
-
         /** @var \Platformsh\Cli\Service\QuestionHelper $questionHelper */
         $questionHelper = $this->getService('question_helper');
 
@@ -62,7 +58,19 @@
             throw new \RuntimeException('Subscription not found: ' . 
$subscriptionId);
         }
 
-        $subscription->delete();
+        try {
+            $subscription->delete();
+        } catch (ClientException $e) {
+            $response = $e->getResponse();
+            if ($response !== null && $response->getStatusCode() === 403) {
+                if ($project->owner !== $this->api()->getMyAccount()['uuid']) {
+                    $this->stdErr->writeln("Only the project's owner can 
delete it.");
+                    return 1;
+                }
+            }
+            throw $e;
+        }
+
         $this->api()->clearProjectsCache();
 
         $this->stdErr->writeln('');
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.26.1/src/Command/Self/SelfBuildCommand.php 
new/platformsh-cli-3.27.0/src/Command/Self/SelfBuildCommand.php
--- old/platformsh-cli-3.26.1/src/Command/Self/SelfBuildCommand.php     
2017-12-28 12:27:23.000000000 +0100
+++ new/platformsh-cli-3.27.0/src/Command/Self/SelfBuildCommand.php     
2018-01-18 18:53:58.000000000 +0100
@@ -209,6 +209,9 @@
                 'show from' => $oldVersion,
                 'hide from' => $version,
             ];
+            $this->stdErr->writeln('<info>Changes:</info>');
+            $this->stdErr->writeln($changelog);
+            $this->stdErr->writeln('');
         }
         $result = file_put_contents($manifestFile, json_encode($manifest, 
JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
         if ($result !== false) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.26.1/src/Console/EventSubscriber.php 
new/platformsh-cli-3.27.0/src/Console/EventSubscriber.php
--- old/platformsh-cli-3.26.1/src/Console/EventSubscriber.php   2017-12-28 
12:27:23.000000000 +0100
+++ new/platformsh-cli-3.27.0/src/Console/EventSubscriber.php   2018-01-18 
18:53:58.000000000 +0100
@@ -18,7 +18,6 @@
 class EventSubscriber implements EventSubscriberInterface
 {
     protected $config;
-    protected $api;
 
     /**
      * @param \Platformsh\Cli\Service\Config $config
@@ -68,22 +67,23 @@
 
             // Create a friendlier message for the OAuth2 "Invalid refresh 
token"
             // error.
-            $loginCommand = sprintf('%s login', 
$this->config->get('application.executable'));
             if ($response->getStatusCode() === 400
                 && $requestConfig['auth'] === 'oauth2'
                 && isset($json['error_description'])
                 && $json['error_description'] === 'Invalid refresh token') {
                 $event->setException(new LoginRequiredException(
-                    "Invalid refresh token. \nPlease log in again by running: 
$loginCommand",
+                    'Invalid refresh token.',
                     $request,
-                    $response
+                    $response,
+                    $this->config
                 ));
                 $event->stopPropagation();
             } elseif ($response->getStatusCode() === 401 && 
$requestConfig['auth'] === 'oauth2') {
                 $event->setException(new LoginRequiredException(
-                    "Unauthorized. \nPlease log in again by running: 
$loginCommand",
+                    'Unauthorized.',
                     $request,
-                    $response
+                    $response,
+                    $this->config
                 ));
                 $event->stopPropagation();
             } elseif ($response->getStatusCode() === 403 && 
$requestConfig['auth'] === 'oauth2') {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.26.1/src/Exception/LoginRequiredException.php 
new/platformsh-cli-3.27.0/src/Exception/LoginRequiredException.php
--- old/platformsh-cli-3.26.1/src/Exception/LoginRequiredException.php  
2017-12-28 12:27:23.000000000 +0100
+++ new/platformsh-cli-3.27.0/src/Exception/LoginRequiredException.php  
2018-01-18 18:53:58.000000000 +0100
@@ -2,8 +2,43 @@
 
 namespace Platformsh\Cli\Exception;
 
+use GuzzleHttp\Message\RequestInterface;
+use GuzzleHttp\Message\ResponseInterface;
+use Platformsh\Cli\Service\Config;
+
 class LoginRequiredException extends HttpException
 {
-    protected $message = 'Not logged in.';
+    protected $message = 'Authentication is required.';
     protected $code = 3;
+    private $config;
+
+    public function __construct(
+        $message = null,
+        RequestInterface $request = null,
+        ResponseInterface $response = null,
+        Config $config = null)
+    {
+        $message = $message ?: $this->message;
+        $this->config = $config ?: new Config();
+        $executable = $this->config->get('application.executable');
+        $message .= "\n\nPlease log in by running:\n    <comment>$executable 
login</comment>";
+        if ($aHelp = $this->getApiTokenHelp()) {
+            $message .= "\n\n" . $aHelp;
+        }
+
+        parent::__construct($message, $request, $response);
+    }
+
+    /**
+     * @return string|null
+     */
+    private function getApiTokenHelp()
+    {
+        if ($this->config->has('service.api_token_help_url')) {
+            return "To authenticate non-interactively using an API token, 
see:\n    <comment>"
+                . $this->config->get('service.api_token_help_url') . 
'</comment>';
+        }
+
+        return null;
+    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.26.1/src/Service/Config.php 
new/platformsh-cli-3.27.0/src/Service/Config.php
--- old/platformsh-cli-3.26.1/src/Service/Config.php    2017-12-28 
12:27:23.000000000 +0100
+++ new/platformsh-cli-3.27.0/src/Service/Config.php    2018-01-18 
18:53:58.000000000 +0100
@@ -204,6 +204,7 @@
             'local.drush_executable' => 'local.drush_executable',
             'experimental' => 'experimental',
             'updates' => 'updates',
+            'application.login_method' => 'application.login_method',
         ];
 
         $userConfig = $this->getUserConfig();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.26.1/src/Service/Url.php 
new/platformsh-cli-3.27.0/src/Service/Url.php
--- old/platformsh-cli-3.26.1/src/Service/Url.php       2017-12-28 
12:27:23.000000000 +0100
+++ new/platformsh-cli-3.27.0/src/Service/Url.php       2018-01-18 
18:53:58.000000000 +0100
@@ -46,6 +46,16 @@
     }
 
     /**
+     * Test whether URL(s) can be opened in the default browser.
+     *
+     * @return bool
+     */
+    public function canOpenUrls()
+    {
+        return $this->hasDisplay() && $this->getDefaultBrowser();
+    }
+
+    /**
      * Open a URL in the browser, or print it.
      *
      * @param string $url
@@ -56,10 +66,30 @@
      */
     public function openUrl($url, $print = true)
     {
+        $browserOption = $this->input->hasOption('browser') ? 
$this->input->getOption('browser') : null;
+        $open = true;
         $success = false;
-        if ($browser = $this->getBrowser()) {
+
+        // If the user wants to pipe the output to another command, stop here.
+        if ($this->input->hasOption('pipe') && 
$this->input->getOption('pipe')) {
+            $open = false;
+        }
+        // Check if the user has requested not to use a browser.
+        elseif ($browserOption === '0') {
+            $open = false;
+        }
+        // Check for a display (if not on Windows or OS X).
+        elseif (!$this->hasDisplay()) {
+            $open = false;
+            $this->stdErr->writeln('Not opening URL (no display found)', 
OutputInterface::VERBOSITY_VERBOSE);
+        }
+
+        // Open the URL.
+        if ($open && ($browser = $this->getBrowser($browserOption))) {
             $success = $this->shell->executeSimple($browser . ' ' . 
escapeshellarg($url)) === 0;
         }
+
+        // Print the URL.
         if ($print) {
             $this->output->writeln($url);
         }
@@ -68,39 +98,33 @@
     }
 
     /**
+     * Check for a display (if not on Windows or OS X).
+     *
+     * @return bool
+     */
+    public function hasDisplay()
+    {
+        return getenv('DISPLAY') || OsUtil::isWindows() || OsUtil::isOsX();
+    }
+
+    /**
      * Finds the browser to use.
      *
+     * @param string|null $browserOption
+     *
      * @return string|false A browser command, or false if no browser can or
      *                      should be used.
      */
-    protected function getBrowser()
+    private function getBrowser($browserOption = null)
     {
-        $browser = $this->input->hasOption('browser') ? 
$this->input->getOption('browser') : null;
-
-        // If the user wants to pipe the output to another command, stop here.
-        if ($this->input->hasOption('pipe') && 
$this->input->getOption('pipe')) {
-            return false;
-        }
-
-        // Check if the user has requested not to use a browser.
-        if ($browser === '0') {
-            return false;
-        }
-
-        // Check for a display (if not on Windows or OS X).
-        if (!getenv('DISPLAY') && !OsUtil::isWindows() && !OsUtil::isOsX()) {
-            $this->stdErr->writeln('Not opening URL (no display found)', 
OutputInterface::VERBOSITY_VERBOSE);
-            return false;
-        }
-
-        if (!empty($browser)) {
-            list($command, ) = explode(' ', $browser, 2);
+        if (!empty($browserOption)) {
+            list($command, ) = explode(' ', $browserOption, 2);
             if (!$this->shell->commandExists($command)) {
                 $this->stdErr->writeln(sprintf('Command not found: 
<error>%s</error>', $command));
                 return false;
             }
 
-            return $browser;
+            return $browserOption;
         }
 
         return $this->getDefaultBrowser();
@@ -111,13 +135,14 @@
      *
      * @return string|false
      */
-    protected function getDefaultBrowser()
+    private function getDefaultBrowser()
     {
+        $browsers = ['xdg-open', 'gnome-open', 'start'];
         if (OsUtil::isOsX()) {
-            return 'open';
+            $browsers = ['open'];
         }
 
-        foreach (['xdg-open', 'gnome-open', 'start'] as $browser) {
+        foreach ($browsers as $browser) {
             if ($this->shell->commandExists($browser)) {
                 return $browser;
             }

++++++ platformsh-cli-vendor.tar.xz ++++++
++++ 2275 lines of diff (skipped)


Reply via email to