• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

eliashaeussler / composer-package-template / 8584679655

07 Apr 2024 12:09AM UTC coverage: 100.0%. Remained the same
8584679655

push

github

web-flow
[TASK] Update all dependencies

352 of 352 relevant lines covered (100.0%)

3.64 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/src/Service/CodeClimateService.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the Composer package "eliashaeussler/composer-package-template".
7
 *
8
 * Copyright (C) 2023-2024 Elias Häußler <elias@haeussler.dev>
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation, either version 3 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22
 */
23

24
namespace EliasHaeussler\ComposerPackageTemplate\Service;
25

26
use CPSIT\ProjectBuilder;
27
use EliasHaeussler\ComposerPackageTemplate\Enums;
28
use EliasHaeussler\ComposerPackageTemplate\Helper;
29
use EliasHaeussler\ComposerPackageTemplate\Resource;
30
use EliasHaeussler\ComposerPackageTemplate\ValueObject;
31
use Nyholm\Psr7;
32
use Psr\Http\Client;
33
use Psr\Http\Message;
34

35
use function json_encode;
36
use function sprintf;
37

38
/**
39
 * CodeClimateService.
40
 *
41
 * @author Elias Häußler <elias@haeussler.dev>
42
 * @license GPL-3.0-or-later
43
 */
44
final class CodeClimateService
45
{
46
    private const API_TOKEN_URL = 'https://codeclimate.com/profile/tokens';
47

48
    private readonly Message\UriInterface $baseUrl;
49

50
    public function __construct(
6✔
51
        private readonly Client\ClientInterface $client,
52
        private readonly ProjectBuilder\IO\InputReader $inputReader,
53
        private readonly ProjectBuilder\IO\Messenger $messenger,
54
        private readonly Resource\TokenStorage $tokenStorage,
55
    ) {
56
        $this->baseUrl = new Psr7\Uri('https://api.codeclimate.com/v1');
6✔
57
    }
58

59
    /**
60
     * @see https://developer.codeclimate.com/#add-public-oss-repository
61
     */
62
    public function addRepository(ValueObject\GitHubRepository $repository): Enums\CreateRepositoryResponse
3✔
63
    {
64
        if ($this->repositoryExists($repository)) {
3✔
65
            return Enums\CreateRepositoryResponse::AlreadyExists;
1✔
66
        }
67

68
        $response = $this->sendPostRequest(
2✔
69
            '/github/repos',
2✔
70
            [
2✔
71
                'data' => [
2✔
72
                    'type' => 'repos',
2✔
73
                    'attributes' => [
2✔
74
                        'url' => (string) $repository->getUrl(),
2✔
75
                    ],
2✔
76
                ],
2✔
77
            ],
2✔
78
        );
2✔
79

80
        if (201 === $response->getStatusCode()) {
2✔
81
            return Enums\CreateRepositoryResponse::Created;
1✔
82
        }
83

84
        return Enums\CreateRepositoryResponse::Failed;
1✔
85
    }
86

87
    public function repositoryExists(ValueObject\GitHubRepository $repository): bool
6✔
88
    {
89
        $response = $this->sendGetRequest(
6✔
90
            '/repos',
6✔
91
            [
6✔
92
                'github_slug' => $repository->getOwner().'/'.$repository->getName(),
6✔
93
            ],
6✔
94
        );
6✔
95

96
        return 200 === $response->getStatusCode();
6✔
97
    }
98

99
    /**
100
     * @param non-empty-string     $path
101
     * @param array<string, mixed> $json
102
     */
103
    private function sendPostRequest(string $path, array $json): Message\ResponseInterface
2✔
104
    {
105
        $request = new Psr7\Request(
2✔
106
            'POST',
2✔
107
            Helper\UriHelper::mergePath($this->baseUrl, $path),
2✔
108
            $this->getRequestHeaders(),
2✔
109
        );
2✔
110
        $request->getBody()->write(json_encode($json, JSON_THROW_ON_ERROR));
2✔
111
        $request->getBody()->rewind();
2✔
112

113
        return $this->client->sendRequest($request);
2✔
114
    }
115

116
    /**
117
     * @param non-empty-string     $path
118
     * @param array<string, mixed> $queryParams
119
     */
120
    private function sendGetRequest(string $path, array $queryParams = []): Message\ResponseInterface
6✔
121
    {
122
        $request = new Psr7\Request(
6✔
123
            'GET',
6✔
124
            Helper\UriHelper::mergePath(
6✔
125
                Helper\UriHelper::mergeQueryParams($this->baseUrl, $queryParams),
6✔
126
                $path,
6✔
127
            ),
6✔
128
            $this->getRequestHeaders(),
6✔
129
        );
6✔
130

131
        return $this->client->sendRequest($request);
6✔
132
    }
133

134
    /**
135
     * @return array{
136
     *     Accept: non-empty-string,
137
     *     Authorization: non-empty-string,
138
     *     Content-Type: non-empty-string,
139
     * }
140
     */
141
    private function getRequestHeaders(): array
6✔
142
    {
143
        return [
6✔
144
            'Accept' => 'application/vnd.api+json',
6✔
145
            // see https://developer.codeclimate.com/#authentication
146
            'Authorization' => 'Token token='.$this->getAccessToken(),
6✔
147
            'Content-Type' => 'application/vnd.api+json',
6✔
148
        ];
6✔
149
    }
150

151
    private function getAccessToken(): string
6✔
152
    {
153
        $token = $this->tokenStorage->get(Enums\TokenIdentifier::CodeClimate);
6✔
154

155
        if (null !== $token) {
6✔
156
            return $token;
5✔
157
        }
158

159
        $this->messenger->write([
1✔
160
            'Requests to CodeClimate API must be authorized by an access token.',
1✔
161
            sprintf('Please create your token at <href=%1$s>%1$s</>.', self::API_TOKEN_URL),
1✔
162
        ]);
1✔
163
        $this->messenger->newLine();
1✔
164

165
        $token = $this->inputReader->staticValue(
1✔
166
            'Please insert your access token',
1✔
167
            required: true,
1✔
168
        );
1✔
169

170
        $this->tokenStorage->set(Enums\TokenIdentifier::CodeClimate, $token);
1✔
171

172
        return $token;
1✔
173
    }
174
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc