Test Failed
Branch feature/decoupled (5e8293)
by Webysther
02:49
created

Clean::flush()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 2
dl 0
loc 16
ccs 0
cts 12
cp 0
crap 12
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Packagist Mirror.
7
 *
8
 * For the full license information, please view the LICENSE.md
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Webs\Mirror\Command;
13
14
use Symfony\Component\Console\Input\InputInterface;
15
use Symfony\Component\Console\Input\InputOption;
16
use Symfony\Component\Console\Output\OutputInterface;
17
use Webs\Mirror\ShortName;
18
19
/**
20
 * Clean mirror outdated files.
21
 *
22
 * @author Webysther Nunes <[email protected]>
23
 */
24
class Clean extends Base
25
{
26
    use ShortName;
27
28
    /**
29
     * @var array
30
     */
31
    protected $changed = [];
32
33
    /**
34
     * @var array
35
     */
36
    protected $packageRemoved = [];
37
38
    /**
39
     * @var bool
40
     */
41
    protected $isScrub = false;
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function __construct($name = '')
47
    {
48
        parent::__construct('clean');
49
        $this->setDescription(
50
            'Clean outdated files of mirror'
51
        );
52
    }
53
54
    /**
55
     * Console params configuration.
56
     */
57
    protected function configure():void
58
    {
59
        parent::configure();
60
        $this->addOption(
61
            'scrub',
62
            null,
63
            InputOption::VALUE_NONE,
64
            'Check all directories for old files, use only to check all disk'
65
        );
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71
    public function execute(InputInterface $input, OutputInterface $output):int
72
    {
73
        $this->progressBar->setConsole($input, $output);
74
        $this->package->setConsole($input, $output);
75
        $this->provider->setConsole($input, $output);
76
77
        if ($this->input->hasOption('scrub') && $this->input->getOption('scrub')) {
78
            $this->isScrub = true;
79
        }
80
81
        if ($this->flushProviders()->stop()) {
82
            return $this->exitCode;
83
        }
84
85
        if ($this->flushPackages()->stop()) {
86
            return $this->exitCode;
87
        }
88
89
        if (!count($this->changed)) {
90
            $output->writeln('<info>Nothing to clean</>');
91
        }
92
93
        return $this->exitCode;
94
    }
95
96
    /**
97
     * Flush old cached files of providers.
98
     *
99
     * @return Clean
100
     */
101
    protected function flushProviders():Clean
102
    {
103
        $providers = $this->package->loadMainJson();
104
        $includes = array_keys($this->provider->normalize($providers));
105
106
        $this->initialized = $this->filesystem->has(self::INIT);
107
108
        foreach ($includes as $uri) {
109
            $pattern = $this->filesystem->normalize($this->shortname($uri));
110
            $glob = $this->filesystem->glob($pattern);
111
112
            $this->output->writeln(
113
                'Check old file of <info>'.
114
                $pattern.
115
                '</>'
116
            );
117
118
            // If have one file and not scrubing
119
            if (count($glob) < 2 && !$this->isScrub) {
120
                continue;
121
            }
122
123
            $this->changed[] = $uri;
124
            $glob = array_diff($glob, [$uri]);
125
126
            foreach ($glob as $file) {
127
                if ($this->isVerbose()) {
128
                    $this->output->writeln(
129
                        'Old provider <fg=blue;>'.$file.'</> was removed!'
130
                    );
131
                }
132
133
                $this->filesystem->remove($file);
0 ignored issues
show
Bug introduced by
The method remove() does not exist on Webs\Mirror\Filesystem. ( Ignorable by Annotation )

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

133
                $this->filesystem->/** @scrutinizer ignore-call */ 
134
                                   remove($file);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
134
            }
135
        }
136
137
        return $this;
138
    }
139
140
    /**
141
     * Flush old cached files of packages.
142
     *
143
     * @return bool True if work, false otherside
144
     */
145
    protected function flushPackages():bool
146
    {
147
        $increment = 0;
148
149
        foreach ($this->changed as $uri) {
150
            $providers = json_decode($this->filesystem->read($uri));
151
            $list = $this->package->normalize($providers->providers);
152
153
            $this->output->writeln(
154
                '['.++$increment.'/'.count($this->changed).'] '.
155
                'Check old packages for provider '.
156
                '<info>'.$this->shortname($uri).'</>'
157
            );
158
            $this->progressBar->start(count($list));
159
            $this->flushPackage(array_keys($list));
160
            $this->progressBar->end();
161
            $this->showRemovedPackages();
162
        }
163
164
        return true;
165
    }
166
167
    /**
168
     * Flush from one provider.
169
     *
170
     * @param array $list List of packages
171
     */
172
    protected function flushPackage(array $list):void
173
    {
174
        $packages = $this->package->getDownloaded();
175
176
        foreach ($list as $uri) {
177
            $this->progressBar->progress();
178
179
            if ($this->initialized) {
180
                continue;
181
            }
182
183
            $folder = dirname($uri);
184
185
            // This folder was changed by last download?
186
            if (count($packages) && !in_array($folder, $packages)) {
187
                continue;
188
            }
189
190
            // If only have the file and link dont exist old files
191
            if ($this->filesystem->count($folder) < 3) {
0 ignored issues
show
Bug introduced by
The method count() does not exist on Webs\Mirror\Filesystem. ( Ignorable by Annotation )

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

191
            if ($this->filesystem->/** @scrutinizer ignore-call */ count($folder) < 3) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
192
                continue;
193
            }
194
195
            $pattern = $this->shortname($this->filesystem->normalize($uri));
196
            $glob = $this->filesystem->glob($pattern);
197
198
            // If only have the file dont exist old files
199
            if (count($glob) < 2) {
200
                continue;
201
            }
202
203
            // Remove current value
204
            $glob = array_diff($glob, [$this->filesystem->normalize($uri)]);
205
            foreach ($glob as $file) {
206
                if ($this->isVerbose()) {
207
                    $this->packageRemoved[] = $file;
208
                }
209
210
                $this->filesystem->remove($file);
211
            }
212
        }
213
    }
214
215
    /**
216
     * Show packages removed.
217
     */
218
    protected function showRemovedPackages():void
219
    {
220
        foreach ($this->packageRemoved as $file) {
221
            $this->output->writeln(
222
                'Old package <fg=blue;>'.$file.'</> was removed!'
223
            );
224
        }
225
    }
226
}
227