From 40273745cecaf98651870bae3793abf7905c4165 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Wed, 8 May 2019 11:57:35 +0200 Subject: [PATCH 1/5] clarify the possible class/interface of the cache When the fallback cache pool is returned (on PHP 5.6, HHVM, or when Opcache is disabled), the configured service can be any implementation of the CacheItemPoolInterface. --- .../Bundle/FrameworkBundle/Resources/config/serializer.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml index b1918047f7..fe93664854 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml @@ -82,7 +82,7 @@ - + %serializer.mapping.cache.file% From ae7ee464651d166d3a2cb9cc19dce7f63a0c3d27 Mon Sep 17 00:00:00 2001 From: Amrouche Hamza Date: Fri, 26 Apr 2019 09:17:50 +0200 Subject: [PATCH 2/5] [Console] Commands with an alias should not be recognized as ambiguous --- src/Symfony/Component/Console/Application.php | 9 ++++++ .../Console/Tests/ApplicationTest.php | 31 ++++++++++++++++--- ...hp => TestAmbiguousCommandRegistering.php} | 8 ++--- ...p => TestAmbiguousCommandRegistering2.php} | 8 ++--- 4 files changed, 43 insertions(+), 13 deletions(-) rename src/Symfony/Component/Console/Tests/Fixtures/{TestToto.php => TestAmbiguousCommandRegistering.php} (65%) rename src/Symfony/Component/Console/Tests/Fixtures/{TestTiti.php => TestAmbiguousCommandRegistering2.php} (62%) diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index 6cc5f5c580..4d10c31699 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -596,6 +596,15 @@ class Application $this->init(); $aliases = []; + + foreach ($this->commands as $command) { + foreach ($command->getAliases() as $alias) { + if (!$this->has($alias)) { + $this->commands[$alias] = $command; + } + } + } + $allCommands = $this->commandLoader ? array_merge($this->commandLoader->getNames(), array_keys($this->commands)) : array_keys($this->commands); $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name); $commands = preg_grep('{^'.$expr.'}', $allCommands); diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index 200568f070..b920d211aa 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -72,8 +72,8 @@ class ApplicationTest extends TestCase require_once self::$fixturesPath.'/BarBucCommand.php'; require_once self::$fixturesPath.'/FooSubnamespaced1Command.php'; require_once self::$fixturesPath.'/FooSubnamespaced2Command.php'; - require_once self::$fixturesPath.'/TestTiti.php'; - require_once self::$fixturesPath.'/TestToto.php'; + require_once self::$fixturesPath.'/TestAmbiguousCommandRegistering.php'; + require_once self::$fixturesPath.'/TestAmbiguousCommandRegistering2.php'; } protected function normalizeLineBreaks($text) @@ -164,6 +164,27 @@ class ApplicationTest extends TestCase $this->assertEquals('foo', $command->getName(), '->register() registers a new command'); } + public function testRegisterAmbiguous() + { + $code = function (InputInterface $input, OutputInterface $output) { + $output->writeln('It works!'); + }; + + $application = new Application(); + $application + ->register('test-foo') + ->setAliases(['test']) + ->setCode($code); + + $application + ->register('test-bar') + ->setCode($code); + + $tester = new ApplicationTester($application); + $tester->run(['test']); + $this->assertContains('It works!', $tester->getDisplay(true)); + } + public function testAdd() { $application = new Application(); @@ -303,9 +324,9 @@ class ApplicationTest extends TestCase public function testFindNonAmbiguous() { $application = new Application(); - $application->add(new \TestTiti()); - $application->add(new \TestToto()); - $this->assertEquals('test-toto', $application->find('test')->getName()); + $application->add(new \TestAmbiguousCommandRegistering()); + $application->add(new \TestAmbiguousCommandRegistering2()); + $this->assertEquals('test-ambiguous', $application->find('test')->getName()); } /** diff --git a/src/Symfony/Component/Console/Tests/Fixtures/TestToto.php b/src/Symfony/Component/Console/Tests/Fixtures/TestAmbiguousCommandRegistering.php similarity index 65% rename from src/Symfony/Component/Console/Tests/Fixtures/TestToto.php rename to src/Symfony/Component/Console/Tests/Fixtures/TestAmbiguousCommandRegistering.php index 2e6a819593..bece09fcdd 100644 --- a/src/Symfony/Component/Console/Tests/Fixtures/TestToto.php +++ b/src/Symfony/Component/Console/Tests/Fixtures/TestAmbiguousCommandRegistering.php @@ -4,19 +4,19 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -class TestToto extends Command +class TestAmbiguousCommandRegistering extends Command { protected function configure() { $this - ->setName('test-toto') - ->setDescription('The test-toto command') + ->setName('test-ambiguous') + ->setDescription('The test-ambiguous command') ->setAliases(['test']) ; } protected function execute(InputInterface $input, OutputInterface $output) { - $output->write('test-toto'); + $output->write('test-ambiguous'); } } diff --git a/src/Symfony/Component/Console/Tests/Fixtures/TestTiti.php b/src/Symfony/Component/Console/Tests/Fixtures/TestAmbiguousCommandRegistering2.php similarity index 62% rename from src/Symfony/Component/Console/Tests/Fixtures/TestTiti.php rename to src/Symfony/Component/Console/Tests/Fixtures/TestAmbiguousCommandRegistering2.php index 72e29d2a0a..9dde486245 100644 --- a/src/Symfony/Component/Console/Tests/Fixtures/TestTiti.php +++ b/src/Symfony/Component/Console/Tests/Fixtures/TestAmbiguousCommandRegistering2.php @@ -4,18 +4,18 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -class TestTiti extends Command +class TestAmbiguousCommandRegistering2 extends Command { protected function configure() { $this - ->setName('test-titi') - ->setDescription('The test:titi command') + ->setName('test-ambiguous2') + ->setDescription('The test-ambiguous2 command') ; } protected function execute(InputInterface $input, OutputInterface $output) { - $output->write('test-titi'); + $output->write('test-ambiguous2'); } } From 36ddfd58b926d29256dba85532ca94283f27b38e Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Wed, 8 May 2019 20:13:28 +0200 Subject: [PATCH 3/5] [Intl] Add FallbackTrait for data generation --- .../Intl/Data/Generator/FallbackTrait.php | 73 +++++++++++++++++ .../Data/Generator/LocaleDataGenerator.php | 82 +++++++------------ 2 files changed, 102 insertions(+), 53 deletions(-) create mode 100644 src/Symfony/Component/Intl/Data/Generator/FallbackTrait.php diff --git a/src/Symfony/Component/Intl/Data/Generator/FallbackTrait.php b/src/Symfony/Component/Intl/Data/Generator/FallbackTrait.php new file mode 100644 index 0000000000..25e177abfa --- /dev/null +++ b/src/Symfony/Component/Intl/Data/Generator/FallbackTrait.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\Data\Generator; + +use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface; +use Symfony\Component\Intl\Locale; + +/** + * @author Roland Franssen + * + * @internal + */ +trait FallbackTrait +{ + private $fallbackCache = []; + private $generatingFallback = false; + + /** + * @param string $tempDir + * @param string $displayLocale + * + * @return array|null + * + * @see AbstractDataGenerator::generateDataForLocale() + */ + abstract protected function generateDataForLocale(BundleEntryReaderInterface $reader, $tempDir, $displayLocale); + + /** + * @param string $tempDir + * + * @return array|null + * + * @see AbstractDataGenerator::generateDataForRoot() + */ + abstract protected function generateDataForRoot(BundleEntryReaderInterface $reader, $tempDir); + + /** + * @param string $tempDir + * @param string $displayLocale + * + * @return array + */ + private function generateFallbackData(BundleEntryReaderInterface $reader, $tempDir, $displayLocale) + { + if (null === $fallback = Locale::getFallback($displayLocale)) { + return []; + } + + if (isset($this->fallbackCache[$fallback])) { + return $this->fallbackCache[$fallback]; + } + + $prevGeneratingFallback = $this->generatingFallback; + $this->generatingFallback = true; + + try { + $data = 'root' === $fallback ? $this->generateDataForRoot($reader, $tempDir) : $this->generateDataForLocale($reader, $tempDir, $fallback); + } finally { + $this->generatingFallback = $prevGeneratingFallback; + } + + return $this->fallbackCache[$fallback] = $data ?: []; + } +} diff --git a/src/Symfony/Component/Intl/Data/Generator/LocaleDataGenerator.php b/src/Symfony/Component/Intl/Data/Generator/LocaleDataGenerator.php index d4f6ab4acc..7fb0096e04 100644 --- a/src/Symfony/Component/Intl/Data/Generator/LocaleDataGenerator.php +++ b/src/Symfony/Component/Intl/Data/Generator/LocaleDataGenerator.php @@ -16,7 +16,6 @@ use Symfony\Component\Intl\Data\Bundle\Compiler\BundleCompilerInterface; use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface; use Symfony\Component\Intl\Data\Util\LocaleScanner; use Symfony\Component\Intl\Exception\MissingResourceException; -use Symfony\Component\Intl\Locale; /** * The rule for compiling the locale bundle. @@ -28,10 +27,10 @@ use Symfony\Component\Intl\Locale; */ class LocaleDataGenerator extends AbstractDataGenerator { - private $locales; - private $localeAliases; - private $fallbackMapping; - private $fallbackCache = []; + use FallbackTrait; + + private $locales = []; + private $localeAliases = []; /** * {@inheritdoc} @@ -40,7 +39,6 @@ class LocaleDataGenerator extends AbstractDataGenerator { $this->locales = $scanner->scanLocales($sourceDir.'/locales'); $this->localeAliases = $scanner->scanAliases($sourceDir.'/locales'); - $this->fallbackMapping = $this->generateFallbackMapping(array_diff($this->locales, array_keys($this->localeAliases)), $this->localeAliases); return $this->locales; } @@ -64,7 +62,6 @@ class LocaleDataGenerator extends AbstractDataGenerator */ protected function preGenerate() { - $this->fallbackCache = []; } /** @@ -73,7 +70,8 @@ class LocaleDataGenerator extends AbstractDataGenerator protected function generateDataForLocale(BundleEntryReaderInterface $reader, $tempDir, $displayLocale) { // Don't generate aliases, as they are resolved during runtime - if (isset($this->localeAliases[$displayLocale])) { + // Unless an alias is needed as fallback for de-duplication purposes + if (isset($this->localeAliases[$displayLocale]) && !$this->generatingFallback) { return; } @@ -85,7 +83,7 @@ class LocaleDataGenerator extends AbstractDataGenerator $localeNames = []; foreach ($this->locales as $locale) { // Ensure a normalized list of pure locales - if (isset($this->localeAliases[$displayLocale]) || \Locale::getAllVariants($locale)) { + if (\Locale::getAllVariants($locale)) { continue; } @@ -102,21 +100,27 @@ class LocaleDataGenerator extends AbstractDataGenerator } } - // Process again to de-duplicate locales and their fallback locales - // Only keep the differences - $fallback = $displayLocale; - while (isset($this->fallbackMapping[$fallback])) { - if (!isset($this->fallbackCache[$fallback = $this->fallbackMapping[$fallback]])) { - $this->fallbackCache[$fallback] = $this->generateDataForLocale($reader, $tempDir, $fallback) ?: []; - } - if (isset($this->fallbackCache[$fallback]['Names'])) { - $localeNames = array_diff($localeNames, $this->fallbackCache[$fallback]['Names']); - } + $data = [ + 'Names' => $localeNames, + ]; + + // Don't de-duplicate a fallback locale + // Ensures the display locale can be de-duplicated on itself + if ($this->generatingFallback) { + return $data; } - if ($localeNames) { - return ['Names' => $localeNames]; + // Process again to de-duplicate locale and its fallback locales + // Only keep the differences + $fallbackData = $this->generateFallbackData($reader, $tempDir, $displayLocale); + if (isset($fallbackData['Names'])) { + $data['Names'] = array_diff($data['Names'], $fallbackData['Names']); } + if (!$data['Names']) { + return; + } + + return $data; } /** @@ -131,12 +135,10 @@ class LocaleDataGenerator extends AbstractDataGenerator */ protected function generateDataForMeta(BundleEntryReaderInterface $reader, $tempDir) { - if ($this->locales || $this->localeAliases) { - return [ - 'Locales' => $this->locales, - 'Aliases' => $this->localeAliases, - ]; - } + return [ + 'Locales' => $this->locales, + 'Aliases' => $this->localeAliases, + ]; } /** @@ -175,30 +177,4 @@ class LocaleDataGenerator extends AbstractDataGenerator return $name; } - - private function generateFallbackMapping(array $displayLocales, array $aliases) - { - $displayLocales = array_flip($displayLocales); - $mapping = []; - - foreach ($displayLocales as $displayLocale => $_) { - $mapping[$displayLocale] = null; - $fallback = $displayLocale; - - // Recursively search for a fallback locale until one is found - while (null !== ($fallback = Locale::getFallback($fallback))) { - // Currently, no locale has an alias as fallback locale. - // If this starts to be the case, we need to add code here. - \assert(!isset($aliases[$fallback])); - - // Check whether the fallback exists - if (isset($displayLocales[$fallback])) { - $mapping[$displayLocale] = $fallback; - break; - } - } - } - - return $mapping; - } } From 1532077e9111f48ceb55025b84582b9d2ac59b2f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 9 May 2019 09:24:55 +0200 Subject: [PATCH 4/5] Update PR template for 4.3 --- .github/PULL_REQUEST_TEMPLATE.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index ac82d7063d..426b55def0 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,20 +1,21 @@ | Q | A | ------------- | --- -| Branch? | master for features / 3.4 up to 4.2 for bug fixes +| Branch? | master for features / 3.4, 4.2 or 4.3 for bug fixes | Bug fix? | yes/no -| New feature? | yes/no +| New feature? | yes/no | BC breaks? | no -| Deprecations? | yes/no +| Deprecations? | yes/no | Tests pass? | yes | Fixed tickets | #... | License | MIT | Doc PR | symfony/symfony-docs#... From 0da4b8319700645fa4057b444c6524bd01d79643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4dlich?= Date: Fri, 3 May 2019 10:56:32 +0200 Subject: [PATCH 5/5] [DI] Removes number of elements information in debug mode --- .../FrameworkBundle/Command/ContainerDebugCommand.php | 1 + .../FrameworkBundle/Console/Descriptor/TextDescriptor.php | 7 ++++++- .../Tests/Console/Descriptor/AbstractDescriptorTest.php | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php index 62adea0e55..eb4f8e4f6d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php @@ -137,6 +137,7 @@ EOF $options['show_arguments'] = $input->getOption('show-arguments'); $options['raw_text'] = $input->getOption('raw'); $options['output'] = $io; + $options['is_debug'] = $this->getApplication()->getKernel()->isDebug(); $helper->describe($io, $object, $options); if (!$input->getArgument('name') && !$input->getOption('tag') && !$input->getOption('parameter') && $input->isInteractive()) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php index 90c7602604..911e60c08b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php @@ -17,6 +17,7 @@ use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\Argument\IteratorArgument; use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; @@ -339,7 +340,11 @@ class TextDescriptor extends Descriptor if ($argument instanceof Reference) { $argumentsInformation[] = sprintf('Service(%s)', (string) $argument); } elseif ($argument instanceof IteratorArgument) { - $argumentsInformation[] = sprintf('Iterator (%d element(s))', \count($argument->getValues())); + if ($argument instanceof TaggedIteratorArgument) { + $argumentsInformation[] = sprintf('Tagged Iterator for "%s"%s', $argument->getTag(), $options['is_debug'] ? '' : sprintf(' (%d element(s))', \count($argument->getValues()))); + } else { + $argumentsInformation[] = sprintf('Iterator (%d element(s))', \count($argument->getValues())); + } } elseif ($argument instanceof Definition) { $argumentsInformation[] = 'Inlined Service'; } else { diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTest.php index 9bc05e538c..248b5396df 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/AbstractDescriptorTest.php @@ -182,6 +182,7 @@ abstract class AbstractDescriptorTest extends TestCase private function assertDescription($expectedDescription, $describedObject, array $options = []) { + $options['is_debug'] = false; $options['raw_output'] = true; $options['raw_text'] = true; $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);