GithubUrl::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 8
rs 10
1
<?php
2
3
namespace Sfneal\Dependencies\Utils;
4
5
use Illuminate\Support\Facades\Cache;
6
use Illuminate\Support\Facades\Http;
7
8
class GithubUrl extends DependencyUrl
9
{
10
    /**
11
     * @var Url
12
     */
13
    private Url $api;
14
15
    /**
16
     * @var string
17
     */
18
    private string $githubRepo;
19
20
    /**
21
     * @var array|null Array of global Img Shields params to be passed to SVG requests
22
     */
23
    private ?array $imgShieldGlobals;
24
25
    /**
26
     * GithubUrl Constructor.
27
     *
28
     * @param  string  $githubRepo  GitHub repo name
29
     */
30
    public function __construct(string $githubRepo, ?array $imgShieldGlobals = null)
31
    {
32
        $this->githubRepo = $githubRepo;
33
        $this->imgShieldGlobals = $imgShieldGlobals;
34
35
        $this->api = Url::from("api.github.com/repos/{$this->githubRepo}");
36
37
        parent::__construct(Url::from("github.com/{$this->githubRepo}"), null);
38
    }
39
40
    /**
41
     * Retrieve the GitHub repo's description.
42
     *
43
     * @return string|null
44
     */
45
    public function description(): ?string
46
    {
47
        return $this->getApiResponse()['description'];
48
    }
49
50
    /**
51
     * Retrieve the GitHub repo's description.
52
     *
53
     * @return string
54
     */
55
    public function defaultBranch(): string
56
    {
57
        return $this->getApiResponse()['default_branch'] ?? 'master';
58
    }
59
60
    /**
61
     * Retrieve a link to download the GitHub repo zip.
62
     *
63
     * @return string
64
     */
65
    public function download(): string
66
    {
67
        return Url::from("github.com/{$this->githubRepo}/archive/refs/heads/{$this->defaultBranch()}.zip")->get();
68
    }
69
70
    /**
71
     * Retrieve a link to the GitHub repo's workflow status page.
72
     *
73
     * @return string
74
     */
75
    public function actions(): string
76
    {
77
        return Url::from("github.com/{$this->githubRepo}/actions")->get();
78
    }
79
80
    /**
81
     * Display pass/fail status for a GitHub repo's workflow.
82
     *
83
     * @param  string  $name
84
     * @param  string  $branch
85
     * @return DependencyUrl
86
     */
87
    public function workflow(string $name, string $branch = 'master'): DependencyUrl
88
    {
89
        return new DependencyUrl(
90
            Url::from("github.com/{$this->githubRepo}/actions"),
91
            ImgShieldsUrl::from("github/actions/workflow/status/{$this->githubRepo}/{$name}?branch={$branch}")
92
                ->withGlobalParams($this->imgShieldGlobals)
93
                ->withParams([
94
                    'logo' => 'github',
95
                    'label' => $name,
96
                ])
97
        );
98
    }
99
100
    /**
101
     * Display the latest GitHub release (by date) for a GitHub repo.
102
     *
103
     * @return DependencyUrl
104
     */
105
    public function release(): DependencyUrl
106
    {
107
        return new DependencyUrl(
108
            Url::from("github.com/{$this->githubRepo}/releases"),
109
            ImgShieldsUrl::from("github/v/release/{$this->githubRepo}")
110
                ->withGlobalParams($this->imgShieldGlobals)
111
                ->withParams([
112
                    'display_name' => 'tag',
113
                    'sort' => 'semver',
114
                    'include_prereleases',
115
                ])
116
        );
117
    }
118
119
    /**
120
     * Retrieve a cached HTTP response from the GitHub api.
121
     *
122
     * @return ?array
123
     */
124
    private function getApiResponse(): ?array
125
    {
126
        $response = Http::withHeaders([
127
            'Authorization' => 'token '.config('dependencies.github_pat'),
128
        ])
129
            ->get($this->api->get());
130
131
        // Client error
132
        if ($response->clientError() && str_contains($response->json('message'), 'API rate limit exceeded')) {
133
            return null;
134
        }
135
136
        // Cache response
137
        return Cache::remember(
138
            config('dependencies.cache.prefix').':api-responses:'.crc32($this->api->get()),
139
            config('dependencies.cache.ttl'),
140
            function () use ($response): array {
141
                return $response->json();
142
            }
143
        );
144
    }
145
}
146