Passed
Push — master ( cd3517...f54951 )
by Stephen
06:34 queued 02:01
created

GithubUrl::actions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
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 $api;
14
15
    /**
16
     * @var string
17
     */
18
    private $githubRepo;
19
20
    /**
21
     * @var array|null Array of global Img Shields params to be passed to SVG requests
22
     */
23
    private $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
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
     * @return DependencyUrl
85
     */
86
    public function workflow(string $name): DependencyUrl
87
    {
88
        return new DependencyUrl(
89
            Url::from("github.com/{$this->githubRepo}/actions"),
90
            ImgShieldsUrl::from("github/workflow/status/{$this->githubRepo}/{$name}")
91
                ->withGlobalParams($this->imgShieldGlobals)
92
                ->withParams([
93
                    'logo' => 'github',
94
                    'label' => $name,
95
                ])
96
        );
97
    }
98
99
    /**
100
     * Display the latest GitHub release (by date) for a GitHub repo.
101
     *
102
     * @return DependencyUrl
103
     */
104
    public function release(): DependencyUrl
105
    {
106
        return new DependencyUrl(
107
            Url::from("github.com/{$this->githubRepo}/releases"),
108
            ImgShieldsUrl::from("github/v/release/{$this->githubRepo}")
109
                ->withGlobalParams($this->imgShieldGlobals)
110
                ->withParams([
111
                    'display_name' => 'tag',
112
                    'sort' => 'semver',
113
                    'include_prereleases',
114
                ])
115
        );
116
    }
117
118
    /**
119
     * Retrieve a cached HTTP response from the GitHub api.
120
     *
121
     * @return ?array
122
     */
123
    private function getApiResponse(): ?array
124
    {
125
        $response = Http::withHeaders([
126
            'Authorization' => 'token '.config('dependencies.github_pat'),
127
        ])
128
            ->get($this->api->get());
129
130
        // Client error
131
        if ($response->clientError() && str_contains($response->json('message'), 'API rate limit exceeded')) {
132
            return null;
133
        }
134
135
        // Cache response
136
        return Cache::remember(
137
            config('dependencies.cache.prefix').':api-responses:'.crc32($this->api->get()),
138
            config('dependencies.cache.ttl'),
139
            function () use ($response): array {
140
                return $response->json();
141
            }
142
        );
143
    }
144
}
145