DependencyService::openIssues()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Sfneal\Dependencies\Services;
4
5
use Sfneal\Dependencies\Utils\DependencyUrl;
6
use Sfneal\Dependencies\Utils\GithubUrl;
7
use Sfneal\Dependencies\Utils\ImgShieldsUrl;
8
use Sfneal\Dependencies\Utils\Url;
9
10
class DependencyService
11
{
12
    /**
13
     * @var string[] Array of supported dependency types
14
     */
15
    private const DEPENDENCY_TYPES = [
16
        'composer',
17
        'docker',
18
        'python',
19
        'node',
20
    ];
21
22
    /**
23
     * @var string Name of the dependency
24
     */
25
    public string $package;
26
27
    /**
28
     * @var string Type of Dependency ('composer', 'docker', 'python' or 'node')
29
     */
30
    public string $type;
31
32
    /**
33
     * @var string Name of the GitHub package.
34
     */
35
    public string $githubRepo;
36
37
    /**
38
     * @var string Name of the project without the GitHub user prefix (used for Python projects).
39
     */
40
    public string $project;
41
42
    /**
43
     * @var array|null Array of global Img Shields params to be passed to SVG requests
44
     */
45
    private ?array $imgShieldGlobals;
46
47
    /**
48
     * DependenciesService constructor.
49
     *
50
     * @param  string  $package
51
     * @param  string  $type
52
     * @param  array|null  $imgShieldGlobals
53
     */
54
    public function __construct(string $package, string $type = 'composer', ?array $imgShieldGlobals = null)
55
    {
56
        $this->package = $package;
57
        $this->setGitHubRepo($package);
58
        $this->setType($type);
59
        $this->setProject($package);
60
        $this->imgShieldGlobals = $imgShieldGlobals;
61
    }
62
63
    /**
64
     * Retrieve a GitHub URL for a dependency.
65
     *
66
     * @return GithubUrl
67
     */
68
    public function gitHub(): GithubUrl
69
    {
70
        return new GithubUrl($this->githubRepo, $this->imgShieldGlobals);
71
    }
72
73
    /**
74
     * Retrieve a Travis CI build status SVG URL for a dependency.
75
     *
76
     * @return DependencyUrl
77
     */
78
    public function travis(): DependencyUrl
79
    {
80
        return new DependencyUrl(
81
            Url::from("app.travis-ci.com/{$this->githubRepo}"),
82
            Url::from("app.travis-ci.com/{$this->githubRepo}.svg")
83
                ->withParams([
84
                    'branch' => 'master',
85
                ]),
86
        );
87
    }
88
89
    /**
90
     * Retrieve the Dependencies latest version.
91
     *
92
     * @return DependencyUrl
93
     */
94
    public function version(): DependencyUrl
95
    {
96
        return match ($this->type) {
97
            'docker' => $this->docker(),
98
            'python' => $this->pypi(),
99
            'node' => $this->node(),
100
            default => $this->packagist(),
101
        };
102
    }
103
104
    // todo: refactor github related methods to GitHubUrl
105
    /**
106
     * Retrieve date of the last GitHub commit.
107
     *
108
     * @return DependencyUrl
109
     */
110
    public function lastCommit(): DependencyUrl
111
    {
112
        return new DependencyUrl(
113
            Url::from("github.com/{$this->githubRepo}"),
114
            ImgShieldsUrl::from("github/last-commit/{$this->githubRepo}")
115
                ->withGlobalParams($this->imgShieldGlobals)
116
        );
117
    }
118
119
    /**
120
     * Retrieve number of open issues.
121
     *
122
     * @return DependencyUrl
123
     */
124
    public function openIssues(): DependencyUrl
125
    {
126
        return new DependencyUrl(
127
            Url::from("github.com/{$this->githubRepo}/issues"),
128
            ImgShieldsUrl::from("github/issues-raw/{$this->githubRepo}")
129
                ->withGlobalParams($this->imgShieldGlobals)
130
        );
131
    }
132
133
    /**
134
     * Retrieve number of closed issues.
135
     *
136
     * @return DependencyUrl
137
     */
138
    public function closedIssues(): DependencyUrl
139
    {
140
        return new DependencyUrl(
141
            Url::from("github.com/{$this->githubRepo}/issues")
142
                ->withParams([
143
                    'q' => 'is%3Aissue+is%3Aclosed',
144
                ]),
145
            ImgShieldsUrl::from("github/issues-closed-raw/{$this->githubRepo}")
146
                ->withParams([
147
                    'color' => 'red',
148
                ])
149
                ->withGlobalParams($this->imgShieldGlobals),
150
        );
151
    }
152
153
    /**
154
     * Retrieve number of open pull requests.
155
     *
156
     * @return DependencyUrl
157
     */
158
    public function openPullRequests(): DependencyUrl
159
    {
160
        return new DependencyUrl(
161
            Url::from("github.com/{$this->githubRepo}/pulls"),
162
            ImgShieldsUrl::from("github/issues-pr-raw/{$this->githubRepo}")
163
                ->withGlobalParams($this->imgShieldGlobals)
164
        );
165
    }
166
167
    /**
168
     * Retrieve number of closed pull requests.
169
     *
170
     * @return DependencyUrl
171
     */
172
    public function closedPullRequests(): DependencyUrl
173
    {
174
        return new DependencyUrl(
175
            Url::from("github.com/{$this->githubRepo}/pulls")
176
                ->withParams([
177
                    'q' => 'is%3Aissue+is%3Aclosed',
178
                ]),
179
            ImgShieldsUrl::from("github/issues-pr-closed-raw/{$this->githubRepo}")
180
                ->withParams([
181
                    'color' => 'red',
182
                ])
183
                ->withGlobalParams($this->imgShieldGlobals)
184
        );
185
    }
186
187
    /**
188
     * Retrieve a Packagist versions SVG URL for a dependency.
189
     *
190
     * @return DependencyUrl
191
     */
192
    private function packagist(): DependencyUrl
193
    {
194
        return new DependencyUrl(
195
            Url::from("packagist.org/packages/{$this->package}"),
196
            ImgShieldsUrl::from("packagist/v/{$this->package}.svg")
197
                ->withGlobalParams($this->imgShieldGlobals)
198
        );
199
    }
200
201
    /**
202
     * Retrieve the latest Docker image tag for a dependency.
203
     *
204
     * @return DependencyUrl
205
     */
206
    private function docker(): DependencyUrl
207
    {
208
        return new DependencyUrl(
209
            Url::from("hub.docker.com/r/{$this->package}"),
210
            ImgShieldsUrl::from("docker/v/{$this->package}.svg")
211
                ->withParams([
212
                    'sort' => 'semver',
213
                ])
214
                ->withGlobalParams($this->imgShieldGlobals)
215
        );
216
    }
217
218
    /**
219
     * Retrieve the latest PyPi version a dependency.
220
     *
221
     * @return DependencyUrl
222
     */
223
    private function pypi(): DependencyUrl
224
    {
225
        $project = explode('/', $this->package)[1];
226
227
        return new DependencyUrl(
228
            Url::from("pypi.org/project/{$project}"),
229
            ImgShieldsUrl::from("pypi/v/{$project}.svg")
230
                ->withGlobalParams($this->imgShieldGlobals)
231
        );
232
    }
233
234
    /**
235
     * Retrieve a Node versions SVG URL for a dependency.
236
     *
237
     * @return DependencyUrl
238
     */
239
    private function node(): DependencyUrl
240
    {
241
        $project = explode('/', $this->package)[1];
242
243
        return new DependencyUrl(
244
            Url::from("npmjs.com/package/{$project}"),
245
            ImgShieldsUrl::from("npm/v/{$project}.svg")
246
                ->withGlobalParams($this->imgShieldGlobals)
247
        );
248
    }
249
250
    /**
251
     * Retrieve the GitHub package name with alias replacement.
252
     *
253
     * @param  string  $fullPackageName
254
     * @return void
255
     */
256
    private function setGitHubRepo(string $fullPackageName): void
257
    {
258
        [$user, $package] = explode('/', $fullPackageName);
259
260
        // Replace GitHub username with alias if one is provided
261
        if (array_key_exists($user, config('dependencies.github_alias'))) {
262
            $this->githubRepo = config('dependencies.github_alias')[$user]."/{$package}";
263
        }
264
265
        // Use default package name
266
        else {
267
            $this->githubRepo = $fullPackageName;
268
        }
269
    }
270
271
    /**
272
     * Set the dependencies type.
273
     *
274
     * @param  string  $type
275
     */
276
    private function setType(string $type): void
277
    {
278
        assert(
279
            in_array($type, self::DEPENDENCY_TYPES),
280
            "'{$type} is not a supported dependency type (supported: ".join(', ', self::DEPENDENCY_TYPES)
281
        );
282
        $this->type = $type;
283
    }
284
285
    /**
286
     * Set the dependency project name.
287
     *
288
     * @param  string  $fullPackageName
289
     */
290
    private function setProject(string $fullPackageName): void
291
    {
292
        if ($this->type == 'python' || $this->type == 'node') {
293
            [$user, $package] = explode('/', $fullPackageName);
294
            $this->project = $package;
295
        } else {
296
            $this->project = $fullPackageName;
297
        }
298
    }
299
}
300