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

Lines Of Code Laravel Package

sebastian/lines-of-code

Count lines of code in PHP source with sebastian/lines-of-code. A lightweight library for analyzing PHP files and reporting LOC metrics, useful for tooling, CI checks, and development workflows. Install easily via Composer as a runtime or dev dependency.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer as a dev dependency:

composer require --dev sebastian/lines-of-code

First use case: Count LOC in your src/ directory from an Artisan command:

use SebastianBergmann\LinesOfCode\Counter;

$counter = new Counter();
$result = $counter->count(base_path('src'));

// Output results
echo "Total LOC: {$result->linesOfCode}\n";
echo "Comment lines: {$result->commentLinesOfCode}\n";
echo "Non-comment lines: {$result->nonCommentLinesOfCode}\n";

Where to look first:


Implementation Patterns

Core Workflows

  1. CI/CD Integration (GitHub Actions example):
- name: Enforce LOC limits
  run: |
    php -r "require 'vendor/autoload.php'; \
    \$counter = new \SebastianBergmann\LinesOfCode\Counter(); \
    \$result = \$counter->count('src'); \
    if (\$result->linesOfCode > 5000) exit(1);"
  1. Artisan Command (for local dev):
// app/Console/Commands/CountLoc.php
protected $signature = 'loc:count {--dir=src : Directory to scan}';
public function handle() {
    $counter = new Counter();
    $result = $counter->count(base_path($this->option('dir')));

    $this->table(['Metric', 'Value'], [
        ['Total LOC', $result->linesOfCode],
        ['Comments', $result->commentLinesOfCode],
        ['Code Lines', $result->nonCommentLinesOfCode],
    ]);
}
  1. PHPUnit Test (guard against bloat):
public function testNoMassivePr() {
    $counter = new Counter();
    $result = $counter->count('src');

    $this->assertLessThan(10000, $result->linesOfCode,
        "Codebase exceeds sustainable size");
}

Integration Tips

  • Directory Scanning: Use glob() to target specific patterns:

    $files = glob(base_path('src/**/*.php'));
    $result = $counter->count($files);
    
  • Caching Results (for CI):

    $cacheKey = 'loc:src';
    $result = cache()->remember($cacheKey, now()->addHours(1), function() use ($counter) {
        return $counter->count(base_path('src'));
    });
    
  • Laravel Event Listener (track model complexity):

    // app/Listeners/TrackModelLoc.php
    public function handle() {
        $counter = new Counter();
        $result = $counter->count(app_path('Models'));
        event(new ModelLocUpdated($result));
    }
    
  • Multi-Directory Comparison:

    $results = [
        'src' => $counter->count(base_path('src')),
        'tests' => $counter->count(base_path('tests')),
    ];
    

Laravel-Specific Patterns

  1. Service Provider Binding (optional):
// app/Providers/AppServiceProvider.php
public function register() {
    $this->app->singleton(Counter::class, function() {
        return new Counter();
    });
}
  1. Command Bus Integration (for async processing):
// app/Console/Commands/AsyncLocCount.php
public function handle() {
    dispatch(new CountLocJob(base_path('src')));
}
  1. View Helper (for admin dashboards):
// app/Helpers/LocHelper.php
if (!function_exists('loc_metrics')) {
    function loc_metrics($directory) {
        $counter = app(Counter::class);
        return $counter->count($directory);
    }
}

Gotchas and Tips

Pitfalls

  1. PHP Version Mismatch:

    • Laravel 10.x uses PHP 8.3 by default, but this package requires 8.4+.
    • Fix: Use a Docker container or dedicated CI job with PHP 8.4+:
      FROM php:8.4-cli
      WORKDIR /app
      COPY . .
      RUN composer install
      CMD ["php", "artisan", "loc:count"]
      
  2. Parser Conflicts:

    • Underlying nikic/php-parser may conflict with other tools (e.g., PHPStan).
    • Fix: Pin the version in composer.json:
      "require-dev": {
          "nikic/php-parser": "5.0.0"
      }
      
  3. Comment Line Edge Cases:

    • Lines with multiple comments (e.g., // comment /* block */) were historically double-counted (fixed in v5.0.1).
    • Tip: Test with files containing:
      // inline /* block */ comment
      
  4. Performance with Large Codebases:

    • Scanning 100K+ LOC files can be slow in CI.
    • Tip: Cache results or split by directory:
      $counter->count(glob(base_path('src/*/'))); // Process subdirs separately
      
  5. False Negatives:

    • Heredoc syntax (<<<EOD) may not be counted as code.
    • Tip: Validate against manual counts for critical files.

Debugging Tips

  1. Inspect Raw Results:

    $result = $counter->count('src');
    dd($result->getFiles()); // Array of File objects with per-file stats
    
  2. Check Parser Errors:

    • Wrap counting in a try-catch:
      try {
          $result = $counter->count('src');
      } catch (\SebastianBergmann\LinesOfCode\ParserError $e) {
          report($e);
          throw new \RuntimeException("LOC parsing failed", 0, $e);
      }
      
  3. Compare with cloc:

    • Install cloc and verify:
      cloc src/ --by-file --include-ext=php
      

Extension Points

  1. Custom File Filters:

    $counter = new Counter();
    $counter->addFilter(function($file) {
        return strpos($file, 'Tests/') === false; // Exclude tests
    });
    
  2. Post-Processing Results:

    $result = $counter->count('src');
    $metrics = [
        'density' => $result->nonCommentLinesOfCode / $result->linesOfCode,
        'growth' => $result->linesOfCode - old('loc.src', 0),
    ];
    
  3. Integrate with Laravel Scout:

    // Track LOC as a searchable metric
    Loc::create([
        'directory' => 'src',
        'lines_of_code' => $result->linesOfCode,
        'timestamp' => now(),
    ]);
    

Configuration Quirks

  1. Case-Sensitive Paths:

    • Ensure paths match filesystem case (e.g., src/ vs Src/ on case-insensitive filesystems).
  2. Symlink Handling:

    • By default, symlinks are followed. To disable:
      $counter->setFollowSymlinks(false);
      
  3. Memory Limits:

    • Large scans may hit PHP’s memory limit. Increase in CI:
      # GitHub Actions
      env:
        PHP_MEMORY_LIMIT: 2G
      

Pro Tips

  1. Track LOC Over Time:

    // Store in database
    DB::table('loc_history')->insert([
        'directory' => 'src',
        'lines_of_code' => $result->linesOfCode,
        'created_at' => now(),
    ]);
    
  2. Slack Alerts for Spikes:

    if ($result->linesOfCode > old('loc.src', 0) * 1.5) {
        Notifiable::route('slack', config('services.slack.webhook'))
                  ->notify(new LocSpikeAlert($result));
    }
    
  3. Exclude Vendors/Generated Code:

    $counter->addFilter(function($file) {
        return !str_contains($file, ['vendor/', 'bootstrap/cache/']);
    });
    
  4. Benchmark Against Baselines:

    $baseline = 5000; // From initial audit
    if ($result->linesOfCode > $baseline * 1.2) {
        // Trigger review process
    }
    
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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata