Hello community, here is the log from the commit of package platformsh-cli for openSUSE:Leap:15.2 checked in at 2020-01-30 06:08:53 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2/platformsh-cli (Old) and /work/SRC/openSUSE:Leap:15.2/.platformsh-cli.new.26092 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "platformsh-cli" Thu Jan 30 06:08:53 2020 rev:38 rq:767296 version:3.52.0 Changes: -------- --- /work/SRC/openSUSE:Leap:15.2/platformsh-cli/platformsh-cli.changes 2020-01-19 15:50:29.977809819 +0100 +++ /work/SRC/openSUSE:Leap:15.2/.platformsh-cli.new.26092/platformsh-cli.changes 2020-01-30 06:09:18.438494804 +0100 @@ -1,0 +2,19 @@ +Sat Jan 25 02:20:06 UTC 2020 - ji...@boombatower.com + +- Update to version 3.52.0: + * Release v3.52.0 + * Hide xdebug command for non-PHP projects + * xdebug command formatting tweaks + * feat(env): add e:xdebug command (#887) + * Avoid word-wrapping closing tag in error message API token help + * Improve argument quoting in db:size (refactoring RemoteHost a little) + * Windows: update README + * Windows: improve PATH install process + * Downplay unknown shell type message when setting up autocompletion + * Windows: use \ in the path of main user-facing directories + * Windows: create .bat executable for easier installation + * Windows-compatible quotes on dev build page + * Windows: fix local server for browser login + * Windows: fix opening URLs + +------------------------------------------------------------------- Old: ---- platformsh-cli-3.51.3.tar.xz New: ---- platformsh-cli-3.52.0.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ platformsh-cli.spec ++++++ --- /var/tmp/diff_new_pack.GEWPSN/_old 2020-01-30 06:09:19.094495170 +0100 +++ /var/tmp/diff_new_pack.GEWPSN/_new 2020-01-30 06:09:19.094495170 +0100 @@ -17,7 +17,7 @@ Name: platformsh-cli -Version: 3.51.3 +Version: 3.52.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.GEWPSN/_old 2020-01-30 06:09:19.114495181 +0100 +++ /var/tmp/diff_new_pack.GEWPSN/_new 2020-01-30 06:09:19.114495181 +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.51.3</param> + <param name="revision">refs/tags/v3.52.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.GEWPSN/_old 2020-01-30 06:09:19.126495188 +0100 +++ /var/tmp/diff_new_pack.GEWPSN/_new 2020-01-30 06:09:19.130495190 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">git://github.com/platformsh/platformsh-cli.git</param> - <param name="changesrevision">d30ca740b27f5e6ec2e338b377a4c784d8eb3a68</param> + <param name="changesrevision">28172cbcf9d23cbce6c0f3449fc9599b0e4229a1</param> </service> </servicedata> ++++++ platformsh-cli-3.51.3.tar.xz -> platformsh-cli-3.52.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.51.3/README.md new/platformsh-cli-3.52.0/README.md --- old/platformsh-cli-3.51.3/README.md 2020-01-17 16:36:13.000000000 +0100 +++ new/platformsh-cli-3.52.0/README.md 2020-01-24 22:46:43.000000000 +0100 @@ -4,12 +4,13 @@ ## Requirements -* Operating system: Linux, OS X, Windows Vista, Windows 7, Windows 8 Pro, or Windows 10 (Windows 8 Standard does not work due to an issue with symlink permissions) +* Operating system: Linux, OS X, or Windows 10 * PHP 5.5.9 or higher, with cURL support * 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: [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. + The built-in Command Prompt may also work for most purposes. * 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) @@ -17,17 +18,9 @@ ## Installation -### Installing on OS X or Linux - -This is the recommended installation method. Simply use this command: +Simply use this command: curl -sS https://platform.sh/cli/installer | php - -### Installing on Windows (Git bash) -```bash -curl https://platform.sh/cli/installer -o cli-installer.php -php cli-installer.php -``` ### Installing manually @@ -35,7 +28,7 @@ [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). + directory in your PATH. 3. Enable autocompletion and shell aliases: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.51.3/dist/dev-build-index.php new/platformsh-cli-3.52.0/dist/dev-build-index.php --- old/platformsh-cli-3.51.3/dist/dev-build-index.php 2020-01-17 16:36:13.000000000 +0100 +++ new/platformsh-cli-3.52.0/dist/dev-build-index.php 2020-01-24 22:46:43.000000000 +0100 @@ -40,8 +40,8 @@ $baseUrl = 'https://' . $_SERVER['HTTP_HOST']; $installScript = sprintf( 'curl -sfS %s | php -- --dev --manifest %s', - escapeshellarg($baseUrl . '/installer'), - escapeshellarg($baseUrl . '/manifest.json'), + $baseUrl . '/installer', + $baseUrl . '/manifest.json', ); ?> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.51.3/dist/installer.php new/platformsh-cli-3.52.0/dist/installer.php --- old/platformsh-cli-3.51.3/dist/installer.php 2020-01-17 16:36:13.000000000 +0100 +++ new/platformsh-cli-3.52.0/dist/installer.php 2020-01-24 22:46:43.000000000 +0100 @@ -253,12 +253,12 @@ if ($homeDir = $this->getHomeDirectory()) { $pharPath = $this->performTask('Moving the Phar to your home directory', function () use ($pharPath, $homeDir) { - $binDir = $homeDir . '/' . $this->configDir . '/bin'; + $binDir = $homeDir . DIRECTORY_SEPARATOR . $this->configDir . DIRECTORY_SEPARATOR . 'bin'; if (!is_dir($binDir) && !mkdir($binDir, 0700, true)) { return TaskResult::failure('Failed to create directory: ' . $binDir); } - $destination = $binDir . '/' . $this->executable; + $destination = $binDir . DIRECTORY_SEPARATOR . $this->executable; if (!rename($pharPath, $destination)) { return TaskResult::failure('Failed to move the Phar to: ' . $destination); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.51.3/dist/manifest.json new/platformsh-cli-3.52.0/dist/manifest.json --- old/platformsh-cli-3.51.3/dist/manifest.json 2020-01-17 16:36:13.000000000 +0100 +++ new/platformsh-cli-3.52.0/dist/manifest.json 2020-01-24 22:46:43.000000000 +0100 @@ -17,10 +17,10 @@ }, { "name": "platform.phar", - "sha1": "8de789f62a8870893a794d3aa2c1ee8ec126a2d8", - "sha256": "0e368c04582107efc02caa56fdaf7df918f51855ec78ba4b05cb433d4b0d5cd1", - "url": "https://github.com/platformsh/platformsh-cli/releases/download/v3.51.3/platform.phar", - "version": "3.51.3", + "sha1": "f230b9726c3b301da91af812bf96f495884d2f69", + "sha256": "b6bd5acd975466edcdd85a982b450143286914c8e02b78731b67d9b9a834eda1", + "url": "https://github.com/platformsh/platformsh-cli/releases/download/v3.52.0/platform.phar", + "version": "3.52.0", "php": { "min": "5.5.9" }, @@ -243,6 +243,11 @@ "notes": "New features:\n\n* Add PLATFORMSH_CLI_NO_INTERACTION environment variable, which can be used to\n disable interactivity everywhere (warning: important confirmation questions\n would be bypassed).\n* Add health.webhook integration type.\n\nOther changes:\n\n* Fix: avoid listing duplicate activities and avoid an infinite loop in\n activity:list (activities) command.\n* Remove handling of activity \"log\" property.\n* Fix init command example GitHub URL.\n* Update the project git URL when adding/deleting an integration.", "show from": "3.50.0", "hide from": "3.51.0" + }, + { + "notes": "New features:\n\n* Add an `environment:xdebug` (`xdebug`) command, which opens an SSH tunnel to\n help debug PHP applications. The application must be configured with an\n xdebug trigger key (help is available by running the command).\n\nImprovements to Windows installation\n\n* Generate a `platform.bat` file during installation (the `self:install`\n command) so `platform` can be found in the Path.\n* Use \\ as the directory separator in user-facing installation paths.\n* Fix browser login: two bugs that prevented starting the local server, and\n preventing opening the URL in the browser.\n* Improve installation help messages for setting up the Path environment\n variable when using the Command Prompt.", + "show from": "3.51.0", + "hide from": "3.52.0" } ] } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.51.3/src/Application.php new/platformsh-cli-3.52.0/src/Application.php --- old/platformsh-cli-3.51.3/src/Application.php 2020-01-17 16:36:13.000000000 +0100 +++ new/platformsh-cli-3.52.0/src/Application.php 2020-01-24 22:46:43.000000000 +0100 @@ -142,6 +142,7 @@ $commands[] = new Command\Environment\EnvironmentSynchronizeCommand(); $commands[] = new Command\Environment\EnvironmentUrlCommand(); $commands[] = new Command\Environment\EnvironmentSetRemoteCommand(); + $commands[] = new Command\Environment\EnvironmentXdebugCommand(); $commands[] = new Command\Integration\IntegrationAddCommand(); $commands[] = new Command\Integration\IntegrationDeleteCommand(); $commands[] = new Command\Integration\IntegrationGetCommand(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.51.3/src/Command/Auth/BrowserLoginCommand.php new/platformsh-cli-3.52.0/src/Command/Auth/BrowserLoginCommand.php --- old/platformsh-cli-3.51.3/src/Command/Auth/BrowserLoginCommand.php 2020-01-17 16:36:13.000000000 +0100 +++ new/platformsh-cli-3.52.0/src/Command/Auth/BrowserLoginCommand.php 2020-01-24 22:46:43.000000000 +0100 @@ -138,7 +138,7 @@ 'CLI_OAUTH_AUTH_URL' => $this->config()->get('api.oauth2_auth_url'), 'CLI_OAUTH_CLIENT_ID' => $this->config()->get('api.oauth2_client_id'), 'CLI_OAUTH_FILE' => $codeFile, - ]); + ] + $this->getParentEnv()); $process->setTimeout(null); $this->stdErr->writeln('Starting local web server with command: <info>' . $process->getCommandLine() . '</info>', OutputInterface::VERBOSITY_VERY_VERBOSE); $process->start(); @@ -235,6 +235,23 @@ } /** + * Attempts to find parent environment variables for the local server. + * + * @return array + */ + private function getParentEnv() + { + if (PHP_VERSION_ID >= 70100) { + return getenv(); + } + if (!empty($_ENV) && stripos(ini_get('variables_order'), 'e') !== false) { + return $_ENV; + } + + return []; + } + + /** * @param array $tokenData * @param SessionInterface $session */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.51.3/src/Command/Environment/EnvironmentXdebugCommand.php new/platformsh-cli-3.52.0/src/Command/Environment/EnvironmentXdebugCommand.php --- old/platformsh-cli-3.51.3/src/Command/Environment/EnvironmentXdebugCommand.php 1970-01-01 01:00:00.000000000 +0100 +++ new/platformsh-cli-3.52.0/src/Command/Environment/EnvironmentXdebugCommand.php 2020-01-24 22:46:43.000000000 +0100 @@ -0,0 +1,142 @@ +<?php +namespace Platformsh\Cli\Command\Environment; + +use Platformsh\Cli\Command\CommandBase; +use Platformsh\Cli\Local\LocalApplication; +use Platformsh\Cli\Service\Ssh; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Process\Process; + +class EnvironmentXdebugCommand extends CommandBase +{ + const SOCKET_PATH = '/run/xdebug-tunnel.sock'; + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('environment:xdebug') + ->setAliases(['xdebug']) + ->addOption('port', null, InputArgument::OPTIONAL, 'The local port', 9000) + ->setDescription('Open a tunnel to Xdebug on the environment'); + $this->addProjectOption() + ->addEnvironmentOption() + ->addRemoteContainerOptions(); + Ssh::configureInput($this->getDefinition()); + $this->addExample('Connect to Xdebug on the environment, listening locally on port 9000.'); + } + + public function isHidden() + { + // Hide this command in the list if the project is not PHP. + $projectRoot = $this->getProjectRoot(); + if ($projectRoot) { + return !$this->isPhp($projectRoot); + } + + return parent::isHidden(); + } + + /** + * Checks if a project contains a PHP app. + * + * @param string $directory + * + * @return bool + */ + private function isPhp($directory) { + static $isPhp; + if (!isset($isPhp)) { + $isPhp = false; + foreach (LocalApplication::getApplications($directory, $this->config()) as $app) { + $type = $app->getType(); + if ($type === 'php' || strpos($type, 'php:') === 0) { + $isPhp = true; + break; + } + } + } + + return $isPhp; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->validateInput($input); + $this->getSelectedEnvironment(); + + $container = $this->selectRemoteContainer($input); + $sshUrl = $container->getSshUrl(); + + $config = $container->getConfig()->getNormalized(); + $key = isset($config['runtime']['xdebug']['key']) ? $config['runtime']['xdebug']['key'] : ''; + + if (!$key) { + $this->stdErr->writeln('<error>No debugging key found.</error>'); + $this->stdErr->writeln(''); + $this->stdErr->writeln('To use Xdebug your project must have a <comment>debugging key</comment> set.'); + $this->stdErr->writeln(''); + $this->stdErr->writeln(sprintf('Set this in the <comment>%s</comment> file as in this example:', $this->config()->get('service.app_config_file'))); + $this->stdErr->writeln( + "\n<comment># ...\n" + . "runtime:\n" + . " xdebug:\n" + . " key: <options=underscore>secret_key</>" + ); + + return 1; + } + + + /** @var Ssh $ssh */ + $ssh = $this->getService('ssh'); + + // The socket is removed to prevent 'file already exists' errors. + $commandCleanup = $ssh->getSshCommand(); + $commandCleanup .= ' ' . escapeshellarg($sshUrl) . ' rm -f ' . escapeshellarg(self::SOCKET_PATH); + $this->debug("Cleanup command: " . $commandCleanup); + $process = new Process($commandCleanup); + $process->run(); + + $this->stdErr->writeln("Opening a local tunnel for Xdebug."); + + // Set up the tunnel + $port = $input->getOption('port'); + + $sshOptions = []; + $sshOptions['ExitOnForwardFailure'] = 'yes'; + + $listenAddress = '127.0.0.1:' . $port; + $commandTunnel = $ssh->getSshCommand($sshOptions) . ' -TNR ' . escapeshellarg(self::SOCKET_PATH . ':' . $listenAddress); + $commandTunnel .= ' ' . escapeshellarg($sshUrl); + $this->debug("Tunnel command: " . $commandTunnel); + $process = new Process($commandTunnel); + $process->setTimeout(null); + $process->start(); + + usleep(100000); + + if (!$process->isRunning() && !$process->isSuccessful()) { + $this->stdErr->writeln(trim($process->getErrorOutput())); + $this->stdErr->writeln('Failed to create the tunnel.'); + return $process->stop(); + } + + $this->stdErr->writeln(''); + $this->stdErr->writeln(sprintf('Xdebug tunnel opened at: <info>%s</info>', $listenAddress)); + $this->stdErr->writeln(''); + $this->stdErr->writeln( + "To start debugging, set a cookie like '<info>XDEBUG_SESSION=$key</info>'" + . " or append '<info>XDEBUG_SESSION_START=$key</info>' in the URL query string when visiting your project." + ); + $this->stdErr->writeln(''); + $this->stdErr->writeln('To close the tunnel, quit this command by pressing <info>Ctrl+C</info>.'); + $this->stdErr->writeln('To change the local port, re-run this command with the <info>--port</info> option.'); + + return $process->wait(); + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.51.3/src/Command/Local/LocalDirCommand.php new/platformsh-cli-3.52.0/src/Command/Local/LocalDirCommand.php --- old/platformsh-cli-3.51.3/src/Command/Local/LocalDirCommand.php 2020-01-17 16:36:13.000000000 +0100 +++ new/platformsh-cli-3.52.0/src/Command/Local/LocalDirCommand.php 2020-01-24 22:46:43.000000000 +0100 @@ -44,7 +44,7 @@ return 1; } - $dir .= '/' . $subDirs[$subDir]; + $dir .= DIRECTORY_SEPARATOR . $subDirs[$subDir]; } if (!is_dir($dir)) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.51.3/src/Command/Self/SelfInstallCommand.php new/platformsh-cli-3.52.0/src/Command/Self/SelfInstallCommand.php --- old/platformsh-cli-3.51.3/src/Command/Self/SelfInstallCommand.php 2020-01-17 16:36:13.000000000 +0100 +++ new/platformsh-cli-3.52.0/src/Command/Self/SelfInstallCommand.php 2020-01-24 22:46:43.000000000 +0100 @@ -31,17 +31,17 @@ $configDir = $this->config()->getUserConfigDir(); $this->stdErr->write('Copying resource files...'); - $rcFiles = [ + $requiredFiles = [ 'shell-config.rc', 'shell-config-bash.rc', ]; $fs = new \Symfony\Component\Filesystem\Filesystem(); try { - foreach ($rcFiles as $rcFile) { - if (($rcContents = file_get_contents(CLI_ROOT . '/' . $rcFile)) === false) { - throw new \RuntimeException(sprintf('Failed to read file: %s', CLI_ROOT . '/' . $rcFile)); + foreach ($requiredFiles as $requiredFile) { + if (($contents = file_get_contents(CLI_ROOT . DIRECTORY_SEPARATOR . $requiredFile)) === false) { + throw new \RuntimeException(sprintf('Failed to read file: %s', CLI_ROOT . '/' . $requiredFile)); } - $fs->dumpFile($configDir . '/' . $rcFile, $rcContents); + $fs->dumpFile($configDir . DIRECTORY_SEPARATOR . $requiredFile, $contents); } } catch (\Exception $e) { $this->stdErr->writeln(''); @@ -53,6 +53,16 @@ $this->stdErr->writeln(' <info>done</info>'); $this->stdErr->writeln(''); + if (OsUtil::isWindows()) { + $this->stdErr->write('Creating .bat executable...'); + $binDir = $configDir . DIRECTORY_SEPARATOR . 'bin'; + $binTarget = $this->config()->get('application.executable'); + $batDestination = $binDir . DIRECTORY_SEPARATOR . $this->config()->get('application.executable') . '.bat'; + $fs->dumpFile($batDestination, $this->generateBatContents($binTarget)); + $this->stdErr->writeln(' <info>done</info>'); + $this->stdErr->writeln(''); + } + $shellType = $input->getOption('shell-type'); if ($shellType === null && getenv('SHELL') !== false) { $shellType = str_replace('.exe', '', basename(getenv('SHELL'))); @@ -79,7 +89,9 @@ // autocompletion probably isn't needed at all, as we are in the // context of some kind of automated build. So ignore the error. if (!$this->isTerminal(STDOUT)) { - $this->stdErr->writeln(' <info>skipped</info>'); + $this->stdErr->writeln(' <info>skipped</info> (not a terminal)'); + } elseif ($shellType === null) { + $this->stdErr->writeln(' <info>skipped</info> (unsupported shell)'); } // Otherwise, print the error and continue. The user probably // wants to know what went wrong, but autocompletion is still not @@ -112,6 +124,39 @@ $shellConfigFile = $this->findShellConfigFile($shellType); } + // Windows command prompt (non-Bash) behavior. + if ($shellConfigFile === false && OsUtil::isWindows()) { + $binDir = $configDir . DIRECTORY_SEPARATOR . 'bin'; + if ($this->inPath($binDir)) { + $this->stdErr->writeln($this->getRunAdvice('', $binDir, true, false)); + + return 0; + } + + // Attempt to add to the PATH automatically using "setx". + $path = getenv('Path', true); + $pathParts = $path !== false ? array_unique(array_filter(explode(';', $path))) : []; + if ($path !== false && !empty($pathParts)) { + $newPath = implode(';', $pathParts) . ';' . $binDir; + /** @var \Platformsh\Cli\Service\Shell $shell */ + $shell = $this->getService('shell'); + $setPathCommand = 'setx PATH ' . OsUtil::escapeShellArg($newPath); + if ($shell->execute($setPathCommand, null, false, true, [], 10) !== false) { + $this->stdErr->writeln($this->getRunAdvice('', $binDir, true, true)); + + return 0; + } + } + + $this->stdErr->writeln(sprintf( + 'To set up the CLI, add this directory to your Path environment variable:' + )); + $this->stdErr->writeln(sprintf('<info>%s</info>', $binDir)); + $this->stdErr->writeln('Then open a new terminal to continue.'); + + return 1; + } + $currentShellConfig = ''; if ($shellConfigFile !== false) { @@ -127,7 +172,7 @@ } $configDirRelative = $this->config()->getUserConfigDir(false); - $rcDestination = $configDirRelative . '/' . 'shell-config.rc'; + $rcDestination = $configDirRelative . DIRECTORY_SEPARATOR . 'shell-config.rc'; $suggestedShellConfig = 'HOME=${HOME:-' . escapeshellarg($this->config()->getHomeDirectory()) . '}'; $suggestedShellConfig .= PHP_EOL . sprintf( 'export PATH=%s:"$PATH"', @@ -246,15 +291,20 @@ /** * @param string $shellConfigFile * @param string $binDir + * @param bool|null $inPath + * @param bool $newTerminal * * @return string[] */ - private function getRunAdvice($shellConfigFile, $binDir) + private function getRunAdvice($shellConfigFile, $binDir, $inPath = null, $newTerminal = false) { $advice = [ - sprintf('To use the %s, run:', $this->config()->get('application.name')) + sprintf('To use the %s,%s run:', $this->config()->get('application.name'), $newTerminal ? ' open a new terminal, and' : '') ]; - if (!$this->inPath($binDir)) { + if ($inPath === null) { + $inPath = $this->inPath($binDir); + } + if (!$inPath) { $sourceAdvice = sprintf(' <info>source %s</info>', $this->formatSourceArg($shellConfigFile)); $sourceAdvice .= ' # (make sure your shell does this by default)'; $advice[] = $sourceAdvice; @@ -267,6 +317,8 @@ /** * Check if a directory is in the PATH. * + * @param string $dir + * * @return bool */ private function inPath($dir) @@ -277,7 +329,7 @@ return false; } - return in_array($realpath, explode(':', $PATH)); + return in_array($realpath, explode(OsUtil::isWindows() ? ';' : ':', $PATH)); } /** @@ -411,4 +463,19 @@ return $spaces . preg_replace('/\r\n|\r|\n/', '$0' . $spaces, $wrapped); } + + /** + * Generates a .bat file for Windows compatibility. + * + * @param string $binTarget + * + * @return string + */ + private function generateBatContents($binTarget) + { + return "@ECHO OFF\r\n". + "setlocal DISABLEDELAYEDEXPANSION\r\n". + "SET BIN_TARGET=%~dp0/" . trim(OsUtil::escapeShellArg($binTarget), '"\'') . "\r\n". + "php \"%BIN_TARGET%\" %*\r\n"; + } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.51.3/src/Exception/LoginRequiredException.php new/platformsh-cli-3.52.0/src/Exception/LoginRequiredException.php --- old/platformsh-cli-3.51.3/src/Exception/LoginRequiredException.php 2020-01-17 16:36:13.000000000 +0100 +++ new/platformsh-cli-3.52.0/src/Exception/LoginRequiredException.php 2020-01-24 22:46:43.000000000 +0100 @@ -32,8 +32,8 @@ 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 'To authenticate non-interactively using an API token, see:' + . "\n " . $this->config->get('service.api_token_help_url'); } return null; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.51.3/src/Local/LocalApplication.php new/platformsh-cli-3.52.0/src/Local/LocalApplication.php --- old/platformsh-cli-3.51.3/src/Local/LocalApplication.php 2020-01-17 16:36:13.000000000 +0100 +++ new/platformsh-cli-3.52.0/src/Local/LocalApplication.php 2020-01-24 22:46:43.000000000 +0100 @@ -47,6 +47,18 @@ } /** + * Returns the type of the app. + * + * @return string|null + */ + public function getType() + { + $config = $this->getConfig(); + + return isset($config['type']) ? $config['type'] : null; + } + + /** * Returns whether this application is the only one in the project. * * @return bool diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.51.3/src/Model/Host/HostInterface.php new/platformsh-cli-3.52.0/src/Model/Host/HostInterface.php --- old/platformsh-cli-3.51.3/src/Model/Host/HostInterface.php 2020-01-17 16:36:13.000000000 +0100 +++ new/platformsh-cli-3.52.0/src/Model/Host/HostInterface.php 2020-01-24 22:46:43.000000000 +0100 @@ -20,9 +20,9 @@ public function getCacheKey(); /** - * @param string|array $command - * @param bool $mustRun - * @param bool $quiet + * @param string $command + * @param bool $mustRun + * @param bool $quiet * * @return string|true * The command's output, or true if it succeeds with no output, or false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.51.3/src/Model/Host/RemoteHost.php new/platformsh-cli-3.52.0/src/Model/Host/RemoteHost.php --- old/platformsh-cli-3.51.3/src/Model/Host/RemoteHost.php 2020-01-17 16:36:13.000000000 +0100 +++ new/platformsh-cli-3.52.0/src/Model/Host/RemoteHost.php 2020-01-24 22:46:43.000000000 +0100 @@ -41,13 +41,6 @@ */ public function runCommand($command, $mustRun = true, $quiet = true) { - if (is_array($command)) { - $args = array_merge(['ssh'], $this->extraSshArgs, $this->sshService->getSshArgs()); - $args[] = implode(' ', array_map([OsUtil::class, 'escapePosixShellArg'], $command)); - - return $this->shell->execute($args, null, $mustRun, $quiet); - } - return $this->shell->execute($this->wrapCommandLine($command), null, $mustRun, $quiet); } @@ -61,7 +54,7 @@ private function wrapCommandLine($commandLine) { return $this->sshService->getSshCommand() - . ($this->extraSshArgs ? ' ' . implode(' ', array_map('escapeshellarg', $this->extraSshArgs)) : '') + . ($this->extraSshArgs ? ' ' . implode(' ', array_map([OsUtil::class, 'escapeShellArg'], $this->extraSshArgs)) : '') . ' ' . escapeshellarg($this->sshUrl) . ' ' . escapeshellarg($commandLine); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.51.3/src/Service/Config.php new/platformsh-cli-3.52.0/src/Service/Config.php --- old/platformsh-cli-3.51.3/src/Service/Config.php 2020-01-17 16:36:13.000000000 +0100 +++ new/platformsh-cli-3.52.0/src/Service/Config.php 2020-01-24 22:46:43.000000000 +0100 @@ -138,7 +138,7 @@ { $path = $this->get('application.user_config_dir'); - return $absolute ? $this->getHomeDirectory() . '/' . $path : $path; + return $absolute ? $this->getHomeDirectory() . DIRECTORY_SEPARATOR . $path : $path; } /** @@ -159,7 +159,7 @@ // If the config directory is not writable (e.g. if we are on a // Platform.sh environment), use a temporary directory instead. if (!$this->fs()->canWrite($configDir) || (file_exists($configDir) && !is_dir($configDir))) { - return sys_get_temp_dir() . '/' . $this->get('application.tmp_sub_dir'); + return sys_get_temp_dir() . DIRECTORY_SEPARATOR . $this->get('application.tmp_sub_dir'); } return $configDir; @@ -170,7 +170,7 @@ */ public function getSessionDir() { - return $this->getWritableUserDir() . '/.session'; + return $this->getWritableUserDir() . DIRECTORY_SEPARATOR . '.session'; } /** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.51.3/src/Service/Url.php new/platformsh-cli-3.52.0/src/Service/Url.php --- old/platformsh-cli-3.51.3/src/Service/Url.php 2020-01-17 16:36:13.000000000 +0100 +++ new/platformsh-cli-3.52.0/src/Service/Url.php 2020-01-24 22:46:43.000000000 +0100 @@ -88,7 +88,12 @@ // Open the URL. if ($open && ($browser = $this->getBrowser($browserOption))) { - $success = $this->shell->executeSimple($browser . ' ' . escapeshellarg($url)) === 0; + if (OsUtil::isWindows() && $browser === 'start') { + $command = $browser . ' "" ' . escapeshellarg($url); + } else { + $command = $browser . ' ' . escapeshellarg($url); + } + $success = $this->shell->executeSimple($command) === 0; } // Print the URL. @@ -145,11 +150,13 @@ */ private function getDefaultBrowser() { - $browsers = ['xdg-open', 'gnome-open', 'start']; + if (OsUtil::isWindows()) { + return 'start'; + } if (OsUtil::isOsX()) { - $browsers = ['open']; + return 'open'; } - + $browsers = ['xdg-open', 'gnome-open']; foreach ($browsers as $browser) { if ($this->shell->commandExists($browser)) { return $browser; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/platformsh-cli-3.51.3/src/Util/OsUtil.php new/platformsh-cli-3.52.0/src/Util/OsUtil.php --- old/platformsh-cli-3.51.3/src/Util/OsUtil.php 2020-01-17 16:36:13.000000000 +0100 +++ new/platformsh-cli-3.52.0/src/Util/OsUtil.php 2020-01-24 22:46:43.000000000 +0100 @@ -35,4 +35,32 @@ { return "'" . str_replace("'", "'\\''", $arg) . "'"; } + + /** + * Escapes a shell argument, with Windows compatibility. + * + * @see \Symfony\Component\Process\Process::escapeArgument() + * + * @param string $argument + * + * @return string + */ + public static function escapeShellArg($argument) + { + if ('\\' !== \DIRECTORY_SEPARATOR) { + return self::escapePosixShellArg($argument); + } + if ('' === $argument = (string) $argument) { + return '""'; + } + if (false !== strpos($argument, "\0")) { + $argument = str_replace("\0", '?', $argument); + } + if (!preg_match('/[\/()%!^"<>&|\s]/', $argument)) { + return $argument; + } + $argument = preg_replace('/(\\\\+)$/', '$1$1', $argument); + + return '"' . str_replace(['"', '^', '%', '!', "\n"], ['""', '"^^"', '"^%"', '"^!"', '!LF!'], $argument) . '"'; + } } ++++++ 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 2020-01-17 21:44:21.767464197 +0100 +++ new/vendor/autoload.php 2020-01-25 03:20:09.078886048 +0100 @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInitd8c966fdb01eb7066c738e0e8bfc76d7::getLoader(); +return ComposerAutoloaderInit40caa9b8f2c9b34902589f9beb6e3e11::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 2020-01-17 21:44:21.767464197 +0100 +++ new/vendor/composer/autoload_real.php 2020-01-25 03:20:09.078886048 +0100 @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInitd8c966fdb01eb7066c738e0e8bfc76d7 +class ComposerAutoloaderInit40caa9b8f2c9b34902589f9beb6e3e11 { private static $loader; @@ -19,15 +19,15 @@ return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInitd8c966fdb01eb7066c738e0e8bfc76d7', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit40caa9b8f2c9b34902589f9beb6e3e11', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInitd8c966fdb01eb7066c738e0e8bfc76d7', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit40caa9b8f2c9b34902589f9beb6e3e11', '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\ComposerStaticInitd8c966fdb01eb7066c738e0e8bfc76d7::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit40caa9b8f2c9b34902589f9beb6e3e11::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\ComposerStaticInitd8c966fdb01eb7066c738e0e8bfc76d7::$files; + $includeFiles = Composer\Autoload\ComposerStaticInit40caa9b8f2c9b34902589f9beb6e3e11::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequired8c966fdb01eb7066c738e0e8bfc76d7($fileIdentifier, $file); + composerRequire40caa9b8f2c9b34902589f9beb6e3e11($fileIdentifier, $file); } return $loader; } } -function composerRequired8c966fdb01eb7066c738e0e8bfc76d7($fileIdentifier, $file) +function composerRequire40caa9b8f2c9b34902589f9beb6e3e11($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 2020-01-17 21:44:21.767464197 +0100 +++ new/vendor/composer/autoload_static.php 2020-01-25 03:20:09.078886048 +0100 @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInitd8c966fdb01eb7066c738e0e8bfc76d7 +class ComposerStaticInit40caa9b8f2c9b34902589f9beb6e3e11 { 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 = ComposerStaticInitd8c966fdb01eb7066c738e0e8bfc76d7::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInitd8c966fdb01eb7066c738e0e8bfc76d7::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInitd8c966fdb01eb7066c738e0e8bfc76d7::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit40caa9b8f2c9b34902589f9beb6e3e11::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit40caa9b8f2c9b34902589f9beb6e3e11::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit40caa9b8f2c9b34902589f9beb6e3e11::$classMap; }, null, ClassLoader::class); }