Skip to content

Commit

Permalink
Merge pull request #374 from jolicode/windows-and-tty-are-in-speedboat
Browse files Browse the repository at this point in the history
Fix some issue with Windows
  • Loading branch information
pyrech authored Apr 3, 2024
2 parents 7a2b0c9 + 45424c4 commit b13c34d
Show file tree
Hide file tree
Showing 86 changed files with 193 additions and 406 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
* Find root directory by looking for a `.castor/castor.php` file
* Allow stub file to be in `.castor/.castor.stub.php`

* Fix issue with PTY on windows, it's now always disabled
* Fix issue when finding root dir on windows
* Fix issue on SymfonyTask creation

* Deprecate loading all PHP files from `[ROOT_DIR]/castor`
* Deprecate `Context::withPath()` in favor of `Context::withWorkingDirectory()`
* Deprecate `path` argument in `capture()`, `exit_code()`, `run()`, `with()` in
Expand Down
37 changes: 29 additions & 8 deletions bin/generate-tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,13 @@
'log:error',
'log:info',
'log:with-context',
'list',
'parallel:sleep',
'remote-import:remote-tasks',
'run:ls',
'run:run-parallel',
'symfony:greet',
'symfony:hello',
// Imported tasks
'pyrech:hello-example',
'pyrech:foobar',
Expand Down Expand Up @@ -140,7 +143,10 @@
add_test(['context:context', '--context', 'production'], 'ContextContextProductionTest');
add_test(['context:context', '--context', 'run'], 'ContextContextRunTest');
add_test(['enabled:hello', '--context', 'production'], 'EnabledInProduction');
add_test(['list', '--raw', '--format', 'txt', '--short'], 'ListTest', skipOnBinary: true);
add_test(['parallel:sleep', '--sleep5', '0', '--sleep7', '0', '--sleep10', '0'], 'ParallelSleepTest');
add_test(['symfony:greet', 'World', '--french', 'COUCOU', '--punctuation', '!'], 'SymfonyGreetTest', skipOnBinary: true);
add_test(['symfony:hello'], 'SymfonyHelloTest', skipOnBinary: true);
// In /tmp
add_test(['completion', 'bash'], 'NoConfigCompletionTest', '/tmp');
add_test(['init'], 'NewProjectInitTest', '/tmp');
Expand All @@ -150,7 +156,7 @@
add_test(['list'], 'LayoutWithFolder', __DIR__ . '/../tests/Examples/fixtures/layout/with-folder');
add_test(['list'], 'LayoutWithOldFolder', __DIR__ . '/../tests/Examples/fixtures/layout/with-old-folder');

