Passed
Push — cli-error-message ( 50ab27 )
by Arnaud
05:31
created

Command::run()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
c 0
b 0
f 0
nc 2
nop 2
dl 0
loc 10
rs 10
1
<?php
2
/**
3
 * This file is part of the Cecil/Cecil package.
4
 *
5
 * Copyright (c) Arnaud Ligny <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Cecil\Command;
12
13
use Cecil\Builder;
14
use Cecil\Util;
15
use Symfony\Component\Console\Command\Command as BaseCommand;
16
use Symfony\Component\Console\Helper\ProgressBar;
17
use Symfony\Component\Console\Input\InputInterface;
18
use Symfony\Component\Console\Output\OutputInterface;
19
use Symfony\Component\Console\Question\ConfirmationQuestion;
20
use Symfony\Component\Filesystem\Filesystem;
21
use Symfony\Component\Yaml\Exception\ParseException;
22
use Symfony\Component\Yaml\Yaml;
23
24
class Command extends BaseCommand
25
{
26
    const CONFIG_FILE = 'config.yml';
27
    const TMP_DIR = '.cecil';
28
29
    /** @var Filesystem */
30
    protected $fs;
31
    /** @var string */
32
    protected $path;
33
    /** @var string */
34
    protected $configFile;
35
    /** @var Builder */
36
    protected $builder;
37
    /** @var ProgressBar */
38
    protected $progressBar = null;
39
    /** @var int */
40
    protected $progressBarMax;
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    public function run(InputInterface $input, $output)
46
    {
47
        try {
48
            parent::run($input, $output);
49
        } catch (\Exception $e) {
50
            // custom error message
51
            $message[] = sprintf('<error></error>');
0 ignored issues
show
Comprehensibility Best Practice introduced by
$message was never initialized. Although not strictly required by PHP, it is generally a good practice to add $message = array(); before regardless.
Loading history...
52
            $message[] = sprintf('<error>  %s</error>', $e->getMessage());
53
            $message[] = sprintf('<error></error>');
54
            $output->writeln($message, OutputInterface::VERBOSITY_QUIET);
55
        }
56
    }
57
58
    /**
59
     * {@inheritdoc}
60
     */
61
    protected function initialize(InputInterface $input, OutputInterface $output)
