4
0
Fork 0
dcat-admin/src/Console/MinifyCommand.php

279 lines
6.2 KiB
PHP

<?php
namespace Dcat\Admin\Console;
use Dcat\Admin\Support\Helper;
use Illuminate\Console\Command;
use Illuminate\Support\Str;
use Symfony\Component\Process\Process;
class MinifyCommand extends Command
{
const ALL = 'all';
const DEFAULT = 'default';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'admin:minify {name}
{--color= : Theme color code}
{--publish : Publish assets files}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Minify the CSS and JS';
/**
* @var array
*/
protected $colors = [
self::DEFAULT => '',
'blue' => '#6d8be6',
'blue-light' => '#62a8ea',
'green' => '#4e9876',
];
/**
* @var string
*/
protected $packagePath;
/**
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* Execute the console command.
*/
public function handle()
{
$this->packagePath = realpath(__DIR__.'/../..');
$this->files = $this->laravel['files'];
$name = $this->argument('name');
if ($name === static::ALL) {
// 编译所有内置主题色
return $this->compileAllColors();
}
$publish = $this->option('publish');
$color = $this->getColor($name);
$this->backupFiles();
$this->replaceFiles($name, $color);
try {
$this->npmInstall();
$this->info("[$name][$color] npm run production...");
// 编译
$this->runProcess("cd {$this->packagePath} && npm run prod", 1800);
if ($publish) {
$this->publishAssets();
}
} finally {
// 重置文件
$this->resetFiles();
}
}
/**
* 编译所有内置主题.
*/
protected function compileAllColors()
{
foreach ($this->colors as $name => $_) {
$this->call('admin:minify', ['name' => $name]);
}
}
/**
* 发布静态资源.
*/
protected function publishAssets()
{
$options = ['--provider' => 'Dcat\Admin\AdminServiceProvider', '--force' => true, '--tag' => 'dcat-admin-assets'];
$this->call('vendor:publish', $options);
}
/**
* 替换文件.
*
* @param $name
* @param $color
*/
protected function replaceFiles($name, $color)
{
if ($name === static::DEFAULT) {
return;
}
$mixFile = $this->getMixFile();
$contents = str_replace('let theme = null', "let theme = '{$name}'", $this->files->get($mixFile));
$this->files->put($mixFile, $contents);
$colorFile = $this->getColorFile();
$this->files->put($colorFile, "\$primary: $color;");
}
/**
* 备份文件.
*/
protected function backupFiles()
{
if (! is_file($this->getMixBakFile())) {
$this->files->copy($this->getMixFile(), $this->getMixBakFile());
} else {
$this->files->delete($this->getMixFile());
$this->files->copy($this->getMixBakFile(), $this->getMixFile());
}
if (! is_file($this->getColorBakFile())) {
$this->files->copy($this->getColorFile(), $this->getColorBakFile());
}
}
/**
* 重置文件.
*/
protected function resetFiles()
{
$mixFile = $this->getMixFile();
$mixBakFile = $this->getMixBakFile();
if (is_file($mixBakFile)) {
$this->files->delete($mixFile);
$this->files->copy($mixBakFile, $mixFile);
$this->files->delete($mixBakFile);
}
$colorFile = $this->getColorFile();
$colorBakFile = $this->getColorBakFile();
if (is_file($colorBakFile)) {
$this->files->delete($colorFile);
$this->files->copy($colorBakFile, $colorFile);
$this->files->delete($colorBakFile);
}
}
/**
* @return string
*/
protected function getMixFile()
{
return $this->packagePath.'/webpack.mix.js';
}
/**
* @return mixed
*/
protected function getMixBakFile()
{
return str_replace('.js', '.bak.js', $this->getMixFile());
}
/**
* @return string
*/
protected function getColorFile()
{
return $this->packagePath.'/resources/assets/dcat/sass/theme/_primary.scss';
}
/**
* @return mixed
*/
protected function getColorBakFile()
{
return str_replace('.scss', '.bak.scss', $this->getColorFile());
}
/**
* 安装依赖.
*/
protected function npmInstall()
{
if (is_dir($this->packagePath.'/node_modules')) {
return;
}
$this->info('npm install...');
$this->runProcess("cd {$this->packagePath} && npm install");
}
/**
* 获取颜色.
*
* @param string $name
* @return string
*/
protected function getColor($name)
{
if ($name === static::DEFAULT) {
return '';
}
INPUT_COLOR:
$color = $this->option('color');
if (! $color && isset($this->colors[$name])) {
return $this->colors[$name];
}
if (! $color) {
$color = $this->formatColor($this->ask('Please enter a color code(hex)'));
}
if (! $color) {
goto INPUT_COLOR;
}
return $this->formatColor($color);
}
/**
* @param string $color
* @return string
*/
protected function formatColor($color)
{
if ($color && ! Str::startsWith($color, '#')) {
$color = "#$color";
}
return $color;
}
/**
* 执行命令.
*
* @param string $command
* @param int $timeout
*/
protected function runProcess($command, $timeout = 1800)
{
$process = Helper::process($command, $timeout);
$process->run(function ($type, $data) {
if ($type === Process::ERR) {
$this->warn($data);
} else {
$this->info($data);
}
});
}
}