CheckCommand::execute()   B
last analyzed

Complexity

Conditions 11
Paths 52

Size

Total Lines 65
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 33
CRAP Score 11.6484

Importance

Changes 0
Metric Value
cc 11
eloc 41
nc 52
nop 2
dl 0
loc 65
ccs 33
cts 40
cp 0.825
crap 11.6484
rs 7.3166
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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