/** * Wait for multiple activities to complete. * * A progress bar tracks the state of each activity. The activity log is * only displayed at the end, if an activity failed. * * @param Activity[] $activities * @param OutputInterface $output * @param Project $project * * @return bool * True if all activities succeed, false otherwise. */ public static function waitMultiple(array $activities, OutputInterface $output, Project $project) { $count = count($activities); if ($count == 0) { return true; } elseif ($count === 1) { return self::waitAndLog(reset($activities), $output); } $output->writeln("Waiting for {$count} activities..."); // Initialize a progress bar which will show elapsed time and all of the // activities' states. $bar = new ProgressBar($output); $states = []; foreach ($activities as $activity) { $state = $activity->state; $states[$state] = isset($states[$state]) ? $states[$state] + 1 : 1; } $bar->setPlaceholderFormatterDefinition('states', function () use(&$states) { $format = ''; foreach ($states as $state => $count) { $format .= $count . ' ' . self::formatState($state) . ', '; } return rtrim($format, ', '); }); $bar->setFormat(" [%bar%] %elapsed:6s% (%states%)"); $bar->start(); // Get the most recent created date of each of the activities, as a Unix // timestamp, so that they can be more efficiently refreshed. $mostRecentTimestamp = 0; foreach ($activities as $activity) { $created = strtotime($activity->created_at); $mostRecentTimestamp = $created > $mostRecentTimestamp ? $created : $mostRecentTimestamp; } // Wait for the activities to complete, polling (refreshing) all of them // with a 1 second delay. $complete = 0; while ($complete < $count) { sleep(1); $states = []; $complete = 0; // Get a list of activities on the project. Any of our activities // which are not contained in this list must be refreshed // individually. $projectActivities = $project->getActivities(0, null, $mostRecentTimestamp ?: null); foreach ($activities as $activity) { $refreshed = false; foreach ($projectActivities as $projectActivity) { if ($projectActivity->id === $activity->id) { $activity = $projectActivity; $refreshed = true; break; } } if (!$refreshed && !$activity->isComplete()) { $activity->refresh(); } if ($activity->isComplete()) { $complete++; } $state = $activity->state; $states[$state] = isset($states[$state]) ? $states[$state] + 1 : 1; } $bar->advance(); } $bar->finish(); $output->writeln(''); // Display success or failure messages for each activity. $success = true; foreach ($activities as $activity) { $description = $activity->getDescription(); switch ($activity['result']) { case Activity::RESULT_SUCCESS: $output->writeln("Activity <info>{$activity->id}</info> succeeded: {$description}"); break; case Activity::RESULT_FAILURE: $success = false; $output->writeln("Activity <error>{$activity->id}</error> failed"); // If the activity failed, show the complete log. $output->writeln(" Description: {$description}"); $output->writeln(" Log:"); $output->writeln(preg_replace('/^/m', ' ', $activity->log)); break; } } return $success; }