From dafd225a35977d2e6d82cef5582a128147614f98 Mon Sep 17 00:00:00 2001 From: Lars Strojny Date: Mon, 14 Sep 2020 21:54:44 +0200 Subject: [PATCH] Allow to pass a string for apcu-autoloader to set the APCu prefix --- src/Composer/Autoload/AutoloadGenerator.php | 8 +-- src/Composer/Command/DumpAutoloadCommand.php | 6 +-- src/Composer/Command/InstallCommand.php | 6 +-- src/Composer/Command/RemoveCommand.php | 6 +-- src/Composer/Command/RequireCommand.php | 6 +-- src/Composer/Command/UpdateCommand.php | 6 +-- src/Composer/Installer.php | 4 +- .../Test/Autoload/AutoloadGeneratorTest.php | 49 +++++++++++++++++++ 8 files changed, 70 insertions(+), 21 deletions(-) diff --git a/src/Composer/Autoload/AutoloadGenerator.php b/src/Composer/Autoload/AutoloadGenerator.php index da4f252b8..619d3b32f 100644 --- a/src/Composer/Autoload/AutoloadGenerator.php +++ b/src/Composer/Autoload/AutoloadGenerator.php @@ -53,7 +53,7 @@ class AutoloadGenerator private $classMapAuthoritative = false; /** - * @var bool + * @var bool|string */ private $apcu = false; @@ -92,11 +92,11 @@ class AutoloadGenerator /** * Whether or not generated autoloader considers APCu caching. * - * @param bool $apcu + * @param bool|string $apcu */ public function setApcu($apcu) { - $this->apcu = (bool) $apcu; + $this->apcu = is_string($apcu) ? $apcu : (bool) $apcu; } /** @@ -858,7 +858,7 @@ CLASSMAPAUTHORITATIVE; } if ($this->apcu) { - $apcuPrefix = substr(base64_encode(md5(uniqid('', true), true)), 0, -3); + $apcuPrefix = is_string($this->apcu) ? $this->apcu : substr(base64_encode(md5(uniqid('', true), true)), 0, -3); $file .= <<setApcuPrefix('$apcuPrefix'); diff --git a/src/Composer/Command/DumpAutoloadCommand.php b/src/Composer/Command/DumpAutoloadCommand.php index 7449d197c..ee6baabdb 100644 --- a/src/Composer/Command/DumpAutoloadCommand.php +++ b/src/Composer/Command/DumpAutoloadCommand.php @@ -33,7 +33,7 @@ class DumpAutoloadCommand extends BaseCommand new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'), new InputOption('optimize', 'o', InputOption::VALUE_NONE, 'Optimizes PSR0 and PSR4 packages to be loaded with classmaps too, good for production.'), new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize`.'), - new InputOption('apcu', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'), + new InputOption('apcu', null, InputOption::VALUE_OPTIONAL, 'Use APCu to cache found/not-found classes.'), new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables autoload-dev rules.'), new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'), new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'), @@ -62,7 +62,7 @@ EOT $optimize = $input->getOption('optimize') || $config->get('optimize-autoloader'); $authoritative = $input->getOption('classmap-authoritative') || $config->get('classmap-authoritative'); - $apcu = $input->getOption('apcu') || $config->get('apcu-autoloader'); + $apcu = strpos($input, '--apcu') !== false || $config->get('apcu-autoloader'); if ($authoritative) { $this->getIO()->write('Generating optimized autoload files (authoritative)'); @@ -77,7 +77,7 @@ EOT $generator = $composer->getAutoloadGenerator(); $generator->setDevMode(!$input->getOption('no-dev')); $generator->setClassMapAuthoritative($authoritative); - $generator->setApcu($apcu); + $generator->setApcu($apcu ? $input->getOption('apcu') ?: true : false); $generator->setRunScripts(!$input->getOption('no-scripts')); $generator->setIgnorePlatformRequirements($ignorePlatformReqs); $numberOfClasses = $generator->dump($config, $localRepo, $package, $installationManager, 'composer', $optimize); diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index f8294c47b..07f388867 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -48,7 +48,7 @@ class InstallCommand extends BaseCommand new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Shows more details including new commits pulled in when updating packages.'), new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump'), new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'), - new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'), + new InputOption('apcu-autoloader', null, InputOption::VALUE_OPTIONAL, 'Use APCu to cache found/not-found classes (passing an argument sets the APCu prefix)'), new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'), new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'), new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Should not be provided, use composer require instead to add a given package to composer.json.'), @@ -102,7 +102,7 @@ EOT $optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader'); $authoritative = $input->getOption('classmap-authoritative') || $config->get('classmap-authoritative'); - $apcu = $input->getOption('apcu-autoloader') || $config->get('apcu-autoloader'); + $apcu = strpos($input, '--apcu-autoloader') !== false || $config->get('apcu-autoloader'); $ignorePlatformReqs = $input->getOption('ignore-platform-reqs') ?: ($input->getOption('ignore-platform-req') ?: false); @@ -118,7 +118,7 @@ EOT ->setRunScripts(!$input->getOption('no-scripts')) ->setOptimizeAutoloader($optimize) ->setClassMapAuthoritative($authoritative) - ->setApcuAutoloader($apcu) + ->setApcuAutoloader($apcu ? $input->getOption('apcu-autoloader') ?: true : false) ->setIgnorePlatformRequirements($ignorePlatformReqs) ; diff --git a/src/Composer/Command/RemoveCommand.php b/src/Composer/Command/RemoveCommand.php index 53c040412..99be3810b 100644 --- a/src/Composer/Command/RemoveCommand.php +++ b/src/Composer/Command/RemoveCommand.php @@ -54,7 +54,7 @@ class RemoveCommand extends BaseCommand new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'), new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump'), new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'), - new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'), + new InputOption('apcu-autoloader', null, InputOption::VALUE_OPTIONAL, 'Use APCu to cache found/not-found classes (passing a string sets the APCu prefix)'), )) ->setHelp( <<getOption('update-no-dev'); $optimize = $input->getOption('optimize-autoloader') || $composer->getConfig()->get('optimize-autoloader'); $authoritative = $input->getOption('classmap-authoritative') || $composer->getConfig()->get('classmap-authoritative'); - $apcu = $input->getOption('apcu-autoloader') || $composer->getConfig()->get('apcu-autoloader'); + $apcu = strpos($input, '--apcu-autoloader') !== false || $composer->getConfig()->get('apcu-autoloader'); $updateAllowTransitiveDependencies = Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS_NO_ROOT_REQUIRE; $flags = ''; @@ -248,7 +248,7 @@ EOT ->setDevMode($updateDevMode) ->setOptimizeAutoloader($optimize) ->setClassMapAuthoritative($authoritative) - ->setApcuAutoloader($apcu) + ->setApcuAutoloader($apcu ? $input->getOption('apcu-autoloader') ?: true : false) ->setUpdate(true) ->setInstall(!$input->getOption('no-install')) ->setUpdateAllowList($packages) diff --git a/src/Composer/Command/RequireCommand.php b/src/Composer/Command/RequireCommand.php index 9525b9e77..b1ad95b67 100644 --- a/src/Composer/Command/RequireCommand.php +++ b/src/Composer/Command/RequireCommand.php @@ -76,7 +76,7 @@ class RequireCommand extends InitCommand new InputOption('sort-packages', null, InputOption::VALUE_NONE, 'Sorts packages when adding/updating a new dependency'), new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump'), new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'), - new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'), + new InputOption('apcu-autoloader', null, InputOption::VALUE_OPTIONAL, 'Use APCu to cache found/not-found classes (passing a string sets the APCu prefix)'), )) ->setHelp( <<getOption('update-no-dev'); $optimize = $input->getOption('optimize-autoloader') || $composer->getConfig()->get('optimize-autoloader'); $authoritative = $input->getOption('classmap-authoritative') || $composer->getConfig()->get('classmap-authoritative'); - $apcu = $input->getOption('apcu-autoloader') || $composer->getConfig()->get('apcu-autoloader'); + $apcu = strpos($input, '--apcu-autoloader') !== false || $composer->getConfig()->get('apcu-autoloader'); $updateAllowTransitiveDependencies = Request::UPDATE_ONLY_LISTED; $flags = ''; @@ -301,7 +301,7 @@ EOT ->setRunScripts(!$input->getOption('no-scripts')) ->setOptimizeAutoloader($optimize) ->setClassMapAuthoritative($authoritative) - ->setApcuAutoloader($apcu) + ->setApcuAutoloader($apcu ? $input->getOption('apcu-autoloader') ?: true : false) ->setUpdate(true) ->setInstall(!$input->getOption('no-install')) ->setUpdateAllowTransitiveDependencies($updateAllowTransitiveDependencies) diff --git a/src/Composer/Command/UpdateCommand.php b/src/Composer/Command/UpdateCommand.php index 809db532c..bff37129f 100644 --- a/src/Composer/Command/UpdateCommand.php +++ b/src/Composer/Command/UpdateCommand.php @@ -59,7 +59,7 @@ class UpdateCommand extends BaseCommand new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Shows more details including new commits pulled in when updating packages.'), new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump.'), new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'), - new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'), + new InputOption('apcu-autoloader', null, InputOption::VALUE_OPTIONAL, 'Use APCu to cache found/not-found classes (passing a string sets the APCu prefix)'), new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'), new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'), new InputOption('prefer-stable', null, InputOption::VALUE_NONE, 'Prefer stable versions of dependencies.'), @@ -189,7 +189,7 @@ EOT $optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader'); $authoritative = $input->getOption('classmap-authoritative') || $config->get('classmap-authoritative'); - $apcu = $input->getOption('apcu-autoloader') || $config->get('apcu-autoloader'); + $apcu = strpos($input, '--apcu-autoloader') !== false || $config->get('apcu-autoloader'); $updateAllowTransitiveDependencies = Request::UPDATE_ONLY_LISTED; if ($input->getOption('with-all-dependencies')) { @@ -210,7 +210,7 @@ EOT ->setRunScripts(!$input->getOption('no-scripts')) ->setOptimizeAutoloader($optimize) ->setClassMapAuthoritative($authoritative) - ->setApcuAutoloader($apcu) + ->setApcuAutoloader($apcu ? $input->getOption('apcu-autoloader') ?: true : false) ->setUpdate(true) ->setInstall(!$input->getOption('no-install')) ->setUpdateMirrors($updateMirrors) diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index 535ad8e4c..17d319e00 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -1023,12 +1023,12 @@ class Installer /** * Whether or not generated autoloader considers APCu caching. * - * @param bool $apcuAutoloader + * @param bool|string $apcuAutoloader * @return Installer */ public function setApcuAutoloader($apcuAutoloader = false) { - $this->apcuAutoloader = (bool) $apcuAutoloader; + $this->apcuAutoloader = is_string($apcuAutoloader) ? $apcuAutoloader : (bool) $apcuAutoloader; return $this; } diff --git a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php index ad38b3c8f..fbc2ba86b 100644 --- a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php +++ b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php @@ -823,6 +823,55 @@ EOF; $this->assertStringContainsString('$loader->setApcuPrefix(', file_get_contents($this->vendorDir.'/composer/autoload_real.php')); } + public function testClassMapAutoloadingAuthoritativeAndApcuPrefix() + { + $package = new Package('a', '1.0', '1.0'); + $package->setRequires(array( + new Link('a', 'a/a', new MatchAllConstraint()), + new Link('a', 'b/b', new MatchAllConstraint()), + new Link('a', 'c/c', new MatchAllConstraint()), + )); + + $packages = array(); + $packages[] = $a = new Package('a/a', '1.0', '1.0'); + $packages[] = $b = new Package('b/b', '1.0', '1.0'); + $packages[] = $c = new Package('c/c', '1.0', '1.0'); + $a->setAutoload(array('psr-4' => array('' => 'src/'))); + $b->setAutoload(array('psr-4' => array('' => './'))); + $c->setAutoload(array('psr-4' => array('' => 'foo/'))); + + $this->repository->expects($this->once()) + ->method('getCanonicalPackages') + ->will($this->returnValue($packages)); + + $this->fs->ensureDirectoryExists($this->vendorDir.'/composer'); + $this->fs->ensureDirectoryExists($this->vendorDir.'/a/a/src'); + $this->fs->ensureDirectoryExists($this->vendorDir.'/b/b'); + $this->fs->ensureDirectoryExists($this->vendorDir.'/c/c/foo'); + file_put_contents($this->vendorDir.'/a/a/src/ClassMapFoo.php', 'vendorDir.'/b/b/ClassMapBar.php', 'vendorDir.'/c/c/foo/ClassMapBaz.php', 'generator->setClassMapAuthoritative(true); + $this->generator->setApcu('customPrefix'); + $this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', false, '_7'); + + $this->assertFileExists($this->vendorDir.'/composer/autoload_classmap.php', "ClassMap file needs to be generated."); + $this->assertEquals( + array( + 'ClassMapBar' => $this->vendorDir.'/b/b/ClassMapBar.php', + 'ClassMapBaz' => $this->vendorDir.'/c/c/foo/ClassMapBaz.php', + 'ClassMapFoo' => $this->vendorDir.'/a/a/src/ClassMapFoo.php', + 'Composer\\InstalledVersions' => $this->vendorDir.'/composer/InstalledVersions.php', + ), + include $this->vendorDir.'/composer/autoload_classmap.php' + ); + $this->assertAutoloadFiles('classmap8', $this->vendorDir.'/composer', 'classmap'); + + $this->assertStringContainsString('$loader->setClassMapAuthoritative(true);', file_get_contents($this->vendorDir.'/composer/autoload_real.php')); + $this->assertStringContainsString('$loader->setApcuPrefix(\'customPrefix\');', file_get_contents($this->vendorDir.'/composer/autoload_real.php')); + } + public function testFilesAutoloadGeneration() { $package = new Package('a', '1.0', '1.0');