62
    {
63
        $this->fs = new Filesystem();
64
65
        if (!in_array($this->getName(), ['self-update'])) {
66
            $this->path = (string) $input->getArgument('path');
67
            if (null === $this->getPath()) {
0 ignored issues
show
introduced by
The condition null === $this->getPath() is always false.
Loading history...
68
                $this->path = getcwd();
69
            }
70
            if (false === realpath($this->getPath())) {
71
                if (!in_array($this->getName(), ['new:site'])) {
72
                    $message = sprintf('"%s" is not valid path.', $this->getPath());
73
74
                    throw new \InvalidArgumentException($message);
75
                }
76
                $helper = $this->getHelper('question');
77
                $question = new ConfirmationQuestion(
78
                    sprintf('The provided <path> "%s" doesn\'t exist.
79
Do you want to create it? [y/n]', $this->getpath()),
80
                    false
81
                );
82
                if (!$helper->ask($input, $output, $question)) {
83
                    return;
84
                }
85
86
                $this->fs->mkdir($this->getPath());
87
            }
88
            $this->path = realpath($this->getPath());
89
            $this->configFile = Util::joinFile($this->getPath(), self::CONFIG_FILE);
90
91
            if (!in_array($this->getName(), ['new:site'])) {
92
                if (!file_exists($this->configFile)) {
93
                    $message = sprintf('Cecil could not find "%s" file in "%s"', self::CONFIG_FILE, $this->getPath());
94
95
                    throw new \InvalidArgumentException($message);
96
                }
97
            }
98
        }
99
100
        parent::initialize($input, $output);
101
    }
102
103
    /**
104
     * Returns the working directory.
105
     *
106
     * @return string|null
107
     */
108
    public function getPath(): ?string
109
    {
110
        return $this->path;
111
    }
112
113
    /**
114
     * Creates or returns a Builder instance.
115
     *
116
     * @param OutputInterface $output
117
     * @param array           $config
118
     *
119
     * @return Builder
120
     */
121
    public function getBuilder(
122
        OutputInterface $output,
123
        array $config = ['debug' => false]
124
    ): Builder {
125
        if (!file_exists($this->configFile)) {
126
            throw new \Exception(sprintf('Config file not found in "%s"!', $this->getPath()));
127
        }
128
129
        try {
130
            $siteConfig = Yaml::parse(file_get_contents($this->configFile));
131
            $config = array_replace_recursive($siteConfig, $config);
132
            $this->builder = (new Builder($config, $this->messageCallback($output)))
133
                ->setSourceDir($this->getPath())
134
                ->setDestinationDir($this->getPath());
135
        } catch (ParseException $e) {
136
            throw new \Exception(sprintf('Config file parse error: %s', $e->getMessage()));
137
        } catch (\Exception $e) {
138
            throw new \Exception(sprintf($e->getMessage()));
139
        }
140
141
        return $this->builder;
142
    }
143
144
    /**
145
     * Creates the Progress bar.
146
     *
147
     * @param OutputInterface $output
148
     * @param int             $max
149
     *
150
     * @return void
151
     */
152
    protected function createProgressBar(OutputInterface $output, $max): void
153
    {
154
        if ($this->progressBar === null || $max != $this->progressBarMax) {
155
            $this->progressBarMax = $max;
156
            $this->progressBar = new ProgressBar($output, $max);
157
            $this->progressBar->setOverwrite(true);
158
            $this->progressBar->setFormat(' %percent:3s%% [%bar%] %current%/%max%');
159
            $this->progressBar->setBarCharacter('#');
160
            $this->progressBar->setEmptyBarCharacter(' ');
161
            $this->progressBar->setProgressCharacter('#');
162
            $this->progressBar->setRedrawFrequency(1);
163
            $this->progressBar->start();
164
        }
165
    }
166
167
    /**
168
     * Returns the Progress Bar.
169
     *
170
     * @return ProgressBar
171
     */
172
    protected function getProgressBar(): ProgressBar
173
    {
174
        return $this->progressBar;
175
    }
176
177
    /**
178
     * Print the Progress Bar.
179
     *
180
     * @param OutputInterface $output
181
     * @param int             $itemsCount
182
     * @param int             $itemsMax
183
     *
184
     * @return void
185
     */
186
    protected function printProgressBar(OutputInterface $output, $itemsCount, $itemsMax): void
187
    {
188
        $this->createProgressBar($output, $itemsMax);
189
        $this->getProgressBar()->clear();
190
        $this->getProgressBar()->setProgress($itemsCount);
191
        $this->getProgressBar()->display();
192
        if ($itemsCount == $itemsMax) {
193
            $this->getProgressBar()->finish();
194
            $output->writeln('');
195
        }
196
    }
197
198
    /**
199
     * Customs messages callback function.
200
     *
201
     * @param OutputInterface $output
202
     *
203
     * @return \Closure
204
     */
205
    public function messageCallback(OutputInterface $output): \Closure
206
    {
207
        return function ($code, $message = '', $itemsCount = 0, $itemsMax = 0) use ($output) {
208
            if (strpos($code, '_PROGRESS') !== false) {
209
                if ($output->isVerbose()) {
210
                    if ($itemsCount > 0) {
211
                        $output->writeln(sprintf(' (%u/%u) %s', $itemsCount, $itemsMax, $message));
212
213
                        return;
214
                    }
215
                    $output->writeln(" $message");
216
217
                    return;
218
                }
219
                if (isset($itemsCount) && $itemsMax > 0) {
220
                    $this->printProgressBar($output, $itemsCount, $itemsMax);
221
222
                    return;
223
                }
224
                $output->writeln(" $message");
225
226
                return;
227
            } elseif (strpos($code, '_ERROR') !== false) {
228
                $output->writeln("<error>$message</error>");
229
230
                return;
231
            } elseif ($code == 'TIME') {
232
                $output->writeln("<comment>$message</comment>");
233
234
                return;
235
            }
236
            $output->writeln("<info>$message</info>");
237
        };
238
    }
239
}
240