Bläddra i källkod

Improve build

Jordi Boggiano 5 år sedan
förälder
incheckning
c5853b9b0f

+ 25 - 2
.github/workflows/continuous-integration.yml

@@ -22,16 +22,35 @@ jobs:
           - "8.0"
           # disabled for now as phpspec/prophecy does not allow 8.1
           # - "8.1"
+        dependencies: [highest]
+        include:
+          - php-version: "7.2"
+            dependencies: lowest
+          - php-version: "8.0"
+            dependencies: lowest
 
     steps:
       - name: "Checkout"
         uses: "actions/checkout@v2"
 
-      - name: "Install PHP 7+"
+      - name: "Install PHP"
         uses: "shivammathur/setup-php@v2"
         with:
           coverage: "none"
           php-version: "${{ matrix.php-version }}"
+          extensions: mongodb, redis, amqp
+
+      - name: Configure sysctl limits
+        run: |
+          sudo swapoff -a
+          sudo sysctl -w vm.swappiness=1
+          sudo sysctl -w fs.file-max=262144
+          sudo sysctl -w vm.max_map_count=262144
+
+      - name: Runs Elasticsearch
+        uses: elastic/elastic-github-actions/elasticsearch@master
+        with:
+          stack-version: 7.6.0
 
       - name: Get composer cache directory
         id: composercache
@@ -44,9 +63,13 @@ jobs:
           key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
           restore-keys: ${{ runner.os }}-composer-
 
+      - name: "Handle lowest dependencies update"
+        if: "contains(matrix.dependencies, 'lowest')"
+        run: "echo \"COMPOSER_FLAGS=$COMPOSER_FLAGS --prefer-lowest\" >> $GITHUB_ENV"
+
       - name: "Install latest dependencies"
         run: |
           composer update ${{ env.COMPOSER_FLAGS }}
 
       - name: "Run tests"
-        run: "composer test"
+        run: "composer exec phpunit -- --verbose"

+ 9 - 6
phpstan.neon.dist

@@ -1,16 +1,19 @@
 parameters:
-    level: 3
+    level: 5
+
+    treatPhpDocTypesAsCertain: false
 
     paths:
         - src/
 #        - tests/
 
-
     ignoreErrors:
         - '#zend_monitor_|ZEND_MONITOR_#'
-        - '#RollbarNotifier#'
-        - '#Predis\\Client#'
         - '#^Cannot call method ltrim\(\) on int\|false.$#'
-        - '#^Access to an undefined property Raven_Client::\$context.$#'
         - '#MongoDB\\(Client|Collection)#'
-        - '#Gelf\\IMessagePublisher#'
+        - message: '#Return type \(string\) of method Monolog\\Formatter\\LineFormatter::normalizeException\(\) should be compatible with return type \(array\) of method Monolog\\Formatter\\NormalizerFormatter::normalizeException\(\)#'
+          paths:
+            - src/Monolog/Formatter/LineFormatter.php
+        - message: '#Method Monolog\\Handler\\LogglyHandler::loadCurlHandle\(\) never returns resource so it can be removed from the return typehint.#'
+          paths:
+            - src/Monolog/Handler/LogglyHandler.php

+ 5 - 6
src/Monolog/ErrorHandler.php

