Skip to content

Commit 62c32fc

Browse files
committed
Update storage signature, add storage of package metadata
1 parent 7838979 commit 62c32fc

File tree

6 files changed

+158
-76
lines changed

6 files changed

+158
-76
lines changed

src/Composer.php

+12-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Winter\Packager\Package\Package;
1212
use Winter\Packager\Package\Packagist;
1313
use Winter\Packager\Package\VersionedPackage;
14+
use Winter\Packager\Storage\Storage;
1415

1516
/**
1617
* Represents a Composer instance.
@@ -467,8 +468,18 @@ public static function newConstraint(mixed ...$arguments): Constraint
467468
*
468469
* `Name or Reference <[email protected]>`
469470
*/
470-
public static function setAgent(string $agent): void
471+
public function setAgent(string $agent): static
471472
{
472473
Packagist::setAgent($agent);
474+
return $this;
475+
}
476+
477+
/**
478+
* Sets the metadata storage for Packagist requests.
479+
*/
480+
public function setStorage(Storage $storage): static
481+
{
482+
Packagist::setStorage($storage);
483+
return $this;
473484
}
474485
}

src/Package/Packagist.php

+39-18
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Psr\Http\Client\ClientInterface;
1010
use Psr\Http\Message\RequestInterface;
1111
use Winter\Packager\Exceptions\PackagistException;
12+
use Winter\Packager\Storage\Storage;
1213

