• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Cecilapp / Cecil / 26414009793

25 May 2026 06:15PM UTC coverage: 82.54%. First build
26414009793

Pull #2383

github

web-flow
Merge e6b723fa2 into 4904a42be
Pull Request #2383: refactor: asset handling and add renderer extensions

282 of 358 new or added lines in 10 files covered. (78.77%)

3503 of 4244 relevant lines covered (82.54%)

0.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.22
/src/Asset/Compiler.php
1
<?php
2

3
/**
4
 * This file is part of Cecil.
5
 *
6
 * (c) Arnaud Ligny <arnaud@ligny.fr>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
declare(strict_types=1);
13

14
namespace Cecil\Asset;
15

16
use Cecil\Builder;
17
use Cecil\Config;
18
use Cecil\Exception\ConfigException;
19
use Cecil\Util;
20
use ScssPhp\ScssPhp\Compiler as ScssCompiler;
21
use ScssPhp\ScssPhp\OutputStyle;
22

23
/**
24
 * Compiles SCSS assets to CSS.
25
 */
26
class Compiler
27
{
28
    /** @var Builder */
29
    protected $builder;
30

31
    /** @var Config */
32
    protected $config;
33

34
    public function __construct(Builder $builder)
35
    {
36
        $this->builder = $builder;
1✔
37
        $this->config = $builder->getConfig();
1✔
38
    }
39

40
    /**
41
     * Compiles SCSS to CSS.
42
     * Returns the updated data array, unchanged if not a SCSS file.
43
     *
44
     * @param array $data Asset data array (must contain 'ext', 'path', 'file', 'content')
45
     *
46
     * @return array Updated data array with CSS content
47
     *
48
     * @throws ConfigException
49
     */
50
    public function compile(array $data): array
51
    {
52
        if ($data['ext'] !== 'scss') {
1✔
53
            return $data;
1✔
54
        }
55

56
        $scssPhp = new ScssCompiler();
1✔
57

58
        // import paths
59
        $importDir = [];
1✔
60
        $importDir[] = Util::joinPath($this->config->getStaticPath());
1✔
61
        $importDir[] = Util::joinPath($this->config->getAssetsPath());
1✔
62
        $scssDir = (array) $this->config->get('assets.compile.import');
1✔
63
        $themes = $this->config->getTheme() ?? [];
1✔
64
        foreach ($scssDir as $dir) {
1✔
65
            $importDir[] = Util::joinPath($this->config->getStaticPath(), $dir);
1✔
66
            $importDir[] = Util::joinPath($this->config->getAssetsPath(), $dir);
1✔
67
            $importDir[] = Util::joinPath(\dirname($data['file']), $dir);
1✔
68
            foreach ($themes as $theme) {
1✔
69
                $importDir[] = Util::joinPath($this->config->getThemeDirPath($theme, "static/$dir"));
1✔
70
                $importDir[] = Util::joinPath($this->config->getThemeDirPath($theme, "assets/$dir"));
1✔
71
            }
72
        }
73
        $scssPhp->setQuietDeps(true);
1✔
74
        $scssPhp->setImportPaths(array_unique($importDir));
1✔
75

76
        // adds source map
77
        if ($this->builder->isDebug() && $this->config->isEnabled('assets.compile.sourcemap')) {
1✔
NEW
78
            $importDir = [];
×
NEW
79
            $assetDir = (string) $this->config->get('assets.dir');
×
NEW
80
            $assetDirPos = strrpos($data['file'], DIRECTORY_SEPARATOR . $assetDir . DIRECTORY_SEPARATOR);
×
NEW
81
            $fileRelPath = substr($data['file'], $assetDirPos + 8);
×
NEW
82
            $filePath = Util::joinFile($this->config->getOutputPath(), $fileRelPath);
×
NEW
83
            $importDir[] = \dirname($filePath);
×
NEW
84
            foreach ($scssDir as $dir) {
×
NEW
85
                $importDir[] = Util::joinFile($this->config->getOutputPath(), $dir);
×
86
            }
NEW
87
            $scssPhp->setImportPaths(array_unique($importDir));
×
NEW
88
            $scssPhp->setSourceMap(ScssCompiler::SOURCE_MAP_INLINE);
×
NEW
89
            $scssPhp->setSourceMapOptions([
×
NEW
90
                'sourceMapBasepath' => Util::joinPath($this->config->getOutputPath()),
×
NEW
91
                'sourceRoot'        => '/',
×
NEW
92
            ]);
×
93
        }
94

95
        // defines output style
96
        $outputStyles = ['expanded', 'compressed'];
1✔
97
        $outputStyle = strtolower((string) $this->config->get('assets.compile.style'));
1✔
98
        if (!\in_array($outputStyle, $outputStyles)) {
1✔
NEW
99
            throw new ConfigException(\sprintf('"%s" value must be "%s".', 'assets.compile.style', implode('" or "', $outputStyles)));
×
100
        }
101
        $scssPhp->setOutputStyle($outputStyle === 'compressed' ? OutputStyle::COMPRESSED : OutputStyle::EXPANDED);
1✔
102

103
        // set variables
104
        $variables = $this->config->get('assets.compile.variables');
1✔
105
        if (!empty($variables)) {
1✔
106
            $variables = array_map('ScssPhp\ScssPhp\ValueConverter::parseValue', $variables);
1✔
107
            $scssPhp->replaceVariables($variables);
1✔
108
        }
109

110
        // debug
111
        if ($this->builder->isDebug()) {
1✔
112
            $scssPhp->setQuietDeps(false);
1✔
113
            $this->builder->getLogger()->debug(\sprintf("SCSS compiler imported paths:\n%s", Util\Str::arrayToList(array_unique($importDir))));
1✔
114
        }
115

116
        // update data
117
        $data['path'] = preg_replace('/sass|scss/m', 'css', $data['path']);
1✔
118
        $data['ext'] = 'css';
1✔
119
        $data['type'] = 'text';
1✔
120
        $data['subtype'] = 'text/css';
1✔
121
        $data['content'] = $scssPhp->compileString($data['content'])->getCss();
1✔
122
        $data['size'] = \strlen($data['content']);
1✔
123

124
        $this->builder->getLogger()->debug(\sprintf('Asset compiled: "%s"', $data['path']));
1✔
125

126
        return $data;
1✔
127
    }
128
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc