Completed
Push — cecil ( 66a45a )
by Arnaud
02:09
created

Serve   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 100
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 13

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 13
dl 0
loc 100
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
B processCommand() 0 58 6
A setUpServer() 0 20 4
A tearDownServer() 0 8 2
1
<?php
2
/*
3
 * This file is part of the PHPoole/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\Util\Plateform;
14
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
15
use Symfony\Component\Finder\Finder;
16
use Symfony\Component\Process\Exception\ProcessFailedException;
17
use Symfony\Component\Process\Process;
18
use Yosymfony\ResourceWatcher\Crc32ContentHash;
19
use Yosymfony\ResourceWatcher\ResourceCacheMemory;
20
use Yosymfony\ResourceWatcher\ResourceWatcher;
21
22
class Serve extends AbstractCommand
23
{
24
    /**
25
     * @var string
26
     */
27
    public static $tmpDir = '.cecil';
28
    /**
29
     * @var bool
30
     */
31
    protected $open;
32
33
    public function processCommand()
34
    {
35
        $this->open = $this->getRoute()->getMatchedParam('open', false);
36
37
        $this->setUpServer();
38
        $command = sprintf(
39
            'php -S %s:%d -t %s %s',
40
            'localhost',
41
            '8000',
42
            $this->getPath().'/'.$this->getPHPoole()->getConfig()->get('output.dir'),
43
            sprintf('%s/%s/router.php', $this->getPath(), self::$tmpDir)
44
        );
45
        $process = new Process($command);
46
47
        // (re)build before serve
48
        $callable = new Build();
49
        $callable($this->getRoute(), $this->getConsole());
50
51
        // handle process
52
        if (!$process->isStarted()) {
53
            // write changes cache
54
            $finder = new Finder();
55
            $finder->files()
56
                ->name('*.md')
57
                ->name('*.twig')
58
                ->name('*.yml')
59
                ->name('*.css')
60
                ->name('*.scss')
61
                ->name('*.js')
62
                ->in($this->getPath())
63
                ->exclude($this->getPHPoole()->getConfig()->get('output.dir'));
64
            $hashContent = new Crc32ContentHash();
65
            $resourceCache = new ResourceCacheMemory();
66
            $resourceWatcher = new ResourceWatcher($resourceCache, $finder, $hashContent);
67
            $resourceWatcher->initialize();
68
            // start server
69
            try {
70
                $this->wlAnnonce(sprintf('Starting server (http://%s:%d)...', 'localhost', '8000'));
71
                $process->start();
72
                if ($this->open) {
73
                    Plateform::openBrowser('http://localhost:8000');
74
                }
75
                while ($process->isRunning()) {
76
                    $result = $resourceWatcher->findChanges();
77
                    if ($result->hasChanges()) {
78
                        // re-build
79
                        $this->wlAlert('Changes detected!');
80
                        $callable($this->getRoute(), $this->getConsole());
81
                    }
82
                    usleep(1000000); // wait 1s
83
                }
84
            } catch (ProcessFailedException $e) {
85
                $this->tearDownServer();
86
87
                throw new \Exception(sprintf($e->getMessage()));
88
            }
89
        }
90
    }
91
92
    public function setUpServer()
93
    {
94
        try {
95
            $root = __DIR__.'/../../';
96
            if (Plateform::isPhar()) {
97
                $root = Plateform::getPharPath().'/';
98
            }
99
            $this->fs->copy($root.'res/router.php', $this->getPath().'/'.self::$tmpDir.'/router.php', true);
100
            $this->fs->copy($root.'res/livereload.js', $this->getPath().'/'.self::$tmpDir.'/livereload.js', true);
101
            $this->fs->dumpFile(
102
                $this->getPath().'/'.self::$tmpDir.'/baseurl',
103
                $this->getPHPoole()->getConfig()->get('site.baseurl')
104
            );
105
        } catch (IOExceptionInterface $e) {
106
            throw new \Exception(sprintf('An error occurred while copying file at "%s"', $e->getPath()));
107
        }
108
        if (!is_file(sprintf('%s/%s/router.php', $this->getPath(), self::$tmpDir))) {
109
            throw new \Exception(sprintf('Router not found: "./%s/router.php"', self::$tmpDir));
110
        }
111
    }
112
113
    public function tearDownServer()
114
    {
115
        try {
116
            $this->fs->remove($this->getPath().'/'.self::$tmpDir);
117
        } catch (IOExceptionInterface $e) {
118
            throw new \Exception(sprintf($e->getMessage()));
119
        }
120
    }
121
}
122