Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions .github/workflows/rector-cs.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Rector + PHP CS Fixer

on:
pull_request_target:
pull_request:
paths:
- 'config/**'
- 'src/**'
Expand All @@ -12,7 +12,7 @@ on:
- '.php-cs-fixer.dist.php'

permissions:
contents: read
contents: write

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand All @@ -21,8 +21,5 @@ concurrency:
jobs:
rector:
uses: yiisoft/actions/.github/workflows/rector-cs.yml@master
secrets:
token: ${{ secrets.YIISOFT_GITHUB_TOKEN }}
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
php: '8.0'
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## 3.1.1 under development

- Enh #83: Explicitly import classes in "use" section (@mspirkov)
- Bug #84: Preserve modification time of rotated log files in `FileRotator` (@terabytesoftw)

## 3.1.0 December 13, 2025

Expand Down
8 changes: 8 additions & 0 deletions src/FileRotator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@
use function fclose;
use function feof;
use function file_exists;
use function filemtime;
use function filesize;
use function flock;
use function fread;
use function ftruncate;
use function is_file;
use function sprintf;
use function substr;
use function touch;
use function unlink;

use const LOCK_EX;
Expand Down Expand Up @@ -69,10 +71,10 @@
* @param bool $compressRotatedFiles Whether to compress rotated files with gzip.
*/
public function __construct(
int $maxFileSize = 10240,

Check warning on line 74 in src/FileRotator.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "IncrementInteger": --- Original +++ New @@ @@ * environment. * @param bool $compressRotatedFiles Whether to compress rotated files with gzip. */ - public function __construct(int $maxFileSize = 10240, int $maxFiles = 5, private ?int $fileMode = null, bool $compressRotatedFiles = false) + public function __construct(int $maxFileSize = 10241, int $maxFiles = 5, private ?int $fileMode = null, bool $compressRotatedFiles = false) { $this->checkCannotBeLowerThanOne($maxFileSize, '$maxFileSize'); $this->checkCannotBeLowerThanOne($maxFiles, '$maxFiles');
int $maxFiles = 5,

Check warning on line 75 in src/FileRotator.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "IncrementInteger": --- Original +++ New @@ @@ * environment. * @param bool $compressRotatedFiles Whether to compress rotated files with gzip. */ - public function __construct(int $maxFileSize = 10240, int $maxFiles = 5, private ?int $fileMode = null, bool $compressRotatedFiles = false) + public function __construct(int $maxFileSize = 10240, int $maxFiles = 6, private ?int $fileMode = null, bool $compressRotatedFiles = false) { $this->checkCannotBeLowerThanOne($maxFileSize, '$maxFileSize'); $this->checkCannotBeLowerThanOne($maxFiles, '$maxFiles');
private ?int $fileMode = null,
bool $compressRotatedFiles = false,

Check warning on line 77 in src/FileRotator.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "FalseValue": --- Original +++ New @@ @@ * environment. * @param bool $compressRotatedFiles Whether to compress rotated files with gzip. */ - public function __construct(int $maxFileSize = 10240, int $maxFiles = 5, private ?int $fileMode = null, bool $compressRotatedFiles = false) + public function __construct(int $maxFileSize = 10240, int $maxFiles = 5, private ?int $fileMode = null, bool $compressRotatedFiles = true) { $this->checkCannotBeLowerThanOne($maxFileSize, '$maxFileSize'); $this->checkCannotBeLowerThanOne($maxFiles, '$maxFiles');
) {
$this->checkCannotBeLowerThanOne($maxFileSize, '$maxFileSize');
$this->checkCannotBeLowerThanOne($maxFiles, '$maxFiles');
Expand All @@ -80,7 +82,7 @@
$this->maxFileSize = $maxFileSize;
$this->maxFiles = $maxFiles;

if ($compressRotatedFiles && !extension_loaded('zlib')) {

Check warning on line 85 in src/FileRotator.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "LogicalAndSingleSubExprNegation": --- Original +++ New @@ @@ $this->checkCannotBeLowerThanOne($maxFiles, '$maxFiles'); $this->maxFileSize = $maxFileSize; $this->maxFiles = $maxFiles; - if ($compressRotatedFiles && !extension_loaded('zlib')) { + if (!$compressRotatedFiles && !extension_loaded('zlib')) { throw new RuntimeException(sprintf('The %s requires the PHP extension "ext-zlib" to compress rotated files.', self::class)); } $this->compressRotatedFiles = $compressRotatedFiles;
throw new RuntimeException(sprintf(
'The %s requires the PHP extension "ext-zlib" to compress rotated files.',
self::class,
Expand All @@ -98,13 +100,13 @@
$newFile = $file . '.' . ($i + 1);

if ($i === $this->maxFiles) {
$this->safeRemove($this->compressRotatedFiles ? $rotateFile . self::COMPRESS_EXTENSION : $rotateFile);

Check warning on line 103 in src/FileRotator.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": --- Original +++ New @@ @@ $rotateFile = $file . ($i === 0 ? '' : '.' . $i); $newFile = $file . '.' . ($i + 1); if ($i === $this->maxFiles) { - $this->safeRemove($this->compressRotatedFiles ? $rotateFile . self::COMPRESS_EXTENSION : $rotateFile); + continue; } if ($this->compressRotatedFiles && is_file($rotateFile . self::COMPRESS_EXTENSION)) {

Check warning on line 103 in src/FileRotator.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "Ternary": --- Original +++ New @@ @@ $rotateFile = $file . ($i === 0 ? '' : '.' . $i); $newFile = $file . '.' . ($i + 1); if ($i === $this->maxFiles) { - $this->safeRemove($this->compressRotatedFiles ? $rotateFile . self::COMPRESS_EXTENSION : $rotateFile); + $this->safeRemove($this->compressRotatedFiles ? $rotateFile : $rotateFile . self::COMPRESS_EXTENSION); continue; } if ($this->compressRotatedFiles && is_file($rotateFile . self::COMPRESS_EXTENSION)) {

Check warning on line 103 in src/FileRotator.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "ConcatOperandRemoval": --- Original +++ New @@ @@ $rotateFile = $file . ($i === 0 ? '' : '.' . $i); $newFile = $file . '.' . ($i + 1); if ($i === $this->maxFiles) { - $this->safeRemove($this->compressRotatedFiles ? $rotateFile . self::COMPRESS_EXTENSION : $rotateFile); + $this->safeRemove($this->compressRotatedFiles ? $rotateFile : $rotateFile); continue; } if ($this->compressRotatedFiles && is_file($rotateFile . self::COMPRESS_EXTENSION)) {

Check warning on line 103 in src/FileRotator.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "ConcatOperandRemoval": --- Original +++ New @@ @@ $rotateFile = $file . ($i === 0 ? '' : '.' . $i); $newFile = $file . '.' . ($i + 1); if ($i === $this->maxFiles) { - $this->safeRemove($this->compressRotatedFiles ? $rotateFile . self::COMPRESS_EXTENSION : $rotateFile); + $this->safeRemove($this->compressRotatedFiles ? self::COMPRESS_EXTENSION : $rotateFile); continue; } if ($this->compressRotatedFiles && is_file($rotateFile . self::COMPRESS_EXTENSION)) {

Check warning on line 103 in src/FileRotator.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "Concat": --- Original +++ New @@ @@ $rotateFile = $file . ($i === 0 ? '' : '.' . $i); $newFile = $file . '.' . ($i + 1); if ($i === $this->maxFiles) { - $this->safeRemove($this->compressRotatedFiles ? $rotateFile . self::COMPRESS_EXTENSION : $rotateFile); + $this->safeRemove($this->compressRotatedFiles ? self::COMPRESS_EXTENSION . $rotateFile : $rotateFile); continue; } if ($this->compressRotatedFiles && is_file($rotateFile . self::COMPRESS_EXTENSION)) {
continue;
}

if ($this->compressRotatedFiles && is_file($rotateFile . self::COMPRESS_EXTENSION)) {
$this->rotate($rotateFile . self::COMPRESS_EXTENSION, $newFile . self::COMPRESS_EXTENSION);
continue;

Check warning on line 109 in src/FileRotator.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "Continue_": --- Original +++ New @@ @@ } if ($this->compressRotatedFiles && is_file($rotateFile . self::COMPRESS_EXTENSION)) { $this->rotate($rotateFile . self::COMPRESS_EXTENSION, $newFile . self::COMPRESS_EXTENSION); - continue; + break; } if (!is_file($rotateFile)) { continue;
}

if (!is_file($rotateFile)) {
Expand All @@ -129,6 +131,8 @@
*/
private function rotate(string $rotateFile, string $newFile): void
{
$mTime = filemtime($rotateFile);

copy($rotateFile, $newFile);

if ($this->compressRotatedFiles && !$this->isCompressed($newFile)) {
Expand All @@ -139,6 +143,10 @@
if ($this->fileMode !== null) {
chmod($newFile, $this->fileMode);
}

if ($mTime !== false) {
touch($newFile, $mTime);
}
}

/**
Expand Down
31 changes: 31 additions & 0 deletions tests/FileRotatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@
use function clearstatcache;
use function dirname;
use function file_get_contents;
use function filemtime;
use function filesize;
use function mkdir;
use function range;
use function str_repeat;
use function time;
use function touch;

final class FileRotatorTest extends TestCase
{
Expand Down Expand Up @@ -71,6 +74,34 @@ public function testRotate(bool $compress): void
}
}

/**
* @dataProvider rotateDataProvider
*/
public function testRotatePreservesModificationTime(bool $compress): void
{
$rotator = new FileRotator(1, 2, null, $compress);
$logFile = $this->getLogFilePath();
$fileTarget = new FileTarget($logFile, $rotator);
$logger = new Logger([$fileTarget]);
$compressExtension = $compress ? '.gz' : '';

$logger->debug($this->generateKilobytesOfData(1));
$logger->flush(true);

$expectedTime = time() - 7200;
touch($logFile, $expectedTime);
clearstatcache();

$logger->debug('x');
$logger->flush(true);

clearstatcache();

$rotatedFile = "{$logFile}.1{$compressExtension}";
$this->assertFileExists($rotatedFile);
$this->assertSame($expectedTime, filemtime($rotatedFile));
}

/**
* @dataProvider rotateDataProvider
*/
Expand Down
Loading