• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TYPO3 / Surf / #729

29 Apr 2025 12:47PM UTC coverage: 89.175% (+0.004%) from 89.171%
#729

push

simonschaufi
[BUGFIX] Fix surf Symfony Container cache for a new release

2 of 3 new or added lines in 1 file covered. (66.67%)

2109 of 2365 relevant lines covered (89.18%)

9.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.67
/src/Cli/Symfony/ConsoleKernel.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of TYPO3 Surf.
7
 *
8
 * For the full copyright and license information, please view the LICENSE.txt
9
 * file that was distributed with this source code.
10
 */
11

12
namespace TYPO3\Surf\Cli\Symfony;
13

14
use Phar;
15
use Psr\Log\LoggerAwareInterface;
16
use Psr\Log\LoggerInterface;
17
use Symfony\Component\Config\FileLocator;
18
use Symfony\Component\Config\Loader\LoaderInterface;
19
use Symfony\Component\DependencyInjection\Container;
20
use Symfony\Component\DependencyInjection\ContainerBuilder;
21
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
22
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
23
use Symfony\Component\DependencyInjection\Reference;
24
use TYPO3\Surf\Cli\Symfony\CompilerPasses\CommandsToApplicationCompilerPass;
25
use TYPO3\Surf\Domain\Service\ShellCommandService;
26
use TYPO3\Surf\Domain\Service\ShellCommandServiceAwareInterface;
27

28
final class ConsoleKernel
29
{
30
    private bool $booted = false;
31
    private ?Container $container = null;
32
    private string $environment;
33
    private ?string $projectDir = null;
34
    private string $version;
35

36
    public function __construct(string $environment = 'dev', string $version = '')
37
    {
38
        $this->environment = $environment;
26✔
39
        $this->version = str_replace('.', '_', $version);
26✔
40
    }
41

42
    private function registerContainerConfiguration(LoaderInterface $loader): void
43
    {
44
        $loader->load(__DIR__ . '/../../../Resources/services.php');
1✔
45
    }
46

47
    private function build(ContainerBuilder $container): void
48
    {
49
        $container->addCompilerPass(new CommandsToApplicationCompilerPass());
1✔
50
        $container->registerForAutoconfiguration(
1✔
51
            ShellCommandServiceAwareInterface::class
1✔
52
        )->addMethodCall(
1✔
53
            'setShellCommandService',
1✔
54
            [new Reference(ShellCommandService::class)]
1✔
55
        );
1✔
56
        $container->registerForAutoconfiguration(
1✔
57
            LoggerAwareInterface::class
1✔
58
        )->addMethodCall(
1✔
59
            'setLogger',
1✔
60
            [new Reference(LoggerInterface::class)]
1✔
61
        );
1✔
62
    }
63

64
    public function boot(): void
65
    {
66
        if (true === $this->booted) {
26✔
67
            return;
×
68
        }
69
        $this->initializeContainer();
26✔
70
        $this->booted = true;
26✔
71
    }
72

73
    public function getContainer(): Container
74
    {
75
        if ($this->container === null) {
298✔
76
            throw new \UnexpectedValueException('Boot the kernel before');
×
77
        }
78

79
        return $this->container;
298✔
80
    }
81

82
    private function initializeContainer(): void
83
    {
84
        if ($this->container !== null) {
26✔
85
            return;
×
86
        }
87

88
        foreach (['cache' => $this->getCacheDir()] as $name => $dir) {
26✔
89
            if (!is_dir($dir)) {
26✔
90
                if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) {
1✔
91
                    throw new \RuntimeException(sprintf('Unable to create the "%s" directory (%s).', $name, $dir));
1✔
92
                }
93
            } elseif (!is_writable($dir)) {
25✔
94
                throw new \RuntimeException(sprintf('Unable to write in the "%s" directory (%s).', $name, $dir));
×
95
            }
96
        }
97

98
        $file = $this->getCacheDir() . '/container.php';
26✔
99

100
        if (file_exists($file)) {
26✔
101
            require_once $file;
25✔
102
            if (!class_exists(\ProjectServiceContainer::class, false)) {
25✔
103
                throw new \UnexpectedValueException('Class ProjectServiceContainer does not exist');
×
104
            }
105

106
            /** @var Container $container */
107
            $container = new \ProjectServiceContainer();
25✔
108
        } else {
109
            $container = new ContainerBuilder();
1✔
110
            $loader = new PhpFileLoader($container, new FileLocator());
1✔
111

112
            $this->registerContainerConfiguration($loader);
1✔
113
            $this->build($container);
1✔
114

115
            $container->compile();
1✔
116

117
            $dumper = new PhpDumper($container);
1✔
118
            file_put_contents($file, $dumper->dump());
1✔
119
        }
120

121
        $this->container = $container;
26✔
122
    }
123

124
    protected function getCacheDir(): string
125
    {
126
        if (Phar::running() !== '') {
26✔
NEW
127
            return sys_get_temp_dir() . '/_surf_' . $this->version;
×
128
        }
129

130
        return $this->getProjectDir() . '/var/cache/' . $this->version . '/' . $this->environment;
26✔
131
    }
132

133
    private function getProjectDir(): string
134
    {
135
        if (null === $this->projectDir) {
26✔
136
            $r = new \ReflectionObject($this);
26✔
137

138
            $dir = $r->getFileName();
26✔
139

140
            if (!$dir || !is_file($dir)) {
26✔
141
                throw new \LogicException(sprintf('Cannot auto-detect project dir for kernel of class "%s".', $r->name));
×
142
            }
143

144
            $dir = $rootDir = \dirname($dir);
26✔
145
            while (!is_file($dir . '/composer.json')) {
26✔
146
                if ($dir === \dirname($dir)) {
26✔
147
                    return $this->projectDir = $rootDir;
×
148
                }
149
                $dir = \dirname($dir);
26✔
150
            }
151
            $this->projectDir = $dir;
26✔
152
        }
153

154
        return $this->projectDir;
26✔
155
    }
156
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc