Skip to content

Commit 9ac609c

Browse files
Fix crash when package is not listed on Packagist
1 parent 45dd897 commit 9ac609c

File tree

4 files changed

+55
-36
lines changed

4 files changed

+55
-36
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ Arguments:
4545
- `path to project`: required, directory containing `composer.json` and `composer.lock` files
4646
- `-q`: optional, quiet mode will only output libraries which are not up-to-date (that is, where "Libyears Behind" > 0)
4747

48+
### Limitations
49+
50+
- Currently only packages listed on Packagist are supported (feel free to submit a PR for issue #1)
51+
4852
## Contributing
4953

5054
Please be sure to read and follow ecoAPM's [Contribution Guidelines](CONTRIBUTING.md) when submitting issues or pull requests.

src/Factory.php

+4-7
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,17 @@
33
namespace LibYear;
44

55
use GuzzleHttp\Client;
6-
use LibYear\Calculator;
7-
use LibYear\ComposerFile;
8-
use LibYear\FileSystem;
9-
use LibYear\PackagistAPI;
6+
use function cli\err;
107

118
class Factory
129
{
13-
public static function App()
14-
{
10+
public static function App(): App
11+
{
1512
$fs = new FileSystem();
1613
$file = new ComposerFile($fs);
1714

1815
$http = new Client();
19-
$api = new PackagistAPI($http);
16+
$api = new PackagistAPI($http, STDERR);
2017

2118
$calculator = new Calculator($file, $api);
2219
return new App($calculator, STDOUT);

src/PackagistAPI.php

+25-10
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,34 @@
33
namespace LibYear;
44

55
use GuzzleHttp\ClientInterface;
6+
use GuzzleHttp\Exception\GuzzleException;
67

78
class PackagistAPI
89
{
9-
private ClientInterface $http_client;
10+
private ClientInterface $http_client;
1011

11-
public function __construct(ClientInterface $http_client)
12-
{
13-
$this->http_client = $http_client;
14-
}
12+
/** @var resource */
13+
private $stderr;
1514

16-
public function getPackageInfo(string $package): array
17-
{
18-
$response = $this->http_client->request('GET', "https://repo.packagist.org/packages/{$package}.json");
19-
return json_decode($response->getBody()->getContents(), true) ?? [];
20-
}
15+
/**
16+
* @param ClientInterface $http_client
17+
* @param resource $stderr
18+
*/
19+
public function __construct(ClientInterface $http_client, $stderr)
20+
{
21+
$this->http_client = $http_client;
22+
$this->stderr = $stderr;
23+
}
24+
25+
public function getPackageInfo(string $package): array
26+
{
27+
try {
28+
$response = $this->http_client->request('GET', "https://repo.packagist.org/packages/{$package}.json");
29+
return json_decode($response->getBody()->getContents(), true) ?? [];
30+
31+
} catch (GuzzleException) {
32+
fwrite($this->stderr, "Could not find info for {$package} on Packagist\n");
33+
return [];
34+
}
35+
}
2136
}

tests/PackagistAPITest.php

+22-19
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ public function testCallsCorrectURL()
1919
//arrange
2020
$http_client = Mockery::mock(ClientInterface::class, [
2121
'request' => Mockery::mock(ResponseInterface::class, [
22+
'getStatusCode' => 200,
2223
'getBody' => Mockery::mock(StreamInterface::class, [
2324
'getContents' => json_encode(['test_field' => 'test value'])
2425
])
2526
])
2627
]);
27-
$api = new PackagistAPI($http_client);
28+
$api = new PackagistAPI($http_client, STDERR);
2829

2930
//act
3031
$package_info = $api->getPackageInfo('vendor_name/package_name');
@@ -38,12 +39,13 @@ public function testCanGetPackageInfo()
3839
//arrange
3940
$http_client = Mockery::mock(ClientInterface::class, [
4041
'request' => Mockery::mock(ResponseInterface::class, [
41-
'getBody' => Mockery::mock(StreamInterface::class, [
42+
'getStatusCode' => 200,
43+
'getBody' => Mockery::mock(StreamInterface::class, [
4244
'getContents' => json_encode(['test_field' => 'test value'])
4345
])
4446
])
4547
]);
46-
$api = new PackagistAPI($http_client);
48+
$api = new PackagistAPI($http_client, STDERR);
4749

4850
//act
4951
$package_info = $api->getPackageInfo('vendor_name/package_name');
@@ -52,22 +54,23 @@ public function testCanGetPackageInfo()
5254
$this->assertEquals('test value', $package_info['test_field']);
5355
}
5456

55-
public function testCanHandleBadResponse()
56-
{
57-
//arrange
58-
$http_client = Mockery::mock(ClientInterface::class, [
59-
'request' => Mockery::mock(ResponseInterface::class, [
60-
'getBody' => Mockery::mock(StreamInterface::class, [
61-
'getContents' => '<html>This is not valid JSON</html>'
62-
])
63-
])
64-
]);
65-
$api = new PackagistAPI($http_client);
57+
public function testCanHandleBadResponse()
58+
{
59+
//arrange
60+
$http_client = Mockery::mock(ClientInterface::class, [
61+
'request' => Mockery::mock(ResponseInterface::class, [
62+
'getStatusCode' => 200,
63+
'getBody' => Mockery::mock(StreamInterface::class, [
64+
'getContents' => '<html>This is not valid JSON</html>'
65+
])
66+
])
67+
]);
68+
$api = new PackagistAPI($http_client, STDERR);
6669

67-
//act
68-
$package_info = $api->getPackageInfo('vendor_name/package_name');
70+
//act
71+
$package_info = $api->getPackageInfo('vendor_name/package_name');
6972

70-
//assert
71-
$this->assertEquals([], $package_info);
72-
}
73+
//assert
74+
$this->assertEquals([], $package_info);
75+
}
7376
}

0 commit comments

Comments
 (0)