Skip to content

Commit 52307f2

Browse files
committed
Convert commands to use constructors to handle initial command creation.
Removes the "handle" method which prevented the use of promoted constructor properties. Also converted some enumerated values to PHP enums.
1 parent 0770bc1 commit 52307f2

File tree

16 files changed

+197
-241
lines changed

16 files changed

+197
-241
lines changed

README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ composer require winter/packager
2323

2424
This library currently provides support for the following Composer commands:
2525

26-
- `version` **(--version)**
2726
- `install`
28-
- `update`
27+
- `search`
2928
- `show`
29+
- `update`
30+
- `version` **(--version)**
3031

3132
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.
3233

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

45-
// Run an install or update
46+
// Run an install or update on the entire project, including dev dependencies
4647
$install = $composer->install();
4748
$update = $composer->update();
4849

50+
// Install project without dev dependencies
51+
$install = $composer->install(false);
52+
4953
// Show installed packages
5054
$show = $composer->show();
55+
56+
// Search packages
57+
$results =
5158
```
5259

5360
Documentation on each command will be forthcoming soon.

src/Commands/BaseCommand.php

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,25 @@ abstract class BaseCommand implements Command
3838
*
3939
* Defines the Composer instance that will run the command.
4040
*
41-
* @param Composer $composer
41+
* @param Composer $composer Composer instance
4242
*/
4343
public function __construct(Composer $composer)
4444
{
4545
$this->composer = $composer;
4646
}
4747

48+
/**
49+
* Make a new instance of the command.
50+
*
51+
* @param \Winter\Packager\Composer $composer
52+
* @param mixed[] $args
53+
*/
54+
public static function make(Composer $composer, mixed ...$args): static
55+
{
56+
/* @phpstan-ignore-next-line */
57+
return new static($composer, ...$args);
58+
}
59+
4860
/**
4961
* Returns the instance of Composer that is running the command.
5062
*
@@ -56,20 +68,25 @@ public function getComposer(): Composer
5668
}
5769

5870
/**
59-
* @inheritDoc
71+
* Provides the command name for Composer.
72+
*
73+
* @return string
6074
*/
61-
public function getCommandName(): string
62-
{
63-
return '';
64-
}
75+
abstract protected function getCommandName(): string;
6576

6677
/**
67-
* @inheritDoc
78+
* Provides if the given command requires the working directory to be available.
79+
*
80+
* @return bool True if it does, false if it does not.
6881
*/
69-
public function requiresWorkDir(): bool
70-
{
71-
return false;
72-
}
82+
abstract protected function requiresWorkDir(): bool;
83+
84+
/**
85+
* Provides the arguments for the wrapped Composer command.
86+
*
87+
* @return array<string|int,string|int|bool|null> An array of arguments to provide the Composer application.
88+
*/
89+
abstract protected function arguments(): array;
7390

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

166180
$this->tearDownComposerApp();

src/Commands/Command.php

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,4 @@ interface Command
1818
* @return mixed The output of the command.
1919
*/
2020
public function execute();
21-
22-
/**
23-
* Provides the command name for Composer.
24-
*
25-
* @return string
26-
*/
27-
public function getCommandName(): string;
28-
29-
/**
30-
* Provides if the given command requires the working directory to be available.
31-
*
32-
* @return bool True if it does, false if it does not.
33-
*/
34-
public function requiresWorkDir(): bool;
35-
36-
/**
37-
* Provides the arguments for the wrapped Composer command.
38-
*
39-
* @return array<string|int,string|int|bool|null> An array of arguments to provide the Composer application.
40-
*/
41-
public function arguments(): array;
4221
}

src/Commands/Install.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Install extends Update
1515
/**
1616
* @inheritDoc
1717
*/
18-
public function getCommandName(): string
18+
protected function getCommandName(): string
1919
{
2020
return 'install';
2121
}

src/Commands/Search.php

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,22 @@
1616
class Search extends BaseCommand
1717
{
1818
/**
19-
* The search query to find packages.
20-
*/
21-
public string $query;
22-
23-
/**
24-
* The type of package to search for.
25-
*/
26-
public ?string $type = null;
27-
28-
/**
29-
* Limit the search parameters. This can be one of the following:
19+
* Command constructor.
3020
*
31-
* - `name`: Search and return package names only
32-
* - `vendor`: Search and return vendors only
33-
*
34-
* @var string|null
21+
* @param Composer $composer
22+
* @param string $query The search query to find packages.
23+
* @param string|null $type The type of package to search for.
24+
* @param string|null $limitTo Limit the search parameters. This can be one of the following:
25+
* - `name`: Search and return package names only
26+
* - `vendor`: Search and return vendors only
3527
*/
36-
public ?string $limitTo = null;
37-
38-
/**
39-
* Command handler.
40-
*/
41-
public function handle(
42-
string $query,
43-
?string $type = null,
44-
bool $onlyNames = false,
45-
bool $onlyVendors = false
46-
): void {
47-
$this->query = $query;
48-
$this->type = $type;
49-
50-
if ($onlyNames) {
51-
$this->limitTo = 'name';
52-
} elseif ($onlyVendors) {
53-
$this->limitTo = 'vendor';
54-
}
28+
final public function __construct(
29+
Composer $composer,
30+
public string $query,
31+
public ?string $type = null,
32+
public ?string $limitTo = null
33+
) {
34+
parent::__construct($composer);
5535
}
5636

5737
/**
@@ -84,23 +64,23 @@ public function execute()
8464
/**
8565
* @inheritDoc
8666
*/
87-
public function getCommandName(): string
67+
protected function getCommandName(): string
8868
{
8969
return 'search';
9070
}
9171

9272
/**
9373
* @inheritDoc
9474
*/
95-
public function requiresWorkDir(): bool
75+
protected function requiresWorkDir(): bool
9676
{
9777
return false;
9878
}
9979

10080
/**
10181
* @inheritDoc
10282
*/
103-
public function arguments(): array
83+
protected function arguments(): array
10484
{
10585
$arguments = [];
10686

src/Commands/Show.php

Lines changed: 23 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Winter\Packager\Commands;
44

55
use Winter\Packager\Composer;
6+
use Winter\Packager\Enums\ShowMode;
67
use Winter\Packager\Enums\VersionStatus;
78
use Winter\Packager\Exceptions\CommandException;
89

@@ -17,67 +18,21 @@
1718
class Show extends BaseCommand
1819
{
1920
/**
20-
* Mode to run the command against
21-
*/
22-
public string $mode = 'installed';
23-
24-
/**
25-
* Individual package to search
26-
*/
27-
public ?string $package;
28-
29-
/**
30-
* Exclude dev dependencies from search
31-
*/
32-
public bool $noDev = false;
33-
34-
/**
35-
* Command handler.
21+
* Command constructor.
3622
*
37-
* The mode can be one of the following:
38-
* - `installed`: Show installed packages
39-
* - `locked`: Show locked packages
40-
* - `platform`: Show platform requirements
41-
* - `available`: Show all available packages
42-
* - `self`: Show the current package
43-
* - `path`: Show the package path
44-
* - `tree`: Show packages in a dependency tree
45-
* - `outdated`: Show only outdated packages
46-
* - `direct`: Show only direct dependencies
47-
*
48-
* @param string|null $mode
49-
* @param string|null $package
50-
* @param boolean $noDev
23+
* @param Composer $composer Composer instance
24+
* @param ShowMode $mode Mode to run the command against
25+
* @param string|null $package Individual package to search
26+
* @param boolean $noDev Exclude dev dependencies from search
5127
* @return void
5228
*/
53-
public function handle(?string $mode = 'installed', string $package = null, bool $noDev = false): void
54-
{
55-
$mode = $mode ?? 'installed';
56-
57-
$validModes = [
58-
'installed',
59-
'locked',
60-
'platform',
61-
'available',
62-
'self',
63-
'path',
64-
'tree',
65-
'outdated',
66-
'direct'
67-
];
68-
69-
if (!in_array(strtolower($mode), $validModes)) {
70-
throw new CommandException(
71-
sprintf(
72-
'Invalid mode, must be one of the following: %s',
73-
implode(', ', $validModes)
74-
)
75-
);
76-
}
77-
78-
$this->mode = $mode;
79-
$this->package = $package;
80-
$this->noDev = $noDev;
29+
final public function __construct(
30+
Composer $composer,
31+
public ShowMode $mode = ShowMode::INSTALLED,
32+
public ?string $package = null,
33+
public bool $noDev = false
34+
) {
35+
parent::__construct($composer);
8136
}
8237

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

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

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

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

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

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

@@ -190,32 +144,32 @@ public function execute()
190144
/**
191145
* @inheritDoc
192146
*/
193-
public function getCommandName(): string
147+
protected function getCommandName(): string
194148
{
195149
return 'show';
196150
}
197151

198152
/**
199153
* @inheritDoc
200154
*/
201-
public function requiresWorkDir(): bool
155+
protected function requiresWorkDir(): bool
202156
{
203157
return true;
204158
}
205159

206160
/**
207161
* @inheritDoc
208162
*/
209-
public function arguments(): array
163+
protected function arguments(): array
210164
{
211165
$arguments = [];
212166

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

217-
if ($this->mode !== 'installed') {
218-
$arguments['--' . $this->mode] = true;
171+
if ($this->mode !== ShowMode::INSTALLED) {
172+
$arguments['--' . $this->mode->value] = true;
219173
}
220174

221175
if ($this->noDev) {

0 commit comments

Comments
 (0)