Passed
Pull Request — master (#381)
by Alejandro
06:51 queued 02:37
created

UpdateDbCommand::handleError()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3.009

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 15
ccs 9
cts 10
cp 0.9
rs 9.9666
c 0
b 0
f 0
cc 3
nc 3
nop 3
crap 3.009
1
<?php
2
declare(strict_types=1);
3
4
namespace Shlinkio\Shlink\CLI\Command\Visit;
5
6
use Shlinkio\Shlink\CLI\Util\ExitCodes;
7
use Shlinkio\Shlink\Common\Exception\RuntimeException;
8
use Shlinkio\Shlink\Common\IpGeolocation\GeoLite2\DbUpdaterInterface;
9
use Symfony\Component\Console\Command\Command;
10
use Symfony\Component\Console\Helper\ProgressBar;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Input\InputOption;
13
use Symfony\Component\Console\Output\OutputInterface;
14
use Symfony\Component\Console\Style\SymfonyStyle;
15
16
use function sprintf;
17
18
class UpdateDbCommand extends Command
19
{
20
    public const NAME = 'visit:update-db';
21
22
    /** @var DbUpdaterInterface */
23
    private $geoLiteDbUpdater;
24
25 3
    public function __construct(DbUpdaterInterface $geoLiteDbUpdater)
26
    {
27 3
        parent::__construct();
28 3
        $this->geoLiteDbUpdater = $geoLiteDbUpdater;
29
    }
30
31 3
    protected function configure(): void
32
    {
33
        $this
34 3
            ->setName(self::NAME)
35 3
            ->setDescription('Updates the GeoLite2 database file used to geolocate IP addresses')
36 3
            ->setHelp(
37
                'The GeoLite2 database is updated first Tuesday every month, so this command should be ideally run '
38 3
                . 'every first Wednesday'
39
            )
40 3
            ->addOption(
41 3
                'ignoreErrors',
42 3
                'i',
43 3
                InputOption::VALUE_NONE,
44 3
                'Makes the command success even iof the update fails.'
45
            );
46
    }
47
48 3
    protected function execute(InputInterface $input, OutputInterface $output): ?int
49
    {
50 3
        $io = new SymfonyStyle($input, $output);
51 3
        $progressBar = new ProgressBar($output);
52 3
        $progressBar->start();
53
54
        try {
55
            $this->geoLiteDbUpdater->downloadFreshCopy(function (int $total, int $downloaded) use ($progressBar) {
56
                $progressBar->setMaxSteps($total);
57
                $progressBar->setProgress($downloaded);
58 3
            });
59
60 1
            $progressBar->finish();
61 1
            $io->newLine();
62
63 1
            $io->success('GeoLite2 database properly updated');
64 1
            return ExitCodes::EXIT_SUCCESS;
65 2
        } catch (RuntimeException $e) {
66 2
            $progressBar->finish();
67 2
            $io->newLine();
68
69 2
            return $this->handleError($e, $io, $input);
70
        }
71
    }
72
73 2
    private function handleError(RuntimeException $e, SymfonyStyle $io, InputInterface $input): int
74
    {
75 2
        $ignoreErrors = $input->getOption('ignoreErrors');
76 2
        $baseErrorMsg = 'An error occurred while updating GeoLite2 database';
77
78 2
        if ($ignoreErrors) {
79 1
            $io->warning(sprintf('%s, but it was ignored', $baseErrorMsg));
80 1
            return ExitCodes::EXIT_SUCCESS;
81
        }
82
83 1
        $io->error($baseErrorMsg);
84 1
        if ($io->isVerbose()) {
85
            $this->getApplication()->renderException($e, $io);
86
        }
87 1
        return ExitCodes::EXIT_FAILURE;
88
    }
89
}
90