Passed
Push — console ( 3b9232...ab6761 )
by Arnaud
08:19 queued 05:36
created

Command::initialize()   A

Complexity

Conditions 6
Paths 13

Size

Total Lines 28
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 1 Features 0
Metric Value
cc 6
eloc 17
c 7
b 1
f 0
nc 13
nop 2
dl 0
loc 28
rs 9.0777
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\Style\SymfonyStyle;
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 InputInterface */
30
    protected $input;
31
    /** @var OutputInterface */
32
    protected $output;
33
    /** @var SymfonyStyle */
34
    protected $io;
35
    /** @var Filesystem */
36
    protected $fs;
37
    /** @var string */
38
    protected $path;
39
    /** @var string */
40
    protected $configFile;
41
    /** @var Builder */
42
    protected $builder;
43
    /** @var ProgressBar */
44
    protected $progressBar = null;
45
    /** @var int */
46
    protected $progressBarMax;
47
48
    /**
49
     * {@inheritdoc}
50
     */
51
    protected function initialize(InputInterface $input, OutputInterface $output)
52
    {
53
        $this->input = $input;
54
        $this->output = $output;
55
        $this->io = new SymfonyStyle($input, $output);
56
        $this->fs = new Filesystem();
57
58
        if (!in_array($this->getName(), ['self-update'])) {
59
            $this->path = (string) $input->getArgument('path');
60
            if (null === $this->getPath()) {
0 ignored issues
show
introduced by
The condition null === $this->getPath() is always false.
Loading history...
61
                $this->path = getcwd();
62
            }
63
            if (false === realpath($this->getPath())) {
64
                $this->fs->mkdir($this->getPath());
65
            }
66
            $this->path = realpath($this->getPath());
67
            $this->configFile = Util::joinFile($this->getPath(), self::CONFIG_FILE);
68
69
            if (!in_array($this->getName(), ['new:site'])) {
70
                if (!file_exists($this->configFile)) {
71
                    $message = sprintf('Could not find "%s" file in "%s"', self::CONFIG_FILE, $this->getPath());
72
73
                    throw new \InvalidArgumentException($message);
74
                }
75
            }
76
        }
77
78
        parent::initialize($input, $output);
79
    }
80
81
    /**
82
     * {@inheritdoc}
83
     */
84
    public function run(InputInterface $input, OutputInterface $output)
85
    {
86
        if ($output->isDebug()) {
87
            parent::run($input, $output);
88
        }
89
        // simplifying error message
90
        try {
91
            parent::run($input, $output);
92
        } catch (\Exception $e) {
93
            $this->io->error($e->getMessage());
94
        }
95
    }
96
97
    /**
98
     * Returns the working directory.
99
     *
100
     * @return string|null
101
     */
102
    protected function getPath(): ?string
103
    {
104
        return $this->path;
105
    }
106
107
    /**
108
     * Creates or returns a Builder instance.
109
     *
110
     * @param array $config
111
     *
112
     * @return Builder
113
     */
114
    protected function getBuilder(array $config = []): Builder
115
    {
116
        if (!file_exists($this->configFile)) {
117
            throw new \Exception(sprintf('Config file not found in "%s"!', $this->getPath()));
118
        }
119
120
        try {
121
            $siteConfig = Yaml::parse(file_get_contents($this->configFile));
122
            $config = array_replace_recursive($siteConfig, $config);
123
            $this->builder = (new Builder($config, $this->messageCallback()))
124
                ->setSourceDir($this->getPath())
125
                ->setDestinationDir($this->getPath());
126
        } catch (ParseException $e) {
127
            throw new \Exception(sprintf('Config file parse error: %s', $e->getMessage()));
128
        } catch (\Exception $e) {
129
            throw new \Exception(sprintf($e->getMessage()));
130
        }
131
132
        return $this->builder;
133
    }
134
135
    /**
136
     * Creates the Progress bar.
137
     *
138
     * @param int $max
139
     *
140
     * @return void
141
     */
142
    protected function createProgressBar($max): void
143
    {
144
        if ($this->progressBar === null || $max != $this->progressBarMax) {
145
            $this->progressBarMax = $max;
146
            $this->progressBar = new ProgressBar($this->output, $max);
147
            $this->progressBar->setOverwrite(true);
148
            $this->progressBar->setFormat(' %percent:3s%% [%bar%] %current%/%max%');
149
            $this->progressBar->setBarCharacter('#');
150
            $this->progressBar->setEmptyBarCharacter(' ');
151
            $this->progressBar->setProgressCharacter('#');
152
            $this->progressBar->setRedrawFrequency(1);
153
            $this->progressBar->start();
154
        }
155
    }
156
157
    /**
158
     * Returns the Progress Bar.
159
     *
160
     * @return ProgressBar
161
     */
162
    protected function getProgressBar(): ProgressBar
163
    {
164
        return $this->progressBar;
165
    }
166
167
    /**
168
     * Prints the Progress Bar.
169
     *
170
     * @param int $itemsCount
171
     * @param int $itemsMax
172
     *
173
     * @return void
174
     */
175
    protected function printProgressBar($itemsCount, $itemsMax): void
176
    {
177
        $this->createProgressBar($itemsMax);
178
        $this->getProgressBar()->clear();
179
        $this->getProgressBar()->setProgress($itemsCount);
180
        $this->getProgressBar()->display();
181
        if ($itemsCount == $itemsMax) {
182
            $this->getProgressBar()->finish();
183
            $this->output->writeln('');
184
        }
185
    }
186
187
    /**
188
     * Customs messages callback function.
189
     *
190
     * @return \Closure
191
     */
192
    public function messageCallback(): \Closure
193
    {
194
        return function ($code, $message = '', $itemsCount = 0, $itemsMax = 0) {
195
            if (strpos($code, '_PROGRESS') !== false) {
196
                if ($this->output->isVerbose()) {
197
                    if ($itemsCount > 0) {
198
                        $this->output->writeln(sprintf(' (%u/%u) %s', $itemsCount, $itemsMax, $message));
199
200
                        return;
201
                    }
202
                    $this->output->writeln(" $message");
203
204
                    return;
205
                }
206
                if (isset($itemsCount) && $itemsMax > 0) {
207
                    $this->printProgressBar($itemsCount, $itemsMax);
208
209
                    return;
210
                }
211
                $this->output->writeln(" $message");
212
213
                return;
214
            } elseif (strpos($code, '_ERROR') !== false) {
215
                $this->output->writeln("<error>$message</error>");
216
217
                return;
218
            } elseif ($code == 'TIME') {
219
                $this->output->writeln("<comment>$message</comment>");
220
221
                return;
222
            }
223
            $this->output->writeln("<info>$message</info>");
224
        };
225
    }
226
}
227