Skip to content

Commit

Permalink
Rewritten logic to load packages and their dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
coenjacobs committed Sep 11, 2024
1 parent 57c0b61 commit 6cf4b13
Show file tree
Hide file tree
Showing 12 changed files with 285 additions and 203 deletions.
7 changes: 6 additions & 1 deletion src/Composer/Autoload/NamespaceAutoloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,14 @@ public function processConfig($autoloadConfig): void
}
}

public function getNamespace(): string
{
return rtrim($this->namespace, '\\') . '\\';
}

public function getSearchNamespace(): string
{
return $this->namespace;
return rtrim($this->namespace, '\\');
}

public function getNamespacePath(): string
Expand Down
12 changes: 12 additions & 0 deletions src/Config/Mozart.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class Mozart
public OverrideAutoload $override_autoload;
public bool $delete_vendor_directories;

public string $workingDir = '';

/**
* @return string[]
*/
Expand Down Expand Up @@ -119,4 +121,14 @@ public function getExcludedPackages(): array
{
return $this->excluded_packages;
}

public function setWorkingDir(string $workingDir): void
{
$this->workingDir = $workingDir;
}

public function getWorkingDir(): string
{
return $this->workingDir;
}
}
37 changes: 28 additions & 9 deletions src/Config/Package.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@
use CoenJacobs\Mozart\Config\Autoload;
use CoenJacobs\Mozart\Config\Extra;
use CoenJacobs\Mozart\Config\ReadsConfig;
use CoenJacobs\Mozart\PackageFinder;
use Exception;
use stdClass;

class Package
{
use ReadsConfig;

/** @var Package[] */
public $requirePackages = [];
public $dependencies = [];

public string $name;

/** @var string[] */
public array $require;
public array $require = [];

public ?Autoload $autoload = null;
public ?Extra $extra = null;
Expand Down Expand Up @@ -68,31 +70,48 @@ public function getAutoloaders(): array
/**
* @return string[]
*/
public function getPackages(): array
public function getRequire(): array
{
return $this->require;
return array_keys($this->require);
}

/**
* @return Package[]
*/
public function getDependencies(): array
{
return $this->requirePackages;
return $this->dependencies;
}

public function registerRequirePackage(Package $package): void
public function loadDependencies(): void
{
array_push($this->requirePackages, $package);
$finder = PackageFinder::instance();
if ($this->isValidMozartConfig() && !empty($this->getExtra())) {
$mozart = $this->getExtra()->getMozart();

if (empty($mozart)) {
throw new Exception("Couldn't load dependencies because config not set.");
}
$finder->setConfig($mozart);
}

$dependencies = $finder->getPackagesBySlugs($this->getRequire());

$this->registerDependencies($dependencies);
}

public function registerDependency(Package $package): void
{
array_push($this->dependencies, $package);
}

/**
* @param Package[] $packages
*/
public function registerRequirePackages(array $packages): void
public function registerDependencies(array $packages): void
{
foreach ($packages as $package) {
$this->registerRequirePackage($package);
$this->registerDependency($package);
}
}
}
20 changes: 0 additions & 20 deletions src/Config/PackageFactory.php

This file was deleted.

197 changes: 29 additions & 168 deletions src/Console/Commands/Compose.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
namespace CoenJacobs\Mozart\Console\Commands;

use CoenJacobs\Mozart\Config\Mozart;
use CoenJacobs\Mozart\Config\Package;
use CoenJacobs\Mozart\Config\PackageFactory;
use CoenJacobs\Mozart\Mover;
use CoenJacobs\Mozart\PackageFactory;
use CoenJacobs\Mozart\PackageFinder;
use CoenJacobs\Mozart\Replacer;
use Exception;
use Symfony\Component\Console\Command\Command;
Expand All @@ -14,17 +14,17 @@

