Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

File Filter Laravel Package

sebastian/file-filter

Filter and whitelist/blacklist files and directories in PHP projects. Extracted from phpunit/phpunit, this lightweight library helps build file lists while honoring include/exclude rules—useful for test runners, coverage tools, and CLI utilities.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require sebastian/file-filter
    

    Add as a dev dependency if only needed for testing:

    composer require --dev sebastian/file-filter
    
  2. First Use Case: Filter files in a directory (e.g., for test isolation or build steps):

    use SebastianBergmann\FileFilter\Filter\DirectoryFilter;
    use SebastianBergmann\FileFilter\Filter\PrefixFilter;
    
    $filter = new DirectoryFilter(
        new PrefixFilter('tests/Unit/'),
        __DIR__ . '/tests'
    );
    $filteredFiles = $filter->getFiles();
    
  3. Key Classes to Explore:

    • DirectoryFilter: Base class for filtering directories.
    • PrefixFilter: Filter files by prefix (e.g., tests/Unit/).
    • SuffixFilter: Filter files by suffix (e.g., .php).
    • NotFilter: Invert another filter’s logic.
    • AndFilter/OrFilter: Combine filters with logical operators.

Implementation Patterns

Common Workflows

  1. Test File Isolation: Dynamically filter test files based on environment or configuration:

    $filter = new AndFilter(
        new PrefixFilter('tests/Feature/'),
        new NotFilter(new SuffixFilter('.skip.php'))
    );
    $testFiles = $filter->getFiles();
    
  2. Build/Deployment Pipelines: Exclude files from artifact generation:

    $excludeFilter = new OrFilter(
        new SuffixFilter('.log'),
        new SuffixFilter('.tmp')
    );
    $buildFiles = (new DirectoryFilter($excludeFilter, __DIR__ . '/src'))->getFiles();
    
  3. Dynamic Filtering: Use runtime conditions (e.g., environment variables):

    $prefix = getenv('TEST_PREFIX') ?: 'tests/Unit/';
    $filter = new PrefixFilter($prefix);
    

Integration Tips

  • Laravel Service Providers: Bind the filter to the container for reusable access:

    $this->app->bind(FilterInterface::class, function () {
        return new AndFilter(
            new PrefixFilter('app/Tests/'),
            new NotFilter(new SuffixFilter('.disabled.php'))
        );
    });
    
  • Artisan Commands: Use filters to process files in commands (e.g., php artisan test:filter):

    public function handle() {
        $filter = resolve(FilterInterface::class);
        $files = $filter->getFiles();
        // Process files...
    }
    
  • Event Listeners: Filter files during events (e.g., files:updated):

    public function handle() {
        $filtered = (new DirectoryFilter(
            new PrefixFilter('storage/logs/'),
            storage_path('logs')
        ))->getFiles();
        // Log filtered files...
    }
    

Gotchas and Tips

Pitfalls

  1. Path Normalization:

    • Filters are case-sensitive by default. Use strtolower() on paths if case-insensitive matching is needed.
    • Gotcha: PrefixFilter('tests/') won’t match tests/ if trailing slashes differ. Use rtrim() or DIRECTORY_SEPARATOR for consistency:
      new PrefixFilter(rtrim('tests/', '/') . DIRECTORY_SEPARATOR)
      
  2. Performance:

    • getFiles() scans directories recursively. Cache results if used frequently:
      $files = $filter->getFiles(); // Expensive; cache this!
      
  3. Edge Cases:

    • Empty directories or non-existent paths throw RuntimeException. Validate paths first:
      if (!is_dir($path)) throw new \InvalidArgumentException("Directory not found: $path");
      

Debugging

  • Verify Filters: Use getFiles() in twig or dd() to inspect filtered results:

    dd((new DirectoryFilter(new PrefixFilter('tests/'), __DIR__))->getFiles());
    
  • Logical Errors: Double-check AndFilter/OrFilter combinations. Test with dd():

    $filter = new AndFilter(
        new PrefixFilter('tests/'),
        new SuffixFilter('.php')
    );
    dd($filter->getFiles()); // Ensure expected files are included/excluded.
    

Extension Points

  1. Custom Filters: Implement FilterInterface for domain-specific logic:

    class SizeFilter implements FilterInterface {
        public function getFiles() {
            return array_filter(scandir($this->directory), fn($file) => filesize($file) > 1024);
        }
    }
    
  2. Combine with Laravel: Extend DirectoryFilter to use Laravel’s Filesystem:

    class LaravelDirectoryFilter extends DirectoryFilter {
        public function __construct(FilterInterface $filter, string $directory, Filesystem $files) {
            parent::__construct($filter, $files->basePath($directory));
        }
    }
    
  3. Configuration: Store filter rules in config/file-filter.php:

    return [
        'test_prefix' => env('TEST_PREFIX', 'tests/Unit/'),
        'excluded_suffixes' => ['.skip.php', '.bak'],
    ];
    

    Then inject dynamically:

    $filter = new AndFilter(
        new PrefixFilter(config('file-filter.test_prefix')),
        new NotFilter(new OrFilter(
            array_map(fn($suffix) => new SuffixFilter($suffix), config('file-filter.excluded_suffixes'))
        ))
    );
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai