Hello community,

here is the log from the commit of package platformsh-cli for openSUSE:Factory 
checked in at 2019-07-15 22:44:02
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/platformsh-cli (Old)
 and      /work/SRC/openSUSE:Factory/.platformsh-cli.new.1887 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "platformsh-cli"

Mon Jul 15 22:44:02 2019 rev:76 rq:714517 version:3.44.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/platformsh-cli/platformsh-cli.changes    
2019-07-02 15:18:12.838721695 +0200
+++ /work/SRC/openSUSE:Factory/.platformsh-cli.new.1887/platformsh-cli.changes  
2019-07-15 22:44:04.179901522 +0200
@@ -1,0 +2,27 @@
+Wed Jul 10 19:38:42 UTC 2019 - ji...@boombatower.com
+
+- Update to version 3.44.0:
+  * Release v3.44.0
+  * Match user email addresess case-insensitively
+  * Substitute phar path at runtime without realpath [skip changelog]
+  * Use Route class for more structure and to fix upstream name
+  * Run phar directly [skip changelog]
+  * Test forcing display on or off
+  * Add examples
+  * Test effect of --primary and --browser options
+  * Group command tests under "commands" and fix namespaces
+  * url command: just print all URLs when there is no display/browser
+  * Always prefer primary route in "url" command
+  * Allow url command to read from local environment
+  * Prefer the primary route as the site URL
+  * Use embedded user information if available
+  * Allow app:config-get to read from PLATFORM_APPLICATION
+  * Fix "Failed to decode" in relationships command when there are no 
relationships
+  * Adapt welcome command for offline-on-container uses
+  * Do not require login for self:stats
+  * Improve app/worker choice message
+  * Update index.php with a source link
+  * Clearer error for no config file
+  * Dynamic app name in dev build web page
+
+-------------------------------------------------------------------

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

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

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

Other differences:
------------------
++++++ platformsh-cli.spec ++++++
--- /var/tmp/diff_new_pack.9sePyw/_old  2019-07-15 22:44:04.967901335 +0200
+++ /var/tmp/diff_new_pack.9sePyw/_new  2019-07-15 22:44:04.971901334 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           platformsh-cli
-Version:        3.43.2
+Version:        3.44.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.9sePyw/_old  2019-07-15 22:44:05.007901325 +0200
+++ /var/tmp/diff_new_pack.9sePyw/_new  2019-07-15 22:44:05.007901325 +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.43.2</param>
+    <param name="revision">refs/tags/v3.44.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.9sePyw/_old  2019-07-15 22:44:05.031901319 +0200
+++ /var/tmp/diff_new_pack.9sePyw/_new  2019-07-15 22:44:05.031901319 +0200
@@ -1,6 +1,6 @@
 <servicedata>
   <service name="tar_scm">
     <param name="url">git://github.com/platformsh/platformsh-cli.git</param>
-    <param 
name="changesrevision">a59718a8f1fda77feae7c0dbada291e6fbbddadd</param>
+    <param 
name="changesrevision">49c17dee8c54c4b64794b787d6d2a09e0372413d</param>
   </service>
 </servicedata>

++++++ platformsh-cli-3.43.2.tar.xz -> platformsh-cli-3.44.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.43.2/.platform.app.yaml 
new/platformsh-cli-3.44.0/.platform.app.yaml
--- old/platformsh-cli-3.43.2/.platform.app.yaml        2019-06-27 
13:54:49.000000000 +0200
+++ new/platformsh-cli-3.44.0/.platform.app.yaml        2019-07-10 
12:59:25.000000000 +0200
@@ -13,6 +13,7 @@
     ./bin/platform self:build --no-composer-rebuild --yes --replace-version 
"$version" --output web/platform.phar
 
     cat << EOF > .environment
+    alias platform="php \${PLATFORM_APP_DIR}/web/platform.phar"
     export CLI_URL_PATH=platform.phar
     export CLI_BUILD_DATE="$(date)"
     export CLI_VERSION="$version"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.43.2/dist/dev-build-index.php 
new/platformsh-cli-3.44.0/dist/dev-build-index.php
--- old/platformsh-cli-3.43.2/dist/dev-build-index.php  2019-06-27 
13:54:49.000000000 +0200
+++ new/platformsh-cli-3.44.0/dist/dev-build-index.php  2019-07-10 
12:59:25.000000000 +0200
@@ -1,8 +1,48 @@
+<?php /** @noinspection PhpLanguageLevelInspection */
+declare(strict_types=1);
+/**
+ * @file
+ * This is the index.php script for automated CLI builds on Platform.sh.
+ */
+
+use Platformsh\Cli\Service\Config;
+
+require '../vendor/autoload.php';
+$config = new Config();
+$appName = $config->get('application.name');
+$envPrefix = $config->get('service.env_prefix');
+$branch = getenv($envPrefix . 'BRANCH', true);
+$treeId = getenv($envPrefix . 'TREE_ID', true);
+
+$pharUrl = getenv('CLI_URL_PATH', true) ?: 'platform.phar';
+$pharHash = hash_file('sha256', __DIR__ . '/' . ltrim(getenv('CLI_URL_PATH', 
true), '/'));
+if ($timestamp = getenv('CLI_BUILD_DATE', true)) {
+    $pharDate = date('c', is_int($timestamp) ? $timestamp : 
strtotime($timestamp));
+} else {
+    $pharDate = false;
+}
+
+if ($config->has('application.github_repo')) {
+    $sourceLink = 'https://github.com/' . 
$config->get('application.github_repo');
+    $sourceLinkSpecific = $sourceLink;
+    if ($branch) {
+        if (strpos($branch, 'pr-') === 0 && is_numeric(substr($branch, 3))) {
+            $sourceLinkSpecific .= '/pull/' . substr($branch, 3);
+        } else {
+            $sourceLinkSpecific .= '/tree/' . rawurlencode($branch);
+        }
+    }
+} else {
+    $sourceLink = false;
+    $sourceLinkSpecific = false;
+}
+
+?>
 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="utf-8">
