Skip to content

Commit 0b63d0b

Browse files
committed
Merge branch 'v1-develop' into v1
2 parents 33b57f4 + 0f5a620 commit 0b63d0b

File tree

9 files changed

+427
-304
lines changed

9 files changed

+427
-304
lines changed

.gitattributes

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/.gitattributes export-ignore
2+
/.gitignore export-ignore
3+
/.php-auto-version export-ignore
4+
/.php-cs-fixer.php export-ignore
5+
/composer.lock export-ignore
6+
/Makefile export-ignore
7+
/phpstan.neon export-ignore
8+
/vendor-bin export-ignore

Css/PreProcessor/Adapter/Less/Processor.php

Lines changed: 78 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
use Magento\Framework\View\Asset\File as AssetFile;
1717
use Magento\Framework\View\Asset\Source;
1818
use Psr\Log\LoggerInterface;
19+
use Symfony\Component\Process\Exception\ProcessFailedException;
20+
use Symfony\Component\Process\Process;
21+
use Symfony\Component\Process\ProcessBuilder;
1922

2023
class Processor implements ContentProcessorInterface
2124
{
@@ -58,17 +61,19 @@ public function processContent(AssetFile $asset)
5861
$content = (string) $this->assetSource->getContent($asset);
5962

6063
if (trim($content) === '') {
61-
return '';
64+
throw new ContentProcessorException(
65+
new Phrase('Compilation from source: LESS file is empty: ' . $path)
66+
);
6267
}
6368

6469
$tmpFilePath = $this->temporaryFile->createFile($path, $content);
6570

66-
$content = $this->compileFile($tmpFilePath);
71+
$content = $this->compileFile($tmpFilePath, $path);
6772

6873
if (trim($content) === '') {
69-
$this->logger->warning('Parsed less file is empty: ' . $path);
70-
71-
return '';
74+
throw new ContentProcessorException(
75+
new Phrase('Compilation from source: CSS is empty from LESS file: ' . $path)
76+
);
7277
} else {
7378
return $content;
7479
}
@@ -85,37 +90,50 @@ public function processContent(AssetFile $asset)
8590
* Compiles less file and returns output as a string
8691
*
8792
* @param string $filePath
93+
* @param string $assetPath
8894
*
8995
* @return string
9096
*
9197
* @throws NotFoundException if the nodejs or less compiler binaries can't be found
9298
* @throws LocalizedException if the shell command returns non-zero exit code
9399
*/
94-
protected function compileFile($filePath)
100+
protected function compileFile($filePath, $assetPath)
95101
{
96102
$nodeCmdArgs = $this->getNodeArgsAsArray();
97103
$lessCmdArgs = $this->getCompilerArgsAsArray();
98104

99-
$cmd = '%s ' . str_repeat(' %s', count($nodeCmdArgs)) . ' %s' . str_repeat(' %s', count($lessCmdArgs)) . ' %s';
100-
$arguments = [];
101-
$arguments[] = $this->getPathToNodeBinary();
102-
$arguments = array_merge($arguments, $nodeCmdArgs);
103-
$arguments[] = $this->getPathToLessCompiler();
104-
$arguments = array_merge($arguments, $lessCmdArgs);
105-
$arguments[] = $filePath;
106-
107-
// to log or not to log, that's the question
108-
// also, it would be better to use the logger in the Shell class,
109-
// since that one will contain the exact correct command, and not this sprintf version
110-
// $logArguments = array_map('escapeshellarg', $arguments);
111-
// $this->logger->debug('Less compilation command: `'
112-
// . sprintf($cmd, ...$logArguments)
113-
// . '`');
114-
115-
return $this->shell->execute(
116-
$cmd,
117-
$arguments
118-
);
105+
$command = [];
106+
$command[] = $this->getPathToNodeBinary();
107+
$command = array_merge($command, $nodeCmdArgs);
108+
$command[] = $this->getPathToLessCompiler();
109+
$command = array_merge($command, $lessCmdArgs);
110+
$command[] = $filePath;
111+
112+
$process = $this->getProcess($command);
113+
114+
try {
115+
$process->mustRun();
116+
} catch (ProcessFailedException $ex) {
117+
throw new ContentProcessorException(
118+
new Phrase('LESS compilation process failed with: %1', [$ex->getMessage()])
119+
);
120+
}
121+
122+
$errorOutput = $process->getErrorOutput();
123+
124+
if ($errorOutput !== '') {
125+
$errorMessage = new Phrase('LESS compilation ran into some problems: %1', [$errorOutput]);
126+
if ($this->isThrowOnErrorEnabled()) {
127+
throw new ContentProcessorException($errorMessage);
128+
} else {
129+
$this->logger->error($errorMessage, [
130+
'asset' => $assetPath,
131+
'file' => $filePath,
132+
]);
133+
}
134+
}
135+
136+
return $process->getOutput();
119137
}
120138

121139
/**
@@ -258,4 +276,38 @@ private function getConfigValueFromPath($path)
258276

259277
return null;
260278
}
279+
280+
/**
281+
* @param string $path
282+
*
283+
* @return bool
284+
*/
285+
private function getConfigValueFromPathAsBool($path)
286+
{
287+
return filter_var($this->scopeConfig->getValue($path), FILTER_VALIDATE_BOOLEAN);
288+
}
289+
290+
/**
291+
* @param array<string> $commandArgs
292+
*
293+
* @return Process
294+
*/
295+
private function getProcess(array $commandArgs)
296+
{
297+
// We can't use Process class in symfony/process 2.x because it takes a string and not an array
298+
// therefore we use ProcessBuilder, which exists only in symfony/process 2.x and was removed from 3.x and higher
299+
if (class_exists(ProcessBuilder::class)) {
300+
return (new ProcessBuilder($commandArgs))->getProcess();
301+
}
302+
303+
return new Process($commandArgs);
304+
}
305+
306+
/**
307+
* @return bool
308+
*/
309+
private function isThrowOnErrorEnabled()
310+
{
311+
return $this->getConfigValueFromPathAsBool('dev/less_js_compiler/throw_on_error');
312+
}
261313
}

