Skip to content
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
12 changes: 6 additions & 6 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 33 additions & 15 deletions src/Cli/RunCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,45 +70,63 @@ public function run(?ArgumentValueList $arguments = null):void {
public function cronRunStep(
int $jobsRan,
?DateTime $wait,
bool $continue
bool $continue,
array $runCommandList = [],
?string $nextCommand = null
):void {
$message = "";
$now = new DateTime();

if(is_null($wait)) {
$this->writeLine("No tasks in crontab.");
exit(0);
}

$jobPlural = "job";
if($jobsRan !== 1) {
$jobPlural .= "s";
}
$jobPlural = $jobsRan === 1 ? "job" : "jobs";
$displayedRunCommands = array_map(
function(string $command):string {
return $this->displayCommandName($command);
},
$runCommandList
);

if($jobsRan > 0) {
$message = "Just ran $jobsRan $jobPlural, ";
$message = "Just ran $jobsRan $jobPlural";
if($displayedRunCommands) {
$message .= " (" . implode(", ", $displayedRunCommands) . ")";
}

$this->stream->writeLine($message);

$message .= "next job at: " . $wait->format("H:i:s");
$message = "Next job at: " . $wait->format("H:i:s");
if($nextCommand) {
$message .= " (" . $this->displayCommandName($nextCommand) . ")";
}

if($now->diff($wait)->format("%a") > 0) {
$message .= " on " . $wait->format("dS M");
}
if($now->diff($wait)->format("%y") > 0) {
$message .= " " . $wait->format("Y");
}
$this->stream->writeLine($message);

if($continue) {
$message .= ". Waiting...";
$this->stream->writeLine("Waiting...");
}
else {
$message .= ". Stopping now.";
}

protected function displayCommandName(string $command):string {
$command = trim($command);
if(strpos($command, "::") !== false) {
$functionExpression = trim(
preg_replace("/\\s*\\(.+$/", "", $command)
);
[$class, $method] = explode("::", $functionExpression, 2);
$class = basename(str_replace("\\", "/", $class));
return "$class::$method";
}

$this->stream->writeLine(
ucfirst($message)
);
$script = preg_split("/\\s+/", $command, 2)[0];
return basename(str_replace("\\", "/", $script));
}

public function getName():string {
Expand Down
24 changes: 24 additions & 0 deletions src/Queue.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,21 @@ public function runDueJobs():int {
return $jobsRan;
}

/** @return string[] */
public function runDueJobsAndGetCommands():array {
$commandList = [];

foreach($this->jobList as $job) {
if(!$job->hasRun()
&& $job->isDue($this->now())) {
$job->run();
$commandList []= $job->getCommand();
}
}

return $commandList;
}

public function runAllJobs():int {
$jobsRan = 0;

Expand Down Expand Up @@ -83,6 +98,15 @@ public function getNextJob():?Job {
return $nextJob;
}

public function commandOfNextJob():?string {
$nextJob = $this->getNextJob();
if(!$nextJob) {
return null;
}

return $nextJob->getCommand();
}

public function now(?DateTime $newNow = null):DateTime {
if(!is_null($newNow)) {
$this->now = $newNow;
Expand Down
9 changes: 5 additions & 4 deletions src/Runner.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,9 @@ public function run(bool $continue = false):int {
$this->continue = $continue;

do {
$jobsRan = 0;
$this->queue->reset();

$jobsRan += $this->queue->runDueJobs();
$runCommandList = $this->queue->runDueJobsAndGetCommands();
$jobsRan = count($runCommandList);

if(is_callable($this->runCallback)) {
$this->queue->now(new DateTime());
Expand All @@ -90,7 +89,9 @@ public function run(bool $continue = false):int {
$this->runCallback,
$jobsRan,
$this->queue->timeOfNextJob(),
$continue
$continue,
$runCommandList,
$this->queue->commandOfNextJob()
);
}

Expand Down
32 changes: 30 additions & 2 deletions test/phpunit/Command/RunCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
namespace Gt\Cron\Test\Command;

use Gt\Cli\Argument\ArgumentValueList;
use Gt\Cli\Stream;
use Gt\Cron\Cli\RunCommand;
use Gt\Cron\Test\Command\CommandTestCase;
use Gt\Cron\Test\Helper\ExampleClass;
Expand Down Expand Up @@ -49,8 +50,19 @@ public function testRunNowFunction() {
ExampleClass::$calls
);

self::assertStreamOutput("Just ran 1 job", $stream);
self::assertStreamOutput("Stopping now", $stream);
$output = $this->getFullOutput($stream);
self::assertStringContainsString(
"Just ran 1 job (ExampleClass::doSomething)",
$output
);
self::assertStringContainsString(
"Next job at:",
$output
);
self::assertStringContainsString(
"(ExampleClass::doSomething)",
$output
);
}

public function testRunNowFunctionWithArguments() {
Expand Down Expand Up @@ -273,6 +285,16 @@ function($command)use(&$calledCommand) {
1,
\Gt\Cron\Test\Helper\ExampleClass::$calls
);

$output = $this->getFullOutput($stream);
self::assertStringContainsString(
"Just ran 2 jobs (doSomething, ExampleClass::doSomething)",
$output
);
self::assertStringContainsString(
"Next job at:",
$output
);
}

public function testRunNowScriptNotExists() {
Expand Down Expand Up @@ -320,4 +342,10 @@ public function testRunNowFunctionNotExists() {
$stream
);
}

protected function getFullOutput(Stream $stream):string {
$out = $stream->getOutStream();
$out->rewind();
return $out->fread(10000);
}
}
41 changes: 41 additions & 0 deletions test/phpunit/RunnerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,41 @@ public function testRunCallbackIsExecuted() {
self::assertEquals(2, $count);
}

public function testRunCallbackIncludesCommands():void {
$cronContents = <<<CRON
* * * * * ExampleClass::example
CRON;

$runner = new Runner(
$this->mockJobRepository(0),
$this->mockQueueRepository(0),
$cronContents
);

$jobsRan = 0;
$runCommandList = [];
$nextCommand = null;
$runner->setRunCallback(
function(
int $jobsRanArg,
?DateTime $wait,
bool $continue,
array $runCommandListArg,
?string $nextCommandArg
) use(&$jobsRan, &$runCommandList, &$nextCommand) {
$jobsRan = $jobsRanArg;
$runCommandList = $runCommandListArg;
$nextCommand = $nextCommandArg;
}
);

$runner->run();

self::assertEquals(1, $jobsRan);
self::assertEquals(["ExampleClass::example"], $runCommandList);
self::assertEquals("ExampleClass::example", $nextCommand);
}

public function testComments() {
$cronContents = <<<CRON
* * * * * ExampleClass::example1
Expand Down Expand Up @@ -323,8 +358,14 @@ protected function mockQueueRepository(int...$wait):QueueRepository {
$queue = self::createMock(Queue::class);
$queue->method("runDueJobs")
->willReturn($numberDueJobs);
$queue->method("runDueJobsAndGetCommands")
->willReturn(
array_fill(0, $numberDueJobs, "ExampleClass::example")
);
$queue->method("secondsUntilNextJob")
->willReturn($secondsUntilNextJob);
$queue->method("commandOfNextJob")
->willReturn("ExampleClass::example");

$repository = self::createMock(QueueRepository::class);
$repository->method("createAtTime")
Expand Down