Skip to content

Commit

Permalink
Merge pull request #5 from minicli/input-layer-initial
Browse files Browse the repository at this point in the history
Input Layer - Initial Implementation
  • Loading branch information
JustSteveKing committed May 20, 2023
2 parents b4e2ca9 + 70d6bbe commit bcc8766
Show file tree
Hide file tree
Showing 14 changed files with 284 additions and 86 deletions.
8 changes: 5 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ jobs:
dependencies:
- "highest"
php-version:
- "8.1"
- "8.2"
operating-system:
- "ubuntu-latest"
Expand Down Expand Up @@ -48,8 +47,11 @@ jobs:
- name: "Validate Composer dependencies"
run: "composer validate"

- name: "Check Style"
run: "composer test:lint"

- name: "Check Static Analysis"
run: "composer stan"
run: "composer test:stan"

- name: "Run Test suite"
run: "composer test"
run: "composer test:unit"
22 changes: 12 additions & 10 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,22 @@
}
},
"scripts": {
"pint": [
"./vendor/bin/pint"
],
"stan": [
"./vendor/bin/phpstan analyse --memory-limit=3G"
],
"lint": ["pint"],
"test:lint": ["pint --test"],
"test:stan": ["phpstan analyse --memory-limit=3G"],
"test:unit": ["pest"],
"test": [
"./vendor/bin/pest"
"@test:lint",
"@test:stan",
"@test:unit"
]
},
"scripts-descriptions": {
"pint": "Run Laravel Pint code styling.",
"stan": "Run PHPStan against code base.",
"test": "Run test suite."
"lint": "Run Laravel Pint code styling.",
"test:lint": "Run Laravel Pint code styling check.",
"test:stan": "Run PHPStan against code base.",
"test:unit": "Run test suite.",
"test": "Run all tests."
},
"minimum-stability": "dev",
"prefer-stable": true,
Expand Down
36 changes: 36 additions & 0 deletions src/Commands/AbstractCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace Minicli\Framework\Commands;

use Minicli\Framework\Contracts\Commands\CommandContract;
use Minicli\Framework\Exceptions\MissingParametersException;
use Minicli\Framework\Input\Input;

abstract class AbstractCommand implements CommandContract
{
/**
* @throws MissingParametersException
*/
public function boot(Input $input): void
{
$missing = array_diff($this->required(), array_keys($input->params()));

if ([] !== $missing) {
throw new MissingParametersException($missing);
}
}

/**
* @return array<int,string>
*/
public function required(): array
{
return [];
}

public function teardown(): void
{
}
}
9 changes: 8 additions & 1 deletion src/Commands/DefaultCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@

namespace Minicli\Framework\Commands;

final class DefaultCommand
use Minicli\Framework\Input\Input;

final class DefaultCommand extends AbstractCommand
{
public string $signature = 'default';

public function handle(Input $input): void
{
// TODO: Implement handle() method.
}
}
52 changes: 0 additions & 52 deletions src/Commands/PendingCommand.php

This file was deleted.

27 changes: 27 additions & 0 deletions src/Contracts/Commands/CommandContract.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Minicli\Framework\Contracts\Commands;

use Minicli\Framework\Input\Input;

interface CommandContract
{
/**
* Executes the command logic.
*/
public function handle(Input $input): void;

/**
* The list of parameters required by the command.
*
* @return array<int,string>
*/
public function required(): array;

/**
* Called after the command is executed successfully.
*/
public function teardown(): void;
}
1 change: 0 additions & 1 deletion src/Contracts/Theme/MiniEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@

interface MiniEnum
{
//
}
25 changes: 13 additions & 12 deletions src/DI/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Minicli\Framework\DI;

use ArrayAccess;
use Closure;
use Minicli\Framework\Exceptions\BindingResolutionException;
use ReflectionClass;
use ReflectionException;
Expand All @@ -14,7 +15,7 @@
/**
* @implements ArrayAccess<string,mixed>
*/
class Container implements ArrayAccess
abstract class Container implements ArrayAccess
{
protected static null|Container $instance = null;

Expand All @@ -26,12 +27,12 @@ class Container implements ArrayAccess
/**
* @var array<string,mixed>
*/
private array $instances = [];
protected array $instances = [];

/**
* @return void
*/
protected function __construct()
public function __construct()
{
}

Expand Down Expand Up @@ -136,19 +137,19 @@ public function build(Closure|string $concrete): mixed
return $concrete($this);
}

if (!class_exists($concrete)) {
throw new BindingResolutionException("Target class [$concrete] does not exist.", 0);
if ( ! class_exists($concrete)) {
throw new BindingResolutionException("Target class [{$concrete}] does not exist.", 0);
}

$reflector = new ReflectionClass($concrete);

if (!$reflector->isInstantiable()) {
throw new BindingResolutionException("Target [$concrete] is not instantiable.");
if ( ! $reflector->isInstantiable()) {
throw new BindingResolutionException("Target [{$concrete}] is not instantiable.");
}

$constructor = $reflector->getConstructor();

if (is_null($constructor)) {
if (null === $constructor) {
return new $concrete();
}

Expand All @@ -164,17 +165,17 @@ public function build(Closure|string $concrete): mixed
* @return array<int,mixed>
* @throws BindingResolutionException|ReflectionException
*/
protected function resolveDependencies(array $dependencies): array
private function resolveDependencies(array $dependencies): array
{
$results = [];

foreach ($dependencies as $dependency) {
// This is a much simpler version of what Laravel does
$type = $dependency->getType(); // ReflectionType|null

if (!$type instanceof ReflectionNamedType || $type->isBuiltin()) {
$declaringClass = is_null($dependency->getDeclaringClass()) ? '' : $dependency->getDeclaringClass()->getName();
throw new BindingResolutionException("Unresolvable dependency resolving [$dependency] in class {$declaringClass}");
if ( ! $type instanceof ReflectionNamedType || $type->isBuiltin()) {
$declaringClass = null === $dependency->getDeclaringClass() ? '' : $dependency->getDeclaringClass()->getName();
throw new BindingResolutionException("Unresolvable dependency resolving [{$dependency}] in class {$declaringClass}");
}

$results[] = $this->make($type->getName());
Expand Down
1 change: 0 additions & 1 deletion src/Exceptions/BindingResolutionException.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@

final class BindingResolutionException extends Exception
{
//
}
1 change: 0 additions & 1 deletion src/Exceptions/MinicliNamingException.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@

final class MinicliNamingException extends InvalidArgumentException
{
//
}
18 changes: 18 additions & 0 deletions src/Exceptions/MissingParametersException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Minicli\Framework\Exceptions;

use Exception;

final class MissingParametersException extends Exception
{
public function __construct(array $missing)
{
parent::__construct(sprintf(
'Missing required parameters: %s',
implode(', ', $missing)
));
}
}
Loading

0 comments on commit bcc8766

Please sign in to comment.