-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGithubAdapterForReadingExternalMetadataSource.php
113 lines (92 loc) · 3.92 KB
/
GithubAdapterForReadingExternalMetadataSource.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php declare(strict_types=1);
/**
* This file is part of the medicalmundi/marketplace-engine
*
* @copyright (c) 2024 MedicalMundi
*
* This software consists of voluntary contributions made by many individuals
* {@link https://github.com/medicalmundi/marketplace-engine/graphs/contributors developer} and is licensed under the MIT license.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
* @license https://github.com/MedicalMundi/marketplace-engine/blob/main/LICENSE MIT
*/
namespace Metadata\AdapterForReadingExternalMetadataSource;
use Github\Api\Repo;
use Github\Client as GithubClient;
use Metadata\Core\Port\Driven\ForReadingExternalMetadataSource\ExternalMetadataDto;
use Metadata\Core\Port\Driven\ForReadingExternalMetadataSource\ForReadingExternalMetadataSource;
use Metadata\Core\Port\Driven\ForReadingExternalMetadataSource\MetadataReaderException;
use Metadata\Core\ValueObject\ComposerJsonFile;
use Metadata\Core\ValueObject\Repository;
use Nyholm\Psr7\Request;
use Psr\Http\Client\ClientInterface;
class GithubAdapterForReadingExternalMetadataSource implements ForReadingExternalMetadataSource
{
public function __construct(
private readonly GithubClient $githubClient,
private readonly ClientInterface $httpclient,
) {
}
public function readMetadataFromExternalSource(string $moduleUrl): ?ExternalMetadataDto
{
$repository = Repository::createFromRepositoryUrl($moduleUrl);
$defaultBranch = $this->getDefaultBranchName($repository);
/**
* TODO: refactor
* $defaultBranch dovrebbe essere sempre un tipo string,
* la funzione sopra non dovrebbe tornare null
* ma eccezione di tipo http del client api
* o eccezione per dati non processabili
*/
if (null === $defaultBranch) {
return null;
}
$composerJsonFileContent = $this->downloadComposerJsonFileContent($moduleUrl, $defaultBranch);
$composerFile = ComposerJsonFile::createFromJson($composerJsonFileContent);
if (! $composerFile->hasMetadata()) {
return null;
}
$extractedMetadata = (array) $composerFile->getMetadata();
$metadataDto = new ExternalMetadataDto(
enableSync: true,
category: (string) $extractedMetadata['category'],
tags: (array) $extractedMetadata['tags'],
);
return $metadataDto;
}
private function doDownloadHttpRequest(string $url): string
{
$request = new Request('GET', $url);
$response = $this->httpclient->sendRequest($request);
return $response->getBody()->getContents();
}
private function downloadComposerJsonFileContent(string $url, string $reference): string
{
try {
$repository = Repository::createFromRepositoryUrl($url);
/** @var Repo $repoApi */
$repoApi = $this->githubClient->api('repo');
$fileInfo = (array) $repoApi
->contents()
->show($repository->getUsername(), $repository->getName(), 'composer.json', $reference);
$composerJsonFileContent = $this->doDownloadHttpRequest((string) $fileInfo['download_url']);
return $composerJsonFileContent;
} catch (\Exception $exception) {
throw new MetadataReaderException('Impossible to read metadata from: ' . $url . ' error: ' . $exception->getMessage());
}
}
private function getDefaultBranchName(Repository $repository): ? string
{
$data = [];
try {
$data = $this->githubClient->repo()->show($repository->getUsername(), $repository->getName());
} catch (\Exception $exception) {
throw $exception;
}
if (! \array_key_exists('default_branch', $data)) {
return null;
}
return (string) $data['default_branch'];
}
}