Skip to content

Commit

Permalink
feat(documentator): Required requirements for Requirements command …
Browse files Browse the repository at this point in the history
…can be specified in `metadata.json`.
  • Loading branch information
LastDragon-ru committed Aug 28, 2023
1 parent e69abd8 commit bdb767f
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 12 deletions.
14 changes: 14 additions & 0 deletions packages/documentator/docs/commands/requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,20 @@ Generates a table with the required versions of PHP/Laravel in Markdown format.

* `lara-asp-documentator:requirements [<cwd>]`

## Description

Requirements will be cached into `<cwd>/metadata.json`. You can also use
this file to specify the required requirements. For example, to include
PHP only:

```json
{
"require": {
"php": "PHP"
}
}
```

## Arguments

### `cwd?`
Expand Down
65 changes: 53 additions & 12 deletions packages/documentator/src/Commands/Requirements.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@
use LastDragon_ru\LaraASP\Documentator\Metadata\Storage;
use LastDragon_ru\LaraASP\Documentator\Package;
use LastDragon_ru\LaraASP\Documentator\Utils\Git;
use LastDragon_ru\LaraASP\Documentator\Utils\Path;
use LastDragon_ru\LaraASP\Documentator\Utils\Version;
use LastDragon_ru\LaraASP\Serializer\Contracts\Serializer;
use Symfony\Component\Console\Attribute\AsCommand;

use function array_combine;
use function array_fill_keys;
use function array_intersect_key;
use function array_keys;
use function array_merge;
use function array_search;
use function array_unique;
use function assert;
use function count;
use function end;
Expand Down Expand Up @@ -48,16 +49,33 @@ class Requirements extends Command {
{cwd? : working directory (should be a git repository)}
SIGNATURE;

/**
* @phpcsSuppress SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingNativeTypeHint
* @var string
*/
protected $help = <<<'HELP'
Requirements will be cached into `<cwd>/metadata.json`. You can also use
this file to specify the required requirements. For example, to include
PHP only:
```json
{
"require": {
"php": "PHP"
}
}
```
HELP;

public function __invoke(Git $git, Serializer $serializer): void {
// Get Versions
$cwd = Cast::toString($this->argument('cwd') ?? getcwd());
$tags = $git->getTags(Version::isVersion(...), $cwd);
$tags[] = 'HEAD';
$cwd = Cast::toString($this->argument('cwd') ?? getcwd());
$tags = $this->getPackageVersions($git, $cwd, ['HEAD']);

// Collect requirements
$storage = new Storage($serializer, $cwd);
$metadata = $storage->load();
$packages = [
$packages = $metadata->require ?: [
'php' => 'PHP',
'laravel/framework' => 'Laravel',
];
Expand All @@ -72,7 +90,7 @@ public function __invoke(Git $git, Serializer $serializer): void {
$package = $this->getPackageInfo($git, $tag, $cwd);

if (!$package) {
continue;
break;
}

// Update
Expand All @@ -84,10 +102,18 @@ public function __invoke(Git $git, Serializer $serializer): void {
}

// Cleanup
$metadata->requirements = array_intersect_key(
$metadata->requirements,
array_fill_keys($tags, null),
);
foreach ($metadata->requirements as $tag => $requirement) {
if (!isset($tags[$tag])) {
unset($metadata->requirements[$tag]);
break;
}

foreach ($requirement as $package => $versions) {
if (!isset($packages[$package])) {
unset($metadata->requirements[$tag][$package]);
}
}
}

// Save
$storage->save($metadata);
Expand All @@ -106,12 +132,27 @@ public function __invoke(Git $git, Serializer $serializer): void {
$this->output->writeln($output);
}

/**
* @param list<string> $tags
*
* @return array<string, string>
*/
protected function getPackageVersions(Git $git, string $cwd, array $tags = []): array {
$tags = array_merge($tags, $git->getTags(Version::isVersion(...), $cwd));
$tags = array_unique($tags);
$tags = array_combine($tags, $tags);

uksort($tags, static fn($a, $b) => -Version::compare($a, $b));

return $tags;
}

/**
* @return array<array-key, mixed>|null
*/
protected function getPackageInfo(Git $git, string $tag, string $cwd): ?array {
try {
$package = $git->getFile('composer.json', $tag, $cwd);
$package = $git->getFile(Path::join($cwd, 'composer.json'), $tag, $cwd);
$package = json_decode($package, true, flags: JSON_THROW_ON_ERROR);

assert(is_array($package));
Expand Down
2 changes: 2 additions & 0 deletions packages/documentator/src/Metadata/Metadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
*/
class Metadata implements Serializable {
/**
* @param array<string, string> $require
* @param array<string, array<string, list<string>>> $requirements
*/
public function __construct(
public string $version = '0.0.0',
public array $require = [],
public array $requirements = [],
) {
// empty
Expand Down

0 comments on commit bdb767f

Please sign in to comment.