Skip to content

Commit

Permalink
[ Feat ] Use TTY mode on Process Facade (#72)
Browse files Browse the repository at this point in the history
* Extract snippets into getter function

* new runner using tty mode on process facade

* add new snippet to use new run command, make default

* Update deprecated GetRunCmd to automatically update hook snippets

* add fallback to support non-tty interfaces

* remove unnecessary shell script

* remove unused 'scripts' command

* remove empty test file

* temporarily skip test

* update assignment operator

* refactor skipped test
  • Loading branch information
ProjektGopher committed May 24, 2024
1 parent ef39f3f commit d51a905
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 93 deletions.
29 changes: 11 additions & 18 deletions app/Commands/GetRunCmd.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,30 @@

namespace ProjektGopher\Whisky\Commands;

use Illuminate\Support\Facades\File;
use LaravelZero\Framework\Commands\Command;
use ProjektGopher\Whisky\Platform;
use ProjektGopher\Whisky\Whisky;

/**
* This command is basically only needed to build the execution path
* to the `run` bash script, or to skip the hooks once.
* This command was only used to construct the execution path
* to the `run-hook` bash script, which is now deprecated.
* Now we can automatically update the hooks snippets.
*/
class GetRunCmd extends Command
{
protected $signature = 'get-run-cmd {hook}';

protected $description = 'Get the bash command to run a given hook';

public function handle(): int
public function handle(): void
{
if (File::exists(Platform::cwd('.git/hooks/skip-once'))) {
File::delete(Platform::cwd('.git/hooks/skip-once'));

return Command::SUCCESS;
}

// Check if the hook is disabled in whisky.json
if (in_array($this->argument('hook'), Whisky::readConfig('disabled'))) {
return Command::SUCCESS;
}

$bin = Whisky::bin_path();
$this->line(Whisky::base_path("bin/run-hook {$this->argument('hook')} {$bin}"));

return Command::SUCCESS;
$commands = collect([
"echo 'The snippet in your hook is deprecated. Updating...'",
"{$bin} update",
"{$bin} run {$this->argument('hook')}",
]);

$this->line($commands->implode(PHP_EOL));
}
}
60 changes: 60 additions & 0 deletions app/Commands/Run.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

namespace ProjektGopher\Whisky\Commands;

use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Process;
use LaravelZero\Framework\Commands\Command;
use ProjektGopher\Whisky\Hook;
use ProjektGopher\Whisky\Platform;
use ProjektGopher\Whisky\Whisky;
use Symfony\Component\Process\Process as SymfonyProcess;

class Run extends Command
{
protected $signature = 'run {hook}';

protected $description = 'Run the scripts for a given hook';

public function handle(): int
{
if (File::missing(Platform::cwd('whisky.json'))) {
$this->error('Whisky has not been initialized in this project, aborting...');
$this->line('Run `./vendor/bin/whisky install` to initialize Whisky in this project.');

return Command::FAILURE;
}

if (File::exists(Platform::cwd('.git/hooks/skip-once'))) {
File::delete(Platform::cwd('.git/hooks/skip-once'));

return Command::SUCCESS;
}

// Check if the hook is disabled in whisky.json
if (in_array($this->argument('hook'), Whisky::readConfig('disabled'))) {
return Command::SUCCESS;
}

$exitCode = Command::SUCCESS;

Hook::make($this->argument('hook'))
->getScripts()
->each(function (string $script) use (&$exitCode): void {
$isTtySupported = SymfonyProcess::isTtySupported();

$result = $isTtySupported
? Process::forever()->tty()->run($script)
: Process::timeout(300)->run($script);

if ($result->failed() && ! $isTtySupported) {
$this->line($result->errorOutput());
$this->line($result->output());
}

$exitCode |= $result->exitCode();
});

return $exitCode;
}
}
31 changes: 0 additions & 31 deletions app/Commands/Scripts.php

This file was deleted.

33 changes: 22 additions & 11 deletions app/Hook.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,9 @@ public function uninstall(): bool
}

$contents = File::get($path);
$commands = [
"eval \"$({$this->bin} get-run-cmd {$this->hook})\"".PHP_EOL,
// TODO: legacy - handle upgrade somehow
"eval \"$(./vendor/bin/whisky get-run-cmd {$this->hook})\"".PHP_EOL,
];
$commands = $this->getSnippets()
->map(fn (string $snippet): string => $snippet.PHP_EOL)
->toArray();

if (! Str::contains($contents, $commands)) {
return false;
Expand Down Expand Up @@ -94,11 +92,7 @@ public function isInstalled(): bool
{
return Str::contains(
File::get(Platform::cwd(".git/hooks/{$this->hook}")),
[
"eval \"$({$this->bin} get-run-cmd {$this->hook})\"",
// TODO: legacy - handle upgrade somehow
"eval \"$(./vendor/bin/whisky get-run-cmd {$this->hook})\"",
],
$this->getSnippets()->toArray(),
);
}

Expand All @@ -109,7 +103,7 @@ public function install(): void
{
File::append(
Platform::cwd(".git/hooks/{$this->hook}"),
"eval \"$({$this->bin} get-run-cmd {$this->hook})\"".PHP_EOL,
$this->getSnippets()->first().PHP_EOL,
);
}

Expand All @@ -126,6 +120,23 @@ public function getScripts(): Collection
return collect(Whisky::readConfig("hooks.{$this->hook}"));
}

/**
* Collect the bash snippet history for calling the Whisky bin.
* The current version of the snippet should always be first.
* We keep this history to make updating our hooks easier.
*
* @return Collection<int, string>
*/
public function getSnippets(): Collection
{
return collect([
"{$this->bin} run {$this->hook}",
// Legacy Snippets.
"eval \"$({$this->bin} get-run-cmd {$this->hook})\"",
"eval \"$(./vendor/bin/whisky get-run-cmd {$this->hook})\"",
]);
}

////////////////////////////////////////
//// Static methods ////
////////////////////////////////////////
Expand Down
28 changes: 0 additions & 28 deletions bin/run-hook

This file was deleted.

13 changes: 8 additions & 5 deletions tests/Feature/RunTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
use Illuminate\Support\Facades\File;
use ProjektGopher\Whisky\Platform;

it('deletes skip-once file if exists and outputs nothing', function () {
it('deletes skip-once file if exists as long as whisky.json exists', function () {
File::shouldReceive('missing')
->once()
->with(Platform::cwd('whisky.json'))
->andReturnFalse();

File::shouldReceive('exists')
->once()
->with(Platform::cwd('.git/hooks/skip-once'))
Expand All @@ -14,9 +19,7 @@
->with(Platform::cwd('.git/hooks/skip-once'))
->andReturnTrue();

$this->artisan('get-run-cmd pre-commit')
$this->artisan('run pre-commit')
->doesntExpectOutputToContain('run-hook')
->assertExitCode(0);
});

it('points correctly to the run-hook script');
})->skip('Needs to be refactored so that the hooks don\'t actually run');
Empty file removed tests/Feature/ScriptsTest.php
Empty file.

0 comments on commit d51a905

Please sign in to comment.