README.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,24 @@ If you want to override the default arguments, you can do this by modifying your
7676
]
7777
```
7878

79-
## Debugging less compilation errors
79+
You can also enable throwing an exception when the less compilation runs into warnings/errors, by default this is disabled and you should find the problems logged in your `var/log/system.log` file.
80+
But if you want to enable throwing an exception during the compilation process, you can by configuring this in your `app/etc/config.php` or `app/etc/env.php` file:
8081

81-
When your `.less` files have a syntax error or contain something which doesn't allow it to compile properly, please have a look at the `var/log/system.log` file, it will contain the error what causes the problem.
82+
```php
83+
'system' => [
84+
'default' => [
85+
'dev' => [
86+
'less_js_compiler' => [
87+
'throw_on_error' => true,
88+
]
89+
]
90+
]
91+
]
92+
```
93+
94+
## Investigating less compilation errors
95+
96+
When your `.less` files have a syntax error or contain something which doesn't allow it to compile properly, please have a look at the `var/log/system.log` file, it will contain some output about what caused the problem.
8297

8398
## Remarks
8499

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
"require": {
2020
"php": "~5.5.0 || ~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.1.0 || ~8.2.0 || ~8.3.0",
2121
"magento/framework": "^100.0.9 || ^101.0.0 || ^102.0.0 || ^103.0.0",
22-
"magento/module-developer": "^100.0.5"
22+
"magento/module-developer": "^100.0.5",
23+
"symfony/process": "^2.8 || ^4.1 || ^5.0 || ^6.0"
2324
},
2425
"require-dev": {
2526
"bamarni/composer-bin-plugin": "^1.8",

0 commit comments

Comments
 (0)