Skip to content

Commit

Permalink
Extract HttpClient to centralize curl dependency (#73)
Browse files Browse the repository at this point in the history
  • Loading branch information
staabm authored Jan 7, 2024
1 parent 723641d commit 0c3d2c2
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 32 deletions.
3 changes: 3 additions & 0 deletions extension.neon
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,6 @@ services:
- %todo_by.ticket.jira.server%
- %todo_by.ticket.jira.credentials%
- %todo_by.ticket.jira.credentialsFilePath%

-
class: staabm\PHPStanTodoBy\utils\HttpClient
2 changes: 1 addition & 1 deletion src/TodoByPackageVersionRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public function processNode(Node $node, Scope $scope): array
$satisfiesOrError = $this->satisfiesInstalledPackage($package, $version, $comment, $match[0][1]);
}

if ($satisfiesOrError instanceof \PHPStan\Rules\RuleError) {
if ($satisfiesOrError instanceof RuleError) {
$errors[] = $satisfiesOrError;
continue;
}
Expand Down
39 changes: 39 additions & 0 deletions src/utils/HttpClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace staabm\PHPStanTodoBy\utils;

use RuntimeException;

use function is_string;

final class HttpClient
{
/**
* @param list<string> $headers
* @return array{int, string}
*/
public function get(string $url, array $headers): array
{
$curl = curl_init($url);
if (!$curl) {
throw new RuntimeException('Could not initialize cURL connection');
}

curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

if ([] !== $headers) {
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
}

$response = curl_exec($curl);

if (!is_string($response)) {
throw new RuntimeException("Could not fetch url $url");
}

$responseCode = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);

return [$responseCode, $response];
}
}
23 changes: 8 additions & 15 deletions src/utils/ticket/GitHubTicketStatusFetcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use RuntimeException;
use staabm\PHPStanTodoBy\utils\CredentialsHelper;
use staabm\PHPStanTodoBy\utils\HttpClient;

use function array_key_exists;
use function is_array;
Expand All @@ -27,13 +28,16 @@ final class GitHubTicketStatusFetcher implements TicketStatusFetcher
*/
private array $cache;

public function __construct(string $defaultOwner, string $defaultRepo, ?string $credentials, ?string $credentialsFilePath)
private HttpClient $httpClient;

public function __construct(string $defaultOwner, string $defaultRepo, ?string $credentials, ?string $credentialsFilePath, HttpClient $httpClient)
{
$this->defaultOwner = $defaultOwner;
$this->defaultRepo = $defaultRepo;
$this->accessToken = CredentialsHelper::getCredentials($credentials, $credentialsFilePath);

$this->cache = [];
$this->httpClient = $httpClient;
}

public function fetchTicketStatus(string $ticketKey): ?string
Expand All @@ -51,11 +55,6 @@ public function fetchTicketStatus(string $ticketKey): ?string
}

$url = "https://api.github.com/repos/$owner/$repo/issues/$number";
$curl = curl_init($url);
if (!$curl) {
throw new RuntimeException('Could not initialize cURL connection');
}

$apiVersion = self::API_VERSION;

$headers = [
Expand All @@ -68,22 +67,16 @@ public function fetchTicketStatus(string $ticketKey): ?string
$headers[] = "Authorization: Bearer $this->accessToken";
}

curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
[$responseCode, $response] = $this->httpClient->get($url, $headers);

$response = curl_exec($curl);

if (404 === $responseCode = curl_getinfo($curl, CURLINFO_RESPONSE_CODE)) {
if (404 === $responseCode) {
return null;
}

if (!is_string($response) || 200 !== $responseCode) {
if (200 !== $responseCode) {
throw new RuntimeException("Could not fetch ticket's status from GitHub with $url");
}

curl_close($curl);

$data = json_decode($response, true);

if (!is_array($data) || !array_key_exists('state', $data) || !is_string($data['state'])) {
Expand Down
27 changes: 11 additions & 16 deletions src/utils/ticket/JiraTicketStatusFetcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use RuntimeException;
use staabm\PHPStanTodoBy\utils\CredentialsHelper;
use staabm\PHPStanTodoBy\utils\HttpClient;

use function array_key_exists;
use function is_array;
Expand All @@ -21,14 +22,17 @@ final class JiraTicketStatusFetcher implements TicketStatusFetcher
*/
private array $cache;

public function __construct(string $host, ?string $credentials, ?string $credentialsFilePath)
private HttpClient $httpClient;

public function __construct(string $host, ?string $credentials, ?string $credentialsFilePath, HttpClient $httpClient)
{
$credentials = CredentialsHelper::getCredentials($credentials, $credentialsFilePath);

$this->host = $host;
$this->authorizationHeader = $credentials ? self::createAuthorizationHeader($credentials) : null;

$this->cache = [];
$this->httpClient = $httpClient;
}

public function fetchTicketStatus(string $ticketKey): ?string
Expand All @@ -40,32 +44,23 @@ public function fetchTicketStatus(string $ticketKey): ?string
$apiVersion = self::API_VERSION;

$url = "{$this->host}/rest/api/$apiVersion/issue/$ticketKey?expand=status";
$curl = curl_init($url);
if (!$curl) {
throw new RuntimeException('Could not initialize cURL connection');
}

curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

$headers = [];
if (null !== $this->authorizationHeader) {
curl_setopt($curl, CURLOPT_HTTPHEADER, [
$headers = [
"Authorization: $this->authorizationHeader",
]);
];
}

$response = curl_exec($curl);
[$responseCode, $response] = $this->httpClient->get($url, $headers);

if (404 === $responseCode = curl_getinfo($curl, CURLINFO_RESPONSE_CODE)) {
if (404 === $responseCode) {
return null;
}

if (!is_string($response) || 200 !== $responseCode) {
if (200 !== $responseCode) {
throw new RuntimeException("Could not fetch ticket's status from Jira with url $url");
}

curl_close($curl);

$data = self::decodeAndValidateResponse($response);

return $this->cache[$ticketKey] = $data['fields']['status']['name'];
Expand Down

0 comments on commit 0c3d2c2

Please sign in to comment.