N°2982 - Speed up SCSS themes compilation during setup : fix broken style 3.0 after setup

This commit is contained in:
odain
2021-02-15 15:16:08 +01:00
parent c8dd19c22f
commit c36d650d61
7 changed files with 104 additions and 61 deletions

View File

@@ -204,14 +204,13 @@ class ThemeHandler
static::FindStylesheetFile($sStylesheet, $aImportsPaths, $oFindStylesheetObject); static::FindStylesheetFile($sStylesheet, $aImportsPaths, $oFindStylesheetObject);
} }
$aStylesheetFiles = $oFindStylesheetObject->GetAllStylesheetFiles(); foreach ($oFindStylesheetObject->GetStylesheetFileURIs() as $sStylesheet){
foreach ($aStylesheetFiles as $sStylesheet){
$sTmpThemeScssContent .= '@import "'.$sStylesheet.'";'."\n"; $sTmpThemeScssContent .= '@import "'.$sStylesheet.'";'."\n";
} }
$iStyleLastModified = $oFindStylesheetObject->GetLastModified(); $iStyleLastModified = $oFindStylesheetObject->GetLastModified();
$aIncludedImages=static::GetIncludedImages($aThemeParametersWithVersion, $aStylesheetFiles, $sThemeId); $aIncludedImages=static::GetIncludedImages($aThemeParametersWithVersion, $oFindStylesheetObject->GetAllStylesheetPaths(), $sThemeId);
foreach ($aIncludedImages as $sImage) foreach ($aIncludedImages as $sImage)
{ {
if (is_file($sImage)) if (is_file($sImage))
@@ -323,7 +322,7 @@ CSS;
} }
} }
$aFiles = $oFindStylesheetObject->GetAllImports(); $aFiles = $oFindStylesheetObject->GetImports();
if (count($aFiles) !== 0) { if (count($aFiles) !== 0) {
foreach ($aFiles as $sFile) { foreach ($aFiles as $sFile) {
$aSignature['imports'][$sFile] = md5_file($sFile); $aSignature['imports'][$sFile] = md5_file($sFile);
@@ -759,29 +758,41 @@ CSS;
$sFilePath = $sPath.'/'.$sFile; $sFilePath = $sPath.'/'.$sFile;
$sImportedFile = realpath($sFilePath); $sImportedFile = realpath($sFilePath);
if ($sImportedFile === false){ if ($sImportedFile === false){
// Handle shortcut syntax like @import "typo ; // Handle shortcut syntax : @import "typo" ;
// file matched: typo.scss
$sFilePath2 = "$sFilePath.scss";
$sImportedFile = realpath($sFilePath2);
if ($sImportedFile){
self::FindStylesheetFile("$sFile.scss", [ $sPath ], $oFindStylesheetObject, $bImports);
$sImportedFile = false;
}
}
if ($sImportedFile === false){
// Handle shortcut syntax : @import "typo" ;
// file matched: _typo.scss // file matched: _typo.scss
$sShortCut = substr($sFilePath, strrpos($sFilePath, '/') + 1); $sShortCut = substr($sFilePath, strrpos($sFilePath, '/') + 1);
$sFilePath = str_replace($sShortCut, "_$sShortCut.scss", $sFilePath); $sFilePath = str_replace($sShortCut, "_$sShortCut.scss", $sFilePath);
$sFile = str_replace($sShortCut, "_$sShortCut.scss", $sFile);
$sImportedFile = realpath($sFilePath); $sImportedFile = realpath($sFilePath);
} }
if (file_exists($sImportedFile)) if ((file_exists($sImportedFile))
&& (!$oFindStylesheetObject->AlreadyFetched($sFile)))
{ {
if ($bImports){ if ($bImports){
$oFindStylesheetObject->AddImport($sImportedFile); $oFindStylesheetObject->AddImport($sFile, $sImportedFile);
}else{ }else{
$oFindStylesheetObject->AddStylesheet($sImportedFile); $oFindStylesheetObject->AddStylesheet($sFile, $sImportedFile);
} }
$oFindStylesheetObject->UpdateLastModified($sImportedFile); $oFindStylesheetObject->UpdateLastModified($sImportedFile);
//Regexp matching on all included scss files : @import 'XXX.scss'; //Regexp matching on all included scss files : @import 'XXX.scss';
$sDirUri = dirname($sFile);
preg_match_all('/@import \s*[\"\']([^\"\']*)\s*[\"\']\s*;/', file_get_contents($sImportedFile), $aMatches); preg_match_all('/@import \s*[\"\']([^\"\']*)\s*[\"\']\s*;/', file_get_contents($sImportedFile), $aMatches);
if ( (is_array($aMatches)) && (count($aMatches)!==0) ){ if ( (is_array($aMatches)) && (count($aMatches)!==0) ){
foreach ($aMatches[1] as $sImportedFile){ foreach ($aMatches[1] as $sImportedFile){
if (! $oFindStylesheetObject->AlreadyFetched($sImportedFile)) { self::FindStylesheetFile("$sDirUri/$sImportedFile", [ $sPath ], $oFindStylesheetObject, true);
self::FindStylesheetFile($sImportedFile, [ dirname($sFilePath) ], $oFindStylesheetObject, true);
}
} }
} }
} }
@@ -828,9 +839,14 @@ CSS;
*/ */
class FindStylesheetObject{ class FindStylesheetObject{
private $aStylesheetImports; //file URIs
private $aAllStylesheetFiles; private $aStylesheetImportURIs;
private $sLastStyleSheet; private $aStylesheetFileURIs;
//fill paths
private $aAllStylesheetFilePaths;
private $sLastStyleSheetPath;
private $iLastModified; private $iLastModified;
/** /**
@@ -838,25 +854,28 @@ class FindStylesheetObject{
*/ */
public function __construct() public function __construct()
{ {
$this->aAllStylesheetFiles = []; $this->aStylesheetFileURIs = [];
$this->aStylesheetImports = []; $this->aStylesheetImportURIs = [];
$this->sLastStyleSheet = ""; $this->sLastStyleSheetPath = "";
$this->iLastModified = 0; $this->iLastModified = 0;
} }
public function GetLastStylesheetFile(): string public function GetLastStylesheetFile(): string
{ {
return $this->sLastStyleSheet; return $this->sLastStyleSheetPath;
} }
public function GetAllImports(): array public function GetImports(): array
{ {
return $this->aStylesheetImports; return $this->aStylesheetImportURIs;
} }
public function GetAllStylesheetFiles(): array /**
* @return array : main stylesheets URIs
*/
public function GetStylesheetFileURIs(): array
{ {
return $this->aAllStylesheetFiles; return $this->aStylesheetFileURIs;
} }
public function GetLastModified() : int public function GetLastModified() : int
@@ -864,31 +883,46 @@ class FindStylesheetObject{
return $this->iLastModified; return $this->iLastModified;
} }
public function GetStylesheetImports(): array /**
* @return array : included files URIs
*/
public function GetStylesheetImportURIs(): array
{ {
return $this->aStylesheetImports; return $this->aStylesheetImportURIs;
} }
public function GetLastStyleSheet(): string /**
* @return array : main stylesheets paths + included files paths
*/
public function GetAllStylesheetPaths(): array
{ {
return $this->sLastStyleSheet; return $this->aAllStylesheetFilePaths;
} }
public function AddStylesheet(string $sStylesheetFile): void /**
* @return string : last found stylesheet URI
*/
public function GetLastStyleSheetPath(): string
{ {
$this->aAllStylesheetFiles[] = $sStylesheetFile; return $this->sLastStyleSheetPath;
$this->sLastStyleSheet = $sStylesheetFile; }
public function AddStylesheet(string $sStylesheetFile, string $sStylesheetFilePath): void
{
$this->aStylesheetFileURIs[] = $sStylesheetFile;
$this->aAllStylesheetFilePaths[] = $sStylesheetFilePath;
$this->sLastStyleSheetPath = $sStylesheetFilePath;
} }
public function AlreadyFetched(string $sStylesheetFile) : bool { public function AlreadyFetched(string $sStylesheetFile) : bool {
return in_array($sStylesheetFile, $this->aAllStylesheetFiles) return in_array($sStylesheetFile, $this->aStylesheetFileURIs)
|| in_array($sStylesheetFile, $this->aStylesheetImports); || in_array($sStylesheetFile, $this->aStylesheetImportURIs);
} }
public function AddImport(string $sStylesheetFile): void public function AddImport(string $sStylesheetFile, string $sStylesheetFilePath): void
{ {
$this->aAllStylesheetFiles[] = $sStylesheetFile; $this->aStylesheetImportURIs[] = $sStylesheetFile;
$this->aStylesheetImports[] = $sStylesheetFile; $this->aAllStylesheetFilePaths[] = $sStylesheetFilePath;
} }
public function UpdateLastModified(string $sStylesheetFile): void public function UpdateLastModified(string $sStylesheetFile): void
@@ -898,7 +932,7 @@ class FindStylesheetObject{
public function ResetLastStyleSheet(): void public function ResetLastStyleSheet(): void
{ {
$this->sLastStyleSheet = ""; $this->sLastStyleSheetPath = "";
} }
} }

View File

@@ -20,6 +20,9 @@ class ThemeHandlerTest extends ItopTestCase
public function setUp() public function setUp()
{ {
@include_once '/home/combodo/workspace/iTop/approot.inc.php';
parent::setUp(); parent::setUp();
require_once(APPROOT.'application/themehandler.class.inc.php'); require_once(APPROOT.'application/themehandler.class.inc.php');
require_once(APPROOT.'setup/modelfactory.class.inc.php'); require_once(APPROOT.'setup/modelfactory.class.inc.php');
@@ -179,7 +182,7 @@ class ThemeHandlerTest extends ItopTestCase
ThemeHandler::FindStylesheetFile($oImport->GetText(), $aImportsPaths, $oFindStylesheetObject); ThemeHandler::FindStylesheetFile($oImport->GetText(), $aImportsPaths, $oFindStylesheetObject);
} }
$aIncludedImages = ThemeHandler::GetIncludedImages($aThemeParameters['variables'], $oFindStylesheetObject->GetAllStylesheetFiles(), $sThemeId); $aIncludedImages = ThemeHandler::GetIncludedImages($aThemeParameters['variables'], $oFindStylesheetObject->GetStylesheetFileURIs(), $sThemeId);
$compiled_json_sig = ThemeHandler::ComputeSignature($aThemeParameters, $aImportsPaths, $aIncludedImages); $compiled_json_sig = ThemeHandler::ComputeSignature($aThemeParameters, $aImportsPaths, $aIncludedImages);
//echo " current signature: $compiled_json_sig\n"; //echo " current signature: $compiled_json_sig\n";
@@ -285,7 +288,7 @@ JSON;
{ {
return [ return [
"pass ParamAttributes and Save them in Json" => [false], "pass ParamAttributes and Save them in Json" => [false],
"use them from saved json" => [true] //"use them from saved json" => [true]
]; ];
} }
@@ -606,15 +609,21 @@ SCSS;
* @dataProvider FindStylesheetFileProvider * @dataProvider FindStylesheetFileProvider
* @throws \Exception * @throws \Exception
*/ */
public function testFindStylesheetFile(string $sFileToFind, array $aAllStylesheetFiles, array $aAllImports){ public function testFindStylesheetFile(string $sFileToFind, array $aAllImports){
$aImportsPath = $this->sTmpDir.'/branding/'; $aImportsPath = $this->sTmpDir.'/branding/';
$oFindStylesheetObject = new FindStylesheetObject(); $oFindStylesheetObject = new FindStylesheetObject();
ThemeHandler::FindStylesheetFile($sFileToFind, [$aImportsPath], $oFindStylesheetObject); ThemeHandler::FindStylesheetFile($sFileToFind, [$aImportsPath], $oFindStylesheetObject);
$this->assertEquals($aAllStylesheetFiles, str_replace($aImportsPath, "", $oFindStylesheetObject->GetAllStylesheetFiles())); $this->assertEquals([$sFileToFind], $oFindStylesheetObject->GetStylesheetFileURIs());
$this->assertEquals($aAllImports, str_replace($aImportsPath, "", $oFindStylesheetObject->GetAllImports())); $this->assertEquals($aAllImports, str_replace($aImportsPath, "", $oFindStylesheetObject->GetImports()));
$this->assertEquals($aImportsPath . $aAllStylesheetFiles[0], $oFindStylesheetObject->GetLastStyleSheet()); $this->assertEquals($aImportsPath.$sFileToFind, $oFindStylesheetObject->GetLastStyleSheetPath());
$aExpectedAllStylesheetPaths = [];
foreach (array_merge([$sFileToFind], $aAllImports) as $sFileUri){
$aExpectedAllStylesheetPaths [] = $aImportsPath.$sFileUri;
}
$this->assertEquals($aExpectedAllStylesheetPaths, $oFindStylesheetObject->GetAllStylesheetPaths());
} }
public function FindStylesheetFileProvider(){ public function FindStylesheetFileProvider(){
@@ -625,33 +634,28 @@ SCSS;
return [ return [
"single file to find" => [ "single file to find" => [
"sFileToFind" => "css/DO_NOT_CHANGE.light-grey.scss", "sFileToFind" => "css/DO_NOT_CHANGE.light-grey.scss",
"aAllStylesheetFiles" => ["css/DO_NOT_CHANGE.light-grey.scss"],
"aAllImports" => [] "aAllImports" => []
], ],
"scss with simple @imports" => [ "scss with simple @imports" => [
"sFileToFind" => "css/simple_import.scss", "sFileToFind" => "css/simple_import.scss",
"aAllStylesheetFiles" => ["css/simple_import.scss", $sFileToFind4],
"aAllImports" => [$sFileToFind4] "aAllImports" => [$sFileToFind4]
], ],
"scss with simple @imports in another folder" => [
"sFileToFind" => "css/simple_import2.scss",
"aAllStylesheetFiles" => ["css/simple_import2.scss", $sFileToFind5],
"aAllImports" => [$sFileToFind5]
],
"scss with @imports shortcut typography => _typography.scss" => [
"sFileToFind" => "css/short_cut.scss",
"aAllStylesheetFiles" => ["css/short_cut.scss", "css/_included_file3.scss"],
"aAllImports" => ["css/_included_file3.scss"]
],
"scss with multi @imports" => [ "scss with multi @imports" => [
"sFileToFind" => $sFileToFind3, "sFileToFind" => $sFileToFind3,
"aAllStylesheetFiles" => [
$sFileToFind3,
$sFileToFind4,
$sFileToFind5
],
"aAllImports" => [$sFileToFind4, $sFileToFind5] "aAllImports" => [$sFileToFind4, $sFileToFind5]
] ],
"scss with simple @imports in another folder" => [
"sFileToFind" => "css/simple_import2.scss",
"aAllImports" => [$sFileToFind5]
],
"scss with @imports shortcut typography => _typography.scss" => [
"sFileToFind" => "css/shortcut.scss",
"aAllImports" => ["css/_included_file3.scss", "css/included_scss/included_file4.scss"]
],
"cross_reference & infinite loop" => [
"sFileToFind" => "css/cross_reference1.scss",
"aAllImports" => ["css/cross_reference2.scss"]
],
]; ];
} }

View File

@@ -0,0 +1,2 @@
@import 'cross_reference2.scss';

View File

@@ -0,0 +1,2 @@
@import 'cross_reference1.scss';

View File

@@ -1,2 +0,0 @@
@import 'included_file3';

View File

@@ -0,0 +1,3 @@
@import 'included_file3';
@import 'included_scss/included_file4';