function add_test(array $args, string $class, ?string $cwd = null, bool $needRemote = false)
function add_test(array $args, string $class, ?string $cwd = null, bool $needRemote = false, bool $skipOnBinary = false)
{
$fp = fopen(__FILE__, 'r');
fseek($fp, __COMPILER_HALT_OFFSET__ + 1);
Expand All @@ -168,18 +174,37 @@ function add_test(array $args, string $class, ?string $cwd = null, bool $needRem
);
$process->run();

$err = OutputCleaner::cleanOutput($process->getErrorOutput());

$code = strtr($template, [
'{{ class_name }}' => $class,
'{{ task }}' => $args[0] ?? 'no task',
'{{ args }}' => implode(', ', array_map(fn ($arg) => var_export($arg, true), $args)),
'{{ exitCode }}' => $process->getExitCode(),
'{{ cwd }}' => $cwd ? ', ' . var_export($cwd, true) : '',
'{{ needRemote }}' => $needRemote ? ', needRemote: true' : '',
'{{ skip-on-binary }}' => match ($skipOnBinary) {
true => <<<'PHP'
if (self::$binary) {
$this->markTestSkipped('This test is not compatible with the binary version of Castor.');
}

PHP,
default => '',
},
'{{ error-assertion }}' => match ((bool) $err) {
true => <<<'PHP'
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
PHP,
default => <<<'PHP'
$this->assertSame('', $process->getErrorOutput());
PHP,
},
]);

file_put_contents(__DIR__ . '/../tests/Examples/Generated/' . $class . '.php', $code);
file_put_contents(__DIR__ . '/../tests/Examples/Generated/' . $class . '.php.output.txt', OutputCleaner::cleanOutput($process->getOutput()));
$err = OutputCleaner::cleanOutput($process->getErrorOutput());
if ($err) {
file_put_contents(__DIR__ . '/../tests/Examples/Generated/' . $class . '.php.err.txt', $err);
}
Expand All @@ -196,15 +221,11 @@ class {{ class_name }} extends TaskTestCase
{
// {{ task }}
public function test(): void
{
{{{ skip-on-binary }}
$process = $this->runTask([{{ args }}]{{ cwd }}{{ needRemote }});

$this->assertSame({{ exitCode }}, $process->getExitCode());
$this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput());
if (file_exists(__FILE__ . '.err.txt')) {
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
} else {
$this->assertSame('', $process->getErrorOutput());
}
{{ error-assertion }}
}
}
7 changes: 6 additions & 1 deletion examples/run.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace run;

use Castor\Attribute\AsTask;
use JoliCode\PhpOsHelper\OsHelper;
use Symfony\Component\Console\Helper\ProcessHelper;

use function Castor\app;
Expand All @@ -15,7 +16,11 @@
#[AsTask(description: 'Run a sub-process and display information about it')]
function ls(): void
{
$process = run('ls -alh && echo $foo', quiet: true, environment: ['foo' => 'ba\'"`r']);
if (OsHelper::isWindows()) {
$process = run('dir');
} else {
$process = run('ls -alh && echo $foo', quiet: true, environment: ['foo' => 'ba\'"`r']);
}

io()->writeln('Output:' . $process->getOutput());
io()->writeln('Error output: ' . $process->getErrorOutput());
Expand Down
4 changes: 2 additions & 2 deletions examples/symfony.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand('hello', 'Says hello from a symfony application')]
#[AsSymfonyTask(name: 'symfony:hello', console: [__FILE__])]
#[AsSymfonyTask(name: 'symfony:hello', console: [\PHP_BINARY, __FILE__])] // We need to force PHP binary to support windows
class HelloCommand extends Command
{
protected function execute(InputInterface $input, OutputInterface $output): int
Expand All @@ -27,7 +27,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}

#[AsCommand('greet')]
#[AsSymfonyTask(name: 'symfony:greet', console: [__FILE__])]
#[AsSymfonyTask(name: 'symfony:greet', console: [\PHP_BINARY, __FILE__])] // We need to force PHP binary to support windows
class GreetCommand extends Command
{
protected function configure(): void
Expand Down
21 changes: 18 additions & 3 deletions src/FunctionFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Castor\Helper\SluggerHelper;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Process\Exception\ExceptionInterface;
use Symfony\Component\Process\Process;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
Expand Down Expand Up @@ -104,6 +105,10 @@ private function doFindFunctions(string $file): iterable
if (class_exists(\RepackedApplication::class)) {
return;
}
// Nor in static binary
if (!\PHP_BINARY) {
return;
}

$newClasses = array_diff(get_declared_classes(), $initialClasses);
foreach ($newClasses as $className) {
Expand Down Expand Up @@ -164,12 +169,22 @@ private function resolveSymfonyTask(\ReflectionClass $reflectionClass): iterable

$key = hash('sha256', implode('-', ['symfony-console-definitions-', ...$console, $this->rootDir]));

$definitions = $this->cache->get($key, function (ItemInterface $item) use ($console) {
$definitions = $this->cache->get($key, function (ItemInterface $item) use ($console, $reflectionClass) {
$item->expiresAfter(60 * 60 * 24);

$p = new Process([...$console, '--format=json']);
$p->mustRun();

return json_decode($p->getOutput(), true);
try {
$p->mustRun();
} catch (ExceptionInterface $e) {
throw new FunctionConfigurationException('Could not run the Symfony console.', $reflectionClass, $e);
}

try {
return json_decode($p->getOutput(), true, 512, \JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
throw new FunctionConfigurationException('Could not run the Symfony console.', $reflectionClass, $e);
}
});

$sfAttribute = $reflectionClass->getAttributes(AsCommand::class);
Expand Down
15 changes: 9 additions & 6 deletions src/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,15 @@ function run(
;
}

if ($context->tty) {
$process->setTty(true);
$process->setInput(\STDIN);
} elseif ($context->pty) {
$process->setPty(true);
$process->setInput(\STDIN);
// TTY does not work on windows, and PTY is a mess, so let's skip everything!
if (!OsHelper::isWindows()) {
if ($context->tty) {
$process->setTty(true);
$process->setInput(\STDIN);
} elseif ($context->pty) {
$process->setPty(true);
$process->setInput(\STDIN);
}
}

if (!$context->quiet && !$callback) {
Expand Down
6 changes: 1 addition & 5 deletions tests/Examples/Generated/ArgPassthruExpanded.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public function test(): void

$this->assertSame(0, $process->getExitCode());
$this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput());
if (file_exists(__FILE__ . '.err.txt')) {
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
} else {
$this->assertSame('', $process->getErrorOutput());
}
$this->assertSame('', $process->getErrorOutput());
}
}
6 changes: 1 addition & 5 deletions tests/Examples/Generated/ArgsAnotherArgsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public function test(): void

$this->assertSame(0, $process->getExitCode());
$this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput());
if (file_exists(__FILE__ . '.err.txt')) {
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
} else {
$this->assertSame('', $process->getErrorOutput());
}
$this->assertSame('', $process->getErrorOutput());
}
}
6 changes: 1 addition & 5 deletions tests/Examples/Generated/ArgsArgsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public function test(): void

$this->assertSame(0, $process->getExitCode());
$this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput());
if (file_exists(__FILE__ . '.err.txt')) {
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
} else {
$this->assertSame('', $process->getErrorOutput());
}
$this->assertSame('', $process->getErrorOutput());
}
}
6 changes: 1 addition & 5 deletions tests/Examples/Generated/ArgsAutocompleteArgumentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public function test(): void