-    <title>Platform.sh CLI | dev build</title>
+    <title><?= htmlspecialchars($appName) ?> | dev build</title>
     <style>
         html {
             font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
@@ -19,6 +59,10 @@
         h1, h2 {
             text-align: center;
         }
+        h1 a {
+            color: inherit !important;
+            text-decoration: none !important;
+        }
 
         body {
             margin: 3em;
@@ -43,32 +87,43 @@
         width="100"
         height="100">
 
-    <h1>Platform.sh CLI</h1>
+    <?php if ($sourceLink): ?>
+        <h1><a href="<?= htmlspecialchars($sourceLink) ?>"><?= 
htmlspecialchars($appName) ?></a></h1>
+    <?php else: ?>
+        <h1>><?= htmlspecialchars($appName) ?></h1>
+    <?php endif; ?>
     <h2>Development build</h2>
 
-    <p>
-        Download:
-        <a href="<?= getenv('CLI_URL_PATH') ?: 'platform.phar' ?>"><?= 
getenv('CLI_URL_PATH') ?: 'platform.phar' ?></a>
-    </p>
-    <p>
-        Build date:
-        <code><?php
-            $date = getenv('CLI_BUILD_DATE');
-            if ($date !== false) {
-                echo date('c', is_int($date) ? $date : strtotime($date));
-            } else {
-                echo 'unknown';
-            }
-            ?></code>
-    </p>
-    <p>
-        SHA-256 hash:
-        <code><?= hash_file('sha256', __DIR__ . '/' . 
ltrim(getenv('CLI_URL_PATH'), '/')) ?></code>
-    </p>
-    <p>
-        Tree ID:
-        <code><?= getenv('PLATFORM_TREE_ID') ?: 'unknown' ?></code>
-    </p>
+    <?php if ($pharUrl): ?>
+        <p>
+            Download: <a href="<?= htmlspecialchars($pharUrl) ?>"><?= 
htmlspecialchars($pharUrl) ?></a>
+        </p>
+    <?php endif; ?>
+    <?php if ($pharDate): ?>
+        <p>
+            Build date: <code><?= htmlspecialchars($pharDate) ?></code>
+        </p>
+    <?php endif; ?>
+    <?php if ($pharHash): ?>
+        <p>
+            SHA-256 hash: <code><?= htmlspecialchars($pharHash) ?></code>
+        </p>
+    <?php endif; ?>
+    <?php if ($treeId): ?>
+        <p>
+            Tree ID: <code><?= htmlspecialchars($treeId) ?></code>
+        </p>
+    <?php endif; ?>
+    <?php if ($branch): ?>
+        <p>
+            Branch: <code><?= htmlspecialchars($branch) ?></code>
+        </p>
+    <?php endif; ?>
+    <?php if ($sourceLinkSpecific): ?>
+        <p>
+            Source: <a href="<?= htmlspecialchars($sourceLinkSpecific) ?>"><?= 
htmlspecialchars($sourceLinkSpecific) ?></a>
+        </p>
+    <?php endif; ?>
 
 </body>
 </html>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.43.2/dist/manifest.json 
new/platformsh-cli-3.44.0/dist/manifest.json
--- old/platformsh-cli-3.43.2/dist/manifest.json        2019-06-27 
13:54:49.000000000 +0200
+++ new/platformsh-cli-3.44.0/dist/manifest.json        2019-07-10 
12:59:25.000000000 +0200
@@ -17,10 +17,10 @@
     },
     {
         "name": "platform.phar",
-        "sha1": "9a5cd1c80f64661e624654b0bdd5aa9f68f1b6d5",
-        "sha256": 
"bce981101ea15f57549a613f45e7e735269d9cc95b889f2b7a2abbc76e8ff1de",
-        "url": 
"https://github.com/platformsh/platformsh-cli/releases/download/v3.43.2/platform.phar";,
-        "version": "3.43.2",
+        "sha1": "46d60cc2b9a106e6cc95d88a9051997979af6acb",
+        "sha256": 
"f1620dfd149fd17071c7bb538eb0b8ccb847d29dd13169ace67ceab8c2a63585",
+        "url": 
"https://github.com/platformsh/platformsh-cli/releases/download/v3.44.0/platform.phar";,
+        "version": "3.44.0",
         "php": {
             "min": "5.5.9"
         },
@@ -203,6 +203,11 @@
                 "notes": "* Allow some commands to read from local environment 
variables when available:\n    * `route:list` (routes) and `route:get` can read 
from PLATFORM_ROUTES\n    * `relationship:list` (relationships) can read from 
PLATFORM_RELATIONSHIPS\n    * New `decode` command, to decode a base64- and 
JSON-encoded string such as\n      PLATFORM_VARIABLES, PLATFORM_APPLICATION, 
etc.\n* Add --id and --primary options to route:get command, to select a 
route.\n* Add `url` property to all relationships in `relationships` command 
(e.g. to\n  extract a DSN for a database).\n* Multiple changes to the `db:size` 
command (by @matthiaz):\n    * Improve accuracy of size estimates by altering 
psql commands and querying\n      for InnoDB-specific information.\n    * Add 
--bytes (-B) option to display sizes in bytes.\n    * Check if InnoDB tables 
can be optimized, and run optimizations\n      automatically with the 
`--cleanup` option.",
                 "show from": "3.42.0",
                 "hide from": "3.43.0"
+            },
+            {
+                "notes": "New features:\n\n* Allow the `app:config` command to 
read from PLATFORM_APPLICATION in the\n  local environment.\n* Improvements to 
the `environment:url` (`url`) command:\n    * Read URLs from PLATFORM_ROUTES in 
the local environment.\n    * Always prefer the primary route URL when sorting 
URLs.\n    * Add a --primary option, to print or open only the primary route 
URL.\n    * Just print URLs (without interaction) when there is no 
display/browser\n      available.\n\nOther changes:\n\n* Prefer the primary 
route as the site URL (for Drush aliases, etc.).\n* Use embedded user account 
information if available in the access API (small\n  performance 
improvement).\n* Fix \"Failed to decode\" in the `relationships` command when 
there are no\n  relationships.\n* Adapt `welcome` command for 
offline-on-container uses. If you install the CLI\n  into your own Platform.sh 
project, running `platform` on its own now gives\n  you a list of useful 
commands that work \"offline\" without needing to\n  configure an API token.\n* 
Do not require login for the `self:stats` command.\n* Improve app/worker choice 
message.\n* Clearer error for no config (`.platform.app.yaml`) file.\n* Match 
user email addresses case-insensitively. This fixes all user commands\n  that 
need an email address (user:add, user:get, user:update and user:delete).",
+                "show from": "3.43.0",
+                "hide from": "3.44.0"
             }
         ]
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.43.2/src/Command/App/AppConfigGetCommand.php 
new/platformsh-cli-3.44.0/src/Command/App/AppConfigGetCommand.php
--- old/platformsh-cli-3.43.2/src/Command/App/AppConfigGetCommand.php   
2019-06-27 13:54:49.000000000 +0200
+++ new/platformsh-cli-3.44.0/src/Command/App/AppConfigGetCommand.php   
2019-07-10 12:59:25.000000000 +0200
@@ -2,6 +2,7 @@
 namespace Platformsh\Cli\Command\App;
 
 use Platformsh\Cli\Command\CommandBase;
