diff --git a/src/Helpers/CommandLine.php b/src/Helpers/CommandLine.php index f0789fd..c49d535 100644 --- a/src/Helpers/CommandLine.php +++ b/src/Helpers/CommandLine.php @@ -2,6 +2,8 @@ namespace AlexTartan\Helpers; +use Webmozart\Assert\Assert; + use function escapeshellarg; use function escapeshellcmd; @@ -10,26 +12,41 @@ class CommandLine public const STDERR_TO_STDOUT = ' 2>&1'; public const STDOUT_TO_DEV_NULL = '/dev/null'; + public const MODE_WRITE = '>'; + public const MODE_APPEND = '>>'; + private string $command; private ?string $workingDirectory; private ?string $stdOut = ''; private ?string $stdErr = ''; - - public function __construct(string $command, ?string $workingDirectory, ?string $stdErr, ?string $stdOut) - { + private bool $background; + + public function __construct( + string $command, + ?string $workingDirectory, + ?string $stdErr, + ?string $stdOut, + string $stdErrMode = self::MODE_WRITE, + string $stdOutMode = self::MODE_WRITE, + bool $background = false + ) { $this->command = escapeshellcmd($command); $this->workingDirectory = $workingDirectory; + $this->background = $background; + + Assert::oneOf($stdErrMode, [self::MODE_WRITE, self::MODE_APPEND]); + Assert::oneOf($stdOutMode, [self::MODE_WRITE, self::MODE_APPEND]); if ($stdErr === self::STDERR_TO_STDOUT) { $this->stdErr = self::STDERR_TO_STDOUT; } elseif ($stdErr !== null) { - $this->stdErr = ' 2> ' . escapeshellarg($stdErr); + $this->stdErr = ' 2' . $stdErrMode . ' ' . escapeshellarg($stdErr); } if ($stdOut === self::STDOUT_TO_DEV_NULL) { - $this->stdOut = ' > ' . $stdOut; + $this->stdOut = ' ' . $stdOutMode . ' ' . $stdOut; } elseif ($stdOut !== null) { - $this->stdOut = ' > ' . escapeshellarg($stdOut); + $this->stdOut = ' ' . $stdOutMode . ' ' . escapeshellarg($stdOut); } } @@ -66,6 +83,10 @@ public function getFullCommand(): string $fullCommand .= $this->stdOut; } + if ($this->background) { + $fullCommand .= ' &'; + } + return $fullCommand; } diff --git a/test/Helpers/CommandLineTest.php b/test/Helpers/CommandLineTest.php index 935d945..56c6c20 100644 --- a/test/Helpers/CommandLineTest.php +++ b/test/Helpers/CommandLineTest.php @@ -98,4 +98,58 @@ public function testAdvancedCommandWithWorkingDirAndStdErrAndStdOut(): void $commandLine->getFullCommand() ); } + + public function testAdvancedCommandWithWorkingDirAndStdErrAndStdOutAppendAndWrite(): void + { + $commandLine = (new CommandLine( + 'ls', + '/opt', + CommandLine::STDERR_TO_STDOUT, + CommandLine::STDOUT_TO_DEV_NULL, + CommandLine::MODE_APPEND, + CommandLine::MODE_APPEND + )) + ->withArgument('-la') + ->withOption('--color', 'auto', '='); + + self::assertSame( + "cd '/opt' && ls '-la' --color='auto' 2>&1 >> /dev/null", + $commandLine->getFullCommand() + ); + } + + public function testSimpleCommandWithWorkingDirAndStdErrAndStdOutNonDefaultAppendAndWrite(): void + { + $commandLine = new CommandLine( + 'ls', + '/opt', + '/var/log/err', + '/var/log/out', + CommandLine::MODE_APPEND, + CommandLine::MODE_WRITE + ); + + self::assertSame( + "cd '/opt' && ls 2>> '/var/log/err' > '/var/log/out'", + $commandLine->getFullCommand() + ); + } + + public function testSimpleCommandWithWorkingDirAndStdErrAndStdOutNonDefaultAppendAndWriteBackgroundTask(): void + { + $commandLine = new CommandLine( + 'ls', + '/opt', + '/var/log/err', + '/var/log/out', + CommandLine::MODE_APPEND, + CommandLine::MODE_WRITE, + true + ); + + self::assertSame( + "cd '/opt' && ls 2>> '/var/log/err' > '/var/log/out' &", + $commandLine->getFullCommand() + ); + } }