Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve activity log formatting #1291

Merged
merged 1 commit into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions src/Command/Activity/ActivityCancelCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$activity = $byId[$id];
}

$this->stdErr->writeln(sprintf(
'Cancelling the activity <info>%s</info> (%s)...',
$activity->id,
ActivityMonitor::getFormattedDescription($activity)
));
$this->stdErr->writeln('Cancelling the activity ' . ActivityMonitor::getFormattedDescription($activity, true, true, 'cyan'));

try {
$activity->cancel();
Expand Down
1 change: 0 additions & 1 deletion src/Command/Environment/EnvironmentResumeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ protected function execute(InputInterface $input, OutputInterface $output)
if (!$questionHelper->confirm('Are you sure you want to resume the paused environment <comment>' . $environment->id . '</comment>?')) {
return 1;
}
$this->stdErr->writeln('');

$activity = $environment->resume();
$this->api()->clearEnvironmentsCache($environment->project);
Expand Down
74 changes: 50 additions & 24 deletions src/Service/ActivityMonitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,8 @@ public function waitAndLog(Activity $activity, $pollInterval = 3, $timestamps =
$logOutput = $logOutput ?: $stdErr;

if ($context) {
$stdErr->writeln(sprintf(
'Waiting for the activity <info>%s</info> (%s):',
$activity->id,
self::getFormattedDescription($activity)
));
$stdErr->writeln('');
$stdErr->writeln('Waiting for the activity: ' . self::getFormattedDescription($activity, true, true, 'cyan'));
$stdErr->writeln('');
}

Expand Down Expand Up @@ -205,23 +202,24 @@ public function waitAndLog(Activity $activity, $pollInterval = 3, $timestamps =
}
$bar->finish();
$stdErr->writeln('');
$stdErr->writeln('');

// Display the success or failure messages.
switch ($activity->result) {
case Activity::RESULT_SUCCESS:
$stdErr->writeln("Activity <info>{$activity->id}</info> succeeded");
$stdErr->writeln('The activity succeeded: ' . self::getFormattedDescription($activity, true, true, 'green'));
return true;

case Activity::RESULT_FAILURE:
if ($activity->state === Activity::STATE_CANCELLED) {
$stdErr->writeln("The activity <error>{$activity->id}</error> was cancelled");
$stdErr->writeln('The activity was cancelled: ' . self::getFormattedDescription($activity, true, true, 'yellow'));
} else {
$stdErr->writeln("Activity <error>{$activity->id}</error> failed");
$stdErr->writeln('The activity failed: ' . self::getFormattedDescription($activity, true, true, 'red'));
}
return false;
}

$stdErr->writeln("The log for activity <info>{$activity->id}</info> finished with an unknown result");
$stdErr->writeln('The activity finished with an unknown result: ' . self::getFormattedDescription($activity, true, true, 'yellow'));

return false;
}
Expand Down Expand Up @@ -290,16 +288,33 @@ public function waitMultiple(array $activities, Project $project)
{
$stdErr = $this->getStdErr();

// If there is 1 activity then display its log.
$count = count($activities);
if ($count == 0) {
return true;
} elseif ($count === 1) {
return $this->waitAndLog(reset($activities));
}

// If there is 1 non-integration activity, then display its log, and
// wait for the integration activities separately.
$nonIntegrationActivities = array_filter($activities, function (Activity $a) {
return strpos($a->type, 'integration.') !== 0;
});
if (count($nonIntegrationActivities) === 1) {
$nonIntegrationActivity = reset($nonIntegrationActivities);
$integrationActivities = array_filter($activities, function (Activity $a) {
return strpos($a->type, 'integration.') === 0;
});
$nonIntegrationSuccess = $this->waitAndLog($nonIntegrationActivity);
$integrationSuccess = $this->waitMultiple($integrationActivities, $project);
return $nonIntegrationSuccess && $integrationSuccess;
}

// For more than one activity, display a progress bar with the status of each.
$stdErr->writeln(sprintf('Waiting for %d activities...', $count));
foreach ($activities as $activity) {
$stdErr->writeln(sprintf(' <info>%s</info>: %s', $activity->id, self::getFormattedDescription($activity)));
$stdErr->writeln(' ', self::getFormattedDescription($activity, true, true, 'cyan'));
}

// The progress bar will show elapsed time and all of the activities'
Expand Down Expand Up @@ -366,19 +381,18 @@ public function waitMultiple(array $activities, Project $project)
// Display success or failure messages for each activity.
$success = true;
foreach ($activities as $activity) {
$description = self::getFormattedDescription($activity);
switch ($activity['result']) {
case Activity::RESULT_SUCCESS:
$stdErr->writeln(sprintf('Activity <info>%s</info> succeeded: %s', $activity->id, $description));
$stdErr->writeln('Activity succeeded: ' . self::getFormattedDescription($activity, true, true, 'green'));
break;

case Activity::RESULT_FAILURE:
$success = false;
$stdErr->writeln(sprintf('Activity <error>%s</error> failed', $activity->id));
$stdErr->writeln(sprintf('Activity failed: <error>%s</error>', $activity->id));

// If the activity failed, show the complete log.
$stdErr->writeln(' Description: ' . $description);
$stdErr->writeln(' Log:');
$stdErr->writeln(' <error>Description:</error> ' . self::getFormattedDescription($activity));
$stdErr->writeln(' <error>Log:</error>');
$stdErr->writeln($this->indent($this->formatLog($activity->readLog())));
break;
}
Expand Down Expand Up @@ -435,31 +449,43 @@ protected function newProgressBar(OutputInterface $output)
/**
* Get the formatted description of an activity.
*
* @param \Platformsh\Client\Model\Activity $activity
* @param bool $withDecoration
* @param \Platformsh\Client\Model\Activity $activity The activity.
* @param bool $withDecoration Add decoration to activity tags.
* @param bool $withId Add the activity ID.
* @param string $fgColor Define a foreground color e.g. 'green', 'red', 'cyan'.
*
* @return string
*/
public static function getFormattedDescription(Activity $activity, $withDecoration = true)
public static function getFormattedDescription(Activity $activity, $withDecoration = true, $withId = false, $fgColor = '')
{
if (!$withDecoration) {
if ($withId) {
return '[' . $activity->id . '] ' . $activity->getDescription(false);
}
return $activity->getDescription(false);
}
$value = $activity->getDescription(true);
$descr = $activity->getDescription(true);

// Replace description HTML elements with Symfony Console decoration
// tags.
$value = preg_replace('@<[^/][^>]+>@', '<options=underscore>', $value);
$value = preg_replace('@</[^>]+>@', '</>', $value);
$descr = preg_replace('@<[^/][^>]+>@', '<options=underscore>', $descr);
$descr = preg_replace('@</[^>]+>@', '</>', $descr);

// Replace literal tags like "&lt;info&;gt;" with escaped tags like
// "\<info>".
$value = preg_replace('@&lt;(/?[a-z][a-z0-9,_=;-]*+)&gt;@i', '\\\<$1>', $value);
$descr = preg_replace('@&lt;(/?[a-z][a-z0-9,_=;-]*+)&gt;@i', '\\\<$1>', $descr);

// Decode other HTML entities.
$value = html_entity_decode($value, ENT_QUOTES, 'utf-8');
$descr = html_entity_decode($descr, ENT_QUOTES, 'utf-8');

if ($withId) {
if ($fgColor) {
return sprintf('<fg=%s>[%s]</> %s', $fgColor, $activity->id, $descr);
}
return sprintf('[%s] %s', $activity->id, $descr);
}

return $value;
return $descr;
}

/**
Expand Down
Loading