@@ -58,6 +58,7 @@ class ErrorHandler
      */
     public static function register(LoggerInterface $logger, $errorLevelMap = [], $exceptionLevelMap = [], $fatalLevel = null): self
     {
+        /** @phpstan-ignore-next-line */
         $handler = new static($logger);
         if ($errorLevelMap !== false) {
             $handler->registerErrorHandler($errorLevelMap);
@@ -74,7 +75,9 @@ class ErrorHandler
 
     public function registerExceptionHandler($levelMap = [], $callPrevious = true): self
     {
-        $prev = set_exception_handler([$this, 'handleException']);
+        $prev = set_exception_handler(function (\Throwable $e): void {
+            $this->handleException($e);
+        });
         $this->uncaughtExceptionLevelMap = $levelMap;
         foreach ($this->defaultExceptionLevelMap() as $class => $level) {
             if (!isset($this->uncaughtExceptionLevelMap[$class])) {
@@ -145,11 +148,7 @@ class ErrorHandler
         ];
     }
 
-    /**
-     * @private
-     * @param \Exception $e
-     */
-    public function handleException($e)
+    private function handleException(\Throwable $e)
     {
         $level = LogLevel::ERROR;
         foreach ($this->uncaughtExceptionLevelMap as $class => $candidate) {

+ 1 - 0
src/Monolog/Formatter/GelfMessageFormatter.php

@@ -134,6 +134,7 @@ class GelfMessageFormatter extends NormalizerFormatter
             $message->setAdditional($this->contextPrefix . $key, $val);
         }
 
+        /** @phpstan-ignore-next-line */
         if (null === $message->getFile() && isset($record['context']['exception']['file'])) {
             if (preg_match("/^(.+):([0-9]+)$/", $record['context']['exception']['file'], $matches)) {
                 $message->setFile($matches[1]);

+ 0 - 2
src/Monolog/Formatter/JsonFormatter.php

@@ -63,8 +63,6 @@ class JsonFormatter extends NormalizerFormatter
 
     /**
      * {@inheritdoc}
-     *
-     * @suppress PhanTypeComparisonToArray
      */
     public function format(array $record): string
     {

+ 0 - 3
src/Monolog/Formatter/LineFormatter.php

@@ -126,9 +126,6 @@ class LineFormatter extends NormalizerFormatter
         return $this->replaceNewlines($this->convertToString($value));
     }
 
-    /**
-     * @suppress PhanParamSignatureMismatch
-     */
     protected function normalizeException(\Throwable $e, int $depth = 0): string
     {
         $str = $this->formatException($e);

+ 2 - 2
src/Monolog/Formatter/MongoDBFormatter.php

@@ -118,7 +118,7 @@ class MongoDBFormatter implements FormatterInterface
 
     private function getMongoDbDateTime(\DateTimeInterface $value): UTCDateTime
     {
-        return new UTCDateTime((int) (string) floor($value->format('U.u') * 1000));
+        return new UTCDateTime((int) floor(((float) $value->format('U.u')) * 1000));
     }
 
     /**
@@ -130,7 +130,7 @@ class MongoDBFormatter implements FormatterInterface
      */
     private function legacyGetMongoDbDateTime(\DateTimeInterface $value): UTCDateTime
     {
-        $milliseconds = floor($value->format('U.u') * 1000);
+        $milliseconds = floor(((float) $value->format('U.u')) * 1000);
 
         $milliseconds = (PHP_INT_SIZE == 8) //64-bit OS?
             ? (int) $milliseconds

+ 7 - 8
src/Monolog/Formatter/NormalizerFormatter.php

@@ -24,10 +24,14 @@ class NormalizerFormatter implements FormatterInterface
 {
     public const SIMPLE_DATE = "Y-m-d\TH:i:sP";
 
+    /** @var string */
     protected $dateFormat;
+    /** @var int */
     protected $maxNormalizeDepth = 9;
+    /** @var int */
     protected $maxNormalizeItemCount = 1000;
 
+    /** @var int */
     private $jsonEncodeOptions = Utils::DEFAULT_JSON_FLAGS;
 
     /**
@@ -159,12 +163,7 @@ class NormalizerFormatter implements FormatterInterface
                 $value = $data->__toString();
             } else {
                 // the rest is normalized by json encoding and decoding it
-                $encoded = $this->toJson($data, true);
-                if ($encoded === false) {
-                    $value = 'JSON_ERROR';
-                } else {
-                    $value = json_decode($encoded, true);
-                }
+                $value = json_decode($this->toJson($data, true), true);
             }
 
             return [Utils::getClass($data) => $value];
@@ -248,12 +247,12 @@ class NormalizerFormatter implements FormatterInterface
         return $date->format($this->dateFormat);
     }
 
-    public function addJsonEncodeOption($option)
+    public function addJsonEncodeOption(int $option)
     {
         $this->jsonEncodeOptions |= $option;
     }
 
-    public function removeJsonEncodeOption($option)
+    public function removeJsonEncodeOption(int $option)
     {
         $this->jsonEncodeOptions &= ~$option;
     }

+ 2 - 2
src/Monolog/Formatter/ScalarFormatter.php

@@ -33,13 +33,13 @@ class ScalarFormatter extends NormalizerFormatter
 
     /**
      * @param  mixed $value
-     * @return mixed
+     * @return string|int|bool|null
      */
     protected function normalizeValue($value)
     {
         $normalized = $this->normalize($value);
 
-        if (is_array($normalized) || is_object($normalized)) {
+        if (is_array($normalized)) {
             return $this->toJson($normalized, true);
         }
 

+ 1 - 1
src/Monolog/Formatter/WildfireFormatter.php

@@ -105,7 +105,7 @@ class WildfireFormatter extends NormalizerFormatter
 
     /**
      * {@inheritdoc}
-     * @suppress PhanTypeMismatchReturn
+     * @return int|bool|string|null|array|object
      */
     protected function normalize($data, int $depth = 0)
     {

+ 1 - 0
src/Monolog/Handler/DynamoDbHandler.php

@@ -53,6 +53,7 @@ class DynamoDbHandler extends AbstractProcessingHandler
      */
     public function __construct(DynamoDbClient $client, string $table, $level = Logger::DEBUG, bool $bubble = true)
     {
+        /** @phpstan-ignore-next-line */
         if (defined('Aws\Sdk::VERSION') && version_compare(Sdk::VERSION, '3.0', '>=')) {
             $this->version = 3;
             $this->marshaler = new Marshaler;

+ 13 - 3
src/Monolog/Handler/FilterHandler.php

@@ -159,9 +159,14 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
      */
     public function setFormatter(FormatterInterface $formatter): HandlerInterface
     {
-        $this->getHandler()->setFormatter($formatter);
+        $handler = $this->getHandler();
+        if ($handler instanceof FormattableHandlerInterface) {
+            $handler->setFormatter($formatter);
 
-        return $this;
+            return $this;
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.');
     }
 
     /**
@@ -169,7 +174,12 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
      */
     public function getFormatter(): FormatterInterface
     {
-        return $this->getHandler()->getFormatter();
+        $handler = $this->getHandler();
+        if ($handler instanceof FormattableHandlerInterface) {
+            return $handler->getFormatter();
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.');
     }
 
     public function reset()

+ 13 - 3
src/Monolog/Handler/FingersCrossedHandler.php

@@ -202,9 +202,14 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa
      */
     public function setFormatter(FormatterInterface $formatter): HandlerInterface
     {
-        $this->getHandler()->setFormatter($formatter);
+        $handler = $this->getHandler();
+        if ($handler instanceof FormattableHandlerInterface) {
+            $handler->setFormatter($formatter);
 
-        return $this;
+            return $this;
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.');
     }
 
     /**
@@ -212,6 +217,11 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa
      */
     public function getFormatter(): FormatterInterface
     {
-        return $this->getHandler()->getFormatter();
+        $handler = $this->getHandler();
+        if ($handler instanceof FormattableHandlerInterface) {
+            return $handler->getFormatter();
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.');
     }
 }

+ 1 - 2
src/Monolog/Handler/FormattableHandlerTrait.php

@@ -22,13 +22,12 @@ use Monolog\Formatter\LineFormatter;
 trait FormattableHandlerTrait
 {
     /**
-     * @var FormatterInterface
+     * @var ?FormatterInterface
      */
     protected $formatter;
 
     /**
      * {@inheritdoc}
-     * @suppress PhanTypeMismatchReturn
      */
     public function setFormatter(FormatterInterface $formatter): HandlerInterface
     {

+ 1 - 1
src/Monolog/Handler/HandlerWrapper.php

@@ -128,7 +128,7 @@ class HandlerWrapper implements HandlerInterface, ProcessableHandlerInterface, F
     public function reset()
     {
         if ($this->handler instanceof ResettableInterface) {
-            return $this->handler->reset();
+            $this->handler->reset();
         }
     }
 }

+ 3 - 3
src/Monolog/Handler/LogglyHandler.php

@@ -68,7 +68,7 @@ class LogglyHandler extends AbstractProcessingHandler
     protected function getCurlHandler(string $endpoint)
     {
         if (!array_key_exists($endpoint, $this->curlHandlers)) {
-            $this->curlHandlers[$endpoint] = $this->loadCurlHandler($endpoint);
+            $this->curlHandlers[$endpoint] = $this->loadCurlHandle($endpoint);
         }
 
         return $this->curlHandlers[$endpoint];
@@ -79,9 +79,9 @@ class LogglyHandler extends AbstractProcessingHandler
      *
      * @param string $endpoint
      *
-     * @return resource
+     * @return resource|\CurlHandle
      */
-    private function loadCurlHandler(string $endpoint)
+    private function loadCurlHandle(string $endpoint)
     {
         $url = sprintf("https://%s/%s/%s/", static::HOST, $endpoint, $this->token);
 

+ 12 - 7
src/Monolog/Handler/MandrillHandler.php

@@ -13,6 +13,7 @@ namespace Monolog\Handler;
 
 use Monolog\Logger;
 use Swift;
+use Swift_Message;
 
 /**
  * MandrillHandler uses cURL to send the emails to the Mandrill API
@@ -21,25 +22,27 @@ use Swift;
  */
 class MandrillHandler extends MailHandler
 {
+    /** @var Swift_Message */
     protected $message;
+    /** @var string */
     protected $apiKey;
 
     /**
-     * @psalm-param Swift_Message|callable(string, array): Swift_Message $message
+     * @psalm-param Swift_Message|callable(): Swift_Message $message
      *
-     * @param string                  $apiKey  A valid Mandrill API key
-     * @param callable|\Swift_Message $message An example message for real messages, only the body will be replaced
-     * @param string|int              $level   The minimum logging level at which this handler will be triggered
-     * @param bool                    $bubble  Whether the messages that are handled can bubble up the stack or not
+     * @param string                 $apiKey  A valid Mandrill API key
+     * @param callable|Swift_Message $message An example message for real messages, only the body will be replaced
+     * @param string|int             $level   The minimum logging level at which this handler will be triggered
+     * @param bool                   $bubble  Whether the messages that are handled can bubble up the stack or not
      */
     public function __construct(string $apiKey, $message, $level = Logger::ERROR, bool $bubble = true)
     {
         parent::__construct($level, $bubble);
 
-        if (!$message instanceof \Swift_Message && is_callable($message)) {
+        if (!$message instanceof Swift_Message && is_callable($message)) {
             $message = $message();
         }
-        if (!$message instanceof \Swift_Message) {
+        if (!$message instanceof Swift_Message) {
             throw new \InvalidArgumentException('You must provide either a Swift_Message instance or a callable returning it');
         }
         $this->message = $message;
@@ -58,9 +61,11 @@ class MandrillHandler extends MailHandler
 
         $message = clone $this->message;
         $message->setBody($content, $mime);
+        /** @phpstan-ignore-next-line */
         if (version_compare(Swift::VERSION, '6.0.0', '>=')) {
             $message->setDate(new \DateTimeImmutable());
         } else {
+            /** @phpstan-ignore-next-line */
             $message->setDate(time());
         }
 

+ 11 - 3
src/Monolog/Handler/OverflowHandler.php

@@ -131,9 +131,13 @@ class OverflowHandler extends AbstractHandler implements FormattableHandlerInter
      */
     public function setFormatter(FormatterInterface $formatter): HandlerInterface
     {
-        $this->handler->setFormatter($formatter);
+        if ($this->handler instanceof FormattableHandlerInterface) {
+            $this->handler->setFormatter($formatter);
 
-        return $this;
+            return $this;
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($this->handler).' does not support formatters.');
     }
 
     /**
@@ -141,6 +145,10 @@ class OverflowHandler extends AbstractHandler implements FormattableHandlerInter
      */
     public function getFormatter(): FormatterInterface
     {
-        return $this->handler->getFormatter();
+        if ($this->handler instanceof FormattableHandlerInterface) {
+            return $this->handler->getFormatter();
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($this->handler).' does not support formatters.');
     }
 }

+ 0 - 3
src/Monolog/Handler/PHPConsoleHandler.php

@@ -93,9 +93,6 @@ class PHPConsoleHandler extends AbstractProcessingHandler
         return array_replace($this->options, $options);
     }
 
-    /**
-     * @suppress PhanTypeMismatchArgument
-     */
     private function initConnector(?Connector $connector = null): Connector
     {
         if (!$connector) {

+ 0 - 1
src/Monolog/Handler/ProcessableHandlerTrait.php

@@ -27,7 +27,6 @@ trait ProcessableHandlerTrait
 
     /**
      * {@inheritdoc}
-     * @suppress PhanTypeMismatchReturn
      */
     public function pushProcessor(callable $callback): HandlerInterface
     {

+ 13 - 3
src/Monolog/Handler/SamplingHandler.php

@@ -100,9 +100,14 @@ class SamplingHandler extends AbstractHandler implements ProcessableHandlerInter
      */
     public function setFormatter(FormatterInterface $formatter): HandlerInterface
     {
-        $this->getHandler()->setFormatter($formatter);
+        $handler = $this->getHandler();
+        if ($handler instanceof FormattableHandlerInterface) {
+            $handler->setFormatter($formatter);
 
-        return $this;
+            return $this;
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.');
     }
 
     /**
@@ -110,6 +115,11 @@ class SamplingHandler extends AbstractHandler implements ProcessableHandlerInter
      */
     public function getFormatter(): FormatterInterface
     {
-        return $this->getHandler()->getFormatter();
+        $handler = $this->getHandler();
+        if ($handler instanceof FormattableHandlerInterface) {
+            return $handler->getFormatter();
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.');
     }
 }

+ 3 - 3
src/Monolog/Handler/Slack/SlackRecord.php

@@ -77,7 +77,7 @@ class SlackRecord
     private $excludeFields;
 
     /**
-     * @var FormatterInterface
+     * @var ?FormatterInterface
      */
     private $formatter;
 
@@ -226,7 +226,7 @@ class SlackRecord
      *
      * @param ?string $channel
      *
-     * @return SlackHandler
+     * @return static
      */
     public function setChannel(?string $channel = null): self
     {
@@ -240,7 +240,7 @@ class SlackRecord
      *
      * @param ?string $username
      *
-     * @return SlackHandler
+     * @return static
      */
     public function setUsername(?string $username = null): self
     {

+ 2 - 0
src/Monolog/Handler/SwiftMailerHandler.php

@@ -93,9 +93,11 @@ class SwiftMailerHandler extends MailHandler
         }
 
         $message->setBody($content, $mime);
+        /** @phpstan-ignore-next-line */
         if (version_compare(Swift::VERSION, '6.0.0', '>=')) {
             $message->setDate(new \DateTimeImmutable());
         } else {
+            /** @phpstan-ignore-next-line */
             $message->setDate(time());
         }
 

+ 1 - 1
src/Monolog/Handler/SyslogUdpHandler.php

@@ -94,7 +94,7 @@ class SyslogUdpHandler extends AbstractSyslogHandler
             $hostname = '-';
         }
 
-        if ($this->rfc === self::RFC3164) {
+        if ($this->rfc === self::RFC3164 && ($datetime instanceof \DateTimeImmutable || $datetime instanceof \DateTime)) {
             $datetime->setTimezone(new \DateTimeZone('UTC'));
         }
         $date = $datetime->format($this->dateFormats[$this->rfc]);

+ 1 - 1
src/Monolog/Handler/ZendMonitorHandler.php

@@ -73,7 +73,7 @@ class ZendMonitorHandler extends AbstractProcessingHandler
      * Write to Zend Monitor Events
      * @param string $type      Text displayed in "Class Name (custom)" field
      * @param string $message   Text displayed in "Error String"
-     * @param mixed  $formatted Displayed in Custom Variables tab
+     * @param array  $formatted Displayed in Custom Variables tab
      * @param int    $severity  Set the event severity level (-1,0,1)
      */
     protected function writeZendMonitorCustomEvent(string $type, string $message, array $formatted, int $severity): void

+ 0 - 3
src/Monolog/SignalHandler.php

@@ -41,9 +41,6 @@ class SignalHandler
 
         if ($callPrevious) {
             $handler = pcntl_signal_get_handler($signo);
-            if ($handler === false) {
-                return $this;
-            }
             $this->previousSignalHandler[$signo] = $handler;
         } else {
             unset($this->previousSignalHandler[$signo]);

+ 0 - 3
src/Monolog/Test/TestCase.php

@@ -49,9 +49,6 @@ class TestCase extends \PHPUnit\Framework\TestCase
         ];
     }
 
-    /**
-     * @suppress PhanTypeMismatchReturn
-     */
     protected function getIdentityFormatter(): FormatterInterface
     {
         $formatter = $this->createMock(FormatterInterface::class);