Skip to content

Commit

Permalink
ExplainCommand
Browse files Browse the repository at this point in the history
  • Loading branch information
mabar committed Mar 4, 2024
1 parent 80a77ad commit d794e94
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Added

- `ExplainCommand`
- explains cron expression syntax
- `ListCommand`
- adds `--explain` option to explain whole expression

Expand Down
8 changes: 8 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Cron job scheduler - with locks, parallelism and more
- [Run job command - run single job](#run-job-command)
- [List command - show all jobs](#list-command)
- [Worker command - run jobs periodically](#worker-command)
- [Explain command - explain cron expression syntax](#explain-command)
- [Lazy loading](#lazy-loading)
- [Integrations and extensions](#integrations-and-extensions)

Expand Down Expand Up @@ -570,6 +571,7 @@ For symfony/console you may use our commands:
- [Run job](#run-job-command)
- [List](#list-command)
- [Worker](#worker-command)
- [Explain](#explain-command)

> Examples assume you run console via executable php script `bin/console`
Expand Down Expand Up @@ -638,6 +640,12 @@ Run scheduler repeatedly, once every minute
- via `your/console scheduler:worker -s=your/console -c=scheduler:run`
- or via setter `$workerCommand->setExecutable('your/console', 'scheduler:run')`

### Explain command

Explain cron expression syntax

`bin/console scheduler:explain`

## Lazy loading

Jobs are executed only when it is their due time. To prevent initializing potentially heavy job dependencies when they
Expand Down
73 changes: 73 additions & 0 deletions src/Command/ExplainCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php declare(strict_types = 1);

namespace Orisai\Scheduler\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

final class ExplainCommand extends Command
{

public static function getDefaultName(): string
{
return 'scheduler:explain';
}

public static function getDefaultDescription(): string
{
return 'Explain cron expression';
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->explainSyntax($output);

return 0;
}

private function explainSyntax(OutputInterface $output): void
{
$output->writeln(
<<<'CMD'
<fg=yellow>* * * * *</>
- - - - -
| | | | |
| | | | |
| | | | +----- day of week (<fg=yellow>0-7</>) (Sunday = <fg=yellow>0</> or <fg=yellow>7</>) (or <fg=yellow>SUN-SAT</>)
| | | +--------- month (<fg=yellow>1-12</>) (or <fg=yellow>JAN-DEC</>)
| | +------------- day of month (<fg=yellow>1-31</>)
| +----------------- hour (<fg=yellow>0-23</>)
+--------------------- minute (<fg=yellow>0-59</>)
Each part of expression can also use wildcard, lists, ranges and steps:
- wildcard - match always
- e.g. <fg=yellow>* * * * *</> - At every minute.
- lists - match list of values, ranges and steps
- e.g. <fg=yellow>15,30 * * * *</> - At minute 15 and 30.
- ranges - match values in range
- e.g. <fg=yellow>1-9 * * * *</> - At every minute from 1 through 9.
- steps - match every nth value in range
- e.g. <fg=yellow>*/5 * * * *</> - At every 5th minute.
- e.g. <fg=yellow>0-30/5 * * * *</> - At every 5th minute from 0 through 30.
- combinations
- e.g. <fg=yellow>0-14,30-44 * * * *</> - At every minute from 0 through 14 and every minute from 30 through 44.
You can also use macro instead of an expression:
- <fg=yellow>@yearly</>, <fg=yellow>@annually</> - Run once a year, midnight, Jan. 1 (same as <fg=yellow>0 0 1 1 *</>)
- <fg=yellow>@monthly</> - Run once a month, midnight, first of month (same as <fg=yellow>0 0 1 * *</>)
- <fg=yellow>@weekly</> - Run once a week, midnight on Sun (same as <fg=yellow>0 0 * * 0</>)
- <fg=yellow>@daily</>, <fg=yellow>@midnight</> - Run once a day, midnight (same as <fg=yellow>0 0 * * *</>)
- <fg=yellow>@hourly</> - Run once an hour, first minute (same as <fg=yellow>0 * * * *</>)
Although they are not part of cron expression syntax, you can also add to job:
- seconds - repeat job every n seconds
- timezone - run only when cron expression matches within given timezone
CMD,
);
}

}
77 changes: 77 additions & 0 deletions tests/Unit/Command/ExplainCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php declare(strict_types = 1);

namespace Tests\Orisai\Scheduler\Unit\Command;

use Orisai\Scheduler\Command\ExplainCommand;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Tester\CommandTester;
use function array_map;
use function explode;
use function implode;
use function putenv;
use function rtrim;
use const PHP_EOL;

final class ExplainCommandTest extends TestCase
{

public function testBasicExplain(): void
{
$command = new ExplainCommand();
$tester = new CommandTester($command);

putenv('COLUMNS=80');
$code = $tester->execute([]);

self::assertSame(
<<<'MSG'
* * * * *
- - - - -
| | | | |
| | | | |
| | | | +----- day of week (0-7) (Sunday = 0 or 7) (or SUN-SAT)
| | | +--------- month (1-12) (or JAN-DEC)
| | +------------- day of month (1-31)
| +----------------- hour (0-23)
+--------------------- minute (0-59)
Each part of expression can also use wildcard, lists, ranges and steps:
- wildcard - match always
- e.g. * * * * * - At every minute.
- lists - match list of values, ranges and steps
- e.g. 15,30 * * * * - At minute 15 and 30.
- ranges - match values in range
- e.g. 1-9 * * * * - At every minute from 1 through 9.
- steps - match every nth value in range
- e.g. */5 * * * * - At every 5th minute.
- e.g. 0-30/5 * * * * - At every 5th minute from 0 through 30.
- combinations
- e.g. 0-14,30-44 * * * * - At every minute from 0 through 14 and every minute from 30 through 44.
You can also use macro instead of an expression:
- @yearly, @annually - Run once a year, midnight, Jan. 1 (same as 0 0 1 1 *)
- @monthly - Run once a month, midnight, first of month (same as 0 0 1 * *)
- @weekly - Run once a week, midnight on Sun (same as 0 0 * * 0)
- @daily, @midnight - Run once a day, midnight (same as 0 0 * * *)
- @hourly - Run once an hour, first minute (same as 0 * * * *)
Although they are not part of cron expression syntax, you can also add to job:
- seconds - repeat job every n seconds
- timezone - run only when cron expression matches within given timezone

MSG,
implode(
PHP_EOL,
array_map(
static fn (string $s): string => rtrim($s),
explode(PHP_EOL, $tester->getDisplay()),
),
),
);
self::assertSame($command::SUCCESS, $code);
}

}

0 comments on commit d794e94

Please sign in to comment.