Skip to content

Commit

Permalink
Add finder depth configuration option (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
frankdekker committed Jan 21, 2024
1 parent 413f33e commit 259974d
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 34 deletions.
5 changes: 0 additions & 5 deletions dev/config/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,5 @@ monolog:
fd_log_viewer:
log_files:
monolog:
type: monolog
name: Monolog
finder:
in: "%kernel.logs_dir%"
name: "*.log"
downloadable: true
deletable: true
11 changes: 11 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ fd_log_viewer:
finder:
in: "%kernel.logs_dir%"
name: "*.log"
depth: '== 0'
ignoreUnreadableDirs: true
followLinks: false
downloadable: false
Expand Down Expand Up @@ -60,6 +61,16 @@ Example:
*.log,*.txt
```

### log_files.finder.depth <small>`int|string|string[]|null`</small>

The maximum depth of directories to search for log files. If set to null all subdirectories will be added. Default: `== 0`

Example:
- `'== 0'` will only search in the specified directory.
- `'>= 0'` will search in the specified directory and all subdirectories.
- `['>= 0', '< 3]` will search in the specified directory and all subdirectories up to a depth of 2.


### log_files.finder.ignoreUnreadableDirs <small>`boolean`</small>

Should unreadable directories by ignored. Default: `true`
Expand Down
4 changes: 4 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ public function getConfigTreeBuilder(): TreeBuilder
->info("The symfony/finder pattern to filter files. Example: *.log")
->defaultNull()
->end()
->scalarNode('depth')
->info("The symfony/finder directory depth to search files for. Example: > 0")
->defaultNull()
->end()
->scalarNode('ignoreUnreadableDirs')
->info("Whether to ignore unreadable directories")
->defaultTrue()
Expand Down
45 changes: 21 additions & 24 deletions src/DependencyInjection/Extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

use FD\LogViewer\Entity\Config\FinderConfig;
use FD\LogViewer\Entity\Config\LogFilesConfig;
use FD\LogViewer\Util\Arrays;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension as BaseExtension;
Expand All @@ -18,6 +19,24 @@
*/
final class Extension extends BaseExtension
{
private const DEFAULT_MONOLOG_CONFIG = [
'log_files' => [
'monolog' => [
'type' => 'monolog',
'name' => 'Monolog',
'downloadable' => false,
'deletable' => false,
'finder' => [
'in' => '%kernel.logs_dir%',
'name' => '*.log',
'depth' => '== 0',
'ignoreUnreadableDirs' => true,
'followLinks' => false,
],
]
]
];

/**
* @inheritDoc
* @throws Throwable
Expand All @@ -31,14 +50,15 @@ public function load(array $configs, ContainerBuilder $container): void

// add defaults
if ($mergedConfigs['enable_default_monolog']) {
$mergedConfigs = self::addMonologDefault($mergedConfigs);
$mergedConfigs = Arrays::merge($mergedConfigs, self::DEFAULT_MONOLOG_CONFIG);
}

foreach ($mergedConfigs['log_files'] as $key => $config) {
$container->register('fd.symfony.log.viewer.log_files_config.finder.' . $key, FinderConfig::class)
->setPublic(false)
->setArgument('$inDirectories', $config['finder']['in'])
->setArgument('$fileName', $config['finder']['name'])
->setArgument('$depth', $config['finder']['depth'])
->setArgument('$ignoreUnreadableDirs', $config['finder']['ignoreUnreadableDirs'])
->setArgument('$followLinks', $config['finder']['followLinks']);

Expand All @@ -61,27 +81,4 @@ public function getAlias(): string
{
return 'fd_log_viewer';
}

/**
* @template T of array
* @phpstan-param T $configs
*
* @phpstan-return T
*/
private static function addMonologDefault(array $configs): array
{
// monolog
$configs['log_files']['monolog']['type'] ??= 'monolog';
$configs['log_files']['monolog']['name'] ??= 'Monolog';
$configs['log_files']['monolog']['downloadable'] ??= false;
$configs['log_files']['monolog']['deletable'] ??= false;

// finder
$configs['log_files']['monolog']['finder']['in'] ??= '%kernel.logs_dir%';
$configs['log_files']['monolog']['finder']['name'] ??= '*.log';
$configs['log_files']['monolog']['finder']['ignoreUnreadableDirs'] ??= true;
$configs['log_files']['monolog']['finder']['followLinks'] ??= false;

return $configs;
}
}
3 changes: 3 additions & 0 deletions src/Entity/Config/FinderConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ class FinderConfig
{
/**
* @codeCoverageIgnore Simple DTO
*
* @param int|string|string[]|null $depth
*/
public function __construct(
public readonly string $inDirectories,
public readonly ?string $fileName,
public readonly int|string|array|null $depth,
public readonly bool $ignoreUnreadableDirs,
public readonly bool $followLinks
) {
Expand Down
4 changes: 4 additions & 0 deletions src/Service/FinderFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ public function createForConfig(FinderConfig $config): Finder
$finder->followLinks();
}

if ($config->depth !== null) {
$finder->depth($config->depth);
}

$finder->files()->in(array_map('trim', explode(',', $config->inDirectories)));

if ($config->fileName !== null) {
Expand Down
35 changes: 35 additions & 0 deletions src/Util/Arrays.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);

namespace FD\LogViewer\Util;

class Arrays
{
/**
* @param array<int|string, mixed> $target
* @param array<int|string, mixed> $source
*
* @return array<int|string, mixed>
*/
public static function merge(array $target, array $source): array
{
foreach ($source as $key => $value) {
// if target key is not set, assign source value
if (array_key_exists($key, $target) === false) {
$target[$key] = $value;
continue;
}

// recursively merge (non-list) arrays
if (is_array($value)
&& is_array($target[$key])
&& array_is_list($value) === false
&& (count($target[$key]) === 0 || array_is_list($target[$key]) === false)
) {
$target[$key] = self::merge($target[$key], $value);
}
}

return $target;
}
}
2 changes: 1 addition & 1 deletion tests/Unit/Service/File/LogFileServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class LogFileServiceTest extends TestCase
protected function setUp(): void
{
parent::setUp();
$this->finderConfig = new FinderConfig(__DIR__, null, false, false);
$this->finderConfig = new FinderConfig(__DIR__, null, null, false, false);
$this->config = $this->createLogFileConfig(['finderConfig' => $this->finderConfig]);

$this->folderService = $this->createMock(FinderFactory::class);
Expand Down
6 changes: 3 additions & 3 deletions tests/Unit/Service/FinderFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@ protected function setUp(): void

public function testFindFilesMinimal(): void
{
$config = new FinderConfig(__DIR__, null, false, false);
$config = new FinderConfig(__DIR__, null, null, false, false);
$expected = (new Finder())->files()->in([__DIR__])->sortByName();

static::assertEquals($expected, $this->service->createForConfig($config));
}

public function testFindFilesFull(): void
{
$config = new FinderConfig(__DIR__, '*.php', true, true);
$expected = (new Finder())->ignoreUnreadableDirs()->followLinks()->files()->in([__DIR__])->name(['*.php'])->sortByName();
$config = new FinderConfig(__DIR__, '*.php', 2, true, true);
$expected = (new Finder())->ignoreUnreadableDirs()->followLinks()->depth(2)->files()->in([__DIR__])->name(['*.php'])->sortByName();

static::assertEquals($expected, $this->service->createForConfig($config));
}
Expand Down
35 changes: 35 additions & 0 deletions tests/Unit/Util/ArraysTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);

namespace FD\LogViewer\Tests\Unit\Util;

use FD\LogViewer\Util\Arrays;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;

#[CoversClass(Arrays::class)]
class ArraysTest extends TestCase
{
public function testMergeSingleDepth(): void
{
static::assertSame(['foo' => 'bar'], Arrays::merge([], ['foo' => 'bar']));
static::assertSame(['foo' => 'bar'], Arrays::merge(['foo' => 'bar'], []));
static::assertSame(['foo' => 'bar'], Arrays::merge(['foo' => 'bar'], ['foo' => 'baz']));
}

public function testMergeMultiDepth(): void
{
static::assertSame(
['foo' => ['bar' => ['baz' => 'qux']]],
Arrays::merge(['foo' => []], ['foo' => ['bar' => ['baz' => 'qux']]])
);
}

public function testMergeMultiDepthLists(): void
{
static::assertSame(
['foo' => ['foo' => 'foo', 'bar' => ['baz', 'qux']]],
Arrays::merge(['foo' => ['foo' => 'foo']], ['foo' => ['bar' => ['baz', 'qux']]])
);
}
}
2 changes: 1 addition & 1 deletion tests/Utility/TestEntityTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function createLogFileConfig(array $arguments = []): LogFilesConfig
'dateFormat' => 'Y-m-d'
];

$arguments['finderConfig'] ??= new FinderConfig('directory', 'file', true, true);
$arguments['finderConfig'] ??= new FinderConfig('directory', 'file', null, true, true);

return new LogFilesConfig(...$arguments);
}
Expand Down

0 comments on commit 259974d

Please sign in to comment.