UpdateCommand::update()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 10
rs 9.9332
cc 1
nc 1
nop 2
1
<?php
2
namespace Peridot\WebDriverManager\Console;
3
4
use Peridot\WebDriverManager\Binary\BinaryInterface;
5
use Symfony\Component\Console\Helper\ProgressBar;
6
use Symfony\Component\Console\Input\InputArgument;
7
use Symfony\Component\Console\Input\InputInterface;
8
use Symfony\Component\Console\Output\OutputInterface;
9
10
/**
11
 * UpdateCommand is used to update all binaries or a specific binary.
12
 *
13
 * @package Peridot\WebDriverManager\Console
14
 */
15
class UpdateCommand extends AbstractManagerCommand
16
{
17
    protected function configure()
18
    {
19
        $this
20
            ->setName('update')
21
            ->setDescription('Download or update Selenium Server and drivers')
22
            ->addArgument(
23
                'name',
24
                InputArgument::OPTIONAL,
25
                'Update a specific binary with the given name'
26
            );
27
    }
28
29
    /**
30
     * @param InputInterface $input
31
     * @param OutputInterface $output
32
     * @return int|null|void
33
     */
34
    protected function execute(InputInterface $input, OutputInterface $output)
35
    {
36
        $name = $input->getArgument('name') ?: '';
37
        $this->update($output, $name);
38
        return 0;
39
    }
40
41
    /**
42
     *
43
     *
44
     * @param OutputInterface $output
45
     * @param $name
46
     * @return void
47
     */
48
    protected function update(OutputInterface $output, $name)
49
    {
50
        $output->writeln("<info>{$this->getPreMessage($name)}</info>");
51
        $this->watchProgress($output);
52
        $pending = $this->manager->getPendingBinaries();
53
54
        $this->manager->update($name);
55
56
        $output->writeln("<info>{$this->getPostMessage($pending, $name)}</info>");
57
    }
58
59
    /**
60
     * Watch for update progress and advance a progress bar.
61
     *
62
     * @param OutputInterface $output
63
     * @return void
64
     */
65
    protected function watchProgress(OutputInterface $output)
66
    {
67
        $progress = new ProgressBar($output);
68
        $progress->setFormat('%bar% (%percent%%)');
69
        $this->manager->on('request.start', function ($url, $bytes) use ($progress, $output) {
70
            $output->writeln('<comment>Downloading ' . basename($url) . '</comment>');
71
            $progress->start($bytes);
72
        });
73
        $this->manager->on('progress', function ($transferred) use ($progress) {
74
            $progress->setProgress($transferred);
75
        });
76
        $this->manager->on('complete', function () use ($progress, $output) {
77
            $progress->finish();
78
            $output->writeln('');
79
        });
80
    }
81
82
    /**
83
     * Get the message to initially display to the user.
84
     *
85
     * @param string $name
86
     * @return string
87
     */
88
    protected function getPreMessage($name)
89
    {
90
        $binaries = $this->manager->getBinaries();
91
        $message = 'Ensuring binaries are up to date';
92
        $isSingleUpdate = $name && array_key_exists($name, $binaries);
93
94
        if (! $isSingleUpdate) {
95
            return $message;
96
        }
97
98
        $binary = $binaries[$name];
99
        return $binary->isSupported() ? "Updating {$binary->getName()}" : "{$binary->getName()} is not supported by your system";
100
    }
101
102
    /**
103
     * Get the result message.
104
     *
105
     * @param array $pending
106
     * @param string $name
107
     * @return string
108
     */
109
    protected function getPostMessage(array $pending, $name)
110
    {
111
        if ($name) {
112
            $pending = array_filter($pending, function (BinaryInterface $binary) use ($name) {
113
                return $binary->getName() === $name;
114
            });
115
        }
116
117
        $count = array_reduce($pending, function ($r, BinaryInterface $binary) {
118
            if ($binary->exists($this->manager->getInstallPath())) {
119
                $r++;
120
            }
121
            return $r;
122
        }, 0);
123
124
        return $this->getResultString($count);
125
    }
126
127
    /**
128
     * Given a count, return an appropriate label.
129
     *
130
     * @param $count
131
     * @return string
132
     */
133
    protected function getResultString($count)
134
    {
135
        if ($count == 0) {
136
            return 'Nothing to update';
137
        }
138
139
        $label = $count > 1 ? 'binaries' : 'binary';
140
141
        return "$count $label updated";
142
    }
143
}
144