diff --git a/examples/user-repositories-releases-async.php b/examples/user-repositories-releases-async.php new file mode 100644 index 0000000000..e9839d24ad --- /dev/null +++ b/examples/user-repositories-releases-async.php @@ -0,0 +1,29 @@ +user($argv[1] ?? 'php-api-clients')->then(function (User $user) use ($argv) { + resource_pretty_print($user); + + return $user->repository($argv[2] ?? 'github'); +})->then(function (Repository $repository) { + resource_pretty_print($repository, 1, true); + $repository->releases()->subscribe(function ($release) { + resource_pretty_print($release, 2, true); + }, function ($error) { + echo (string)$error; + }); +})->done(null, 'display_throwable'); + +$loop->run(); + +displayState($client->getRateLimitState()); diff --git a/examples/user-repositories-tags-async.php b/examples/user-repositories-tags-async.php new file mode 100644 index 0000000000..45bc8f3ee2 --- /dev/null +++ b/examples/user-repositories-tags-async.php @@ -0,0 +1,29 @@ +user($argv[1] ?? 'php-api-clients')->then(function (User $user) use ($argv) { + resource_pretty_print($user); + + return $user->repository($argv[2] ?? 'github'); +})->then(function (Repository $repository) { + resource_pretty_print($repository, 1, true); + $repository->tags()->subscribe(function ($tag) { + resource_pretty_print($tag, 2, true); + }, function ($error) { + echo (string)$error; + }); +})->done(null, 'display_throwable'); + +$loop->run(); + +displayState($client->getRateLimitState()); diff --git a/src/CommandBus/Command/Repository/ReleasesCommand.php b/src/CommandBus/Command/Repository/ReleasesCommand.php new file mode 100644 index 0000000000..8ffc828295 --- /dev/null +++ b/src/CommandBus/Command/Repository/ReleasesCommand.php @@ -0,0 +1,32 @@ +fullName = $fullName; + } + + /** + * @return string + */ + public function getFullName(): string + { + return $this->fullName; + } +} diff --git a/src/CommandBus/Command/Repository/TagsCommand.php b/src/CommandBus/Command/Repository/TagsCommand.php new file mode 100644 index 0000000000..368077771c --- /dev/null +++ b/src/CommandBus/Command/Repository/TagsCommand.php @@ -0,0 +1,32 @@ +fullName = $fullName; + } + + /** + * @return string + */ + public function getFullName(): string + { + return $this->fullName; + } +} diff --git a/src/CommandBus/Handler/Repository/ReleasesHandler.php b/src/CommandBus/Handler/Repository/ReleasesHandler.php new file mode 100644 index 0000000000..835634c7bf --- /dev/null +++ b/src/CommandBus/Handler/Repository/ReleasesHandler.php @@ -0,0 +1,51 @@ +iteratePagesService = $iteratePagesService; + $this->hydrator = $hydrator; + } + + /** + * @param TagsCommand $command + * @return PromiseInterface + */ + public function handle(ReleasesCommand $command): PromiseInterface + { + return resolve( + $this->iteratePagesService->iterate('repos/' . $command->getFullName() . '/releases') + ->flatMap(function ($labels) { + return observableFromArray($labels); + })->map(function ($label) { + return $this->hydrator->hydrate(ReleaseInterface::HYDRATE_CLASS, $label); + }) + ); + } +} diff --git a/src/CommandBus/Handler/Repository/TagsHandler.php b/src/CommandBus/Handler/Repository/TagsHandler.php new file mode 100644 index 0000000000..ab2bc669a2 --- /dev/null +++ b/src/CommandBus/Handler/Repository/TagsHandler.php @@ -0,0 +1,50 @@ +iteratePagesService = $iteratePagesService; + $this->hydrator = $hydrator; + } + + /** + * @param TagsCommand $command + * @return PromiseInterface + */ + public function handle(TagsCommand $command): PromiseInterface + { + return resolve( + $this->iteratePagesService->iterate('repos/' . $command->getFullName() . '/tags') + ->flatMap(function ($labels) { + return observableFromArray($labels); + })->map(function ($label) { + return $this->hydrator->hydrate(TagInterface::HYDRATE_CLASS, $label); + }) + ); + } +} diff --git a/src/Resource/Async/Repository.php b/src/Resource/Async/Repository.php index a1c2746390..af1a229b57 100644 --- a/src/Resource/Async/Repository.php +++ b/src/Resource/Async/Repository.php @@ -9,6 +9,8 @@ use ApiClients\Client\Github\CommandBus\Command\Repository\CommunityHealthCommand; use ApiClients\Client\Github\CommandBus\Command\Repository\ContentsCommand; use ApiClients\Client\Github\CommandBus\Command\Repository\LabelsCommand; +use ApiClients\Client\Github\CommandBus\Command\Repository\ReleasesCommand; +use ApiClients\Client\Github\CommandBus\Command\Repository\TagsCommand; use ApiClients\Client\Github\Resource\Repository as BaseRepository; use React\Promise\PromiseInterface; use Rx\Observable; @@ -67,4 +69,18 @@ public function communityHealth(): PromiseInterface new CommunityHealthCommand($this->fullName()) ); } + + public function tags(): ObservableInterface + { + return unwrapObservableFromPromise($this->handleCommand( + new TagsCommand($this->fullName()) + )); + } + + public function releases(): ObservableInterface + { + return unwrapObservableFromPromise($this->handleCommand( + new ReleasesCommand($this->fullName()) + )); + } } diff --git a/src/Resource/Async/Repository/EmptyRelease.php b/src/Resource/Async/Repository/EmptyRelease.php new file mode 100644 index 0000000000..c6c8686c2a --- /dev/null +++ b/src/Resource/Async/Repository/EmptyRelease.php @@ -0,0 +1,9 @@ +id; + } + + /** + * @return string + */ + public function tagName(): string + { + return $this->tag_name; + } + + /** + * @return string + */ + public function targetCommitish(): string + { + return $this->target_commitish; + } + + /** + * @return string + */ + public function name(): string + { + return $this->name; + } + + /** + * @return string + */ + public function body(): string + { + return $this->body; + } + + /** + * @return bool + */ + public function draft(): bool + { + return $this->draft; + } + + /** + * @return bool + */ + public function prerelease(): bool + { + return $this->prerelease; + } + + /** + * @return DateTimeInterface + */ + public function createdAt(): DateTimeInterface + { + return $this->created_at; + } + + /** + * @return DateTimeInterface + */ + public function updatedAt(): DateTimeInterface + { + return $this->updated_at; + } + + /** + * @return User + */ + public function author(): User + { + return $this->author; + } + + /** + * @return array + */ + public function assets(): array + { + return $this->assets; + } +} diff --git a/src/Resource/Repository/Release/Asset.php b/src/Resource/Repository/Release/Asset.php new file mode 100644 index 0000000000..c9a84a5154 --- /dev/null +++ b/src/Resource/Repository/Release/Asset.php @@ -0,0 +1,173 @@ +url; + } + + /** + * @return string + */ + public function browserDownloadUrl(): string + { + return $this->browser_download_url; + } + + /** + * @return int + */ + public function id(): int + { + return $this->id; + } + + /** + * @return string + */ + public function name(): string + { + return $this->name; + } + + /** + * @return string + */ + public function label(): string + { + return $this->label; + } + + /** + * @return string + */ + public function state(): string + { + return $this->state; + } + + /** + * @return string + */ + public function contentType(): string + { + return $this->content_type; + } + + /** + * @return int + */ + public function size(): int + { + return $this->size; + } + + /** + * @return int + */ + public function downloadCount(): int + { + return $this->download_count; + } + + /** + * @return DateTimeInterface + */ + public function createdAt(): DateTimeInterface + { + return $this->created_at; + } + + /** + * @return DateTimeInterface + */ + public function updatedAt(): DateTimeInterface + { + return $this->updated_at; + } + + /** + * @return User + */ + public function uploader(): User + { + return $this->uploader; + } +} diff --git a/src/Resource/Repository/Release/AssetInterface.php b/src/Resource/Repository/Release/AssetInterface.php new file mode 100644 index 0000000000..243c3e5a47 --- /dev/null +++ b/src/Resource/Repository/Release/AssetInterface.php @@ -0,0 +1,71 @@ +name; + } + + /** + * @return Tree + */ + public function commit(): Tree + { + return $this->commit; + } + + /** + * @return string + */ + public function zipballUrl(): string + { + return $this->zipball_url; + } + + /** + * @return string + */ + public function tarballUrl(): string + { + return $this->tarball_url; + } +} diff --git a/src/Resource/Repository/TagInterface.php b/src/Resource/Repository/TagInterface.php new file mode 100644 index 0000000000..4a4db387b9 --- /dev/null +++ b/src/Resource/Repository/TagInterface.php @@ -0,0 +1,30 @@ +wait($this->handleCommand( + new BuildAsyncFromSyncCommand(self::HYDRATE_CLASS, $this) + )->then(function (ReleaseInterface $release) { + return $release->refresh(); + })); + } +} diff --git a/src/Resource/Sync/Repository/Release/Asset.php b/src/Resource/Sync/Repository/Release/Asset.php new file mode 100644 index 0000000000..e20a964503 --- /dev/null +++ b/src/Resource/Sync/Repository/Release/Asset.php @@ -0,0 +1,19 @@ +wait($this->handleCommand( + new BuildAsyncFromSyncCommand(self::HYDRATE_CLASS, $this) + )->then(function (AssetInterface $asset) { + return $asset->refresh(); + })); + } +} diff --git a/src/Resource/Sync/Repository/Release/EmptyAsset.php b/src/Resource/Sync/Repository/Release/EmptyAsset.php new file mode 100644 index 0000000000..677ded1a3b --- /dev/null +++ b/src/Resource/Sync/Repository/Release/EmptyAsset.php @@ -0,0 +1,9 @@ +wait( + $this->handleCommand( + new BuildAsyncFromSyncCommand(self::HYDRATE_CLASS, $this) + )->then(function (TagInterface $tag) { + return $tag->refresh(); + }) + ); + } +} diff --git a/tests/CommandBus/Handler/Repository/TagsHandlerTest.php b/tests/CommandBus/Handler/Repository/TagsHandlerTest.php new file mode 100644 index 0000000000..24a5746fcc --- /dev/null +++ b/tests/CommandBus/Handler/Repository/TagsHandlerTest.php @@ -0,0 +1,41 @@ + 'bar', + ]; + $tag = $this->prophesize(Tag::class)->reveal(); + + $command = new TagsCommand('api-clients/github'); + + $iteratePagesService = $this->prophesize(IteratePagesService::class); + $iteratePagesService->iterate('repos/api-clients/github/tags') + ->shouldBeCalled() + ->willReturn(Observable::fromArray([[$tagArray]])); + + $hydrator = $this->prophesize(Hydrator::class); + $hydrator->hydrate(TagInterface::HYDRATE_CLASS, $tagArray)->shouldBeCalled()->wilLReturn($tag); + + $tagsHandler = new TagsHandler( + $iteratePagesService->reveal(), + $hydrator->reveal() + ); + + self::assertSame($tag, $this->await(Promise::fromObservable($this->await($tagsHandler->handle($command))))); + } +} diff --git a/tests/Resource/Async/Repository/EmptyReleaseTest.php b/tests/Resource/Async/Repository/EmptyReleaseTest.php new file mode 100644 index 0000000000..1f6f1fffcc --- /dev/null +++ b/tests/Resource/Async/Repository/EmptyReleaseTest.php @@ -0,0 +1,19 @@ +