CheckCommand   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Test Coverage

Coverage 91.46%

Importance

Changes 0
Metric Value
eloc 76
dl 0
loc 122
ccs 75
cts 82
cp 0.9146
rs 10
c 0
b 0
f 0
wmc 13

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A configure() 0 40 1
B execute() 0 65 11
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SavinMikhail\DistSizeOptimizer\Command;
6
7
use InvalidArgumentException;
8
use SavinMikhail\DistSizeOptimizer\Formatters\ConsoleReportFormatter;
0 ignored issues
show
Bug introduced by
The type SavinMikhail\DistSizeOpt...\ConsoleReportFormatter was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use SavinMikhail\DistSizeOptimizer\Formatters\FormatterInterface;
10
use SavinMikhail\DistSizeOptimizer\Formatters\JsonReportFormatter;
0 ignored issues
show
Bug introduced by
The type SavinMikhail\DistSizeOpt...ers\JsonReportFormatter was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use SavinMikhail\DistSizeOptimizer\GitAttributesManager\GitAttributesManager;
12
use SavinMikhail\DistSizeOptimizer\PackageManager\PackageManager;
0 ignored issues
show
Bug introduced by
The type SavinMikhail\DistSizeOpt...eManager\PackageManager was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use SavinMikhail\DistSizeOptimizer\Scanner\ExportIgnoreScanner;
0 ignored issues
show
Bug introduced by
The type SavinMikhail\DistSizeOpt...ner\ExportIgnoreScanner was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use SavinMikhail\DistSizeOptimizer\SizeCalculator\FileSizeCalculator;
0 ignored issues
show
Bug introduced by
The type SavinMikhail\DistSizeOpt...ator\FileSizeCalculator was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use Symfony\Component\Console\Command\Command;
16
use Symfony\Component\Console\Input\InputArgument;
17
use Symfony\Component\Console\Input\InputInterface;
18
use Symfony\Component\Console\Input\InputOption;
19
use Symfony\Component\Console\Output\OutputInterface;
20
21
use function count;
22
use function SavinMikhail\DistSizeOptimizer\formatBytes;
0 ignored issues
show
introduced by
The function SavinMikhail\DistSizeOptimizer\formatBytes was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
23
24
final class CheckCommand extends Command
25
{
26
    private const DEFAULT_CONFIG = __DIR__ . '/../../export-ignore.php';
27
28 5
    public function __construct(
29
        private readonly ExportIgnoreScanner $scanner = new ExportIgnoreScanner(),
30
        private readonly FileSizeCalculator $calculator = new FileSizeCalculator(),
31
        private FormatterInterface $formatter = new ConsoleReportFormatter(),
32
        private readonly PackageManager $packageManager = new PackageManager(),
33
        private readonly GitAttributesManager $gitAttributesManager = new GitAttributesManager(),
34
    ) {
35 5
        parent::__construct();
36
    }
37
38 5
    protected function configure(): void
39
    {
40 5
        $this
41 5
            ->setName(name: 'check')
42 5
            ->setDescription(description: 'Check which files and folders are not excluded via export-ignore')
43 5
            ->addArgument(
44 5
                name: 'package',
45 5
                mode: InputArgument::OPTIONAL,
46 5
                description: 'Package name (e.g. vendor/package). If not provided, checks current project',
47 5
            )
48 5
            ->addOption(
49 5
                name: 'json',
50 5
                shortcut: null,
51 5
                mode: InputOption::VALUE_NONE,
52 5
                description: 'Output results as JSON',
53 5
            )
54 5
            ->addOption(
55 5
                name: 'config',
56 5
                shortcut: 'c',
57 5
                mode: InputOption::VALUE_REQUIRED,
58 5
                description: 'Path to config file with patterns to check',
59 5
                default: self::DEFAULT_CONFIG,
60 5
            )
61 5
            ->addOption(
62 5
                name: 'workdir',
63 5
                shortcut: 'w',
64 5
                mode: InputOption::VALUE_OPTIONAL,
65 5
                description: 'Path to project workdir',
66 5
            )
67 5
            ->addOption(
68 5
                name: 'dry-run',
69 5
                shortcut: null,
70 5
                mode: InputOption::VALUE_NONE,
71 5
                description: 'Only show what would be added to .gitattributes without making changes',
72 5
            )
73 5
            ->addOption(
74 5
                name: 'clean',
75 5
                shortcut: null,
76 5
                mode: InputOption::VALUE_NONE,
77 5
                description: 'Clean .gitattributes of non-existent entries',
78 5
            );
79
    }
80
81 5
    protected function execute(InputInterface $input, OutputInterface $output): int
82
    {
83 5
        if ($input->getOption('clean')) {
84
            $output->writeln('<info>Cleaning .gitattributes of stale patterns...</info>');
85
            $this->gitAttributesManager->cleanPatterns();
86
            $output->writeln('<info>Cleanup complete!</info>');
87
88
            return Command::SUCCESS;
89
        }
90
91 5
        $package = $input->getArgument('package');
92 5
        $configPath = $input->getOption('config');
93 5
        $isDryRun = $input->getOption('dry-run');
94 5
        $workdir = $input->getOption('workdir');
95
96 5
        if (!file_exists(filename: $configPath)) {
97 1
            throw new InvalidArgumentException(message: "Config file not found: {$configPath}");
98
        }
99
100 4
        $this->packageManager->setWorkdir(workdir: $workdir);
101
102
        try {
103 4
            if ($package === null) {
104 2
                $path = $this->packageManager->createGitArchive();
105
            } else {
106 2
                if (!str_contains(haystack: (string) $package, needle: '/')) {
107 1
                    throw new InvalidArgumentException(message: 'Package must be in format vendor/package');
108
                }
109 1
                $path = $this->packageManager->downloadPackage(packageName: $package);
110
            }
111
112 3
            $patterns = require $configPath;
113
114 3
            $violating = $this->scanner->scan(packagePath: $path, patterns: $patterns);
115
116 3
            if (count(value: $violating['files']) === 0 && count(value: $violating['directories']) === 0) {
117
                $output->writeln('<info>No unnecessary files or directories found. All good!</info>');
118
119
                return Command::SUCCESS;
120
            }
121
122 3
            $totalSize = $this->calculator->calculateTotalSize(
123 3
                basePath: $path,
124 3
                paths: array_merge($violating['files'], $violating['directories']),
125 3
            );
126 3
            $humanSize = formatBytes(bytes: $totalSize);
0 ignored issues
show
Bug introduced by
The function formatBytes was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

126
            $humanSize = /** @scrutinizer ignore-call */ formatBytes(bytes: $totalSize);
Loading history...
127
128 3
            if ($input->getOption('json')) {
129 2
                $this->formatter = new JsonReportFormatter();
130
            }
131 3
            $this->formatter->output($output, $violating, $totalSize, $humanSize);
132
133 3
            $status = Command::FAILURE;
134
135 3
            if (!$isDryRun && $package === null) {
136 1
                $this->gitAttributesManager->appendPatterns(violatingFilesAndDirs: $violating);
137 1
                $output->writeln('<info>Patterns have been added to .gitattributes</info>');
138 1
                $status = Command::SUCCESS;
139 2
            } elseif (!$isDryRun) {
140
                $output->writeln('<comment>Note: --dry-run is ignored when checking a specific package</comment>');
141
            }
142
143 3
            return $status;
144
        } finally {
145 4
            $this->packageManager->cleanup();
146
        }
147
    }
148
}
149