Skip to content

Commit

Permalink
Convert commands to use constructors to handle initial command creation.
Browse files Browse the repository at this point in the history
Removes the "handle" method which prevented the use of promoted constructor properties.

Also converted some enumerated values to PHP enums.
  • Loading branch information
bennothommo committed Apr 9, 2024
1 parent 0770bc1 commit 52307f2
Show file tree
Hide file tree
Showing 16 changed files with 197 additions and 241 deletions.
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ composer require winter/packager

This library currently provides support for the following Composer commands:

- `version` **(--version)**
- `install`
- `update`
- `search`
- `show`
- `update`
- `version` **(--version)**

You can create a `Composer` instance in your PHP script and run these commands like so, defining a working directory which contains a `composer.json` file, and a home directory in which cached packages are stored.

Expand All @@ -42,12 +43,18 @@ $composer
// Get the Composer version
$version = $composer->version();

// Run an install or update
// Run an install or update on the entire project, including dev dependencies
$install = $composer->install();
$update = $composer->update();

// Install project without dev dependencies
$install = $composer->install(false);

// Show installed packages
$show = $composer->show();

// Search packages
$results =
```

Documentation on each command will be forthcoming soon.
Expand Down
42 changes: 28 additions & 14 deletions src/Commands/BaseCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,25 @@ abstract class BaseCommand implements Command
*
* Defines the Composer instance that will run the command.
*
* @param Composer $composer
* @param Composer $composer Composer instance
*/
public function __construct(Composer $composer)
{
$this->composer = $composer;
}

/**
* Make a new instance of the command.
*
* @param \Winter\Packager\Composer $composer
* @param mixed[] $args
*/
public static function make(Composer $composer, mixed ...$args): static
{
/* @phpstan-ignore-next-line */
return new static($composer, ...$args);
}

/**
* Returns the instance of Composer that is running the command.
*
Expand All @@ -56,20 +68,25 @@ public function getComposer(): Composer
}

/**
* @inheritDoc
* Provides the command name for Composer.
*
* @return string
*/
public function getCommandName(): string
{
return '';
}
abstract protected function getCommandName(): string;

/**
* @inheritDoc
* Provides if the given command requires the working directory to be available.
*
* @return bool True if it does, false if it does not.
*/
public function requiresWorkDir(): bool
{
return false;
}
abstract protected function requiresWorkDir(): bool;

/**
* Provides the arguments for the wrapped Composer command.
*
* @return array<string|int,string|int|bool|null> An array of arguments to provide the Composer application.
*/
abstract protected function arguments(): array;

/**
* Sets up the environment and creates the Composer application.
Expand Down Expand Up @@ -158,9 +175,6 @@ protected function runComposerCommand(): array
'output' => preg_split('/(\n|\r\n)/', $e->getMessage()),
'exception' => $e,
];
} finally {
// Restores the error handler away from Composer's in-built error handler
restore_error_handler();
}

$this->tearDownComposerApp();
Expand Down
21 changes: 0 additions & 21 deletions src/Commands/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,4 @@ interface Command
* @return mixed The output of the command.
*/
public function execute();

/**
* Provides the command name for Composer.
*
* @return string
*/
public function getCommandName(): string;

/**
* Provides if the given command requires the working directory to be available.
*
* @return bool True if it does, false if it does not.
*/
public function requiresWorkDir(): bool;

/**
* Provides the arguments for the wrapped Composer command.
*
* @return array<string|int,string|int|bool|null> An array of arguments to provide the Composer application.
*/
public function arguments(): array;
}
2 changes: 1 addition & 1 deletion src/Commands/Install.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Install extends Update
/**
* @inheritDoc
*/
public function getCommandName(): string
protected function getCommandName(): string
{
return 'install';
}
Expand Down
54 changes: 17 additions & 37 deletions src/Commands/Search.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,42 +16,22 @@
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:
* Command constructor.
*
* - `name`: Search and return package names only
* - `vendor`: Search and return vendors only
*
* @var string|null
* @param Composer $composer
* @param string $query The search query to find packages.
* @param string|null $type The type of package to search for.
* @param string|null $limitTo Limit the search parameters. This can be one of the following:
* - `name`: Search and return package names only
* - `vendor`: Search and return vendors only
*/
public ?string $limitTo = null;

/**
* 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';
}
final public function __construct(
Composer $composer,
public string $query,
public ?string $type = null,
public ?string $limitTo = null
) {
parent::__construct($composer);
}

/**
Expand Down Expand Up @@ -84,23 +64,23 @@ public function execute()
/**
* @inheritDoc
*/
public function getCommandName(): string
protected function getCommandName(): string
{
return 'search';
}

/**
* @inheritDoc
*/
public function requiresWorkDir(): bool
protected function requiresWorkDir(): bool
{
return false;
}

/**
* @inheritDoc
*/
public function arguments(): array
protected function arguments(): array
{
$arguments = [];

Expand Down
92 changes: 23 additions & 69 deletions src/Commands/Show.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Winter\Packager\Commands;

use Winter\Packager\Composer;
use Winter\Packager\Enums\ShowMode;
use Winter\Packager\Enums\VersionStatus;
use Winter\Packager\Exceptions\CommandException;

Expand All @@ -17,67 +18,21 @@
class Show extends BaseCommand
{
/**
* Mode to run the command against
*/
public string $mode = 'installed';

/**
* Individual package to search
*/
public ?string $package;

/**
* Exclude dev dependencies from search
*/
public bool $noDev = false;

/**
* Command handler.
* Command constructor.
*
* The mode can be one of the following:
* - `installed`: Show installed packages
* - `locked`: Show locked packages
* - `platform`: Show platform requirements
* - `available`: Show all available packages
* - `self`: Show the current package
* - `path`: Show the package path
* - `tree`: Show packages in a dependency tree
* - `outdated`: Show only outdated packages
* - `direct`: Show only direct dependencies
*
* @param string|null $mode
* @param string|null $package
* @param boolean $noDev
* @param Composer $composer Composer instance
* @param ShowMode $mode Mode to run the command against
* @param string|null $package Individual package to search
* @param boolean $noDev Exclude dev dependencies from search
* @return void
*/
public function handle(?string $mode = 'installed', string $package = null, bool $noDev = false): void
{
$mode = $mode ?? 'installed';

$validModes = [
'installed',
'locked',
'platform',
'available',
'self',
'path',
'tree',
'outdated',
'direct'
];

if (!in_array(strtolower($mode), $validModes)) {
throw new CommandException(
sprintf(
'Invalid mode, must be one of the following: %s',
implode(', ', $validModes)
)
);
}

$this->mode = $mode;
$this->package = $package;
$this->noDev = $noDev;
final public function __construct(
Composer $composer,
public ShowMode $mode = ShowMode::INSTALLED,
public ?string $package = null,
public bool $noDev = false
) {
parent::__construct($composer);
}

/**
Expand All @@ -103,10 +58,9 @@ public function execute()
$results = json_decode(implode(PHP_EOL, $output['output']), true);
$packages = [];

if (is_null($this->package) && in_array($this->mode, ['installed', 'locked', 'platform', 'path', 'outdated', 'direct'])) {
if (is_null($this->package) && $this->mode->isCollectible()) {
// Convert packages in simple lists to a package collection
$key = (!in_array($this->mode, ['locked', 'platform'])) ? 'installed' : $this->mode;
$results = $results[$key];
$results = $results[$this->mode->getComposerArrayKeyName()];

foreach ($results as $result) {
[$namespace, $name] = $this->nameSplit($result['name']);
Expand All @@ -130,9 +84,9 @@ public function execute()
}

return Composer::newCollection($packages);
} elseif (is_null($this->package) && $this->mode === 'available') {
} elseif (is_null($this->package) && $this->mode === ShowMode::AVAILABLE) {
// Convert entire available package list into a package collection
foreach ($results['available'] as $result) {
foreach ($results[$this->mode->getComposerArrayKeyName()] as $result) {
[$namespace, $name] = $this->nameSplit($result['name']);

$packages[] = Composer::newPackage(
Expand All @@ -143,7 +97,7 @@ public function execute()
}

return Composer::newCollection($packages);
} elseif ($this->mode === 'self') {
} elseif ($this->mode === ShowMode::SELF) {
$result = $results;
[$namespace, $name] = $this->nameSplit($result['name']);

Expand Down Expand Up @@ -190,32 +144,32 @@ public function execute()
/**
* @inheritDoc
*/
public function getCommandName(): string
protected function getCommandName(): string
{
return 'show';
}

/**
* @inheritDoc
*/
public function requiresWorkDir(): bool
protected function requiresWorkDir(): bool
{
return true;
}

/**
* @inheritDoc
*/
public function arguments(): array
protected function arguments(): array
{
$arguments = [];

if (!empty($this->package)) {
$arguments['package'] = $this->package;
}

if ($this->mode !== 'installed') {
$arguments['--' . $this->mode] = true;
if ($this->mode !== ShowMode::INSTALLED) {
$arguments['--' . $this->mode->value] = true;
}

if ($this->noDev) {
Expand Down
Loading

0 comments on commit 52307f2

Please sign in to comment.