Browse Source

feat: Compiler les CSS dans un fichier.

On utilise Finder d’ailleurs.
pull/27/head
Matthieu Marcillaud 3 weeks ago
parent
commit
03ec0690b6
  1. 8
      compile
  2. 116
      compiler/PharArchive.php
  3. 3
      composer.json
  4. 3
      loader/public/index.php
  5. 8
      loader/src/Template/Template.php

8
compile

@ -4,9 +4,6 @@
use League\CLImate\CLImate;
use Spip\Loader\Compiler\Build;
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once 'vendor/autoload.php';
$config = [
@ -28,6 +25,11 @@ foreach ($argv as $option) {
}
}
if ($config['debug']) {
error_reporting(E_ALL);
@ini_set('display_errors', 1);
}
$build = new Build(
sourceDirectory: __DIR__ . '/loader',
buildDirectory: __DIR__ . '/build',

116
compiler/PharArchive.php

@ -2,13 +2,10 @@
namespace Spip\Loader\Compiler;
use CallbackFilterIterator;
use Composer\Pcre\Preg;
use FilesystemIterator;
use Iterator;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use IteratorAggregate;
use Seld\PharUtils\Timestamps;
use Symfony\Component\Finder\Finder;
class PharArchive {
private const FILENAME = 'spip_loader.phar';
@ -20,33 +17,36 @@ class PharArchive {
) {
}
public function getPhpFiles(): Iterator {
$iterator = new RecursiveDirectoryIterator(
$this->sourceDirectory,
RecursiveDirectoryIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS
);
$iterator = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);
$iterator = new CallbackFilterIterator($iterator, function ($file) {
/** @var \SplFileInfo $file */
if (!$file->isFile()) {
return false;
}
if (!in_array($file->getExtension(), ['php', 'php8'])) {
return false;
}
if ($file->getPathName() === $this->sourceDirectory . '/phar/stub.php') {
return false;
}
return true;
});
return $iterator;
public function getPhpFiles(): IteratorAggregate {
return (new Finder())->files()
->in($this->sourceDirectory)
->name(['*.php', '*.php8'])
# /!\ Méga attention, ça enlèvera aussi les mêmes répertoires
# dans des sous dossiers https://github.com/symfony/symfony/issues/28158
->exclude(['phar/', 'tests/']);
}
public function getAssetsFiles(): Iterator {
return new FilesystemIterator(
$this->sourceDirectory . '/public/assets',
FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS
);
public function getCssFiles(): IteratorAggregate {
$order = [
'minipage.vars.css',
'reset.css',
'clear.css',
'minipage.css',
'minipres.css',
'app.css',
];
return (new Finder())->files()
->in($this->sourceDirectory. '/public/assets')
->name('*.css')
->sort(function($a, $b) use ($order) {
return array_search($a->getFilename(), $order) <=> array_search($b->getFilename(), $order);
});
}
public function getAssetsFiles(): IteratorAggregate {
return (new Finder())->files()
->in($this->sourceDirectory. '/public/assets')
->notName('*.css');
}
/** @return int Nombre de fichiers insérés dans l’archive */
@ -54,26 +54,34 @@ class PharArchive {
string $version,
\DateTimeInterface $versionDate,
): int {
$file = $this->buildDirectory . '/' . $this->filename;
$p = new \Phar($file, 0, $this->filename);
$p->setSignatureAlgorithm(\Phar::SHA512);
$p->startBuffering();
$p->setStub(file_get_contents($this->sourceDirectory . '/phar/stub.php'));
$p['/version.php'] = "<?php return '$version';";
$p['/index.php'] = "<?php require 'public/index.php';";
foreach ($this->getPhpFiles() as $phpFile) {
$_file = str_replace($this->sourceDirectory . '/', '', $phpFile);
$p[$_file] = $this->stripWhitespace(file_get_contents($phpFile));
$p[$_file]->compress(\Phar::GZ);
$destFile = $this->buildDirectory . '/' . $this->filename;
$phar = new \Phar($destFile, 0, $this->filename);
$phar->setSignatureAlgorithm(\Phar::SHA512);
$phar->startBuffering();
$phar->setStub(file_get_contents($this->sourceDirectory . '/phar/stub.php'));
$phar['/version.php'] = "<?php return '$version';";
$phar['/index.php'] = "<?php require 'public/index.php';";
foreach ($this->getPhpFiles() as $file) {
$_file = str_replace($this->sourceDirectory . '/', '', $file);
$phar[$_file] = $this->stripWhitespacePhpFile(file_get_contents($file));
$phar[$_file]->compress(\Phar::GZ);
}
$p->buildFromIterator($this->getAssetsFiles(), $this->sourceDirectory);
$p->stopBuffering();
#$p->compressFiles(\Phar::GZ); # casse les assets
$nb = $p->count();
$util = new Timestamps($file);
$css = '';
foreach ($this->getCssFiles() as $file) {
$css .= $this->stripWhitespace(file_get_contents($file)) . "\n";
}
$phar['/public/assets/all.css'] = $css;
$phar->buildFromIterator($this->getAssetsFiles(), $this->sourceDirectory);
$phar->stopBuffering();
#$phar->compressFiles(\Phar::GZ); # casse les assets
$nb = $phar->count();
$util = new Timestamps($destFile);
$util->updateTimestamps($versionDate);
$util->save($file, \Phar::SHA512);
$util->save($destFile, \Phar::SHA512);
return $nb;
}
@ -88,7 +96,7 @@ class PharArchive {
* @param string $source A PHP string
* @return string The PHP string with the whitespace removed
*/
private function stripWhitespace(string $source): string {
private function stripWhitespacePhpFile(string $source): string {
if (!function_exists('token_get_all')) {
return $source;
}
@ -114,4 +122,16 @@ class PharArchive {
return $output;
}
private function stripWhitespace(string $content): string {
$lines = explode("\n", $content);
$lines = array_map('trim', $lines);
$lines = array_filter($lines);
$content = implode("\n", $lines);
$content = preg_replace("# \s+#", " ", $content); # /!\ casse des content: " " (y en a pas)
$content = preg_replace("#\/\*(.*)\*\/#sU", '', $content);
return $content;
}
}

3
composer.json

@ -3,7 +3,8 @@
"composer/pcre": "*",
"seld/phar-utils": "^1.2",
"phpunit/php-timer": "^6.0",
"league/climate": "^3.8"
"league/climate": "^3.8",
"symfony/finder": "^6.2"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",

3
loader/public/index.php

@ -10,9 +10,6 @@ use Spip\Loader\Http\Response;
use Spip\Loader\Template\Error as TemplateError;
use Spip\Loader\Template\Utils;
#error_reporting(E_ALL);
#ini_set('display_errors', 1);
require __DIR__ . '/../vendor/autoload.php';
try {

8
loader/src/Template/Template.php

@ -37,6 +37,8 @@ class Template {
'app.css',
];
private $css_compile_file = 'all.css';
/** @var string */
private $inner = '';
@ -139,9 +141,13 @@ HTML;
/** @return string */
protected function css_files() {
// Dans le phar, les CSS sont compilées dans un fichier unique.
if (file_exists(__DIR__ . '/../../public/assets/' . $this->css_compile_file)) {
return sprintf('<link rel="stylesheet" href="./assets/%s" type="text/css">', $this->css_compile_file) . "\n";
}
// Sinon chacunes visibles
$css = '';
foreach ($this->css_files as $file) {
#$css .= file_get_contents(__DIR__ . '/../../assets/' . $file);
$css .= sprintf('<link rel="stylesheet" href="./assets/%s" type="text/css">', $file) . "\n";
}
return $css;

Loading…
Cancel
Save