+use Platformsh\Cli\Model\AppConfig;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
@@ -29,15 +30,25 @@
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
-        $this->validateInput($input);
-        $this->warnAboutDeprecatedOptions(['identity-file']);
+        // Allow override via PLATFORM_APPLICATION.
+        $prefix = $this->config()->get('service.env_prefix');
+        if (getenv($prefix . 'APPLICATION') && 
!$this->doesEnvironmentConflictWithCommandLine($input)) {
+            $this->debug('Reading application config from environment variable 
' . $prefix . 'APPLICATION');
+            $decoded = json_decode(base64_decode(getenv($prefix . 
'APPLICATION'), true), true);
+            if (!is_array($decoded)) {
+                throw new \RuntimeException('Failed to decode: ' . $prefix . 
'APPLICATION');
+            }
+            $appConfig = new AppConfig($decoded);
+        } else {
+            $this->validateInput($input);
+            $this->warnAboutDeprecatedOptions(['identity-file']);
 
-        $appConfig = $this->selectRemoteContainer($input, false)
-            ->getConfig()
-            ->getNormalized();
+            $appConfig = $this->selectRemoteContainer($input, false)
+                ->getConfig();
+        }
 
         /** @var \Platformsh\Cli\Service\PropertyFormatter $formatter */
         $formatter = $this->getService('property_formatter');
-        $formatter->displayData($output, $appConfig, 
$input->getOption('property'));
+        $formatter->displayData($output, $appConfig->getNormalized(), 
$input->getOption('property'));
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.43.2/src/Command/CommandBase.php 
new/platformsh-cli-3.44.0/src/Command/CommandBase.php
--- old/platformsh-cli-3.43.2/src/Command/CommandBase.php       2019-06-27 
13:54:49.000000000 +0200
+++ new/platformsh-cli-3.44.0/src/Command/CommandBase.php       2019-07-10 
12:59:25.000000000 +0200
@@ -341,6 +341,7 @@
             if ($method === 'browser') {
                 /** @var \Platformsh\Cli\Service\QuestionHelper 
$questionHelper */
                 $questionHelper = $this->getService('question_helper');
+                /** @var \Platformsh\Cli\Service\Url $url */
                 $urlService = $this->getService('url');
                 if ($urlService->canOpenUrls()
                     && $questionHelper->confirm("Authentication is 
required.\nLog in via a browser?")) {
@@ -957,7 +958,7 @@
         } elseif ($input->isInteractive()) {
             /** @var \Platformsh\Cli\Service\QuestionHelper $questionHelper */
             $questionHelper = $this->getService('question_helper');
-            if ($includeWorkers) {
+            if ($includeWorkers && count($deployment->workers)) {
                 $text = sprintf('Enter a number to choose %s app or %s 
worker:',
                     count($appNames) === 1 ? 'the' : 'an',
                     count($choices) === 2 ? 'its' : 'a'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.43.2/src/Command/Environment/EnvironmentRelationshipsCommand.php
 
new/platformsh-cli-3.44.0/src/Command/Environment/EnvironmentRelationshipsCommand.php
--- 
old/platformsh-cli-3.43.2/src/Command/Environment/EnvironmentRelationshipsCommand.php
       2019-06-27 13:54:49.000000000 +0200
+++ 
new/platformsh-cli-3.44.0/src/Command/Environment/EnvironmentRelationshipsCommand.php
       2019-07-10 12:59:25.000000000 +0200
@@ -39,7 +39,7 @@
         if (getenv($prefix . 'RELATIONSHIPS') && 
!$this->doesEnvironmentConflictWithCommandLine($input)) {
             $this->debug('Reading relationships from local environment 
variable ' . $prefix . 'RELATIONSHIPS');
             $decoded = json_decode(base64_decode(getenv($prefix . 
'RELATIONSHIPS'), true), true);
-            if (empty($decoded)) {
+            if (!is_array($decoded)) {
                 throw new \RuntimeException('Failed to decode: ' . $prefix . 
'RELATIONSHIPS');
             }
             $relationships = $decoded;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.43.2/src/Command/Environment/EnvironmentUrlCommand.php 
new/platformsh-cli-3.44.0/src/Command/Environment/EnvironmentUrlCommand.php
--- old/platformsh-cli-3.43.2/src/Command/Environment/EnvironmentUrlCommand.php 
2019-06-27 13:54:49.000000000 +0200
+++ new/platformsh-cli-3.44.0/src/Command/Environment/EnvironmentUrlCommand.php 
2019-07-10 12:59:25.000000000 +0200
@@ -2,8 +2,10 @@
 namespace Platformsh\Cli\Command\Environment;
 
 use Platformsh\Cli\Command\CommandBase;
+use Platformsh\Cli\Model\Route;
 use Platformsh\Cli\Service\Url;
 use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
 
 class EnvironmentUrlCommand extends CommandBase
@@ -14,41 +16,135 @@
         $this
             ->setName('environment:url')
             ->setAliases(['url'])
-            ->setDescription('Get the public URLs of an environment');
+            ->setDescription('Get the public URLs of an environment')
+            ->addOption('primary', null, InputOption::VALUE_NONE, 'Only return 
the URL for the primary route');
         Url::configureInput($this->getDefinition());
         $this->addProjectOption()
              ->addEnvironmentOption();
+        $this->addExample('Give a choice of URLs to open (or print all URLs if 
there is no browser)');
+        $this->addExample('Print all URLs', '--pipe');
+        $this->addExample('Print and/or open the primary route URL', 
'--primary');
+        $this->addExample('Print the primary route URL', '--primary --pipe');
     }
 
     protected function execute(InputInterface $input, OutputInterface $output)
     {
-        $this->validateInput($input);
-
-        $selectedEnvironment = $this->getSelectedEnvironment();
+        // Allow override via PLATFORM_ROUTES.
+        $prefix = $this->config()->get('service.env_prefix');
+        if (getenv($prefix . 'ROUTES') && 
!$this->doesEnvironmentConflictWithCommandLine($input)) {
+            $this->debug('Reading URLs from environment variable ' . $prefix . 
'ROUTES');
+            $decoded = json_decode(base64_decode(getenv($prefix . 'ROUTES'), 
true), true);
+            if (empty($decoded)) {
+                throw new \RuntimeException('Failed to decode: ' . $prefix . 
'ROUTES');
+            }
+            $routes = Route::fromVariables($decoded);
+        } else {
+            $this->debug('Reading URLs from the API');
+            $this->validateInput($input);
+            $deployment = 
$this->api()->getCurrentDeployment($this->getSelectedEnvironment());
+            $routes = Route::fromDeploymentApi($deployment->routes);
+        }
+        if (empty($routes)) {
+            $output->writeln('No URLs found.');
 
-        $urls = $selectedEnvironment->getRouteUrls();
-        if (empty($urls)) {
-            $output->writeln("No URLs found");
             return 1;
         }
 
+        $primaryUrl = $this->findPrimaryRouteUrl($routes);
+
+        // Handle the --primary option: just display the primary route's URL.
+        if ($input->getOption('primary')) {
+            if ($primaryUrl === null) {
+                $this->stdErr->writeln('No primary route found.');
+
+                return 1;
+            }
+
+            $this->displayOrOpenUrls([$primaryUrl], $input, $output);
+
+            return 0;
+        }
+
+        // Build a list of all the route URLs.
+        $urls = array_map(function (Route $route) {
+            return $route->url;
+        }, $routes);
+
+        // Sort URLs by preference (HTTPS first, shorter URLs first).
         usort($urls, [$this->api(), 'urlSort']);
 
+        // Shift the primary URL to the top of the list.
+        if ($primaryUrl !== null) {
+            array_unshift($urls, $primaryUrl);
+            $urls = array_unique($urls);
+        }
+
+        $this->displayOrOpenUrls($urls, $input, $output);
+
+        return 0;
+    }
+
+    /**
+     * Displays or opens URLs.
+     *
+     * @param string[]                                          $urls
+     * @param \Symfony\Component\Console\Input\InputInterface   $input
+     * @param \Symfony\Component\Console\Output\OutputInterface $output
+     */
+    private function displayOrOpenUrls(array $urls, InputInterface $input, 
OutputInterface $output)
+    {
         // Just display the URLs if --browser is 0 or if --pipe is set.
         if ($input->getOption('pipe') || $input->getOption('browser') === '0') 
{
             $output->writeln($urls);
-            return 0;
+            return;
+        }
+        // Just display the URLs if there is no DISPLAY available or if there
+        // is no browser.
+        $toDisplay = $urls;
+        if (!$input->isInteractive()) {
+            // For backwards compatibility, ensure only one URL is output for
+            // non-interactive input.
+            $toDisplay = $urls[0];
+        }
+        /** @var \Platformsh\Cli\Service\Url $urlService */
+        $urlService = $this->getService('url');
+        if (!$urlService->hasDisplay()) {
+            $this->debug('Not opening URLs (no display found)');
+            $output->writeln($toDisplay);
+            return;
+        } elseif (!$urlService->canOpenUrls()) {
+            $this->debug('Not opening URLs (no browser found)');
+            $output->writeln($toDisplay);
+            return;
         }
 
         // Allow the user to choose a URL to open.
-        /** @var \Platformsh\Cli\Service\QuestionHelper $questionHelper */
-        $questionHelper = $this->getService('question_helper');
-        $url = $questionHelper->choose(array_combine($urls, $urls), 'Enter a 
number to open a URL', $urls[0]);
+        if (count($urls) === 1) {
+            $url = $urls[0];
+        } else {
+            /** @var \Platformsh\Cli\Service\QuestionHelper $questionHelper */
+            $questionHelper = $this->getService('question_helper');
+            $url = $questionHelper->choose(array_combine($urls, $urls), 'Enter 
a number to open a URL', $urls[0]);
+        }
 
-        /** @var \Platformsh\Cli\Service\Url $urlService */
-        $urlService = $this->getService('url');
         $urlService->openUrl($url);
+    }
 
-        return 0;
+    /**
+     * Finds the URL of the primary route.
+     *
+     * @param Route[] $routes
+     *
+     * @return string|null
+     */
+    private function findPrimaryRouteUrl(array $routes)
+    {
+        foreach ($routes as $route) {
+            if ($route->primary) {
+                return $route->url;
+            }
+        }
+
+        return null;
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.43.2/src/Command/Route/RouteListCommand.php 
new/platformsh-cli-3.44.0/src/Command/Route/RouteListCommand.php
--- old/platformsh-cli-3.43.2/src/Command/Route/RouteListCommand.php    
2019-06-27 13:54:49.000000000 +0200
+++ new/platformsh-cli-3.44.0/src/Command/Route/RouteListCommand.php    
2019-07-10 12:59:25.000000000 +0200
@@ -34,7 +34,7 @@
         if (getenv($prefix . 'ROUTES') && 
!$this->doesEnvironmentConflictWithCommandLine($input)) {
             $this->debug('Reading routes from environment variable ' . $prefix 
. 'ROUTES');
             $decoded = json_decode(base64_decode(getenv($prefix . 'ROUTES'), 
true), true);
-            if (empty($decoded)) {
+            if (!is_array($decoded)) {
                 throw new \RuntimeException('Failed to decode: ' . $prefix . 
'ROUTES');
             }
             $routes = Route::fromVariables($decoded);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.43.2/src/Command/Self/SelfStatsCommand.php 
new/platformsh-cli-3.44.0/src/Command/Self/SelfStatsCommand.php
--- old/platformsh-cli-3.43.2/src/Command/Self/SelfStatsCommand.php     
2019-06-27 13:54:49.000000000 +0200
+++ new/platformsh-cli-3.44.0/src/Command/Self/SelfStatsCommand.php     
2019-07-10 12:59:25.000000000 +0200
@@ -1,6 +1,7 @@
 <?php
 namespace Platformsh\Cli\Command\Self;
 
+use GuzzleHttp\Client;
 use Platformsh\Cli\Command\CommandBase;
 use Platformsh\Cli\Service\PropertyFormatter;
 use Platformsh\Cli\Service\Table;
@@ -31,13 +32,11 @@
     {
         $repo = $this->config()->get('application.github_repo');
         $repoUrl = implode('/', array_map('rawurlencode', explode('/', 
$repo)));
-        $releases = $this->api()
-            ->getHttpClient()
+        $releases = (new Client())
             ->get('https://api.github.com/repos/' . $repoUrl . '/releases', [
                 'headers' => [
                     'Accept' => 'application/vnd.github.v3+json',
                 ],
-                'auth' => false,
                 'query' => [
                     'page' => (int) $input->getOption('page'),
                     'per_page' => 20,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.43.2/src/Command/WelcomeCommand.php 
new/platformsh-cli-3.44.0/src/Command/WelcomeCommand.php
--- old/platformsh-cli-3.43.2/src/Command/WelcomeCommand.php    2019-06-27 
13:54:49.000000000 +0200
+++ new/platformsh-cli-3.44.0/src/Command/WelcomeCommand.php    2019-07-10 
12:59:25.000000000 +0200
@@ -2,6 +2,7 @@
 
 namespace Platformsh\Cli\Command;
 
+use Platformsh\Client\Model\Project;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
 
@@ -21,42 +22,137 @@
     {
         $this->stdErr->writeln("Welcome to " . 
$this->config()->get('service.name') . "!\n");
 
-        // Ensure the user is logged in in this parent command, because the
-        // delegated commands below will not have interactive input.
-        $this->api()->getClient();
-
-        $executable = $this->config()->get('application.executable');
+        $envPrefix = $this->config()->get('service.env_prefix');
+        $onContainer = getenv($envPrefix . 'PROJECT') && getenv($envPrefix . 
'BRANCH');
 
         if ($project = $this->getCurrentProject()) {
-            $projectUri = $project->getLink('#ui');
-            $this->stdErr->writeln("Project title: 
<info>{$project->title}</info>");
-            $this->stdErr->writeln("Project ID: <info>{$project->id}</info>");
-            $this->stdErr->writeln("Project dashboard: 
<info>$projectUri</info>\n");
-
-            // Warn if the project is suspended.
-            if ($project->isSuspended()) {
-                $messages = [];
-                $messages[] = '<comment>This project is suspended.</comment>';
-                if ($project->owner === $this->api()->getMyAccount()['id']) {
-                    $messages[] = '<comment>Update your payment details to 
re-activate it: '
-                        . $this->config()->get('service.accounts_url')
-                        . '</comment>';
-                }
-                $messages[] = '';
-                $this->stdErr->writeln($messages);
-            }
-
-            // Show the environments.
-            $this->runOtherCommand('environments', ['--refresh' => 0]);
-            $this->stdErr->writeln("\nYou can list other projects by running 
<info>$executable projects</info>\n");
+            $this->welcomeForLocalProjectDir($project);
+        } elseif ($onContainer) {
+            $this->welcomeOnContainer();
         } else {
-            // The project is not known. Show all projects.
-            $this->runOtherCommand('projects', ['--refresh' => 0]);
-            $this->stdErr->writeln('');
+            $this->defaultWelcome();
         }
 
-        $this->stdErr->writeln("Manage your SSH keys by running 
<info>$executable ssh-keys</info>\n");
+        $executable = $this->config()->get('application.executable');
+
+        if ($this->api()->isLoggedIn()) {
+            $this->stdErr->writeln("Manage your SSH keys by running 
<info>$executable ssh-keys</info>\n");
+        }
+
+        $this->stdErr->writeln("To view all commands, run: <info>$executable 
list</info>");
+    }
+
+    /**
+     * Display default welcome message, when not in a project directory.
+     */
+    private function defaultWelcome()
+    {
+        // The project is not known. Show all projects.
+        $this->runOtherCommand('projects', ['--refresh' => 0]);
+        $this->stdErr->writeln('');
+    }
 
-        $this->stdErr->writeln("Type <info>$executable list</info> to see all 
available commands.");
+    /**
+     * Display welcome for a local project directory.
+     *
+     * @param \Platformsh\Client\Model\Project $project
+     */
+    private function welcomeForLocalProjectDir(Project $project)
+    {
+        $projectUri = $project->getLink('#ui');
+        $this->stdErr->writeln("Project title: 
<info>{$project->title}</info>");
+        $this->stdErr->writeln("Project ID: <info>{$project->id}</info>");
+        $this->stdErr->writeln("Project dashboard: 
<info>$projectUri</info>\n");
+
+        // Show the environments.
+        $this->runOtherCommand('environments', [
+            '--refresh' => 0,
+            '--project' => $project->id,
+        ]);
+        $executable = $this->config()->get('application.executable');
+        $this->stdErr->writeln("\nYou can list other projects by running 
<info>$executable projects</info>\n");
+    }
+
+    /**
+     * Warn the user if a project is suspended.
+     *
+     * @param \Platformsh\Client\Model\Project $project
+     */
+    private function warnIfSuspended(Project $project)
+    {
+        if ($project->isSuspended()) {
+            $messages = [];
+            $messages[] = '<comment>This project is suspended.</comment>';
+            if ($project->owner === $this->api()->getMyAccount()['id']) {
+                $messages[] = '<comment>Update your payment details to 
re-activate it: '
+                    . $this->config()->get('service.accounts_url')
+                    . '</comment>';
+            }
+            $messages[] = '';
+            $this->stdErr->writeln($messages);
+        }
+    }
+
+    /**
+     * Display welcome when the user is in a cloud container environment.
+     */
+    private function welcomeOnContainer()
+    {
+        $envPrefix = $this->config()->get('service.env_prefix');
+        $executable = $this->config()->get('application.executable');
+
+        $projectId = getenv($envPrefix . 'PROJECT');
+        $environmentId = getenv($envPrefix . 'BRANCH');
+        $appName = getenv($envPrefix . 'APPLICATION_NAME');
+
+        $project = false;
+        $environment = false;
+        if ($this->api()->isLoggedIn()) {
+            $project = $this->api()->getProject($projectId);
+            if ($project && $environmentId) {
+                $environment = $this->api()->getEnvironment($environmentId, 
$project);
+            }
+        }
+
+        if ($project) {
+            $this->stdErr->writeln('Project: ' . 
$this->api()->getProjectLabel($project));
+            if ($environment) {
+                $this->stdErr->writeln('Environment: ' . 
$this->api()->getEnvironmentLabel($environment));
+            }
+            if ($appName) {
+                $this->stdErr->writeln('Application name: <info>' . $appName . 
'</info>');
+            }
+
+            $this->warnIfSuspended($project);
+        } else {
+            $this->stdErr->writeln('Project ID: <info>' . $projectId . 
'</info>');
+            if ($environmentId) {
+                $this->stdErr->writeln('Environment ID: <info>' . 
$environmentId . '</info>');
+            }
+            if ($appName) {
+                $this->stdErr->writeln('Application name: <info>' . $appName . 
'</info>');
+            }
+        }
+
+        $this->stdErr->writeln('');
+        $examples = [];
+        if (getenv($envPrefix . 'APPLICATION')) {
+            $examples[] = "To view application config, run: <info>$executable 
app:config</info>";
+        }
+        if (getenv($envPrefix . 'RELATIONSHIPS')) {
+            $examples[] = "To view relationships, run: <info>$executable 
relationships</info>";
+        }
+        if (getenv($envPrefix . 'ROUTES')) {
+            $examples[] = "To view routes, run: <info>$executable 
routes</info>";
+        }
+        if (getenv($envPrefix . 'VARIABLES')) {
+            $examples[] = "To view variables, run: <info>$executable decode 
\${$envPrefix}VARIABLES</info>";
+        }
+        if (!empty($examples)) {
+            $this->stdErr->writeln('Local environment commands:');
+            $this->stdErr->writeln('');
+            $this->stdErr->writeln(preg_replace('/^/m', '  ', implode("\n", 
$examples)));
+            $this->stdErr->writeln('');
+        }
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.43.2/src/Local/LocalApplication.php 
new/platformsh-cli-3.44.0/src/Local/LocalApplication.php
--- old/platformsh-cli-3.43.2/src/Local/LocalApplication.php    2019-06-27 
13:54:49.000000000 +0200
+++ new/platformsh-cli-3.44.0/src/Local/LocalApplication.php    2019-07-10 
12:59:25.000000000 +0200
@@ -135,6 +135,7 @@
      * Get the application's configuration, parsed from its YAML definition.
      *
      * @return array
+     * @throws \Exception
      */
     public function getConfig()
     {
@@ -144,19 +145,18 @@
     /**
      * Get the application's configuration as an object.
      *
-     * @throws \Exception if the configuration file cannot be read
-     * @throws InvalidConfigException if config is invalid
+     * @throws InvalidConfigException if config is not found or invalid
      *
      * @return AppConfig
      */
     private function getConfigObject()
     {
         if (!isset($this->config)) {
-            $config = [];
             $file = $this->appRoot . '/' . 
$this->cliConfig->get('service.app_config_file');
-            if (file_exists($file)) {
-                $config = (array) (new YamlParser())->parseFile($file);
+            if (!file_exists($file)) {
+                throw new InvalidConfigException('Configuration file not 
found: ' . $file);
             }
+            $config = (array) (new YamlParser())->parseFile($file);
             $this->config = new AppConfig($config);
         }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.43.2/src/Model/Route.php 
new/platformsh-cli-3.44.0/src/Model/Route.php
--- old/platformsh-cli-3.43.2/src/Model/Route.php       2019-06-27 
13:54:49.000000000 +0200
+++ new/platformsh-cli-3.44.0/src/Model/Route.php       2019-07-10 
12:59:25.000000000 +0200
@@ -22,6 +22,19 @@
     }
 
     /**
+     * Gets the app or service name that is the upstream for a route.
+     *
+     * @return string|false
+     */
+    public function getUpstreamName() {
+        if (!isset($this->data['upstream'])) {
+            return false;
+        }
+
+        return explode(':', $this->data['upstream'], 2)[0];
+    }
+
+    /**
      * Translates routes found in $environment->getRoutes() to Route objects.
      *
      * @see \Platformsh\Client\Model\Environment::getRoutes()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.43.2/src/Service/Api.php 
new/platformsh-cli-3.44.0/src/Service/Api.php
--- old/platformsh-cli-3.43.2/src/Service/Api.php       2019-06-27 
13:54:49.000000000 +0200
+++ new/platformsh-cli-3.44.0/src/Service/Api.php       2019-07-10 
12:59:25.000000000 +0200
@@ -6,6 +6,7 @@
 use GuzzleHttp\ClientInterface;
 use GuzzleHttp\Event\ErrorEvent;
 use Platformsh\Cli\Event\EnvironmentsChangedEvent;
+use Platformsh\Cli\Model\Route;
 use Platformsh\Cli\Session\KeychainStorage;
 use Platformsh\Cli\Util\NestedArrayUtil;
 use Platformsh\Client\Connection\Connector;
@@ -454,23 +455,30 @@
     /**
      * Get a user's account info.
      *
-     * @param ProjectAccess $user
-     * @param bool $reset
+     * @param ProjectAccess $access
+     * @param bool          $reset
      *
      * @return array
      *   An array containing 'email' and 'display_name'.
      */
-    public function getAccount(ProjectAccess $user, $reset = false)
+    public function getAccount(ProjectAccess $access, $reset = false)
     {
-        if (isset(self::$accountsCache[$user->id]) && !$reset) {
-            return self::$accountsCache[$user->id];
+        if (isset(self::$accountsCache[$access->id]) && !$reset) {
+            return self::$accountsCache[$access->id];
         }
 
-        $cacheKey = 'account:' . $user->id;
+        $cacheKey = 'account:' . $access->id;
         if ($reset || !($details = $this->cache->fetch($cacheKey))) {
-            $details = $user->getAccount()->getProperties();
-            $this->cache->save($cacheKey, $details, 
$this->config->get('api.users_ttl'));
-            self::$accountsCache[$user->id] = $details;
+            $data = $access->getData();
+            // Use embedded user information if possible.
+            if (isset($data['_embedded']['users'][0]) && 
count($data['_embedded']['users']) === 1) {
+                $details = $data['_embedded']['users'][0];
+                self::$accountsCache[$access->id] = $details;
+            } else {
+                $details = $access->getAccount()->getProperties();
+                $this->cache->save($cacheKey, $details, 
$this->config->get('api.users_ttl'));
+                self::$accountsCache[$access->id] = $details;
+            }
         }
 
         return $details;
@@ -606,7 +614,7 @@
     {
         foreach ($this->getProjectAccesses($project, $reset) as $user) {
             $account = $this->getAccount($user);
-            if ($account['email'] === $email) {
+            if ($account['email'] === $email || strtolower($account['email']) 
=== strtolower($email)) {
                 return $user;
             }
         }
@@ -730,7 +738,7 @@
     }
 
     /**
-     * Get the HTTP client.
+     * Get the authenticated HTTP client.
      *
      * @return ClientInterface
      */
@@ -819,11 +827,16 @@
     public function getSiteUrl(Environment $environment, $appName, 
EnvironmentDeployment $deployment = null)
     {
         $deployment = $deployment ?: $this->getCurrentDeployment($environment);
-        $routes = $deployment->routes;
+        $routes = Route::fromDeploymentApi($deployment->routes);
         $appUrls = [];
-        foreach ($routes as $url => $route) {
-            if ($route->type === 'upstream' && $route->__get('upstream') === 
$appName) {
-                $appUrls[] = $url;
+        foreach ($routes as $route) {
+            if ($route->type === 'upstream' && $route->getUpstreamName() === 
$appName) {
+                // Use the primary route, if it matches this app.
+                if ($route->primary) {
+                    return $route->url;
+                }
+
+                $appUrls[] = $route->url;
             }
         }
         usort($appUrls, [$this, 'urlSort']);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.43.2/src/Service/Url.php 
new/platformsh-cli-3.44.0/src/Service/Url.php
--- old/platformsh-cli-3.43.2/src/Service/Url.php       2019-06-27 
13:54:49.000000000 +0200
+++ new/platformsh-cli-3.44.0/src/Service/Url.php       2019-07-10 
12:59:25.000000000 +0200
@@ -52,7 +52,8 @@
      */
     public function canOpenUrls()
     {
-        return $this->hasDisplay() && $this->getDefaultBrowser();
+        return $this->hasDisplay()
+            && $this->getBrowser($this->input->hasOption('browser') ? 
$this->input->getOption('browser') : null) !== false;
     }
 
     /**
@@ -105,7 +106,11 @@
      */
     public function hasDisplay()
     {
-        return getenv('DISPLAY') || OsUtil::isWindows() || OsUtil::isOsX();
+        if (getenv('DISPLAY')) {
+            return getenv('DISPLAY') !== 'none';
+        }
+
+        return OsUtil::isWindows() || OsUtil::isOsX();
     }
 
     /**
@@ -118,7 +123,9 @@
      */
     private function getBrowser($browserOption = null)
     {
-        if (!empty($browserOption)) {
+        if ($browserOption === '0') {
+            return false;
+        } elseif (!empty($browserOption)) {
             list($command, ) = explode(' ', $browserOption, 2);
             if (!$this->shell->commandExists($command)) {
                 $this->stdErr->writeln(sprintf('Command not found: 
<error>%s</error>', $command));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.43.2/src/Util/YamlParser.php 
new/platformsh-cli-3.44.0/src/Util/YamlParser.php
--- old/platformsh-cli-3.43.2/src/Util/YamlParser.php   2019-06-27 
13:54:49.000000000 +0200
+++ new/platformsh-cli-3.44.0/src/Util/YamlParser.php   2019-07-10 
12:59:25.000000000 +0200
@@ -17,6 +17,8 @@
      *
      * @param string $filename
      *
+     * @throws \Platformsh\Cli\Exception\InvalidConfigException if the config 
is invalid
+     * @throws ParseException if the config could not be parsed
      * @throws \Exception if the file cannot be read
      *
      * @return mixed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.43.2/tests/Command/App/AppConfigGetTest.php 
new/platformsh-cli-3.44.0/tests/Command/App/AppConfigGetTest.php
--- old/platformsh-cli-3.43.2/tests/Command/App/AppConfigGetTest.php    
1970-01-01 01:00:00.000000000 +0100
+++ new/platformsh-cli-3.44.0/tests/Command/App/AppConfigGetTest.php    
2019-07-10 12:59:25.000000000 +0200
@@ -0,0 +1,49 @@
+<?php
+
+namespace Platformsh\Cli\Tests\Command\App;
+
+use Platformsh\Cli\Command\App\AppConfigGetCommand;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Output\BufferedOutput;
+use Symfony\Component\Yaml\Parser;
+
+class AppConfigGetTest extends \PHPUnit_Framework_TestCase
+{
+    private function runCommand(array $args) {
+        $output = new BufferedOutput();
+        (new AppConfigGetCommand())
+            ->run(new ArrayInput($args), $output);
+
+        return $output->fetch();
+    }
+
+    public function testGetConfig() {
+        $app = base64_encode(json_encode([
+            'type' => 'php:7.3',
+            'name' => 'app',
+            'disk' => 512,
+            'mounts' => [],
+            'blank' => null,
+        ]));
+        putenv('PLATFORM_APPLICATION=' . $app);
+        $this->assertEquals(
+            'app',
+            (new Parser)->parse($this->runCommand([
+                '--property' => 'name',
+            ]))
+        );
+        $this->assertEquals(
+            [],
+            (new Parser)->parse($this->runCommand([
+                '--property' => 'mounts',
+            ]))
+        );
+        $this->assertEquals(
+            '',
+            (new Parser)->parse($this->runCommand([
+                '--property' => 'blank',
+            ]))
+        );
+        putenv('PLATFORM_APPLICATION=');
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/platformsh-cli-3.43.2/tests/Command/DecodeTest.php 
new/platformsh-cli-3.44.0/tests/Command/DecodeTest.php
--- old/platformsh-cli-3.43.2/tests/Command/DecodeTest.php      2019-06-27 
13:54:49.000000000 +0200
+++ new/platformsh-cli-3.44.0/tests/Command/DecodeTest.php      2019-07-10 
12:59:25.000000000 +0200
@@ -1,11 +1,14 @@
 <?php
 
-namespace Platformsh\Cli\Tests\Command\Helper;
+namespace Platformsh\Cli\Tests\Command;
 
 use Platformsh\Cli\Command\DecodeCommand;
 use Symfony\Component\Console\Input\ArrayInput;
 use Symfony\Component\Console\Output\BufferedOutput;
 
+/**
+ * @group commands
+ */
 class DecodeTest extends \PHPUnit_Framework_TestCase
 {
     private function runCommand(array $args) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.43.2/tests/Command/Environment/EnvironmentRelationshipsTest.php
 
new/platformsh-cli-3.44.0/tests/Command/Environment/EnvironmentRelationshipsTest.php
--- 
old/platformsh-cli-3.43.2/tests/Command/Environment/EnvironmentRelationshipsTest.php
        2019-06-27 13:54:49.000000000 +0200
+++ 
new/platformsh-cli-3.44.0/tests/Command/Environment/EnvironmentRelationshipsTest.php
        2019-07-10 12:59:25.000000000 +0200
@@ -1,11 +1,14 @@
 <?php
 
-namespace Platformsh\Cli\Tests\Command\Helper;
+namespace Platformsh\Cli\Tests\Command\Environment;
 
 use Platformsh\Cli\Command\Environment\EnvironmentRelationshipsCommand;
 use Symfony\Component\Console\Input\ArrayInput;
 use Symfony\Component\Console\Output\BufferedOutput;
 
+/**
+ * @group commands
+ */
 class EnvironmentRelationshipsTest extends \PHPUnit_Framework_TestCase
 {
     public function setUp() {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.43.2/tests/Command/Environment/EnvironmentUrlTest.php 
new/platformsh-cli-3.44.0/tests/Command/Environment/EnvironmentUrlTest.php
--- old/platformsh-cli-3.43.2/tests/Command/Environment/EnvironmentUrlTest.php  
1970-01-01 01:00:00.000000000 +0100
+++ new/platformsh-cli-3.44.0/tests/Command/Environment/EnvironmentUrlTest.php  
2019-07-10 12:59:25.000000000 +0200
@@ -0,0 +1,80 @@
+<?php
+
+namespace Platformsh\Cli\Tests\Command\Environment;
+
+use Platformsh\Cli\Command\Environment\EnvironmentUrlCommand;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Output\BufferedOutput;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * @group commands
+ */
+class EnvironmentUrlTest extends \PHPUnit_Framework_TestCase
+{
+    public function setUp() {
+        $mockRoutes = base64_encode(json_encode([
+            'https://example.com' => [
+                'primary' => true,
+                'type' => 'upstream',
+                'upstream' => 'app:http',
+                'original_url' => 'https://{default}',
+            ],
+            'http://example.com' => [
+                'type' => 'redirect',
+                'to' => 'https://{default}',
+                'original_url' => 'http://{default}',
+            ],
+        ]));
+        putenv('PLATFORM_ROUTES=' . $mockRoutes);
+    }
+
+    public function tearDown() {
+        putenv('PLATFORM_ROUTES=');
+    }
+
+    private function runCommand(array $args, $verbosity = 
OutputInterface::VERBOSITY_NORMAL) {
+        $output = new BufferedOutput();
+        $output->setVerbosity($verbosity);
+        (new EnvironmentUrlCommand())
+            ->run(new ArrayInput($args), $output);
+
+        return $output->fetch();
+    }
+
+    public function testUrl() {
+        $this->assertEquals(
+            "https://example.com\n";
+            . "http://example.com\n";,
+            $this->runCommand([
+                '--pipe' => true,
+            ])
+        );
+    }
+
+    public function testPrimaryUrl() {
+        $this->assertEquals(
+            'https://example.com',
+            rtrim($this->runCommand([
+                '--primary' => true,
+                '--browser' => '0',
+            ]), "\n")
+        );
+    }
+
+    public function testNonExistentBrowserIsNotFound() {
+        putenv('DISPLAY=fake');
+        $result = $this->runCommand([
+            '--browser' => 'nonexistent',
+        ]);
+        $this->assertContains('Command not found: nonexistent', $result);
+        $this->assertContains("https://example.com\n";, $result);
+
+        putenv('DISPLAY=none');
+        $result = $this->runCommand([
+            '--browser' => 'nonexistent',
+        ], OutputInterface::VERBOSITY_DEBUG);
+        $this->assertContains('no display found', $result);
+        $this->assertContains("https://example.com\n";, $result);
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.43.2/tests/Command/Route/RouteGetTest.php 
new/platformsh-cli-3.44.0/tests/Command/Route/RouteGetTest.php
--- old/platformsh-cli-3.43.2/tests/Command/Route/RouteGetTest.php      
2019-06-27 13:54:49.000000000 +0200
+++ new/platformsh-cli-3.44.0/tests/Command/Route/RouteGetTest.php      
2019-07-10 12:59:25.000000000 +0200
@@ -1,11 +1,14 @@
 <?php
 
-namespace Platformsh\Cli\Tests\Command\Helper;
+namespace Platformsh\Cli\Tests\Command\Route;
 
 use Platformsh\Cli\Command\Route\RouteGetCommand;
 use Symfony\Component\Console\Input\ArrayInput;
 use Symfony\Component\Console\Output\BufferedOutput;
 
+/**
+ * @group commands
+ */
 class RouteGetTest extends \PHPUnit_Framework_TestCase
 {
     public function setUp() {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.43.2/tests/Command/Route/RouteListTest.php 
new/platformsh-cli-3.44.0/tests/Command/Route/RouteListTest.php
--- old/platformsh-cli-3.43.2/tests/Command/Route/RouteListTest.php     
2019-06-27 13:54:49.000000000 +0200
+++ new/platformsh-cli-3.44.0/tests/Command/Route/RouteListTest.php     
2019-07-10 12:59:25.000000000 +0200
@@ -1,11 +1,14 @@
 <?php
 
-namespace Platformsh\Cli\Tests\Command\Helper;
+namespace Platformsh\Cli\Tests\Command\Route;
 
 use Platformsh\Cli\Command\Route\RouteListCommand;
 use Symfony\Component\Console\Input\ArrayInput;
 use Symfony\Component\Console\Output\BufferedOutput;
 
+/**
+ * @group commands
+ */
 class RouteListTest extends \PHPUnit_Framework_TestCase
 {
     public function setUp() {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.43.2/tests/Command/WelcomeCommandTest.php 
new/platformsh-cli-3.44.0/tests/Command/WelcomeCommandTest.php
--- old/platformsh-cli-3.43.2/tests/Command/WelcomeCommandTest.php      
1970-01-01 01:00:00.000000000 +0100
+++ new/platformsh-cli-3.44.0/tests/Command/WelcomeCommandTest.php      
2019-07-10 12:59:25.000000000 +0200
@@ -0,0 +1,37 @@
+<?php
+
+namespace Platformsh\Cli\Tests\Command\App;
+
+use Platformsh\Cli\Command\WelcomeCommand;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Output\BufferedOutput;
+
+class WelcomeCommandTest extends \PHPUnit_Framework_TestCase
+{
+    private function runCommand(array $args) {
+        $output = new BufferedOutput();
+        $input = new ArrayInput($args);
+        $input->setInteractive(false);
+        (new WelcomeCommand())
+            ->run($input, $output);
+
+        return $output->fetch();
+    }
+
+    public function testWelcomeOnLocalContainer() {
+        chdir('/');
+        putenv('PLATFORM_PROJECT=test-project');
+        putenv('PLATFORM_BRANCH=test-environment');
+        putenv('PLATFORM_ROUTES=' . base64_encode(json_encode([])));
+        putenv('PLATFORMSH_CLI_SESSION_ID=test' . rand(100, 999));
+        $result = $this->runCommand([]);
+        $this->assertContains(
+            'Project ID: test-project',
+            $result
+        );
+        $this->assertContains(
+            'Local environment commands',
+            $result
+        );
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.43.2/tests/Local/BuildFlavor/InvalidAppTest.php 
new/platformsh-cli-3.44.0/tests/Local/BuildFlavor/InvalidAppTest.php
--- old/platformsh-cli-3.43.2/tests/Local/BuildFlavor/InvalidAppTest.php        
1970-01-01 01:00:00.000000000 +0100
+++ new/platformsh-cli-3.44.0/tests/Local/BuildFlavor/InvalidAppTest.php        
2019-07-10 12:59:25.000000000 +0200
@@ -0,0 +1,14 @@
+<?php
+
+namespace Platformsh\Cli\Tests\BuildFlavor;
+
+use Platformsh\Cli\Exception\InvalidConfigException;
+
+class InvalidAppTest extends BaseBuildFlavorTest
+{
+    public function testNoAppConfigThrowsException()
+    {
+        $this->setExpectedException(InvalidConfigException::class, 
'Configuration file not found');
+        $this->assertBuildSucceeds('tests/data/apps/invalid', [], false);
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/platformsh-cli-3.43.2/tests/data/apps/invalid/index.html 
new/platformsh-cli-3.44.0/tests/data/apps/invalid/index.html
--- old/platformsh-cli-3.43.2/tests/data/apps/invalid/index.html        
1970-01-01 01:00:00.000000000 +0100
+++ new/platformsh-cli-3.44.0/tests/data/apps/invalid/index.html        
2019-07-10 12:59:25.000000000 +0200
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<html lang="en">
+<head><title>Invalid app example</title></head>
+<body>Invalid app example</body>
+</html>

++++++ platformsh-cli-vendor.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/autoload.php new/vendor/autoload.php
--- old/vendor/autoload.php     2019-06-27 17:54:04.766201922 +0200
+++ new/vendor/autoload.php     2019-07-10 21:38:44.398202600 +0200
@@ -4,4 +4,4 @@
 
 require_once __DIR__ . '/composer/autoload_real.php';
 
-return ComposerAutoloaderInita72cbe0112d2c74e2290941511fcd78f::getLoader();
+return ComposerAutoloaderInit4011949b48404cad63159961b9f979ba::getLoader();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/composer/autoload_real.php 
new/vendor/composer/autoload_real.php
--- old/vendor/composer/autoload_real.php       2019-06-27 17:54:04.766201922 
+0200
+++ new/vendor/composer/autoload_real.php       2019-07-10 21:38:44.398202600 
+0200
@@ -2,7 +2,7 @@
 
 // autoload_real.php @generated by Composer
 
-class ComposerAutoloaderInita72cbe0112d2c74e2290941511fcd78f
+class ComposerAutoloaderInit4011949b48404cad63159961b9f979ba
 {
     private static $loader;
 
@@ -19,15 +19,15 @@
             return self::$loader;
         }
 
-        
spl_autoload_register(array('ComposerAutoloaderInita72cbe0112d2c74e2290941511fcd78f',
 'loadClassLoader'), true, true);
+        
spl_autoload_register(array('ComposerAutoloaderInit4011949b48404cad63159961b9f979ba',
 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
-        
spl_autoload_unregister(array('ComposerAutoloaderInita72cbe0112d2c74e2290941511fcd78f',
 'loadClassLoader'));
+        
spl_autoload_unregister(array('ComposerAutoloaderInit4011949b48404cad63159961b9f979ba',
 '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\ComposerStaticInita72cbe0112d2c74e2290941511fcd78f::getInitializer($loader));
+            
call_user_func(\Composer\Autoload\ComposerStaticInit4011949b48404cad63159961b9f979ba::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\ComposerStaticInita72cbe0112d2c74e2290941511fcd78f::$files;
+            $includeFiles = 
Composer\Autoload\ComposerStaticInit4011949b48404cad63159961b9f979ba::$files;
         } else {
             $includeFiles = require __DIR__ . '/autoload_files.php';
         }
         foreach ($includeFiles as $fileIdentifier => $file) {
-            composerRequirea72cbe0112d2c74e2290941511fcd78f($fileIdentifier, 
$file);
+            composerRequire4011949b48404cad63159961b9f979ba($fileIdentifier, 
$file);
         }
 
         return $loader;
     }
 }
 
-function composerRequirea72cbe0112d2c74e2290941511fcd78f($fileIdentifier, 
$file)
+function composerRequire4011949b48404cad63159961b9f979ba($fileIdentifier, 
$file)
 {
     if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
         require $file;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/composer/autoload_static.php 
new/vendor/composer/autoload_static.php
--- old/vendor/composer/autoload_static.php     2019-06-27 17:54:04.766201922 
+0200
+++ new/vendor/composer/autoload_static.php     2019-07-10 21:38:44.398202600 
+0200
@@ -4,7 +4,7 @@
 
 namespace Composer\Autoload;
 
-class ComposerStaticInita72cbe0112d2c74e2290941511fcd78f
+class ComposerStaticInit4011949b48404cad63159961b9f979ba
 {
     public static $files = array (
         '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . 
'/symfony/polyfill-ctype/bootstrap.php',
@@ -193,9 +193,9 @@
     public static function getInitializer(ClassLoader $loader)
     {
         return \Closure::bind(function () use ($loader) {
-            $loader->prefixLengthsPsr4 = 
ComposerStaticInita72cbe0112d2c74e2290941511fcd78f::$prefixLengthsPsr4;
-            $loader->prefixDirsPsr4 = 
ComposerStaticInita72cbe0112d2c74e2290941511fcd78f::$prefixDirsPsr4;
-            $loader->classMap = 
ComposerStaticInita72cbe0112d2c74e2290941511fcd78f::$classMap;
+            $loader->prefixLengthsPsr4 = 
ComposerStaticInit4011949b48404cad63159961b9f979ba::$prefixLengthsPsr4;
+            $loader->prefixDirsPsr4 = 
ComposerStaticInit4011949b48404cad63159961b9f979ba::$prefixDirsPsr4;
+            $loader->classMap = 
ComposerStaticInit4011949b48404cad63159961b9f979ba::$classMap;
 
         }, null, ClassLoader::class);
     }


Reply via email to