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

Create option: --no-buffer #103

Merged
merged 5 commits into from
Dec 29, 2024
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
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ provision/drall:
# Drall, it must be re-installed inside the Drupal installation.
.PHONY: refresh
refresh:
rsync -Ervu --inplace --delete --exclude=.coverage --exclude=.phpunit.cache --exclude=.idea --exclude=.git --exclude=vendor /opt/drall/ /opt/no-drupal/vendor/jigarius/drall/
rsync -Ervu --inplace --delete --exclude=.coverage --exclude=.phpunit.cache --exclude=.idea --exclude=.git --exclude=vendor /opt/drall/ /opt/empty-drupal/vendor/jigarius/drall/
rsync -Ervu --inplace --delete --exclude=.coverage --exclude=.phpunit.cache --exclude=.idea --exclude=.git --exclude=vendor /opt/drall/ /opt/drupal/vendor/jigarius/drall/
rsync -Ervu --inplace --delete --exclude=.coverage --exclude=.phpunit.cache --exclude=.idea --exclude=.git --exclude=test --exclude=vendor /opt/drall/ /opt/no-drupal/vendor/jigarius/drall/
rsync -Ervu --inplace --delete --exclude=.coverage --exclude=.phpunit.cache --exclude=.idea --exclude=.git --exclude=test --exclude=vendor /opt/drall/ /opt/empty-drupal/vendor/jigarius/drall/
rsync -Ervu --inplace --delete --exclude=.coverage --exclude=.phpunit.cache --exclude=.idea --exclude=.git --exclude=test --exclude=vendor /opt/drall/ /opt/drupal/vendor/jigarius/drall/


.PHONY: coverage-report/text
Expand All @@ -107,7 +107,7 @@ lint:

.PHONY: test
test:
DRALL_ENVIRONMENT=test XDEBUG_MODE=coverage composer --working-dir=/opt/drall run test
XDEBUG_MODE=coverage composer --working-dir=/opt/drall run test


.PHONY: info
Expand Down
85 changes: 42 additions & 43 deletions src/Command/ExecCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
namespace Drall\Command;

use Amp\ByteStream;
use Amp\ByteStream\WritableResourceStream;
use Amp\Pipeline\Pipeline;
use Amp\Process\Process;
use Drall\Model\EnvironmentId;
use Drall\Model\Placeholder;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\SignalableCommandInterface;
Expand All @@ -15,6 +15,7 @@
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\StreamOutput;

/**
* A command to execute a shell command on multiple sites.
Expand Down Expand Up @@ -83,9 +84,16 @@ protected function configure() {
'Do not execute commands, only display them.'
);

$this->addOption(
'no-buffer',
'B',
InputOption::VALUE_NONE,
'Do not buffer output.'
);

$this->addOption(
'no-progress',
NULL,
'P',
InputOption::VALUE_NONE,
'Do not show a progress bar.'
);
Expand Down Expand Up @@ -191,9 +199,14 @@ protected function preExecute(InputInterface $input, OutputInterface $output): v
if ($interval = $input->getOption('interval')) {
$this->logger->notice("Using a $interval-second interval between commands.", ['interval' => $interval]);
}

if ($input->getOption('no-buffer')) {
$this->logger->notice("Using no output buffering.");
}
}

protected function execute(InputInterface $input, OutputInterface $output): int {
/** @var \Symfony\Component\Console\Output\ConsoleOutput $output */
$this->preExecute($input, $output);

if (!$command = $this->getCommand($input, $output)) {
Expand Down Expand Up @@ -225,25 +238,29 @@ protected function execute(InputInterface $input, OutputInterface $output): int
if ($input->getOption('dry-run')) {
foreach ($values as $value) {
$pCommand = Placeholder::replace([$placeholder->value => $value], $command);
$output->writeln("• $value: Preview");
$output->writeln($pCommand, OutputInterface::VERBOSITY_QUIET);
$output->writeln($pCommand);
}

return Command::SUCCESS;
}

$textSection = $output->section();
$progressBar = new ProgressBar(
$this->isProgressBarHidden($input) ? new NullOutput() : $output,
$input->getOption('no-progress') ? new NullOutput() : $output->section(),
count($values)
);

$exitCode = Command::SUCCESS;

// Within the iteration, all output must go through the output sections.
// This keeps the text at the top and the progress bar at the bottom.
Pipeline::fromIterable($values)
->concurrent($input->getOption('workers'))
->unordered()
->forEach((function ($value) use (
$input,
$output,
$textSection,
$command,
$placeholder,
$progressBar,
Expand All @@ -255,27 +272,30 @@ protected function execute(InputInterface $input, OutputInterface $output): int

$pCommand = Placeholder::replace([$placeholder->value => $value], $command);
$process = Process::start("($pCommand) 2>&1");
$this->logger->debug('Running: {command}', ['command' => $pCommand]);

// @todo Improve formatting of headings.
$pOutput = ByteStream\buffer($process->getStdout());
$pStatus = 'Done';
$pIcon = '✔';
if (Command::SUCCESS !== $process->join()) {
$pStatus = 'Failed';
$pIcon = '✖';
$exitCode = Command::FAILURE;
}

$pMessage = "$pIcon $value: $pStatus";
// Send process output directly to the output stream.
if (
$input->getOption('no-buffer') &&
is_a($output, StreamOutput::class)
) {
$wStream = new WritableResourceStream($output->getStream());
ByteStream\pipe($process->getStdout(), $wStream);
}
// Buffer process output until it finishes.
elseif ($pOutput = rtrim(ByteStream\buffer($process->getStdout()))) {
// Always display command output, even in --quiet mode.
$textSection->writeln($pOutput, OutputInterface::VERBOSITY_QUIET);
}

$progressBar->clear();
// Always display command output, even in --quiet mode.
$output->writeln($pMessage, OutputInterface::VERBOSITY_QUIET);
$output->write($pOutput);
if (Command::SUCCESS === $process->join()) {
$textSection->writeln("✔ $value: Done");
}
else {
$textSection->writeln("✖ $value: Failed");
$exitCode = Command::FAILURE;
}

$progressBar->advance();
$progressBar->display();

// Wait between commands if --interval is specified.
if ($interval = $input->getOption('interval')) {
Expand All @@ -289,7 +309,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}

$progressBar->finish();
$output->writeln('');

return $exitCode;
}
Expand Down Expand Up @@ -348,26 +367,6 @@ private function getUniquePlaceholder(string $command): ?Placeholder {
return reset($placeholders);
}

/**
* Whether the Drall progress bar should be hidden.
*
* @param \Symfony\Component\Console\Input\InputInterface $input
* The input.
*
* @return bool
* True or false.
*/
private function isProgressBarHidden(InputInterface $input): bool {
if (
EnvironmentId::Test->isActive() ||
$input->getOption('no-progress')
) {
return TRUE;
}

return FALSE;
}

public function getSubscribedSignals(): array {
return [SIGINT];
}
Expand Down
26 changes: 0 additions & 26 deletions src/Model/EnvironmentId.php

This file was deleted.

Loading
Loading