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

onmoon / openapi-server-bundle / 15881876638

25 Jun 2025 04:28PM UTC coverage: 80.585% (-0.5%) from 81.095%
15881876638

Pull #196

github

web-flow
Merge 90ce8070d into c35fba5f2
Pull Request #196: Fix minimum versions install

9 of 29 new or added lines in 5 files covered. (31.03%)

44 existing lines in 12 files now uncovered.

1378 of 1710 relevant lines covered (80.58%)

3.8 hits per line

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

90.7
/src/Command/GenerateApiCodeCommand.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace OnMoon\OpenApiServerBundle\Command;
6

7
use FilesystemIterator;
8
use OnMoon\OpenApiServerBundle\CodeGenerator\ApiServerCodeGenerator;
9
use OnMoon\OpenApiServerBundle\Specification\SpecificationLoader;
10
use RecursiveDirectoryIterator;
11
use RecursiveIteratorIterator;
12
use SplFileInfo;
13
use Symfony\Component\Console\Attribute\AsCommand;
14
use Symfony\Component\Console\Command\Command;
15
use Symfony\Component\Console\Input\InputInterface;
16
use Symfony\Component\Console\Input\InputOption;
17
use Symfony\Component\Console\Output\OutputInterface;
18
use Symfony\Contracts\Cache\TagAwareCacheInterface;
19

20
use function in_array;
21
use function is_dir;
22
use function iterator_count;
23
use function Safe\rmdir;
24
use function Safe\unlink;
25
use function sprintf;
26

27
#[AsCommand(name: 'open-api:generate')]
28
final class GenerateApiCodeCommand extends Command
29
{
30
    public const COMMAND = 'open-api:generate';
31

32
    private ApiServerCodeGenerator $apiServerCodeGenerator;
33
    private TagAwareCacheInterface $cache;
34
    private string $rootPath;
35

36
    public function __construct(
37
        ApiServerCodeGenerator $apiServerCodeGenerator,
38
        TagAwareCacheInterface $cache,
39
        string $rootPath,
40
        ?string $name = null
41
    ) {
42
        $this->apiServerCodeGenerator = $apiServerCodeGenerator;
1✔
43
        $this->cache                  = $cache;
1✔
44
        $this->rootPath               = $rootPath;
1✔
45

46
        parent::__construct($name);
1✔
47
    }
48

49
    protected function configure(): void
50
    {
51
        $this
1✔
52
            ->setDescription('Generates API server code')
1✔
53
            ->addOption(
1✔
54
                'keep',
1✔
55
                'k',
1✔
56
                InputOption::VALUE_NONE,
1✔
57
                'Keep files that are no longer part of specification'
1✔
58
            );
1✔
59
    }
60

61
    /**
62
     * phpcs:disable SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingNativeTypeHint
63
     *
64
     * @var string|null
65
     */
66
    protected static $defaultName = self::COMMAND;
67

68
    protected function execute(InputInterface $input, OutputInterface $output): int
69
    {
70
        $keep = (bool) $input->getOption('keep');
1✔
71

72
        $this->cache->invalidateTags([SpecificationLoader::CACHE_TAG]);
1✔
73
        $files = $this->apiServerCodeGenerator->generate();
1✔
74

75
        if (! $keep) {
1✔
76
            $this->removeExtraFiles($this->rootPath, $files);
1✔
77
            $this->removeEmptyDirectories($this->rootPath);
1✔
78
        }
79

80
        $output->writeln(sprintf('API server code generated in: %s', $this->rootPath));
1✔
81

82
        return 0;
1✔
83
    }
84

85
    /** @param string[] $generatedFiles */
86
    private function removeExtraFiles(string $root, array $generatedFiles): void
87
    {
88
        if (! is_dir($root)) {
1✔
UNCOV
89
            return;
×
90
        }
91

92
        $iterator = new RecursiveIteratorIterator(
1✔
93
            new RecursiveDirectoryIterator(
1✔
94
                $root,
1✔
95
                FilesystemIterator::SKIP_DOTS
1✔
96
            ),
1✔
97
            RecursiveIteratorIterator::CHILD_FIRST
1✔
98
        );
1✔
99

100
        /** @var SplFileInfo $directoryOrFile */
101
        foreach ($iterator as $directoryOrFile) {
1✔
102
            if ($directoryOrFile->isDir() || in_array($directoryOrFile->getPathname(), $generatedFiles, true)) {
1✔
103
                continue;
1✔
104
            }
105

UNCOV
106
            unlink($directoryOrFile->getPathname());
×
107
        }
108
    }
109

110
    private function removeEmptyDirectories(string $root): void
111
    {
112
        if (! is_dir($root)) {
1✔
UNCOV
113
            return;
×
114
        }
115

116
        $directories = new RecursiveIteratorIterator(
1✔
117
            new RecursiveDirectoryIterator($root, FilesystemIterator::SKIP_DOTS),
1✔
118
            RecursiveIteratorIterator::CHILD_FIRST
1✔
119
        );
1✔
120

121
        /**
122
         * @var SplFileInfo $dir
123
         * @psalm-suppress PossiblyNullArgument
124
         */
125
        foreach ($directories as $dir) {
1✔
126
            if (! $dir->isDir() || iterator_count($directories->callGetChildren()) !== 0) {
1✔
127
                continue;
1✔
128
            }
129

UNCOV
130
            rmdir($dir->getPathname());
×
131
        }
132
    }
133
}
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