-
-
Notifications
You must be signed in to change notification settings - Fork 687
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updated Rector to commit 2dda748541be13dac8ef328011bc50233f2030bc
rectorphp/rector-src@2dda748 [DX] Introduce set providers, to enable package + version based set registration (#5976)
- Loading branch information
1 parent
9d08250
commit 856c640
Showing
19 changed files
with
348 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
|
||
declare (strict_types=1); | ||
namespace Rector\Composer; | ||
|
||
use RectorPrefix202406\Nette\Utils\FileSystem; | ||
use RectorPrefix202406\Nette\Utils\Json; | ||
use Rector\Composer\ValueObject\InstalledPackage; | ||
use Rector\Exception\ShouldNotHappenException; | ||
use RectorPrefix202406\Webmozart\Assert\Assert; | ||
/** | ||
* @see \Rector\Tests\Composer\InstalledPackageResolverTest | ||
*/ | ||
final class InstalledPackageResolver | ||
{ | ||
/** | ||
* @var array<string, InstalledPackage[]> | ||
*/ | ||
private $resolvedInstalledPackages = []; | ||
/** | ||
* @return InstalledPackage[] | ||
*/ | ||
public function resolve(string $projectDirectory) : array | ||
{ | ||
// cache | ||
if (isset($this->resolvedInstalledPackages[$projectDirectory])) { | ||
return $this->resolvedInstalledPackages[$projectDirectory]; | ||
} | ||
Assert::directory($projectDirectory); | ||
$installedPackagesFilePath = $projectDirectory . '/vendor/composer/installed.json'; | ||
if (!\file_exists($installedPackagesFilePath)) { | ||
throw new ShouldNotHappenException('The installed package json not found. Make sure you run `composer update` and "vendor/composer/installed.json" file exists'); | ||
} | ||
$installedPackageFileContents = FileSystem::read($installedPackagesFilePath); | ||
$installedPackagesFilePath = Json::decode($installedPackageFileContents, \true); | ||
$installedPackages = []; | ||
foreach ($installedPackagesFilePath['packages'] as $installedPackage) { | ||
$installedPackages[] = new InstalledPackage($installedPackage['name'], $installedPackage['version_normalized']); | ||
} | ||
$this->resolvedInstalledPackages[$projectDirectory] = $installedPackages; | ||
return $installedPackages; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?php | ||
|
||
declare (strict_types=1); | ||
namespace Rector\Composer\ValueObject; | ||
|
||
final class InstalledPackage | ||
{ | ||
/** | ||
* @readonly | ||
* @var string | ||
*/ | ||
private $name; | ||
/** | ||
* @readonly | ||
* @var string | ||
*/ | ||
private $version; | ||
public function __construct(string $name, string $version) | ||
{ | ||
$this->name = $name; | ||
$this->version = $version; | ||
} | ||
public function getName() : string | ||
{ | ||
return $this->name; | ||
} | ||
public function getVersion() : string | ||
{ | ||
return $this->version; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?php | ||
|
||
declare (strict_types=1); | ||
namespace Rector\Set\Contract; | ||
|
||
interface SetInterface | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?php | ||
|
||
declare (strict_types=1); | ||
namespace Rector\Set\Contract; | ||
|
||
interface SetProviderInterface | ||
{ | ||
/** | ||
* @return SetInterface[] | ||
*/ | ||
public function provide() : array; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
|
||
declare (strict_types=1); | ||
namespace Rector\Set\Enum; | ||
|
||
final class SetGroup | ||
{ | ||
public const TWIG = 'twig'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
<?php | ||
|
||
declare (strict_types=1); | ||
namespace Rector\Set; | ||
|
||
use Rector\Composer\InstalledPackageResolver; | ||
use Rector\Set\Contract\SetProviderInterface; | ||
use Rector\Set\ValueObject\ComposerTriggeredSet; | ||
use RectorPrefix202406\Webmozart\Assert\Assert; | ||
/** | ||
* @see \Rector\Tests\Set\SetCollector\SetCollectorTest | ||
*/ | ||
final class SetManager | ||
{ | ||
/** | ||
* @var SetProviderInterface[] | ||
* @readonly | ||
*/ | ||
private $setProviders; | ||
/** | ||
* @param SetProviderInterface[] $setProviders | ||
*/ | ||
public function __construct(array $setProviders) | ||
{ | ||
$this->setProviders = $setProviders; | ||
Assert::allIsInstanceOf($setProviders, SetProviderInterface::class); | ||
} | ||
/** | ||
* @return ComposerTriggeredSet[] | ||
*/ | ||
public function matchComposerTriggered(string $groupName) : array | ||
{ | ||
$matchedSets = []; | ||
foreach ($this->setProviders as $setProvider) { | ||
foreach ($setProvider->provide() as $set) { | ||
if (!$set instanceof ComposerTriggeredSet) { | ||
continue; | ||
} | ||
if ($set->getGroupName() === $groupName) { | ||
$matchedSets[] = $set; | ||
} | ||
} | ||
} | ||
return $matchedSets; | ||
} | ||
/** | ||
* @param string[] $setGroups | ||
* @return string[] | ||
*/ | ||
public function matchBySetGroups(array $setGroups) : array | ||
{ | ||
$installedPackageResolver = new InstalledPackageResolver(); | ||
$installedComposerPackages = $installedPackageResolver->resolve(\getcwd()); | ||
$groupLoadedSets = []; | ||
foreach ($setGroups as $setGroup) { | ||
$composerTriggeredSets = $this->matchComposerTriggered($setGroup); | ||
foreach ($composerTriggeredSets as $composerTriggeredSet) { | ||
if ($composerTriggeredSet->matchInstalledPackages($installedComposerPackages)) { | ||
// @todo add debug note somewhere | ||
// echo sprintf('Loaded "%s" set as it meets the conditions', $composerTriggeredSet->getSetFilePath()); | ||
// it matched composer package + version requirements → load set | ||
$groupLoadedSets[] = $composerTriggeredSet->getSetFilePath(); | ||
} | ||
} | ||
} | ||
return $groupLoadedSets; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?php | ||
|
||
declare (strict_types=1); | ||
namespace Rector\Set\SetProvider; | ||
|
||
use Rector\Set\Contract\SetInterface; | ||
use Rector\Set\Contract\SetProviderInterface; | ||
use Rector\Set\Enum\SetGroup; | ||
use Rector\Set\ValueObject\ComposerTriggeredSet; | ||
use Rector\Symfony\Set\TwigSetList; | ||
/** | ||
* Temporary location, move to rector-symfony package once this is merged | ||
* @experimental 2024-06 | ||
*/ | ||
final class TwigSetProvider implements SetProviderInterface | ||
{ | ||
/** | ||
* @return SetInterface[] | ||
*/ | ||
public function provide() : array | ||
{ | ||
// @todo temporary name to test, these will be located in rector-symfony, rector-doctrine, rector-phpunit packages | ||
return [new ComposerTriggeredSet(SetGroup::TWIG, 'twig/twig', '1.12', TwigSetList::TWIG_112)]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
<?php | ||
|
||
declare (strict_types=1); | ||
namespace Rector\Set\ValueObject; | ||
|
||
use Rector\Composer\ValueObject\InstalledPackage; | ||
use Rector\Set\Contract\SetInterface; | ||
use RectorPrefix202406\Webmozart\Assert\Assert; | ||
/** | ||
* @api used by extensions | ||
*/ | ||
final class ComposerTriggeredSet implements SetInterface | ||
{ | ||
/** | ||
* @readonly | ||
* @var string | ||
*/ | ||
private $groupName; | ||
/** | ||
* @readonly | ||
* @var string | ||
*/ | ||
private $packageName; | ||
/** | ||
* @readonly | ||
* @var string | ||
*/ | ||
private $version; | ||
/** | ||
* @readonly | ||
* @var string | ||
*/ | ||
private $setFilePath; | ||
/** | ||
* @var string | ||
* @see https://regex101.com/r/xRjQ2X/1 | ||
*/ | ||
private const PACKAGE_REGEX = '#^[a-z0-9-]+\\/[a-z0-9-_]+$#'; | ||
public function __construct(string $groupName, string $packageName, string $version, string $setFilePath) | ||
{ | ||
$this->groupName = $groupName; | ||
$this->packageName = $packageName; | ||
$this->version = $version; | ||
$this->setFilePath = $setFilePath; | ||
Assert::regex($this->packageName, self::PACKAGE_REGEX); | ||
Assert::fileExists($setFilePath); | ||
} | ||
public function getGroupName() : string | ||
{ | ||
return $this->groupName; | ||
} | ||
public function getSetFilePath() : string | ||
{ | ||
return $this->setFilePath; | ||
} | ||
/** | ||
* @param InstalledPackage[] $installedPackages | ||
*/ | ||
public function matchInstalledPackages(array $installedPackages) : bool | ||
{ | ||
foreach ($installedPackages as $installedPackage) { | ||
if ($installedPackage->getName() !== $this->packageName) { | ||
continue; | ||
} | ||
return \version_compare($installedPackage->getVersion(), $this->version) !== -1; | ||
} | ||
return \false; | ||
} | ||
} |
Oops, something went wrong.