Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
pjcdawkins committed Oct 8, 2015
2 parents d890b3a + f419946 commit cf40ae9
Show file tree
Hide file tree
Showing 14 changed files with 110 additions and 56 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"require": {
"doctrine/cache": "~1.4.2",
"platformsh/console-form": "0.0.4",
"platformsh/client": "0.1.27",
"platformsh/client": "0.1.31",
"symfony/console": "~2.5 >=2.5.2",
"symfony/yaml": "~2.5",
"symfony/finder": "~2.5",
Expand Down
14 changes: 7 additions & 7 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion platform
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

define('CLI_ROOT', __DIR__);

error_reporting(E_ERROR | E_WARNING | E_PARSE);
error_reporting(getenv('PLATFORMSH_CLI_DEBUG') ? E_ALL : false);

if (file_exists(CLI_ROOT . '/vendor/autoload.php')) {
require CLI_ROOT . '/vendor/autoload.php';
Expand Down
7 changes: 4 additions & 3 deletions src/Command/Activity/ActivityListCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ protected function configure()
->addOption('limit', null, InputOption::VALUE_REQUIRED, 'Limit the number of results displayed', 5)
->addOption('pipe', null, InputOption::VALUE_NONE, 'Output tab-separated results')
->addOption('start', null, InputOption::VALUE_REQUIRED, 'Only activities created before this date will be listed')
->setDescription('Get the most recent activities for an environment');
->setDescription('Get a list of activities for an environment');
$this->addProjectOption()
->addEnvironmentOption();
$this->addExample('List recent activities on the current environment')
->addExample('List recent pushes', '--type environment.push');
->addExample('List recent pushes', '--type environment.push')
->addExample('List pushes made before 15 March', '--type environment.push --start 2015-03-15');
}

protected function execute(InputInterface $input, OutputInterface $output)
Expand Down Expand Up @@ -73,7 +74,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
return 0;
}

$this->stdErr->writeln("Recent activities for the environment <info>" . $environment['id'] . "</info>");
$this->stdErr->writeln("Activities for the environment <info>" . $environment['id'] . "</info>");
$table = new Table($output);
$table->setHeaders($headers);
$table->addRows($rows);
Expand Down
2 changes: 2 additions & 0 deletions src/Command/Snapshot/SnapshotListCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ protected function configure()
->addOption('start', null, InputOption::VALUE_REQUIRED, 'Only snapshots created before this date will be listed');
$this->addProjectOption()
->addEnvironmentOption();
$this->addExample('List the most recent snapshots')
->addExample('List snapshots made before last week', "--start '1 week ago'");
}

protected function execute(InputInterface $input, OutputInterface $output)
Expand Down
26 changes: 24 additions & 2 deletions src/Command/User/UserAddCommand.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php
namespace Platformsh\Cli\Command\User;

use Platformsh\Cli\Util\ActivityUtil;
use Platformsh\Client\Model\Activity;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
Expand All @@ -16,7 +18,8 @@ protected function configure()
->setName('user:add')
->setDescription('Add a user to the project')
->addArgument('email', InputArgument::OPTIONAL, "The new user's email address")
->addOption('role', null, InputOption::VALUE_REQUIRED, "The new user's role: 'admin' or 'viewer'");
->addOption('role', null, InputOption::VALUE_REQUIRED, "The new user's role: 'admin' or 'viewer'")
->addOption('wait', null, InputOption::VALUE_NONE, 'Wait for environment(s) to be redeployed, if necessary');
$this->addProjectOption();
$this->addExample('Add Alice as a new administrator', '[email protected] --role admin');
}
Expand Down Expand Up @@ -106,7 +109,26 @@ protected function execute(InputInterface $input, OutputInterface $output)
}
}

$project->addUser($email, $projectRole);
$this->stdErr->writeln("Adding the user to the project");
$user = $project->addUser($email, $projectRole);

if (!empty($environmentRoles)) {
$this->stdErr->writeln("Setting environment role(s)");
$activities = [];
foreach ($environmentRoles as $environmentId => $role) {
if (!isset($environments[$environmentId])) {
$this->stdErr->writeln("<error>Environment not found: $environmentId</error>");
continue;
}
$result = $user->changeEnvironmentRole($environments[$environmentId], $role);
if ($result instanceof Activity) {
$activities[] = $result;
}
}
if ($input->getOption('wait')) {
ActivityUtil::waitMultiple($activities, $this->stdErr, 'Waiting for environment(s) to be redeployed');
}
}

$this->stdErr->writeln("User <info>$email</info> created");
return 0;
Expand Down
15 changes: 13 additions & 2 deletions src/Command/User/UserRoleCommand.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php
namespace Platformsh\Cli\Command\User;

use Platformsh\Cli\Util\ActivityUtil;
use Platformsh\Client\Model\Activity;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
Expand All @@ -17,7 +19,8 @@ protected function configure()
->addArgument('email', InputArgument::REQUIRED, "The user's email address")
->addOption('role', 'r', InputOption::VALUE_REQUIRED, "A new role for the user")
->addOption('level', 'l', InputOption::VALUE_REQUIRED, "The role level ('project' or 'environment')", 'project')
->addOption('pipe', null, InputOption::VALUE_NONE, 'Output the role only');
->addOption('pipe', null, InputOption::VALUE_NONE, 'Output the role only')
->addOption('wait', null, InputOption::VALUE_NONE, 'Wait for environment(s) to be redeployed, if necessary');
$this->addProjectOption()
->addEnvironmentOption();
$this->addExample("View Alice's role on the project", '[email protected]');
Expand Down Expand Up @@ -85,8 +88,16 @@ protected function execute(InputInterface $input, OutputInterface $output)
$this->stdErr->writeln("User <info>$email</info> updated");
}
elseif ($role && $level == 'environment') {
$selectedUser->changeEnvironmentRole($this->getSelectedEnvironment(), $role);
$result = $selectedUser->changeEnvironmentRole($this->getSelectedEnvironment(), $role);
$this->stdErr->writeln("User <info>$email</info> updated");
if ($input->getOption('wait') && $result instanceof Activity) {
ActivityUtil::waitAndLog(
$result,
$this->stdErr,
'Environment redeployed successfully',
'Failed to redeploy environment'
);
}
}

