Skip to content

Commit

Permalink
Resolve #252: Integrate symfony/console and split out composer plugin…
Browse files Browse the repository at this point in the history
… implementation

Signed-off-by: Andreas Frömer <andreas.froemer@check24.de>
  • Loading branch information
Andreas Frömer authored and icanhazstring committed Jan 4, 2022
1 parent c3c6d69 commit b4d1c1c
Show file tree
Hide file tree
Showing 31 changed files with 367 additions and 234 deletions.
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@

## [Unreleased] - TBA
### Added

- Added CLI argument `composer-json` which can be used to parse external projects.
This will default to the current working directory.
### Changed

- Change `bin/composer-unused` to be used as standalone binary
- Package type is now `library` instead of `composer-plugin`
### Removed
- Removed ability to work as `composer-plugin` (will be supported using `composer-unused/composer-unused-plugin`)
- Dropped support for php `7.3`

## [0.7.7] - 2021-07-26
### Added
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
PHP_VERSION=8.0
PHP_VERSION=7.4

up: ## Run all containers in all versions
docker compose up -d
Expand Down Expand Up @@ -39,7 +39,7 @@ box: ## Compile /build/composer-unused.phar
docker compose run php$(PHP_VERSION) php box.phar compile

ssh: ## SSH into container
docker compose run $(PHP_VERSION) /bin/sh
docker compose run php$(PHP_VERSION) /bin/sh

help: ## Displays this list of targets with descriptions
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}'
Expand Down
16 changes: 4 additions & 12 deletions bin/composer-unused
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

<?php

use Composer\Composer;
use Composer\Console\Application;
use Composer\IO\IOInterface;
use Icanhazstring\Composer\Unused\Console\Command\UnusedCommand;
use Psr\Container\ContainerInterface;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\ArgvInput;

(static function ($argv) {
Expand Down Expand Up @@ -36,19 +35,12 @@ use Symfony\Component\Console\Input\ArgvInput;

require UNUSED_COMPOSER_INSTALL;

/** @var ContainerInterface $container */
$container = require __DIR__ . '/../config/container.php';

$application = new Application();

$container->register(IOInterface::class, $application->getIO());
$container->register(Composer::class, $application->getComposer());

$application->add($container->get(UnusedCommand::class));

// Add 'unused' command if necessary
if (!isset($argv[1]) || $argv[1] !== 'unused') {
$argv = array_merge([$argv[0], 'unused'], array_slice($argv, 1));
}
$application->setDefaultCommand('unused', true);

$application->run(new ArgvInput($argv));
})($argv);
16 changes: 7 additions & 9 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "icanhazstring/composer-unused",
"type": "composer-plugin",
"type": "library",
"description": "Show unused packages by scanning your code",
"keywords": [
"composer",
Expand All @@ -17,17 +17,18 @@
}
],
"require": {
"php": "^7.3 || ^8.0",
"composer-plugin-api": "^2.0",
"composer-unused/symbol-parser": "^0.1.3",
"php": "^7.4 || ^8.0",
"composer-unused/contracts": "dev-main",
"composer-unused/symbol-parser": "dev-main",
"nikic/php-parser": "^4.13",
"psr/container": "^1.0 || ^2.0",
"psr/log": "^1.1 || ^2 || ^3"
"psr/log": "^1.1 || ^2 || ^3",
"symfony/console": "^4.4 || ^5.4 || ^6.0",
"symfony/serializer": "^4.4 || ^5.4 || ^6.0"
},
"require-dev": {
"ext-ds": "*",
"ext-zend-opcache": "*",
"composer/composer": "^2.2.3",
"jangregor/phpstan-prophecy": "^0.8.1",
"phpspec/prophecy-phpunit": "^2.0.1",
"phpstan/phpstan": "^0.12.99",
Expand All @@ -39,9 +40,6 @@
"preferred-install": "dist",
"sort-packages": true
},
"extra": {
"class": "Icanhazstring\\Composer\\Unused\\UnusedPlugin"
},
"autoload": {
"psr-4": {
"Icanhazstring\\Composer\\Unused\\": "src"
Expand Down
2 changes: 2 additions & 0 deletions config/service_manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Icanhazstring\Composer\Unused\Command\Handler\Factory\CollectConsumedSymbolsCommandHandlerFactory;
use Icanhazstring\Composer\Unused\Command\Handler\Factory\CollectFilteredDependenciesCommandHandlerFactory;
use Icanhazstring\Composer\Unused\Command\Handler\Factory\CollectRequiredDependenciesCommandHandlerFactory;
use Icanhazstring\Composer\Unused\Composer\ConfigFactory;
use Icanhazstring\Composer\Unused\Console\Command\UnusedCommand;
use Icanhazstring\Composer\Unused\Console\Command\UnusedCommandFactory;
use Icanhazstring\Composer\Unused\Di\InvokableFactory;
Expand All @@ -24,5 +25,6 @@
ConsumedSymbolLoaderBuilder::class => InvokableFactory::class,
ProvidedSymbolLoaderBuilder::class => InvokableFactory::class,
PackageResolver::class => InvokableFactory::class,
ConfigFactory::class => InvokableFactory::class,
]
];
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ services:
container_name: composer-unused-7.4
volumes:
- .:/docker/composer-unused:rw
- ../contracts:/docker/contracts:rw
- ../symbol-parser:/docker/symbol-parser:rw
tty: true