class Compose extends Command
{
/** @var Mover */
private $mover;
private Mover $mover;
private Replacer $replacer;
private Mozart $config;
private PackageFinder $finder;
private string $workingDir;

/** @var Replacer */
private $replacer;

/** @var string */
private $workingDir;

/** @var Mozart */
private $config;
public function __construct()
{
$this->workingDir = getcwd();
parent::__construct();
}

protected function configure(): void
{
Expand All @@ -35,17 +35,13 @@ protected function configure(): void

protected function execute(InputInterface $input, OutputInterface $output): int
{
$workingDir = getcwd();

if (! $workingDir) {
if (! $this->workingDir) {
throw new Exception('Could not determine working directory.');
}

$this->workingDir = $workingDir;

$composerFile = $workingDir . DIRECTORY_SEPARATOR. 'composer.json';
$composerFile = $this->workingDir . DIRECTORY_SEPARATOR. 'composer.json';
try {
$package = PackageFactory::createPackage($composerFile);
$package = PackageFactory::createPackage($composerFile, null, false);
} catch (Exception $e) {
$output->write('Unable to read the composer.json file');
return 1;
Expand All @@ -64,165 +60,30 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}

$this->config = $config;
$this->config->setWorkingDir($this->workingDir);

$require = $this->config->getPackages();
if (empty($require)) {
$require = $package->getPackages();
$require = $package->getRequire();
}

$this->mover = new Mover($workingDir, $this->config);
$this->replacer = new Replacer($workingDir, $this->config);
$this->finder = PackageFinder::instance();
$this->finder->setConfig($this->config);

$package->loadDependencies();

$packages = $this->finder->getPackagesBySlugs($require);
$packages = $this->finder->findPackages($packages);

$packages = $this->findPackages($require);
$this->mover = new Mover($this->workingDir, $this->config);
$this->replacer = new Replacer($this->workingDir, $this->config);

$this->mover->deleteTargetDirs($packages);
$this->movePackages($packages);
$this->replacePackages($packages);
$this->replaceParentInTree($packages);
$this->mover->movePackages($packages);
$this->replacer->replacePackages($packages);
$this->replacer->replaceParentInTree($packages);
$this->replacer->replaceParentClassesInDirectory($this->config->getClassmapDirectory());

return 0;
}

/**
* @param Package[] $packages
*/
protected function movePackages($packages): void
{
foreach ($packages as $package) {
$this->movePackage($package);
}

$this->mover->deleteEmptyDirs();
}

/**
* @param Package[] $packages
*/
protected function replacePackages($packages): void
{
foreach ($packages as $package) {
$this->replacePackage($package);
}
}

/**
* Move all the packages over, one by one, starting on the deepest level of dependencies.
*/
public function movePackage(Package $package): void
{
if ($this->config->isExcludedPackage($package)) {
return;
}

if (! empty($package->dependencies)) {
foreach ($package->getDependencies() as $dependency) {
$this->movePackage($dependency);
}
}

$this->mover->movePackage($package);
}

/**
* Replace contents of all the packages, one by one, starting on the deepest level of dependencies.
*/
public function replacePackage(Package $package): void
{
if ($this->config->isExcludedPackage($package)) {
return;
}

if (! empty($package->dependencies)) {
foreach ($package->getDependencies() as $dependency) {
$this->replacePackage($dependency);
}
}

$this->replacer->replacePackage($package);
}

/**
* Loops through all dependencies and their dependencies and so on...
* will eventually return a list of all packages required by the full tree.
*
* @param ((int|string)|mixed)[] $slugs
*
* @return Package[]
*/
private function findPackages(array $slugs): array
{
$packages = [];

foreach ($slugs as $package_slug) {
$packageDir = $this->workingDir . DIRECTORY_SEPARATOR . 'vendor'
. DIRECTORY_SEPARATOR . $package_slug . DIRECTORY_SEPARATOR;

if (! is_dir($packageDir)) {
continue;
}

$autoloaders = null;
$override_autoload = $this->config->getOverrideAutoload();
if ($override_autoload !== false && isset($override_autoload->$package_slug)) {
$autoloaders = $override_autoload->$package_slug;
}

$package = PackageFactory::createPackage($packageDir . 'composer.json', $autoloaders);

if ($this->config->isExcludedPackage($package)) {
continue;
}

$dependencies = $package->getDependencies();

$package->registerRequirePackages($this->findPackages($dependencies));
$packages[$package_slug] = $package;
}

return $packages;
}

/**
* Get an array containing all the dependencies and dependencies
* @param Package $package
* @param Package[] $dependencies
* @return Package[]
*/
private function getAllDependenciesOfPackage(Package $package, $dependencies = []): array
{
if ($this->config->isExcludedPackage($package)) {
return $dependencies;
}

if (empty($package->getDependencies())) {
return $dependencies;
}

foreach ($package->getDependencies() as $dependency) {
$dependencies[] = $dependency;
}

foreach ($package->getDependencies() as $dependency) {
$dependencies = $this->getAllDependenciesOfPackage($dependency, $dependencies);
}

return $dependencies;
}

/**
* @param Package[] $packages
*/
private function replaceParentInTree(array $packages): void
{
foreach ($packages as $package) {
$dependencies = $this->getAllDependenciesOfPackage($package);

foreach ($dependencies as $dependency) {
$this->replacer->replaceParentPackage($dependency, $package);
}

$this->replaceParentInTree($package->getDependencies());
}
}
}
Loading

0 comments on commit 6cf4b13

Please sign in to comment.