1314
/**
1415
* Packagist class.
@@ -27,13 +28,22 @@ class Packagist
2728

2829
protected static string $agent = 'Winter Packager <[email protected]>';
2930

31+
protected static ?Storage $storage = null;
32+
3033
/**
3134
* Get information on a package in the Packagist API.
3235
*
3336
* @return array<string, mixed>
3437
*/
35-
public static function getPackage(string $namespace, string $name, ?string $version = null): array
36-
{
38+
public static function getPackage(
39+
string $namespace,
40+
string $name,
41+
?string $version = null
42+
): array {
43+
if (!is_null(static::$storage) && static::$storage->has($namespace, $name, $version)) {
44+
return static::$storage->get($namespace, $name, $version);
45+
}
46+
3747
$client = static::getClient();
3848
$request = static::newRepoRequest($namespace . '/' . $name . '.json');
3949

@@ -49,29 +59,32 @@ public static function getPackage(string $namespace, string $name, ?string $vers
4959

5060
$body = json_decode($response->getBody()->getContents(), true);
5161

52-
if (is_null($version)) {
53-
if (!isset($body['packages'][$namespace . '/' . $name][0])) {
54-
throw new PackagistException('Package information not found');
55-
}
56-
} else {
57-
if (!isset($body['packages'][$namespace . '/' . $name])) {
58-
throw new PackagistException('Package information not found');
59-
}
62+
if (!isset($body['packages'][$namespace . '/' . $name])) {
63+
throw new PackagistException('Package information not found');
64+
}
6065

61-
$versions = MetadataMinifier::expand($body['packages'][$namespace . '/' . $name]);
62-
$parser = new VersionParser;
63-
$packageVersionNormalized = $parser->normalize($version);
66+
$versions = [];
67+
foreach (MetadataMinifier::expand($body['packages'][$namespace . '/' . $name]) as $packageVersion) {
68+
$versions[$packageVersion['version_normalized']] = $packageVersion;
6469

65-
foreach ($versions as $packageVersion) {
66-
if ($packageVersion['version_normalized'] === $packageVersionNormalized) {
67-
return $packageVersion;
68-
}
70+
// Store metadata
71+
if (!is_null(static::$storage)) {
72+
static::$storage->set($namespace, $name, $packageVersion['version_normalized'], $packageVersion);
6973
}
74+
}
7075

76+
if (is_null($version)) {
77+
return reset($versions);
78+
}
79+
80+
$parser = new VersionParser;
81+
$versionNormalized = $parser->normalize($version);
82+
83+
if (!array_key_exists($versionNormalized, $versions)) {
7184
throw new PackagistException('Package version not found');
7285
}
7386

74-
return $body['packages'][$namespace . '/' . $name][0];
87+
return $versions[$versionNormalized];
7588
}
7689

7790
public static function getClient(): ClientInterface
@@ -104,6 +117,14 @@ public static function setAgent(string $agent): void
104117
static::$agent = trim($name) . ' <' . trim($email) . '>';
105118
}
106119

120+
/**
121+
* Sets the storage for metadata.
122+
*/
123+
public static function setStorage(?Storage $storage = null): void
124+
{
125+
static::$storage = $storage;
126+
}
127+
107128
public static function newApiRequest(string $url = ''): RequestInterface
108129
{
109130
$request = Psr17FactoryDiscovery::findRequestFactory()->createRequest('GET', self::PACKAGIST_API_URL . ltrim($url, '/'));

src/Storage/Memory.php

+18-13
Original file line numberDiff line numberDiff line change
@@ -37,58 +37,58 @@ public function __construct(?VersionParser $versionParser = null)
3737
/**
3838
* {@inheritDoc}
3939
*/
40-
public function get(string $package, ?string $version = null): ?array
40+
public function get(string $namespace, string $name, ?string $version = null): ?array
4141
{
4242
if (isset($version)) {
4343
$versionNormalized = $this->versionParser->normalize($version);
4444

45-
return $this->packages[$package][$versionNormalized] ?? null;
45+
return $this->packages[$this->packageName($namespace, $name)][$versionNormalized] ?? null;
4646
}
4747

48-
return $this->packages[$package] ?? null;
48+
return $this->packages[$this->packageName($namespace, $name)] ?? null;
4949
}
5050

5151
/**
5252
* {@inheritDoc}
5353
*/
54-
public function set(string $package, string $version, array $packageData): void
54+
public function set(string $namespace, string $name, string $version, array $packageData): void
5555
{
56-
if (!isset($this->packages[$package])) {
57-
$this->packages[$package] = [];
56+
if (!isset($this->packages[$this->packageName($namespace, $name)])) {
57+
$this->packages[$this->packageName($namespace, $name)] = [];
5858
}
5959

6060
$versionNormalized = $this->versionParser->normalize($version);
6161

62-
$this->packages[$package][$versionNormalized] = $packageData;
62+
$this->packages[$this->packageName($namespace, $name)][$versionNormalized] = $packageData;
6363
}
6464

6565
/**
6666
* {@inheritDoc}
6767
*/
68-
public function forget(string $package, ?string $version = null): void
68+
public function forget(string $namespace, string $name, ?string $version = null): void
6969
{
7070
if (isset($version)) {
7171
$versionNormalized = $this->versionParser->normalize($version);
7272

73-
unset($this->packages[$package][$versionNormalized]);
73+
unset($this->packages[$this->packageName($namespace, $name)][$versionNormalized]);
7474
return;
7575
}
7676

77-
unset($this->packages[$package]);
77+
unset($this->packages[$this->packageName($namespace, $name)]);
7878
}
7979

8080
/**
8181
* {@inheritDoc}
8282
*/
83-
public function has(string $package, ?string $version = null): bool
83+
public function has(string $namespace, string $name, ?string $version = null): bool
8484
{
8585
if (isset($version)) {
8686
$versionNormalized = $this->versionParser->normalize($version);
8787

88-
return isset($this->packages[$package][$versionNormalized]);
88+
return isset($this->packages[$this->packageName($namespace, $name)][$versionNormalized]);
8989
}
9090

91-
return isset($this->packages[$package]);
91+
return isset($this->packages[$this->packageName($namespace, $name)]);
9292
}
9393

9494
/**
@@ -98,4 +98,9 @@ public function clear(): void
9898
{
9999
$this->packages = [];
100100
}
101+
102+
protected function packageName(string $namespace, string $name): string
103+
{
104+
return $namespace . '/' . $name;
105+
}
101106
}

src/Storage/Storage.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ interface Storage
2222
*
2323
* @return array<string|int, mixed>|null
2424
*/
25-
public function get(string $package, ?string $version = null): ?array;
25+
public function get(string $namespace, string $name, ?string $version = null): ?array;
2626

2727
/**
2828
* Sets the package metadata for the given package name and version.
2929
*
3030
* @param array<string, mixed> $packageData
3131
*/
32-
public function set(string $packageName, string $version, array $packageData): void;
32+
public function set(string $namespace, string $name, string $version, array $packageData): void;
3333

3434
/**
3535
* Forgets the package metadata for the given package name.
@@ -39,12 +39,12 @@ public function set(string $packageName, string $version, array $packageData): v
3939
*
4040
* This should be a no-op if the package metadata does not exist.
4141
*/
42-
public function forget(string $package, ?string $version = null): void;
42+
public function forget(string $namespace, string $name, ?string $version = null): void;
4343

4444
/**
4545
* Determines if the package metadata exists in storage, optionally with the specified version.
4646
*/
47-
public function has(string $package, ?string $version = null): bool;
47+
public function has(string $namespace, string $name, ?string $version = null): bool;
4848

4949
/**
5050
* Clears all package metadata.

tests/Cases/Package/PackageTest.php

+45
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Winter\Packager\Tests\Cases\Package;
66

77
use Winter\Packager\Composer;
8+
use Winter\Packager\Package\Packagist;
89
use Winter\Packager\Tests\ComposerTestCase;
910

1011
/**
@@ -53,4 +54,48 @@ public function itCanConvertAVersionedPackageToADetailedPackage()
5354
$this->assertEquals('pages', $package->getExtras()['installer-name']);
5455
$this->assertEquals('2.0.3.0', $package->getVersionNormalized());
5556
}
57+
58+
/**
59+
* @test
60+
* @testdox it can store and retrieve a package from storage
61+
* @covers \Winter\Packager\Package\VersionedPackage::toDetailed
62+
*/
63+
public function itCanStoreAndRetrieveAPackageFromStorage()
64+
{
65+
$proxy = new \Winter\Packager\Storage\Memory;
66+
$storage = $this->getMockBuilder(\Winter\Packager\Storage\Memory::class)
67+
->setProxyTarget($proxy)
68+
->enableProxyingToOriginalMethods()
69+
->getMock();
70+
71+
Packagist::setStorage($storage);
72+
73+
$storage->expects($this->atLeastOnce())
74+
->method('set')
75+
->with('winter', 'wn-pages-plugin', $this->anything(), $this->anything());
76+
77+
$package = Composer::newVersionedPackage('winter', 'wn-pages-plugin', '', 'v2.0.3');
78+
$package = $package->toDetailed();
79+
80+
$storage->expects($this->once())
81+
->method('has')
82+
->with('winter', 'wn-pages-plugin', 'v2.0.3');
83+
84+
$storage->expects($this->once())
85+
->method('get')
86+
->with('winter', 'wn-pages-plugin', 'v2.0.3');
87+
88+
$package = Composer::newVersionedPackage('winter', 'wn-pages-plugin', '', 'v2.0.3');
89+
$package = $package->toDetailed();
90+
91+
$this->assertInstanceOf(\Winter\Packager\Package\DetailedVersionedPackage::class, $package);
92+
$this->assertEquals('winter', $package->getNamespace());
93+
$this->assertEquals('wn-pages-plugin', $package->getName());
94+
$this->assertEquals('winter-plugin', $package->getType());
95+
$this->assertEquals('https://github.com/wintercms/wn-pages-plugin', $package->getHomepage());
96+
$this->assertArrayHasKey('installer-name', $package->getExtras());
97+
$this->assertArrayNotHasKey('winter', $package->getExtras());
98+
$this->assertEquals('pages', $package->getExtras()['installer-name']);
99+
$this->assertEquals('2.0.3.0', $package->getVersionNormalized());
100+
}
56101
}

0 commit comments

Comments
 (0)