-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d113b26
commit a790af3
Showing
5 changed files
with
235 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
<?php | ||
|
||
namespace Winter\Packager\Commands; | ||
|
||
use Winter\Packager\Exceptions\CommandException; | ||
|
||
/** | ||
* Search command. | ||
* | ||
* Runs "composer search" within PHP. | ||
* | ||
* @author Ben Thomson | ||
* @since 0.2.0 | ||
*/ | ||
class Search extends BaseCommand | ||
{ | ||
/** | ||
* The search query to find packages. | ||
*/ | ||
public string $query; | ||
|
||
/** | ||
* The type of package to search for. | ||
*/ | ||
public ?string $type = null; | ||
|
||
/** | ||
* Limit the search parameters. This can be one of the following: | ||
* | ||
* - `name`: Search and return package names only | ||
* - `vendor`: Search and return vendors only | ||
* | ||
* @var string|null | ||
*/ | ||
public ?string $limitTo = null; | ||
|
||
/** | ||
* @var array<int, mixed> The results returned from the query. | ||
*/ | ||
public array $results = []; | ||
|
||
/** | ||
* Command handler. | ||
*/ | ||
public function handle( | ||
string $query, | ||
?string $type = null, | ||
bool $onlyNames = false, | ||
bool $onlyVendors = false | ||
): void { | ||
$this->query = $query; | ||
$this->type = $type; | ||
|
||
if ($onlyNames) { | ||
$this->limitTo = 'name'; | ||
} elseif ($onlyVendors) { | ||
$this->limitTo = 'vendor'; | ||
} | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function execute() | ||
{ | ||
$output = $this->runComposerCommand(); | ||
|
||
if ($output['code'] !== 0) { | ||
throw new CommandException(implode(PHP_EOL, $output['output'])); | ||
} | ||
|
||
$this->results = json_decode(implode(PHP_EOL, $output['output']), true); | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function getCommandName(): string | ||
{ | ||
return 'search'; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function requiresWorkDir(): bool | ||
{ | ||
return false; | ||
} | ||
|
||
/** | ||
* Returns the list of results found. | ||
* | ||
* @return array<int, mixed> | ||
*/ | ||
public function getResults(): array | ||
{ | ||
return $this->results; | ||
} | ||
|
||
/** | ||
* Returns the number of results found. | ||
*/ | ||
public function count(): int | ||
{ | ||
return count($this->results); | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function arguments(): array | ||
{ | ||
$arguments = []; | ||
|
||
if (!empty($this->type)) { | ||
$arguments['--type'] = $this->type; | ||
} | ||
|
||
if ($this->limitTo === 'name') { | ||
$arguments['--only-name'] = true; | ||
} elseif ($this->limitTo === 'vendor') { | ||
$arguments['--only-vendor'] = true; | ||
} | ||
|
||
$arguments['--format'] = 'json'; | ||
|
||
$arguments['tokens'] = preg_split('/ +/', $this->query, -1, PREG_SPLIT_NO_EMPTY); | ||
|
||
return $arguments; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Winter\Packager\Tests\Cases; | ||
|
||
use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts; | ||
use Winter\Packager\Commands\Search; | ||
use Winter\Packager\Tests\ComposerTestCase; | ||
|
||
/** | ||
* @testdox The Search command | ||
* @coversDefaultClass \Winter\Packager\Commands\Search | ||
*/ | ||
final class SearchTest extends ComposerTestCase | ||
{ | ||
use ArraySubsetAsserts; | ||
|
||
/** | ||
* @test | ||
* @testdox can run a (mocked) search and show a few results. | ||
* @covers ::handle | ||
* @covers ::execute | ||
* @covers ::getResults | ||
* @covers ::count | ||
*/ | ||
public function itCanRunAMockedSearch(): void | ||
{ | ||
$this->mockCommandOutput( | ||
'search', | ||
Search::class, | ||
0, | ||
json_encode([ | ||
[ | ||
'name' => 'winter/wn-system-module', | ||
'description' => 'System module for Winter CMS', | ||
'url' => 'https://packagist.org/packages/winter/wn-system-module', | ||
'repository' => 'https://github.com/wintercms/wn-system-module', | ||
], | ||
[ | ||
'name' => 'winter/wn-cms-module', | ||
'description' => 'CMS module for Winter CMS', | ||
'url' => 'https://packagist.org/packages/winter/wn-cms-module', | ||
'repository' => 'https://github.com/wintercms/wn-cms-module', | ||
], | ||
[ | ||
'name' => 'winter/wn-backend-module', | ||
'description' => 'Backend module for Winter CMS', | ||
'url' => 'https://packagist.org/packages/winter/wn-backend-module', | ||
'repository' => 'https://github.com/wintercms/wn-backend-module', | ||
], | ||
], JSON_PRETTY_PRINT) | ||
); | ||
|
||
$search = $this->composer->search('winter', 'winter-module'); | ||
|
||
$this->assertArraySubset([ | ||
[ | ||
'name' => 'winter/wn-system-module', | ||
], | ||
[ | ||
'name' => 'winter/wn-cms-module', | ||
], | ||
[ | ||
'name' => 'winter/wn-backend-module', | ||
], | ||
], $search->getResults()); | ||
$this->assertEquals(3, $search->count()); | ||
} | ||
|
||
/** | ||
* @test | ||
* @testdox can run a real search and show a few results. | ||
* @covers ::handle | ||
* @covers ::execute | ||
* @covers ::getResults | ||
* @covers ::count | ||
*/ | ||
public function itCanRunRealSearch(): void | ||
{ | ||
$search = $this->composer->search('winter', 'winter-module'); | ||
|
||
$this->assertArraySubset([ | ||
[ | ||
'name' => 'winter/wn-system-module', | ||
], | ||
[ | ||
'name' => 'winter/wn-cms-module', | ||
], | ||
[ | ||
'name' => 'winter/wn-backend-module', | ||
], | ||
], $search->getResults()); | ||
$this->assertEquals(3, $search->count()); | ||
} | ||
} |