Skip to content

Commit

Permalink
Github Actions: Add Phpstan (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
nilmerg authored Aug 24, 2023
2 parents 8614b6b + 2e32fb7 commit 49e548a
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 13 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ jobs:
if: success() || matrix.allow_failure
run: phpcs -wps --colors

- name: PHPStan
uses: php-actions/phpstan@v3
if: success() || matrix.allow_failure

test:
name: Unit tests with PHP ${{ matrix.php }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
Expand Down
36 changes: 36 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
parameters:
ignoreErrors:
-
message: "#^Method ipl\\\\Scheduler\\\\Cron\\:\\:getNextDue\\(\\) should return DateTimeInterface but returns DateTimeInterface\\|null\\.$#"
count: 2
path: src/Cron.php

-
message: "#^Method ipl\\\\Scheduler\\\\Cron\\:\\:jsonSerialize\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: src/Cron.php

-
message: "#^Method ipl\\\\Scheduler\\\\RRule\\:\\:getNextDue\\(\\) should return DateTimeInterface but returns DateTimeInterface\\|null\\.$#"
count: 1
path: src/RRule.php

-
message: "#^Method ipl\\\\Scheduler\\\\RRule\\:\\:jsonSerialize\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: src/RRule.php

-
message: "#^Parameter \\#1 \\$timezone of class DateTimeZone constructor expects string, string\\|null given\\.$#"
count: 1
path: src/RRule.php

-
message: "#^Parameter \\#2 \\$before of class Recurr\\\\Transformer\\\\Constraint\\\\BetweenConstraint constructor expects DateTimeInterface, DateTimeInterface\\|null given\\.$#"
count: 1
path: src/RRule.php

-
message: "#^Parameter \\#1 \\$timer of static method React\\\\EventLoop\\\\Loop\\:\\:cancelTimer\\(\\) expects React\\\\EventLoop\\\\TimerInterface, React\\\\EventLoop\\\\TimerInterface\\|null given\\.$#"
count: 1
path: src/Scheduler.php
32 changes: 32 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
includes:
- phpstan-baseline.neon

parameters:
level: max

checkFunctionNameCase: true
checkInternalClassCaseSensitivity: true
treatPhpDocTypesAsCertain: false

paths:
- src

scanDirectories:
- vendor

ignoreErrors:
-
messages:
- '#Unsafe usage of new static\(\)#'
- '#. but return statement is missing#'
reportUnmatched: false

- '#Call to an undefined method DateTimeInterface::#'

- '#Call to an undefined method React\\Promise\\PromiseInterface::#'

- '#Method ipl\\Scheduler\\.* should return \$this.* but returns static#'

- '#Parameter \#1 \$rrule of class Recurr\\Rule constructor expects string\|null, array.*\|string given#'

- '#Parameter \#1 \$callback of function call_user_func_array expects callable\(\): mixed, array{Recurr\\Rule, string} given#'
4 changes: 1 addition & 3 deletions src/Common/Promises.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

trait Promises
{
/** @var SplObjectStorage */
/** @var SplObjectStorage<UuidInterface, ArrayObject<int, PromiseInterface>> */
protected $promises;

/**
Expand Down Expand Up @@ -100,9 +100,7 @@ protected function detachPromises(UuidInterface $uuid): array
return [];
}

/** @var ArrayObject $promises */
$promises = $this->promises[$uuid];

$this->promises->detach($uuid);

return $promises->getArrayCopy();
Expand Down
2 changes: 1 addition & 1 deletion src/Common/Timers.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

trait Timers
{
/** @var SplObjectStorage */
/** @var SplObjectStorage<UuidInterface, TimerInterface> */
protected $timers;

/**
Expand Down
15 changes: 13 additions & 2 deletions src/Cron.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use InvalidArgumentException;
use ipl\Scheduler\Contract\Frequency;

use function ipl\Stdlib\get_php_type;

class Cron implements Frequency
{
public const PART_MINUTE = 0;
Expand All @@ -20,10 +22,10 @@ class Cron implements Frequency
/** @var CronExpression */
protected $cron;

/** @var DateTimeInterface Start time of this frequency */
/** @var ?DateTimeInterface Start time of this frequency */
protected $start;

/** @var DateTimeInterface End time of this frequency */
/** @var ?DateTimeInterface End time of this frequency */
protected $end;

/** @var string String representation of the cron expression */
Expand Down Expand Up @@ -163,6 +165,15 @@ public static function isValid(string $expression): bool
public static function fromJson(string $json): Frequency
{
$data = json_decode($json, true);
if (! is_array($data)) {
throw new InvalidArgumentException(
sprintf(
'%s expects json decoded value to be an array, got %s instead',
__METHOD__,
get_php_type($data)
)
);
}

$self = new static($data['expression']);
if (isset($data['start'])) {
Expand Down
12 changes: 12 additions & 0 deletions src/OneOff.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
use DateTime;
use DateTimeInterface;
use DateTimeZone;
use InvalidArgumentException;
use ipl\Scheduler\Contract\Frequency;

use function ipl\Stdlib\get_php_type;

class OneOff implements Frequency
{
/** @var DateTimeInterface Start time of this frequency */
Expand Down Expand Up @@ -46,6 +49,15 @@ public function getEnd(): ?DateTimeInterface
public static function fromJson(string $json): Frequency
{
$data = json_decode($json, true);
if (! is_string($data)) {
throw new InvalidArgumentException(
sprintf(
'%s expects json decoded value to be string, got %s instead',
__METHOD__,
get_php_type($data)
)
);
}

return new static(new DateTime($data));
}
Expand Down
15 changes: 11 additions & 4 deletions src/RRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Recurr\Transformer\ArrayTransformerConfig;
use Recurr\Transformer\Constraint\AfterConstraint;
use Recurr\Transformer\Constraint\BetweenConstraint;
use stdClass;

use function ipl\Stdlib\get_php_type;

Expand Down Expand Up @@ -62,7 +63,7 @@ class RRule implements Frequency
/**
* Construct a new rrule instance
*
* @param string|array $rule
* @param string|array<string, mixed> $rule
*
* @throws InvalidRRule
*/
Expand Down Expand Up @@ -124,11 +125,17 @@ public static function fromFrequency(string $frequency): self

public static function fromJson(string $json): Frequency
{
/** @var stdClass $data */
$data = json_decode($json);
$self = new static($data->rrule);
$self->frequency = $data->frequency;
if (isset($data->start)) {
$self->startAt(DateTime::createFromFormat(static::SERIALIZED_DATETIME_FORMAT, $data->start));
$start = DateTime::createFromFormat(static::SERIALIZED_DATETIME_FORMAT, $data->start);
if (! $start) {
throw new InvalidArgumentException(sprintf('Cannot deserialize start time: %s', $data->start));
}

$self->startAt($start);
}

return $self;
Expand Down Expand Up @@ -240,7 +247,7 @@ public function getFrequency(): string
* @param int $limit Limit the recurrences to be generated to the given value
* @param bool $include Whether to include the passed time in the result set
*
* @return Generator
* @return Generator<DateTimeInterface>
*/
public function getNextRecurrences(
DateTimeInterface $dateTime,
Expand Down Expand Up @@ -296,7 +303,7 @@ public function jsonSerialize(): array
* Redirect all public method calls to the underlying rrule object
*
* @param string $methodName
* @param array $args
* @param array<mixed> $args
*
* @return mixed
*
Expand Down
7 changes: 4 additions & 3 deletions src/Scheduler.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ class Scheduler
*/
public const ON_TASK_EXPIRED = 'task-expired';

/** @var SplObjectStorage The scheduled tasks of this scheduler */
/** @var SplObjectStorage<Task, null> The scheduled tasks of this scheduler */
protected $tasks;

public function __construct()
Expand Down Expand Up @@ -262,7 +262,7 @@ public function schedule(Task $task, Frequency $frequency): self
return $this;
}

public function isValidEvent($event)
public function isValidEvent(string $event): bool
{
$events = array_flip([
static::ON_TASK_CANCEL,
Expand All @@ -285,9 +285,10 @@ protected function cancelTask(Task $task): void
{
Loop::cancelTimer($this->detachTimer($task->getUuid()));

/** @var ExtendedPromiseInterface[] $promises */
$promises = $this->detachPromises($task->getUuid());
if (! empty($promises)) {
/** @var ExtendedPromiseInterface[] $promises */
/** @var Promise\CancellablePromiseInterface $promise */
foreach ($promises as $promise) {
$promise->cancel();
}
Expand Down

0 comments on commit 49e548a

Please sign in to comment.