提交 050af358 编写于 作者: weixin_47267244's avatar weixin_47267244

修复热更新排序规则不生效问题,优化热更新

上级 553bd054
......@@ -90,7 +90,7 @@ class Annotation
$list = [];
foreach ($ignoredNamespaces as $ns)
{
$list[] = str_replace('\\*', '.*', preg_quote($ns));
$list[] = Imi::parseRule($ns);
}
$pattern = '/^((' . implode(')|(', $list) . '))$/';
}
......
<?php
declare(strict_types=1);
namespace Imi\HotUpdate\Monitor;
use Imi\Util\File;
use Imi\Util\Imi;
class FileMTime extends BaseMonitor
{
......@@ -20,6 +23,13 @@ class FileMTime extends BaseMonitor
*/
private $changedFiles = [];
/**
* 排除规则.
*
* @var string
*/
private $excludeRule = '';
/**
* 初始化.
*
......@@ -27,48 +37,36 @@ class FileMTime extends BaseMonitor
*/
protected function init()
{
$excludePaths = &$this->excludePaths;
$includePaths = &$this->includePaths;
foreach ($excludePaths as $i => $path)
{
if (!$excludePaths[$i] = realpath($path))
{
unset($excludePaths[$i]);
continue;
}
$excludePaths[$i] .= '/';
}
foreach ($includePaths as $i => $path)
$excludePaths = array_map(function ($item) {
return Imi::parseRule($item);
}, $this->excludePaths);
$this->excludeRule = $excludeRule = '/^(?!((' . implode(')|(', $excludePaths) . ')))/';
foreach ($includePaths as $path)
{
if (!$includePaths[$i] = $path = realpath($path))
{
unset($includePaths[$i]);
continue;
}
foreach (File::enumFile($path) as $file)
if ($enumResult = File::enumFile($path))
{
$fullPath = $file->getFullPath();
foreach ($excludePaths as $path)
foreach ($enumResult as $file)
{
if (substr($fullPath, 0, \strlen($path)) === $path)
$fullPath = $file->getFullPath();
if ('' !== $excludeRule && !preg_match($excludeRule, $fullPath))
{
$file->setContinue(false);
continue 2;
continue;
}
$this->parseInitFile($fullPath);
}
$this->parseInitFile($fullPath);
}
}
}
/**
* 处理初始化文件.
*
* @param string $fileName
*
* @return void
*/
protected function parseInitFile($fileName)
protected function parseInitFile(string $fileName): void
{
if (is_file($fileName))
{
......@@ -81,14 +79,12 @@ class FileMTime extends BaseMonitor
/**
* 检测文件是否有更改.
*
* @return bool
*/
public function isChanged(): bool
{
$changed = false;
$files = &$this->files;
$files = array_map(function ($item) {
$files = array_map(function (array $item): array {
$item['exists'] = false;
return $item;
......@@ -97,29 +93,27 @@ class FileMTime extends BaseMonitor
$changedFiles = [];
$excludePaths = &$this->excludePaths;
$includePaths = $this->includePaths;
$excludeRule = $this->excludeRule;
// 包含的路径中检测
if ($includePaths)
{
foreach ($includePaths as $path)
{
foreach (File::enumFile($path) as $file)
if ($enumResult = File::enumFile($path))
{
$fullPath = $file->getFullPath();
if ($excludePaths)
foreach ($enumResult as $file)
{
foreach ($excludePaths as $path)
$fullPath = $file->getFullPath();
if ('' !== $excludeRule && !preg_match($excludeRule, $fullPath))
{
if (substr($fullPath, 0, \strlen($path)) === $path)
{
$file->setContinue(false);
continue 2;
}
$file->setContinue(false);
continue;
}
if ($this->parseCheckFile($fullPath))
{
$changedFiles[] = $fullPath;
$changed = true;
}
}
if ($this->parseCheckFile($fullPath))
{
$changedFiles[] = $fullPath;
$changed = true;
}
}
}
......@@ -140,8 +134,6 @@ class FileMTime extends BaseMonitor
/**
* 获取变更的文件们.
*
* @return array
*/
public function getChangedFiles(): array
{
......@@ -150,12 +142,8 @@ class FileMTime extends BaseMonitor
/**
* 处理检查文件是否更改,返回是否更改.
*
* @param string $fileName
*
* @return bool
*/
protected function parseCheckFile($fileName)
protected function parseCheckFile(string $fileName): bool
{
$files = &$this->files;
$isFile = is_file($fileName);
......
<?php
declare(strict_types=1);
namespace Imi\HotUpdate\Monitor;
use Imi\Util\Bit;
use Imi\Util\File;
use Imi\Util\Imi;
class Inotify extends BaseMonitor
{
......@@ -40,7 +42,7 @@ class Inotify extends BaseMonitor
*
* @var string
*/
private $excludeRule;
private $excludeRule = '';
/**
* 初始化.
......@@ -56,9 +58,11 @@ class Inotify extends BaseMonitor
$this->handler = $handler = inotify_init();
stream_set_blocking($handler, false);
$excludePaths = &$this->excludePaths;
$excludeRule = &$this->excludeRule;
$excludeRule = implode('|', array_map('\Imi\Util\Imi::parseRule', $excludePaths));
$excludePaths = array_map(function ($item) {
return Imi::parseRule($item);
}, $this->excludePaths);
$this->excludeRule = $excludeRule = '/^(?!((' . implode(')|(', $excludePaths) . ')))/';
$paths = &$this->paths;
$mask = &$this->mask;
$includePaths = $this->includePaths;
......@@ -66,46 +70,24 @@ class Inotify extends BaseMonitor
{
foreach ($includePaths as $path)
{
if (!is_dir($path))
if (is_file($path) && !is_dir($path))
{
continue;
}
inotify_add_watch($handler, $path, $mask);
$directory = new \RecursiveDirectoryIterator($path, \FilesystemIterator::KEY_AS_PATHNAME | \FilesystemIterator::CURRENT_AS_FILEINFO);
$iterator = new \RecursiveIteratorIterator($directory);
if ('' === $excludeRule)
$paths[$path] ??= inotify_add_watch($handler, $path, $mask);
foreach (File::enumFile($path) as $file)
{
foreach ($iterator as $fileName => $fileInfo)
$fullPath = $file->getFullPath();
if (!is_dir($fullPath))
{
$filePath = \dirname($fileName);
if (!isset($paths[$filePath]))
{
$paths[$filePath] = inotify_add_watch($handler, $filePath, $mask);
}
continue;
}
}
else
{
foreach (File::enumFile($path) as $file)
if ('' !== $excludeRule && !preg_match($excludeRule, $fullPath))
{
$fullPath = $file->getFullPath();
if ($excludePaths)
{
foreach ($excludePaths as $path)
{
if (substr($fullPath, 0, \strlen($path)) === $path)
{
$file->setContinue(false);
continue 2;
}
}
}
$filePath = $file->getPath();
if (!isset($paths[$filePath]))
{
$paths[$filePath] = inotify_add_watch($handler, $filePath, $mask);
}
$file->setContinue(false);
continue;
}
$paths[$fullPath] ??= inotify_add_watch($handler, $fullPath, $mask);
}
}
}
......@@ -113,8 +95,6 @@ class Inotify extends BaseMonitor
/**
* 检测文件是否有更改.
*
* @return bool
*/
public function isChanged(): bool
{
......@@ -123,6 +103,7 @@ class Inotify extends BaseMonitor
$paths = &$this->paths;
$handler = &$this->handler;
$mask = &$this->mask;
$excludeRule = $this->excludeRule;
do
{
/** @var array|false $readResult */
......@@ -138,39 +119,21 @@ class Inotify extends BaseMonitor
{
continue;
}
$filePath = File::path((string) $key, $item['name']);
$filePath = File::path($key, $item['name']);
$filePathIsDir = is_dir($filePath);
if (!$filePathIsDir)
if (!$filePathIsDir && ('' === $excludeRule || preg_match($excludeRule, $filePath)))
{
$changedFiles[] = $filePath;
}
if ((Bit::has($item['mask'], \IN_CREATE) || Bit::has($item['mask'], \IN_MOVED_TO)) && $filePathIsDir && !$this->isExclude($filePath))
{
$paths[$filePath] = inotify_add_watch($handler, $filePath, $mask);
}
}
} while (true);
}
/**
* 获取变更的文件们.
*
* @return array
*/
public function getChangedFiles(): array
{
return array_values(array_unique($this->changedFiles));
}
/**
* 判断路径是否被排除.
*
* @param string $filePath
*
* @return bool
*/
protected function isExclude($filePath)
{
return preg_match("/^(?!{$this->excludeRule}).+$/i", $filePath) > 0;
}
}
......@@ -70,11 +70,9 @@ abstract class File
/**
* 枚举文件,支持自定义中断进入下一级目录.
*
* @param string $dirPath
*
* @return \Generator
* @return \Generator|false
*/
public static function enumFile(string $dirPath)
public static function enumFile(string $dirPath, ?string $pattern = null, array $extensionNames = [])
{
if (!is_dir($dirPath))
{
......@@ -86,10 +84,18 @@ abstract class File
if ('.' !== $file && '..' !== $file)
{
$item = new FileEnumItem($dirPath, $file);
yield $item;
if (is_dir($item) && $item->getContinue())
$fullPath = $item->getFullPath();
if (null !== $pattern && !preg_match($pattern, $fullPath))
{
continue;
}
if (!$extensionNames || \in_array(pathinfo($fullPath, \PATHINFO_EXTENSION), $extensionNames))
{
yield $item;
}
if ($item->getContinue() && is_dir($fullPath))
{
foreach (static::enumFile($item) as $fileItem)
foreach (static::enumFile($fullPath, $pattern, $extensionNames) as $fileItem)
{
yield $fileItem;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册