if ($input->getOption('pipe')) {
Expand Down
31 changes: 17 additions & 14 deletions src/Console/EventSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@

use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\ParseException;
use GuzzleHttp\Exception\ServerException;
use Platformsh\Cli\Command\PlatformCommand;
use Platformsh\Cli\Exception\ConnectionFailedException;
use Platformsh\Cli\Exception\HttpException;
use Platformsh\Cli\Exception\LoginRequiredException;
use Platformsh\Cli\Exception\PermissionDeniedException;
use Platformsh\Client\Exception\EnvironmentStateException;
Expand Down Expand Up @@ -44,40 +45,42 @@ public function onException(ConsoleExceptionEvent $event)
$event->stopPropagation();
}

// Handle Guzzle client exceptions, i.e. HTTP 4xx errors.
if ($exception instanceof ClientException && ($response = $exception->getResponse())) {
// Handle Guzzle exceptions, i.e. HTTP 4xx or 5xx errors.
if (($exception instanceof ClientException || $exception instanceof ServerException) && ($response = $exception->getResponse())) {
$request = $exception->getRequest();
try {
$response->getBody()->seek(0);
$json = $response->json();
}
catch (ParseException $e) {
$json = [];
}
$response->getBody()->seek(0);
$json = (array) json_decode($response->getBody()->getContents(), true);

// Create a friendlier message for the OAuth2 "Invalid refresh token"
// error.
if ($response->getStatusCode() === 400 && isset($json['error_description']) && $json['error_description'] === 'Invalid refresh token') {
$event->setException(new LoginRequiredException(
"Invalid refresh token: please log in again.",
$request
$request,
$response
));
$event->stopPropagation();
}
elseif ($response->getStatusCode() === 401) {
$event->setException(new LoginRequiredException(
"Unauthorized: please log in again.",
$request
$request,
$response
));
$event->stopPropagation();
}
elseif ($response->getStatusCode() === 403) {
$event->setException(new PermissionDeniedException(
"Permission denied. Check your project or environment permissions.",
$request
"Permission denied. Check your project or environment permissions.",
$request,
$response
));
$event->stopPropagation();
}
else {
$event->setException(new HttpException(null, $request, $response));
$event->stopPropagation();
}
}

// When an environment is found to be in the wrong state, perhaps our
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/ConnectionFailedException.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Platformsh\Cli\Exception;

class ConnectionFailedException extends HttpExceptionBase
class ConnectionFailedException extends HttpException
{
protected $message = 'No Internet connection available.';
protected $code = 5;
Expand Down
31 changes: 31 additions & 0 deletions src/Exception/HttpException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Platformsh\Cli\Exception;

use GuzzleHttp\Message\RequestInterface;
use GuzzleHttp\Message\ResponseInterface;
use Platformsh\Client\Exception\ApiResponseException;

class HttpException extends \RuntimeException
{
protected $message = 'An API error occurred.';

/**
* @param string $message
* @param RequestInterface $request
* @param ResponseInterface $response
*/
public function __construct($message = null, RequestInterface $request = null, ResponseInterface $response = null)
{
$message = $message ?: $this->message;
if ($request !== null && $response !== null) {
$details = "[url] " . $request->getUrl();
$details .= " [status code] " . $response->getStatusCode();
$details .= " [reason phrase] " . $response->getReasonPhrase();
$details .= ApiResponseException::getErrorDetails($response);
$message .= "\nDetails:\n " . wordwrap($details);
}

parent::__construct($message, $this->code);
}
}
21 changes: 0 additions & 21 deletions src/Exception/HttpExceptionBase.php

This file was deleted.

2 changes: 1 addition & 1 deletion src/Exception/LoginRequiredException.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Platformsh\Cli\Exception;

class LoginRequiredException extends HttpExceptionBase
class LoginRequiredException extends HttpException
{
protected $message = 'Not logged in.';
protected $code = 3;
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/PermissionDeniedException.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Platformsh\Cli\Exception;

class PermissionDeniedException extends HttpExceptionBase
class PermissionDeniedException extends HttpException
{
protected $message = 'Permission denied. Check your project or environment permissions.';
protected $code = 6;
Expand Down
9 changes: 7 additions & 2 deletions src/Util/ActivityUtil.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,20 @@ function ($log) use ($output) {
*
* @param Activity[] $activities
* @param OutputInterface $output
* @param string|null $message
*/
public static function waitMultiple(array $activities, OutputInterface $output)
public static function waitMultiple(array $activities, OutputInterface $output, $message = null)
{
$count = count($activities);
if ($count <= 0) {
return;
}
$complete = 0;
$output->writeln("Waiting...");
if ($message === null) {
$activitiesPlural = $count > 1 ? 'activities' : 'activity';
$message = "Waiting for the $activitiesPlural to complete...";
}
$output->writeln($message);
$bar = new ProgressBar($output);
$bar->start($count);
$bar->setFormat('verbose');
Expand Down

0 comments on commit cf40ae9

Please sign in to comment.