php8.0:
Expand Down
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ parameters:
level: max
inferPrivatePropertyTypeFromConstructor: true
paths:
- bin/
- src/
- tests/
tmpDir: data
2 changes: 1 addition & 1 deletion src/Command/CollectConsumedSymbolsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Icanhazstring\Composer\Unused\Command;

use Composer\Package\PackageInterface;
use ComposerUnused\Contracts\PackageInterface;

final class CollectConsumedSymbolsCommand
{
Expand Down
4 changes: 2 additions & 2 deletions src/Command/Handler/CollectConsumedSymbolsCommandHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function __construct(ConsumedSymbolLoaderBuilder $consumedSymbolLoaderBui
public function collect(CollectConsumedSymbolsCommand $command): Generator
{
$package = $command->getPackage();
$symbolLoader = $this->consumedSymbolLoaderBuilder->build($command->getPackageRoot());
$symbolLoader = $this->consumedSymbolLoaderBuilder->build();

$rootNamespaces = array_merge(
array_keys($package->getAutoload()['psr-0'] ?? []),
Expand All @@ -38,7 +38,7 @@ public function collect(CollectConsumedSymbolsCommand $command): Generator

yield from $this->filterRootPackageSymbols(
$rootNamespaces,
$symbolLoader->load($package)
$symbolLoader->withBaseDir($command->getPackageRoot())->load($package)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Icanhazstring\Composer\Unused\Command\FilterDependencyCollectionCommand;
use Icanhazstring\Composer\Unused\Dependency\DependencyCollection;
use Icanhazstring\Composer\Unused\Dependency\DependencyInterface;

final class CollectFilteredDependenciesCommandHandler
{
Expand All @@ -14,11 +15,11 @@ public function collect(FilterDependencyCollectionCommand $command): DependencyC
$namedExclusion = $command->getNamedExclusion();
$patternExclusion = $command->getPatternExclusion();

return $command->getRequiredDependencyCollection()->filter(static function ($dependency) use (
return $command->getRequiredDependencyCollection()->filter(static function (DependencyInterface $dependency) use (
$namedExclusion,
$patternExclusion
) {
if (in_array($dependency->getName(), $namedExclusion)) {
if (in_array($dependency->getName(), $namedExclusion, true)) {
return false;
}

Expand Down
13 changes: 10 additions & 3 deletions src/Command/Handler/CollectRequiredDependenciesCommandHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function __construct(
public function collect(LoadRequiredDependenciesCommand $command): DependencyCollection
{
$dependencyCollection = new DependencyCollection();
$providedSymbolLoader = $this->providedSymbolLoaderBuilder->build($command->getBaseDir());
$providedSymbolLoader = $this->providedSymbolLoaderBuilder->build();

foreach ($command->getPackageLinks() as $require) {
$composerPackage = $this->packageResolver->resolve(
Expand All @@ -39,15 +39,22 @@ public function collect(LoadRequiredDependenciesCommand $command): DependencyCol
);

if ($composerPackage === null) {
$dependencyCollection->add(new InvalidDependency($require, 'Unable to locate package'));
$dependencyCollection->add(
new InvalidDependency(
$require,
'Dependency can\'t be located. Maybe not installed?'
)
);
continue;
}

$packageBaseDir = $command->getBaseDir() . DIRECTORY_SEPARATOR . $composerPackage->getName();

$dependencyCollection->add(
new RequiredDependency(
$composerPackage,
(new SymbolList())->addAll(
$providedSymbolLoader->load($composerPackage)
$providedSymbolLoader->withBaseDir($packageBaseDir)->load($composerPackage)
)
)
);
Expand Down
10 changes: 5 additions & 5 deletions src/Command/LoadRequiredDependenciesCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@

namespace Icanhazstring\Composer\Unused\Command;

use Composer\Package\Link;
use Composer\Repository\RepositoryInterface;
use ComposerUnused\Contracts\LinkInterface;
use ComposerUnused\Contracts\RepositoryInterface;

final class LoadRequiredDependenciesCommand
{
/** @var string */
private $baseDir;
/** @var array<Link> */
/** @var array<LinkInterface> */
private $packageLinks;
/** @var RepositoryInterface */
private $packageRepository;

/**
* @param array<Link> $packageLinks
* @param array<LinkInterface> $packageLinks
*/
public function __construct(string $baseDir, array $packageLinks, RepositoryInterface $packageRepository)
{
Expand All @@ -32,7 +32,7 @@ public function getBaseDir(): string
}

/**
* @return array<Link>
* @return array<LinkInterface>
*/
public function getPackageLinks(): array
{
Expand Down
48 changes: 48 additions & 0 deletions src/Composer/Config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

namespace Icanhazstring\Composer\Unused\Composer;

final class Config
{
/** @var array<string, mixed> */
protected array $config = [];
protected string $name;
/** @var array<string, mixed> */
private array $require = [];
/** @var array<string, mixed> */
private array $autoload = [];

public function getName(): string
{
return $this->name;
}

/**
* @return array<string, mixed>
*/
public function getRequire(): array
{
return $this->require;
}

/**
* @return array<string, mixed>
*/
public function getAutoload(): array
{
return $this->autoload;
}

public function get(string $property): string
{
$value = $this->config[$property] ?? null;

if ($property === 'vendor-dir') {
$value = $value ?? 'vendor';
}

return $value;
}
}
29 changes: 29 additions & 0 deletions src/Composer/ConfigFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Icanhazstring\Composer\Unused\Composer;

use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\SerializerInterface;

final class ConfigFactory
{
private SerializerInterface $serializer;

public function __construct()
{
$encoders = [new JsonEncoder()];
$normalizers = [new PropertyNormalizer(null, new CamelCaseToSnakeCaseNameConverter())];

$this->serializer = new Serializer($normalizers, $encoders);
}

public function fromComposerJson(string $jsonContent): Config
{
return $this->serializer->deserialize($jsonContent, Config::class, 'json');
}
}
22 changes: 22 additions & 0 deletions src/Composer/Link.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Icanhazstring\Composer\Unused\Composer;

use ComposerUnused\Contracts\LinkInterface;

final class Link implements LinkInterface
{
private string $target;

public function __construct(string $target)
{
$this->target = $target;
}

public function getTarget(): string
{
return $this->target;
}
}

0 comments on commit b4d1c1c

Please sign in to comment.