Verified Commit 37ae91a1 authored by Elias Häußler's avatar Elias Häußler 🐛
Browse files

[TASK] Apply Symfony rules in PHP-CS-Fixer and fix linting issues

parent 15a4cc21
<?php
declare(strict_types=1);
/*
......@@ -21,10 +22,12 @@ declare(strict_types=1);
*/
$finder = \PhpCsFixer\Finder::create()
->in([__DIR__ . '/src', __DIR__ . '/tests']);
->in([__DIR__.'/src', __DIR__.'/tests']);
$config = new \PhpCsFixer\Config();
return $config->setRules([
'@PSR2' => true,
'@Symfony' => true,
])
->setFinder($finder);
<?php
declare(strict_types=1);
namespace EliasHaeussler\ComposerUpdateReporter;
/*
......@@ -28,7 +30,7 @@ use Composer\Plugin\PluginInterface;
use EliasHaeussler\ComposerUpdateCheck\Event\PostUpdateCheckEvent;
/**
* Plugin
* Plugin.
*
* @author Elias Häußler <elias@haeussler.dev>
* @license GPL-3.0-or-later
......@@ -60,7 +62,7 @@ class Plugin implements PluginInterface, EventSubscriberInterface
{
return [
PostUpdateCheckEvent::NAME => [
['onPostUpdateCheck']
['onPostUpdateCheck'],
],
];
}
......
<?php
declare(strict_types=1);
namespace EliasHaeussler\ComposerUpdateReporter;
/*
......@@ -36,7 +38,7 @@ use EliasHaeussler\ComposerUpdateReporter\Service\Slack;
use EliasHaeussler\ComposerUpdateReporter\Service\Teams;
/**
* Reporter
* Reporter.
*
* @author Elias Häußler <elias@haeussler.dev>
* @license GPL-3.0-or-later
......@@ -94,10 +96,7 @@ class Reporter
/** @var ServiceInterface $registeredService */
foreach ($this->registeredServices as $registeredService) {
if (!in_array(ServiceInterface::class, class_implements($registeredService), true)) {
throw new \InvalidArgumentException(
sprintf('Service "%s" must implement "%s".', $registeredService, ServiceInterface::class),
1600814017
);
throw new \InvalidArgumentException(sprintf('Service "%s" must implement "%s".', $registeredService, ServiceInterface::class), 1600814017);
}
if ($registeredService::isEnabled($this->configuration)) {
$service = $registeredService::fromConfiguration($this->configuration);
......@@ -106,6 +105,7 @@ class Reporter
$services[] = $service;
}
}
return $services;
}
......@@ -122,6 +122,7 @@ class Reporter
public function setRegisteredServices(array $registeredServices): self
{
$this->registeredServices = $registeredServices;
return $this;
}
......
......@@ -33,7 +33,7 @@ use Spatie\Emoji\Emoji;
use Spatie\Emoji\Exceptions\UnknownCharacter;
/**
* AbstractService
* AbstractService.
*
* @author Elias Häußler <elias@haeussler.dev>
* @license GPL-3.0-or-later
......@@ -53,14 +53,14 @@ abstract class AbstractService implements ServiceInterface
public static function isEnabled(array $configuration): bool
{
$identifier = static::getIdentifier();
$envVariable = strtoupper($identifier . '_enable');
$envVariable = strtoupper($identifier.'_enable');
$extra = $configuration[strtolower($identifier)] ?? null;
if (getenv($envVariable) !== false) {
return (bool)getenv($envVariable);
if (false !== getenv($envVariable)) {
return (bool) getenv($envVariable);
}
return is_array($extra) && (bool)($extra['enable'] ?? false);
return is_array($extra) && (bool) ($extra['enable'] ?? false);
}
abstract protected static function getIdentifier(): string;
......@@ -70,19 +70,20 @@ abstract class AbstractService implements ServiceInterface
public function report(UpdateCheckResult $result): bool
{
// Fall back to default output behavior if no custom behavior is defined
if ($this->behavior === null) {
if (null === $this->behavior) {
$this->behavior = $this->getDefaultBehavior();
}
$outdatedPackages = $result->getOutdatedPackages();
// Do not send report if packages are up to date
if ($outdatedPackages === []) {
if ([] === $outdatedPackages) {
if (!$this->behavior->style->isJson()) {
$this->behavior->io->write(
sprintf('%s Skipped %s report', Emoji::prohibited(), static::getName())
);
}
return true;
}
......@@ -93,6 +94,7 @@ abstract class AbstractService implements ServiceInterface
$this->behavior->io->writeError(
sprintf('%s <error>Error during %s report</error>', Emoji::crossMark(), static::getName())
);
return false;
}
......@@ -111,21 +113,19 @@ abstract class AbstractService implements ServiceInterface
return true;
}
/**
* @param UpdateCheckResult $result
* @return bool
*/
abstract protected function sendReport(UpdateCheckResult $result): bool;
public function setBehavior(OutputBehavior $behavior): ServiceInterface
{
$this->behavior = $behavior;
return $this;
}
public function setOptions(Options $options): ServiceInterface
{
$this->options = $options;
return $this;
}
......
<?php
declare(strict_types=1);
namespace EliasHaeussler\ComposerUpdateReporter\Service;
/*
......@@ -30,7 +32,7 @@ use Symfony\Component\Mailer\Transport\TransportInterface;
use Symfony\Component\Mime\Email as SymfonyEmail;
/**
* Email
* Email.
*
* @author Elias Häußler <elias@haeussler.dev>
* @license GPL-3.0-or-later
......@@ -68,38 +70,29 @@ class Email extends AbstractService
// Parse Email DSN
if (is_array($extra) && array_key_exists('dsn', $extra)) {
$dsn = (string)$extra['dsn'];
} elseif (getenv('EMAIL_DSN') !== false) {
$dsn = (string) $extra['dsn'];
} elseif (false !== getenv('EMAIL_DSN')) {
$dsn = getenv('EMAIL_DSN');
} else {
throw new \RuntimeException(
'Email DSN is not defined. Define it either in composer.json or as $EMAIL_DSN.',
1601391909
);
throw new \RuntimeException('Email DSN is not defined. Define it either in composer.json or as $EMAIL_DSN.', 1601391909);
}
// Parse Email receivers
if (is_array($extra) && array_key_exists('receivers', $extra)) {
$receivers = explode(',', (string)$extra['receivers']);
} elseif (getenv('EMAIL_RECEIVERS') !== false) {
$receivers = explode(',', (string) $extra['receivers']);
} elseif (false !== getenv('EMAIL_RECEIVERS')) {
$receivers = explode(',', getenv('EMAIL_RECEIVERS'));
} else {
throw new \RuntimeException(
'Email receivers are not defined. Define it either in composer.json or as $EMAIL_RECEIVERS.',
1601391943
);
throw new \RuntimeException('Email receivers are not defined. Define it either in composer.json or as $EMAIL_RECEIVERS.', 1601391943);
}
// Parse Email sender
if (is_array($extra) && array_key_exists('sender', $extra)) {
$sender = (string)$extra['sender'];
} elseif (getenv('EMAIL_SENDER') !== false) {
$sender = (string) $extra['sender'];
} elseif (false !== getenv('EMAIL_SENDER')) {
$sender = getenv('EMAIL_SENDER');
} else {
throw new \RuntimeException(
'Email sender is not defined. Define it either in composer.json or as $EMAIL_SENDER.',
1601391961
);
throw new \RuntimeException('Email sender is not defined. Define it either in composer.json or as $EMAIL_SENDER.', 1601391961);
}
return new self($dsn, array_map('trim', array_filter($receivers)), $sender);
......@@ -116,7 +109,8 @@ class Email extends AbstractService
}
/**
* @inheritDoc
* {@inheritDoc}
*
* @throws TransportExceptionInterface
*/
protected function sendReport(UpdateCheckResult $result): bool
......@@ -125,7 +119,7 @@ class Email extends AbstractService
// Set subject
$count = count($outdatedPackages);
$subject = sprintf('%d outdated package%s', $count, $count !== 1 ? 's' : '');
$subject = sprintf('%d outdated package%s', $count, 1 !== $count ? 's' : '');
// Set plain text body and html content
$body = $this->parsePlainBody($outdatedPackages);
......@@ -133,7 +127,7 @@ class Email extends AbstractService
// Send email
if (!$this->behavior->style->isJson()) {
$this->behavior->io->write(Emoji::rocket() . ' Sending report via Email...');
$this->behavior->io->write(Emoji::rocket().' Sending report via Email...');
}
$email = (new SymfonyEmail())
->from($this->sender)
......@@ -143,12 +137,11 @@ class Email extends AbstractService
->html($html);
$sentMessage = $this->transport->send($email);
return $sentMessage !== null;
return null !== $sentMessage;
}
/**
* @param OutdatedPackage[] $outdatedPackages
* @return string
*/
private function parsePlainBody(array $outdatedPackages): string
{
......@@ -166,39 +159,40 @@ class Email extends AbstractService
$outdatedPackage->getNewVersion()
);
}
return implode(PHP_EOL, $textParts);
}
/**
* @param OutdatedPackage[] $outdatedPackages
* @return string
*/
private function parseHtmlBody(array $outdatedPackages): string
{
$html = [];
$html[] = '<table>';
$html[] = '<tr>';
$html[] = '<th>Package name</th>';
$html[] = '<th>Outdated version</th>';
$html[] = '<th>New version</th>';
$html[] = '</tr>';
$html[] = '<tr>';
$html[] = '<th>Package name</th>';
$html[] = '<th>Outdated version</th>';
$html[] = '<th>New version</th>';
$html[] = '</tr>';
foreach ($outdatedPackages as $outdatedPackage) {
$insecure = '';
if ($outdatedPackage->isInsecure()) {
$insecure = ' <strong style="color: red;">(insecure)</strong>';
}
$html[] = '<tr>';
/** @noinspection HtmlUnknownTarget */
$html[] = sprintf(
/* @noinspection HtmlUnknownTarget */
$html[] = sprintf(
'<td><a href="%s">%s</a></td>',
$outdatedPackage->getProviderLink(),
$outdatedPackage->getName()
);
$html[] = '<td>' . $outdatedPackage->getOutdatedVersion() . $insecure . '</td>';
$html[] = '<td><strong>' . $outdatedPackage->getNewVersion() . '</strong></td>';
$html[] = '<td>'.$outdatedPackage->getOutdatedVersion().$insecure.'</td>';
$html[] = '<td><strong>'.$outdatedPackage->getNewVersion().'</strong></td>';
$html[] = '</tr>';
}
$html[] = '</table>';
return implode(PHP_EOL, $html);
}
......@@ -219,25 +213,22 @@ class Email extends AbstractService
private function validateReceivers(): void
{
if ($this->receivers === []) {
if ([] === $this->receivers) {
throw new \InvalidArgumentException('Email receivers must not be empty.', 1601395103);
}
foreach ($this->receivers as $receiver) {
if (filter_var($receiver, FILTER_VALIDATE_EMAIL) === false) {
throw new \InvalidArgumentException(
sprintf('Email receiver "%s" is no valid email address.', $receiver),
1601395301
);
if (false === filter_var($receiver, FILTER_VALIDATE_EMAIL)) {
throw new \InvalidArgumentException(sprintf('Email receiver "%s" is no valid email address.', $receiver), 1601395301);
}
}
}
private function validateSender(): void
{
if (trim($this->sender) === '') {
if ('' === trim($this->sender)) {
throw new \InvalidArgumentException('Email sender must not be empty.', 1601395109);
}
if (filter_var($this->sender, FILTER_VALIDATE_EMAIL) === false) {
if (false === filter_var($this->sender, FILTER_VALIDATE_EMAIL)) {
throw new \InvalidArgumentException('Email sender is no valid email address.', 1601395313);
}
}
......
<?php
declare(strict_types=1);
namespace EliasHaeussler\ComposerUpdateReporter\Service;
/*
......@@ -32,7 +34,7 @@ use Spatie\Emoji\Emoji;
use Symfony\Component\HttpClient\Psr18Client;
/**
* GitLab
* GitLab.
*
* @author Elias Häußler <elias@haeussler.dev>
* @license GPL-3.0-or-later
......@@ -68,26 +70,20 @@ class GitLab extends AbstractService
// Parse GitLab URL
if (is_array($extra) && array_key_exists('url', $extra)) {
$uri = new Uri((string)$extra['url']);
} elseif (getenv('GITLAB_URL') !== false) {
$uri = new Uri((string) $extra['url']);
} elseif (false !== getenv('GITLAB_URL')) {
$uri = new Uri(getenv('GITLAB_URL'));
} else {
throw new \RuntimeException(
'GitLab URL is not defined. Define it either in composer.json or as $GITLAB_URL.',
1600852917
);
throw new \RuntimeException('GitLab URL is not defined. Define it either in composer.json or as $GITLAB_URL.', 1600852917);
}
// Parse GitLab authorization key
if (is_array($extra) && array_key_exists('authKey', $extra)) {
$authKey = (string)$extra['authKey'];
} elseif (getenv('GITLAB_AUTH_KEY') !== false) {
$authKey = (string) $extra['authKey'];
} elseif (false !== getenv('GITLAB_AUTH_KEY')) {
$authKey = getenv('GITLAB_AUTH_KEY');
} else {
throw new \RuntimeException(
'GitLab authorization key is not defined. Define it either in composer.json or as $GITLAB_AUTH_KEY.',
1600852990
);
throw new \RuntimeException('GitLab authorization key is not defined. Define it either in composer.json or as $GITLAB_AUTH_KEY.', 1600852990);
}
return new self($uri, $authKey);
......@@ -104,7 +100,8 @@ class GitLab extends AbstractService
}
/**
* @inheritDoc
* {@inheritDoc}
*
* @throws ClientExceptionInterface
*/
protected function sendReport(UpdateCheckResult $result): bool
......@@ -114,21 +111,20 @@ class GitLab extends AbstractService
// Build JSON payload
$count = count($outdatedPackages);
$payload = array_merge([
'title' => sprintf('%d outdated package%s', $count, $count !== 1 ? 's' : ''),
'title' => sprintf('%d outdated package%s', $count, 1 !== $count ? 's' : ''),
], $this->getPackagesPayload($outdatedPackages));
// Send report
if (!$this->behavior->style->isJson()) {
$this->behavior->io->write(Emoji::rocket() . ' Sending report to GitLab...');
$this->behavior->io->write(Emoji::rocket().' Sending report to GitLab...');
}
$response = $this->sendRequest($payload, ['Authorization' => 'Bearer ' . $this->authorizationKey,]);
$response = $this->sendRequest($payload, ['Authorization' => 'Bearer '.$this->authorizationKey]);
return $response->getStatusCode() < 400;
}
/**
* @param OutdatedPackage[] $outdatedPackages
* @return array
*/
private function getPackagesPayload(array $outdatedPackages): array
{
......@@ -145,6 +141,7 @@ class GitLab extends AbstractService
$outdatedPackage->getNewVersion()
);
}
return $payload;
}
......@@ -161,17 +158,17 @@ class GitLab extends AbstractService
private function validateUri(): void
{
$uri = (string) $this->uri;
if (trim($uri) === '') {
if ('' === trim($uri)) {
throw new \InvalidArgumentException('GitLab URL must not be empty.', 1600852837);
}
if (filter_var($uri, FILTER_VALIDATE_URL) === false) {
if (false === filter_var($uri, FILTER_VALIDATE_URL)) {
throw new \InvalidArgumentException('GitLab URL is no valid URL.', 1600852841);
}
}
private function validateAuthorizationKey(): void
{
if (trim($this->authorizationKey) === '') {
if ('' === trim($this->authorizationKey)) {
throw new \InvalidArgumentException('GitLab authorization key must not be empty.', 1600852864);
}
}
......
<?php
declare(strict_types=1);
namespace EliasHaeussler\ComposerUpdateReporter\Service;
/*
......@@ -32,7 +34,7 @@ use Spatie\Emoji\Emoji;
use Symfony\Component\HttpClient\Psr18Client;
/**
* Mattermost
* Mattermost.
*
* @author Elias Häußler <elias@haeussler.dev>
* @license GPL-3.0-or-later
......@@ -74,33 +76,27 @@ class Mattermost extends AbstractService
// Parse Mattermost URL
if (is_array($extra) && array_key_exists('url', $extra)) {
$uri = new Uri((string)$extra['url']);
} elseif (getenv('MATTERMOST_URL') !== false) {
$uri = new Uri((string) $extra['url']);
} elseif (false !== getenv('MATTERMOST_URL')) {
$uri = new Uri(getenv('MATTERMOST_URL'));
} else {
throw new \RuntimeException(
'Mattermost URL is not defined. Define it either in composer.json or as $MATTERMOST_URL.',
1600283681
);
throw new \RuntimeException('Mattermost URL is not defined. Define it either in composer.json or as $MATTERMOST_URL.', 1600283681);
}
// Parse Mattermost channel name
if (is_array($extra) && array_key_exists('channel', $extra)) {
$channelName = (string)$extra['channel'];
} elseif (getenv('MATTERMOST_CHANNEL') !== false) {
$channelName = (string) $extra['channel'];
} elseif (false !== getenv('MATTERMOST_CHANNEL')) {
$channelName = getenv('MATTERMOST_CHANNEL');
} else {
throw new \RuntimeException(
'Mattermost channel name is not defined. Define it either in composer.json or as $MATTERMOST_CHANNEL.',
1600284246
);
throw new \RuntimeException('Mattermost channel name is not defined. Define it either in composer.json or as $MATTERMOST_CHANNEL.', 1600284246);
}
// Parse Mattermost username
$username = null;
if (is_array($extra) && array_key_exists('username', $extra)) {
$username = (string)$extra['username'];
} elseif (getenv('MATTERMOST_USERNAME') !== false) {
$username = (string) $extra['username'];
} elseif (false !== getenv('MATTERMOST_USERNAME')) {
$username = getenv('MATTERMOST_USERNAME');
}
......@@ -118,7 +114,8 @@ class Mattermost extends AbstractService
}
/**
* @inheritDoc
* {@inheritDoc}
*
* @throws ClientExceptionInterface
*/
protected function sendReport(UpdateCheckResult $result): bool
......@@ -135,13 +132,13 @@ class Mattermost extends AbstractService
],
],
];
if ($this->username !== null) {
if (null !== $this->username) {
$payload['username'] = $this->username;
}
// Send report
if (!$this->behavior->style->isJson()) {
$this->behavior->io->write(Emoji::rocket() . ' Sending report to Mattermost...');
$this->behavior->io->write(Emoji::rocket().' Sending report to Mattermost...');
}
$response = $this->sendRequest($payload);
......@@ -150,13 +147,12 @@ class Mattermost extends AbstractService
/**
* @param OutdatedPackage[] $outdatedPackages
* @return string
*/
private function renderText(array $outdatedPackages): string
{
$count = count($outdatedPackages);
$textParts = [
sprintf('#### :rotating_light: %d outdated package%s', $count, $count !== 1 ? 's' : ''),
sprintf('#### :rotating_light: %d outdated package%s', $count, 1 !== $count ? 's' : ''),
'| Package | Current version | New version |',
'|:------- |:--------------- |:----------- |',
];
......@@ -174,6 +170,7 @@ class Mattermost extends AbstractService
$outdatedPackage->getNewVersion()
);
}
return implode(PHP_EOL, $textParts);
}
......@@ -195,17 +192,17 @@ class Mattermost extends AbstractService
private function validateUri(): void
{
$uri = (string) $this->uri;
if (trim($uri) === '') {
if ('' === trim($uri)) {
throw new \InvalidArgumentException('Mattermost URL must not be empty.', 1600793015);
}
if (filter_var($uri, FILTER_VALIDATE_URL) === false) {
if (false === filter_var($uri, FILTER_VALIDATE_URL)) {
throw new \InvalidArgumentException('Mattermost URL is no valid URL.', 1600792942);
}
}
private function validateChannelName(): void
{
if (trim($this->channelName) === '') {
if ('' === trim($this->channelName)) {
throw new \InvalidArgumentException('Mattermost channel name must not be empty.', 1600793071);
}
}
......
<?php
declare(strict_types=1);
namespace EliasHaeussler\ComposerUpdateReporter\Service;
/*
......@@ -26,7 +28,7 @@ use EliasHaeussler\ComposerUpdateCheck\Options;
use EliasHaeussler\ComposerUpdateCheck\Package\UpdateCheckResult;
/**
* ServiceInterface
* ServiceInterface.
*
* @author Elias Häußler <elias@haeussler.dev>
* @license GPL-3.0-or-later
......@@ -34,31 +36,20 @@ use EliasHaeussler\ComposerUpdateCheck\Package\UpdateCheckResult;
interface ServiceInterface
{
/**
* @param array $configuration
* @return static
*/
public static function fromConfiguration(array $configuration): self;