$this->assertSame(0, $process->getExitCode());
$this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput());
if (file_exists(__FILE__ . '.err.txt')) {
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
} else {
$this->assertSame('', $process->getErrorOutput());
}
$this->assertSame('', $process->getErrorOutput());
}
}
6 changes: 1 addition & 5 deletions tests/Examples/Generated/ArgsPassthruTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public function test(): void

$this->assertSame(0, $process->getExitCode());
$this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput());
if (file_exists(__FILE__ . '.err.txt')) {
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
} else {
$this->assertSame('', $process->getErrorOutput());
}
$this->assertSame('', $process->getErrorOutput());
}
}
6 changes: 1 addition & 5 deletions tests/Examples/Generated/AutocompleteInvalidTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public function test(): void

$this->assertSame(1, $process->getExitCode());
$this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput());
if (file_exists(__FILE__ . '.err.txt')) {
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
} else {
$this->assertSame('', $process->getErrorOutput());
}
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
}
}
6 changes: 1 addition & 5 deletions tests/Examples/Generated/BarBarTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public function test(): void

$this->assertSame(0, $process->getExitCode());
$this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput());
if (file_exists(__FILE__ . '.err.txt')) {
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
} else {
$this->assertSame('', $process->getErrorOutput());
}
$this->assertSame('', $process->getErrorOutput());
}
}
6 changes: 1 addition & 5 deletions tests/Examples/Generated/CacheComplexTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public function test(): void

$this->assertSame(0, $process->getExitCode());
$this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput());
if (file_exists(__FILE__ . '.err.txt')) {
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
} else {
$this->assertSame('', $process->getErrorOutput());
}
$this->assertSame('', $process->getErrorOutput());
}
}
6 changes: 1 addition & 5 deletions tests/Examples/Generated/CacheSimpleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public function test(): void

$this->assertSame(0, $process->getExitCode());
$this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput());
if (file_exists(__FILE__ . '.err.txt')) {
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
} else {
$this->assertSame('', $process->getErrorOutput());
}
$this->assertSame('', $process->getErrorOutput());
}
}
6 changes: 1 addition & 5 deletions tests/Examples/Generated/CdDirectoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public function test(): void

$this->assertSame(0, $process->getExitCode());
$this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput());
if (file_exists(__FILE__ . '.err.txt')) {
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
} else {
$this->assertSame('', $process->getErrorOutput());
}
$this->assertSame('', $process->getErrorOutput());
}
}
6 changes: 1 addition & 5 deletions tests/Examples/Generated/ContextContextDoNotExistTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public function test(): void

$this->assertSame(1, $process->getExitCode());
$this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput());
if (file_exists(__FILE__ . '.err.txt')) {
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
} else {
$this->assertSame('', $process->getErrorOutput());
}
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
}
}
6 changes: 1 addition & 5 deletions tests/Examples/Generated/ContextContextDynamicTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public function test(): void

$this->assertSame(0, $process->getExitCode());
$this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput());
if (file_exists(__FILE__ . '.err.txt')) {
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
} else {
$this->assertSame('', $process->getErrorOutput());
}
$this->assertSame('', $process->getErrorOutput());
}
}
6 changes: 1 addition & 5 deletions tests/Examples/Generated/ContextContextInfoForcedTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public function test(): void

$this->assertSame(0, $process->getExitCode());
$this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput());
if (file_exists(__FILE__ . '.err.txt')) {
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
} else {
$this->assertSame('', $process->getErrorOutput());
}
$this->assertSame('', $process->getErrorOutput());
}
}
6 changes: 1 addition & 5 deletions tests/Examples/Generated/ContextContextMyDefaultTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public function test(): void

$this->assertSame(0, $process->getExitCode());
$this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput());
if (file_exists(__FILE__ . '.err.txt')) {
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
} else {
$this->assertSame('', $process->getErrorOutput());
}
$this->assertSame('', $process->getErrorOutput());
}
}
6 changes: 1 addition & 5 deletions tests/Examples/Generated/ContextContextPathTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public function test(): void

$this->assertSame(0, $process->getExitCode());
$this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput());
if (file_exists(__FILE__ . '.err.txt')) {
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
} else {
$this->assertSame('', $process->getErrorOutput());
}
$this->assertSame('', $process->getErrorOutput());
}
}
6 changes: 1 addition & 5 deletions tests/Examples/Generated/ContextContextProductionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public function test(): void

$this->assertSame(0, $process->getExitCode());
$this->assertStringEqualsFile(__FILE__ . '.output.txt', $process->getOutput());
if (file_exists(__FILE__ . '.err.txt')) {
$this->assertStringEqualsFile(__FILE__ . '.err.txt', $process->getErrorOutput());
} else {
$this->assertSame('', $process->getErrorOutput());
}
$this->assertSame('', $process->getErrorOutput());
}
}
Loading

0 comments on commit b13c34d

Please sign in to comment.