parent
c7e696dbde
commit
892eaacedf
|
@ -102,11 +102,21 @@ class PoolBuilder
|
||||||
* @var BasePackage[]
|
* @var BasePackage[]
|
||||||
*/
|
*/
|
||||||
private $unacceptableFixedOrLockedPackages = [];
|
private $unacceptableFixedOrLockedPackages = [];
|
||||||
/** @var string[] */
|
/** @var array<string> */
|
||||||
private $updateAllowList = [];
|
private $updateAllowList = [];
|
||||||
/** @var array<string, array<PackageInterface>> */
|
/** @var array<string, array<PackageInterface>> */
|
||||||
private $skippedLoad = [];
|
private $skippedLoad = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If provided, only these package names are loaded
|
||||||
|
*
|
||||||
|
* This is a special-use functionality of the Request class to optimize the pool creation process
|
||||||
|
* when only a minimal subset of packages is needed and we do not need their dependencies.
|
||||||
|
*
|
||||||
|
* @var array<string, int>|null
|
||||||
|
*/
|
||||||
|
private $restrictedPackagesList = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keeps a list of dependencies which are locked but were auto-unlocked as they are path repositories
|
* Keeps a list of dependencies which are locked but were auto-unlocked as they are path repositories
|
||||||
*
|
*
|
||||||
|
@ -165,6 +175,8 @@ class PoolBuilder
|
||||||
*/
|
*/
|
||||||
public function buildPool(array $repositories, Request $request): Pool
|
public function buildPool(array $repositories, Request $request): Pool
|
||||||
{
|
{
|
||||||
|
$this->restrictedPackagesList = $request->getRestrictedPackages() !== null ? array_flip($request->getRestrictedPackages()) : null;
|
||||||
|
|
||||||
if ($request->getUpdateAllowList()) {
|
if ($request->getUpdateAllowList()) {
|
||||||
$this->updateAllowList = $request->getUpdateAllowList();
|
$this->updateAllowList = $request->getUpdateAllowList();
|
||||||
$this->warnAboutNonMatchingUpdateAllowList($request);
|
$this->warnAboutNonMatchingUpdateAllowList($request);
|
||||||
|
@ -366,6 +378,10 @@ class PoolBuilder
|
||||||
private function loadPackagesMarkedForLoading(Request $request, array $repositories): void
|
private function loadPackagesMarkedForLoading(Request $request, array $repositories): void
|
||||||
{
|
{
|
||||||
foreach ($this->packagesToLoad as $name => $constraint) {
|
foreach ($this->packagesToLoad as $name => $constraint) {
|
||||||
|
if ($this->restrictedPackagesList !== null && !isset($this->restrictedPackagesList[$name])) {
|
||||||
|
unset($this->packagesToLoad[$name]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$this->loadedPackages[$name] = $constraint;
|
$this->loadedPackages[$name] = $constraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -559,7 +575,7 @@ class PoolBuilder
|
||||||
*/
|
*/
|
||||||
private function isUpdateAllowed(BasePackage $package): bool
|
private function isUpdateAllowed(BasePackage $package): bool
|
||||||
{
|
{
|
||||||
foreach ($this->updateAllowList as $pattern => $void) {
|
foreach ($this->updateAllowList as $pattern) {
|
||||||
$patternRegexp = BasePackage::packageNameToRegexp($pattern);
|
$patternRegexp = BasePackage::packageNameToRegexp($pattern);
|
||||||
if (Preg::isMatch($patternRegexp, $package->getName())) {
|
if (Preg::isMatch($patternRegexp, $package->getName())) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -571,7 +587,7 @@ class PoolBuilder
|
||||||
|
|
||||||
private function warnAboutNonMatchingUpdateAllowList(Request $request): void
|
private function warnAboutNonMatchingUpdateAllowList(Request $request): void
|
||||||
{
|
{
|
||||||
foreach ($this->updateAllowList as $pattern => $void) {
|
foreach ($this->updateAllowList as $pattern) {
|
||||||
$patternRegexp = BasePackage::packageNameToRegexp($pattern);
|
$patternRegexp = BasePackage::packageNameToRegexp($pattern);
|
||||||
// update pattern matches a locked package? => all good
|
// update pattern matches a locked package? => all good
|
||||||
foreach ($request->getLockedRepository()->getPackages() as $package) {
|
foreach ($request->getLockedRepository()->getPackages() as $package) {
|
||||||
|
|
|
@ -50,10 +50,12 @@ class Request
|
||||||
protected $lockedPackages = [];
|
protected $lockedPackages = [];
|
||||||
/** @var array<string, BasePackage> */
|
/** @var array<string, BasePackage> */
|
||||||
protected $fixedLockedPackages = [];
|
protected $fixedLockedPackages = [];
|
||||||
/** @var string[] */
|
/** @var array<string> */
|
||||||
protected $updateAllowList = [];
|
protected $updateAllowList = [];
|
||||||
/** @var false|self::UPDATE_* */
|
/** @var false|self::UPDATE_* */
|
||||||
protected $updateAllowTransitiveDependencies = false;
|
protected $updateAllowTransitiveDependencies = false;
|
||||||
|
/** @var non-empty-list<string>|null */
|
||||||
|
private $restrictedPackages = null;
|
||||||
|
|
||||||
public function __construct(?LockArrayRepository $lockedRepository = null)
|
public function __construct(?LockArrayRepository $lockedRepository = null)
|
||||||
{
|
{
|
||||||
|
@ -118,7 +120,7 @@ class Request
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string[] $updateAllowList
|
* @param array<string> $updateAllowList
|
||||||
* @param false|self::UPDATE_* $updateAllowTransitiveDependencies
|
* @param false|self::UPDATE_* $updateAllowTransitiveDependencies
|
||||||
*/
|
*/
|
||||||
public function setUpdateAllowList(array $updateAllowList, $updateAllowTransitiveDependencies): void
|
public function setUpdateAllowList(array $updateAllowList, $updateAllowTransitiveDependencies): void
|
||||||
|
@ -128,7 +130,7 @@ class Request
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string[]
|
* @return array<string>
|
||||||
*/
|
*/
|
||||||
public function getUpdateAllowList(): array
|
public function getUpdateAllowList(): array
|
||||||
{
|
{
|
||||||
|
@ -233,4 +235,22 @@ class Request
|
||||||
{
|
{
|
||||||
return $this->lockedRepository;
|
return $this->lockedRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restricts the pool builder from loading other packages than those listed here
|
||||||
|
*
|
||||||
|
* @param non-empty-list<string> $names
|
||||||
|
*/
|
||||||
|
public function restrictPackages(array $names): void
|
||||||
|
{
|
||||||
|
$this->restrictedPackages = $names;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list<string>
|
||||||
|
*/
|
||||||
|
public function getRestrictedPackages(): ?array
|
||||||
|
{
|
||||||
|
return $this->restrictedPackages;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,7 +180,7 @@ class Installer
|
||||||
/**
|
/**
|
||||||
* Array of package names/globs flagged for update
|
* Array of package names/globs flagged for update
|
||||||
*
|
*
|
||||||
* @var string[]|null
|
* @var non-empty-list<string>|null
|
||||||
*/
|
*/
|
||||||
protected $updateAllowList = null;
|
protected $updateAllowList = null;
|
||||||
/** @var Request::UPDATE_* */
|
/** @var Request::UPDATE_* */
|
||||||
|
@ -242,7 +242,7 @@ class Installer
|
||||||
gc_collect_cycles();
|
gc_collect_cycles();
|
||||||
gc_disable();
|
gc_disable();
|
||||||
|
|
||||||
if ($this->updateAllowList && $this->updateMirrors) {
|
if ($this->updateAllowList !== null && $this->updateMirrors) {
|
||||||
throw new \RuntimeException("The installer options updateMirrors and updateAllowList are mutually exclusive.");
|
throw new \RuntimeException("The installer options updateMirrors and updateAllowList are mutually exclusive.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,7 +436,7 @@ class Installer
|
||||||
$lockedRepository = $this->locker->getLockedRepository(true);
|
$lockedRepository = $this->locker->getLockedRepository(true);
|
||||||
}
|
}
|
||||||
} catch (\Seld\JsonLint\ParsingException $e) {
|
} catch (\Seld\JsonLint\ParsingException $e) {
|
||||||
if ($this->updateAllowList || $this->updateMirrors) {
|
if ($this->updateAllowList !== null || $this->updateMirrors) {
|
||||||
// in case we are doing a partial update or updating mirrors, the lock file is needed so we error
|
// in case we are doing a partial update or updating mirrors, the lock file is needed so we error
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
@ -444,7 +444,7 @@ class Installer
|
||||||
// doing a full update
|
// doing a full update
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($this->updateAllowList || $this->updateMirrors) && !$lockedRepository) {
|
if (($this->updateAllowList !== null || $this->updateMirrors) && !$lockedRepository) {
|
||||||
$this->io->writeError('<error>Cannot update ' . ($this->updateMirrors ? 'lock file information' : 'only a partial set of packages') . ' without a lock file present. Run `composer update` to generate a lock file.</error>', true, IOInterface::QUIET);
|
$this->io->writeError('<error>Cannot update ' . ($this->updateMirrors ? 'lock file information' : 'only a partial set of packages') . ' without a lock file present. Run `composer update` to generate a lock file.</error>', true, IOInterface::QUIET);
|
||||||
|
|
||||||
return self::ERROR_NO_LOCK_FILE_FOR_PARTIAL_UPDATE;
|
return self::ERROR_NO_LOCK_FILE_FOR_PARTIAL_UPDATE;
|
||||||
|
@ -467,7 +467,7 @@ class Installer
|
||||||
$this->requirePackagesForUpdate($request, $lockedRepository, true);
|
$this->requirePackagesForUpdate($request, $lockedRepository, true);
|
||||||
|
|
||||||
// pass the allow list into the request, so the pool builder can apply it
|
// pass the allow list into the request, so the pool builder can apply it
|
||||||
if ($this->updateAllowList) {
|
if ($this->updateAllowList !== null) {
|
||||||
$request->setUpdateAllowList($this->updateAllowList, $this->updateAllowTransitiveDependencies);
|
$request->setUpdateAllowList($this->updateAllowList, $this->updateAllowTransitiveDependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1337,7 +1337,11 @@ class Installer
|
||||||
*/
|
*/
|
||||||
public function setUpdateAllowList(array $packages): self
|
public function setUpdateAllowList(array $packages): self
|
||||||
{
|
{
|
||||||
$this->updateAllowList = array_flip(array_map('strtolower', $packages));
|
if (count($packages) === 0) {
|
||||||
|
$this->updateAllowList = null;
|
||||||
|
} else {
|
||||||
|
$this->updateAllowList = array_values(array_unique(array_map('strtolower', $packages)));
|
||||||
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -367,12 +367,18 @@ class RepositorySet
|
||||||
{
|
{
|
||||||
$request = new Request($lockedRepo);
|
$request = new Request($lockedRepo);
|
||||||
|
|
||||||
|
$allowedPackages = [];
|
||||||
foreach ($packageNames as $packageName) {
|
foreach ($packageNames as $packageName) {
|
||||||
if (PlatformRepository::isPlatformPackage($packageName)) {
|
if (PlatformRepository::isPlatformPackage($packageName)) {
|
||||||
throw new \LogicException('createPoolForPackage(s) can not be used for platform packages, as they are never loaded by the PoolBuilder which expects them to be fixed. Use createPoolWithAllPackages or pass in a proper request with the platform packages you need fixed in it.');
|
throw new \LogicException('createPoolForPackage(s) can not be used for platform packages, as they are never loaded by the PoolBuilder which expects them to be fixed. Use createPoolWithAllPackages or pass in a proper request with the platform packages you need fixed in it.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$request->requireName($packageName);
|
$request->requireName($packageName);
|
||||||
|
$allowedPackages[] = strtolower($packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($allowedPackages) > 0) {
|
||||||
|
$request->restrictPackages($allowedPackages);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->createPool($request, new NullIO());
|
return $this->createPool($request, new NullIO());
|
||||||
|
|
|
@ -126,7 +126,7 @@ class PoolBuilderTest extends TestCase
|
||||||
if (isset($requestData['allowTransitiveDeps']) && $requestData['allowTransitiveDeps']) {
|
if (isset($requestData['allowTransitiveDeps']) && $requestData['allowTransitiveDeps']) {
|
||||||
$transitiveDeps = Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS;
|
$transitiveDeps = Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS;
|
||||||
}
|
}
|
||||||
$request->setUpdateAllowList(array_flip($requestData['allowList']), $transitiveDeps);
|
$request->setUpdateAllowList($requestData['allowList'], $transitiveDeps);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($fixed as $fixedPackage) {
|
foreach ($fixed as $fixedPackage) {
|
||||||
|
|
Loading…
Reference in New Issue