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

Lint Report Laravel Package

sweetchuck/lint-report

Laravel package to generate lint reports from your PHP and frontend tooling, suitable for CI pipelines. Aggregates linter outputs into a consistent report format to help track issues across runs and surface results in build artifacts.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require sweetchuck/lint-report
    

    Add the service provider to config/app.php:

    'providers' => [
        Sweetchuck\LintReport\LintReportServiceProvider::class,
    ],
    
  2. Publish Config (optional):

    php artisan vendor:publish --provider="Sweetchuck\LintReport\LintReportServiceProvider" --tag="config"
    

    This generates config/lint-report.php with default settings.

  3. First Use Case: Generate a report from a lint tool (e.g., PHPStan, PSR-12):

    use Sweetchuck\LintReport\Facades\LintReport;
    
    $report = LintReport::generate([
        'tool' => 'phpstan',
        'results' => [
            ['file' => 'app/Models/User.php', 'message' => 'Type error: Expected string, got int', 'severity' => 'error'],
        ],
    ]);
    

Key Configuration

  • Default Report Format: JSON (adjustable via config/lint-report.php).
  • Supported Tools: Extendable via tool_handlers in config (e.g., PHPStan, ESLint, PHP-CS-Fixer).
  • Output: Reports are stored in storage/app/lint-reports/ by default.

Implementation Patterns

Workflow: Integrating with CI/CD

  1. Run Linters: Execute your linter (e.g., PHPStan) and capture output as an array:

    vendor/bin/phpstan analyse --error-format=json > phpstan-results.json
    

    Parse the JSON into an array for the package:

    $results = json_decode(file_get_contents('phpstan-results.json'), true);
    
  2. Generate Report:

    $report = LintReport::generate([
        'tool' => 'phpstan',
        'results' => $results,
        'options' => ['include_severity' => true],
    ]);
    
  3. Store/Process Report:

    • Save to storage:
      $report->save(); // Uses default path: storage/app/lint-reports/{tool}-{timestamp}.json
      
    • Attach to a GitHub issue or Slack notification:
      $report->toMarkdown(); // For issue templates
      $report->toArray();    // For API responses
      

Common Patterns

  1. Tool-Specific Handling: Override default tool handlers in config/lint-report.php:

    'tool_handlers' => [
        'phpstan' => \App\Services\CustomPhpStanHandler::class,
    ],
    

    Implement Sweetchuck\LintReport\Contracts\ToolHandler:

    class CustomPhpStanHandler implements ToolHandler {
        public function transform(array $results): array {
            return array_map(fn($item) => [
                'file' => $item['file'],
                'message' => $item['message'],
                'line' => $item['line'] ?? null,
            ], $results);
        }
    }
    
  2. Batch Processing: Process multiple lint runs in a loop:

    foreach ($lintTools as $tool) {
        $results = $this->runLinter($tool);
        LintReport::generate(compact('tool', 'results'))->save();
    }
    
  3. Artisan Command: Create a custom command for CLI integration:

    use Sweetchuck\LintReport\Facades\LintReport;
    
    class GenerateLintReportCommand extends Command {
        protected $signature = 'lint:report {tool} {--results= : Path to results file}';
        public function handle() {
            $results = json_decode(file_get_contents($this->option('results')), true);
            $report = LintReport::generate([
                'tool' => $this->argument('tool'),
                'results' => $results,
            ]);
            $report->save();
            $this->info("Report saved: {$report->path}");
        }
    }
    

Integration Tips

  • Laravel Testing: Mock the LintReport facade in tests:
    $this->mock(LintReport::class)->shouldReceive('generate')->andReturn($mockReport);
    
  • Queue Reports: Dispatch report generation as a job:
    GenerateLintReportJob::dispatch($tool, $results);
    
  • Webhooks: Trigger reports on Git push via webhook:
    Route::post('/lint-webhook', function (Request $request) {
        $report = LintReport::generate($request->all());
        $report->save();
        return response()->json(['status' => 'processed']);
    });
    

Gotchas and Tips

Pitfalls

  1. Tool Compatibility:

    • Not all linters output data in a structured format. Use tool_handlers to transform raw output.
    • Example: PHP-CS-Fixer’s CLI output may need regex parsing before passing to the package.
  2. File Path Handling:

    • Reports use absolute paths by default. For multi-environment setups, normalize paths:
      $report->setPath('relative/path/to/report.json');
      
    • Avoid hardcoding storage/ paths; use Laravel’s storage_path().
  3. Memory Limits:

    • Large lint result sets (e.g., 1000+ files) may hit memory limits. Stream results or batch processing:
      foreach (array_chunk($results, 100) as $chunk) {
          LintReport::generate(['tool' => 'phpstan', 'results' => $chunk])->save();
      }
      
  4. Config Overrides:

    • Publishing the config does not merge existing keys. Backup config/lint-report.php before publishing.

Debugging

  1. Validate Input: Ensure results array adheres to the expected schema:

    $validator = Validator::make($input, [
        'tool' => 'required|string',
        'results' => 'required|array',
        'results.*.file' => 'required|string',
        'results.*.message' => 'required|string',
    ]);
    
  2. Log Raw Data: Dump raw lint results before processing:

    \Log::debug('Raw lint results', ['results' => $results]);
    
  3. Check Storage Permissions: Ensure storage/app/lint-reports/ is writable:

    mkdir -p storage/app/lint-reports
    chmod -R 775 storage/app/lint-reports
    

Extension Points

  1. Custom Report Formats: Extend the Report class to add new formats (e.g., CSV, XML):

    class CsvReport extends \Sweetchuck\LintReport\Report {
        public function toCsv(): string {
            $headers = ['file', 'message', 'severity'];
            $rows = array_map(fn($item) => [$item['file'], $item['message'], $item['severity']], $this->results);
            return implode("\n", array_merge([implode(',', $headers)], array_map(fn($row) => implode(',', $row), $rows)));
        }
    }
    
  2. Database Storage: Store reports in a database table:

    class DatabaseReport extends \Sweetchuck\LintReport\Report {
        public function save(): void {
            DB::table('lint_reports')->insert([
                'tool' => $this->tool,
                'results' => json_encode($this->results),
                'created_at' => now(),
            ]);
        }
    }
    
  3. Slack Notifications: Integrate with Slack via a custom handler:

    class SlackNotifier {
        public function notify(LintReport $report) {
            $webhook = config('services.slack.webhook');
            $message = $report->toMarkdown();
            Http::post($webhook, ['form_params' => ['text' => $message]]);
        }
    }
    

Pro Tips

  1. Template Reports: Use Blade templates for human-readable reports:

    $report->render('reports::template', ['title' => 'Lint Report']);
    

    Create a view at resources/views/reports/template.blade.php.

  2. GitHub Actions: Upload reports as artifacts:

    - name: Generate Lint Report
      run: php artisan lint:report phpstan --results=phpstan-results.json
    - name: Upload Report
      uses: actions/upload-artifact@v3
      with:
        name: lint-report
        path: storage/app/lint-reports/*.json
    
  3. Severity Filtering: Filter results by severity in the config:

    'default_options' => [
        'min_severity' => 'warning', // Ignore 'info' severity
    ],
    
  4. Retroactive Analysis: Parse historical lint data

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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor