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

Phpquality Bundle Laravel Package

amoifr/phpquality-bundle

Symfony bundle and Docker image for PHP static code analysis. Generates reports on complexity, maintainability, coupling, architecture/SOLID layer violations, and coverage. Built as a modern replacement for the unmaintained phpmetrics/phpmetrics.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Bundle:

    composer require amoifr/phpquality-bundle
    

    Register in config/bundles.php:

    PhpQuality\PhpQualityBundle::class => ['all' => true],
    
  2. Run First Analysis (Laravel project):

    php bin/console phpquality:analyze --source=app --type=laravel
    

    Outputs HTML report in var/reports/.

  3. Quick Docker Alternative (no Symfony setup):

    docker run --rm -v $(pwd):/project amoifr13/phpquality --source=/project/app --type=laravel
    

First Use Case

Onboarding New Developers:

  • Run with --no-html for terminal summary:
    php bin/console phpquality:analyze --source=app --type=laravel --no-html
    
  • Focus on:
    • Architecture Score (0-100) for project health
    • CCN (complexity) for critical methods
    • DIP violations in service layer

Implementation Patterns

Daily Workflows

  1. Pre-Commit Hook (fail fast):

    php bin/console phpquality:analyze --source=app --type=laravel --fail-on-violation --exclude=tests
    

    Tip: Cache results with --baseline to ignore intentional violations.

  2. Pull Request Analysis:

    php bin/console phpquality:analyze --source=app --type=laravel --coverage=coverage.xml --report-html=pr-reports
    
    • Compare pr-reports against baseline
    • Check Hall of Fame for contributor-specific metrics
  3. CI Pipeline (GitHub Actions):

    - name: Run PhpQuality
      run: |
        php bin/console phpquality:analyze --source=app --type=laravel \
          --baseline=phpquality.baseline.json --fail-on-violation
    

Integration Tips

  • Laravel-Specific:

    • Use --type=laravel to auto-exclude:
      • Eloquent models (treated as Domain)
      • Service Providers (treated as Wiring)
      • Facades/Queue traits (ignored in DIP)
    • Override in phpquality.json:
      {
        "layers": {
          "rules": [
            { "match": "App\\Services\\**", "layer": "Application" }
          ]
        }
      }
      
  • Test Coverage: Generate coverage first:

    ./vendor/bin/phpunit --coverage-clover=coverage.xml
    

    Then analyze:

    php bin/console phpquality:analyze --source=app --coverage=coverage.xml
    

    Focus: Package Coverage for Laravel modules (e.g., App\\Http, App\\Console).

  • Baseline Workflow:

    # Step 1: Generate baseline (run once)
    php bin/console phpquality:analyze --source=app --generate-baseline=phpquality.baseline.json
    
    # Step 2: Enforce new violations only
    php bin/console phpquality:analyze --source=app --baseline=phpquality.baseline.json --fail-on-violation
    

Reporting Patterns

  • Terminal Output:

    php bin/console phpquality:analyze --source=app --no-html | grep -E "CCN|MI|DIP"
    

    Use case: CI logs for critical metrics.

  • HTML Reports:

    • report/analysis.html: Dependency graph (D3.js)
    • report/coverage.html: Package-level coverage heatmap
    • report/metrics.html: Method complexity breakdown
  • JSON Export:

    php bin/console phpquality:analyze --source=app --json=metrics.json
    

    Use case: Feed metrics to monitoring tools (e.g., Prometheus).


Gotchas and Tips

Pitfalls

  1. False Positives in Laravel:

    • Symptom: DIP violations for Carbon, Illuminate\Support\Collection.
    • Fix: Use --type=laravel or whitelist in phpquality.json:
      {
        "abstractionRatio": { "ignore": ["Carbon\\*", "Illuminate\\*"] }
      }
      
  2. Performance:

    • Symptom: Slow analysis on large codebases (>50K LOC).
    • Fix:
      • Exclude directories: --exclude=vendor --exclude=storage
      • Use --no-html for terminal-only output
      • Cache baseline to skip repeated violations
  3. Git Blame Overhead:

    • Symptom: --git-blame adds 10x runtime.
    • Fix: Run separately:
      php bin/console phpquality:analyze --source=app --git-blame --no-html
      
  4. Layer Detection:

    • Symptom: Custom App\Domain not recognized.
    • Fix: Override in phpquality.json:
      {
        "layers": {
          "rules": [
            { "match": "App\\Domain\\**", "layer": "Domain" }
          ]
        }
      }
      

Debugging

  • Verbose Output:

    php bin/console phpquality:analyze --source=app --verbose
    

    Look for: Skipping [file] or Class [Class] categorized as [Layer].

  • Dry Run:

    php bin/console phpquality:analyze --source=app --dry-run
    

    Use case: Test phpquality.json changes without generating reports.

  • Isolated Analysis:

    php bin/console phpquality:analyze --source=app/Services --type=php
    

    Use case: Debug a specific module.

Extension Points

  1. Custom Metrics:

    • Extend PhpQuality\Analyzer\ProjectAnalyzer to add:
      public function addCustomMetric(Project $project, string $name, callable $calculator) { ... }
      
  2. Report Templates:

    • Override Twig templates in var/cache/dev/phpquality/report/ or extend:
      // config/packages/phpquality.yaml
      phpquality:
        report:
          template_path: '%kernel.project_dir%/templates/phpquality'
      
  3. CLI Integration:

    • Reuse PhpQuality\Command\AnalyzeCommand in custom commands:
      $analyzer = $this->get('phpquality.analyzer');
      $result = $analyzer->analyze($sourceDir, $projectType);
      
  4. Preset Extensions:

    • Create a custom preset by subclassing PhpQuality\Analyzer\ProjectType\ProjectType:
      class CustomProjectType extends ProjectType {
        protected function getLayerRules(): array {
          return array_merge(parent::getLayerRules(), [
            'App\\Custom\\**' => 'CustomLayer',
          ]);
        }
      }
      

Pro Tips

  • Threshold Tuning: Adjust in phpquality.json:

    {
      "thresholds": {
        "ccn": 10,          // Max allowed CCN
        "mi": 20,           // Min required MI
        "dip": 0.7,         // Min abstraction ratio
        "layerViolations": 0 // Allow 0 layer violations
      }
    }
    
  • Selective Analysis:

    # Only analyze critical paths
    php bin/console phpquality:analyze --source=app/Http --source=app/Services
    
  • Historical Trends:

    # Compare against previous baseline
    php bin/console phpquality:analyze --source=app --baseline=old.baseline.json --json=diff.json
    

    Tool: Use jq to parse diff.json for trend analysis.

  • Laravel Artisan Integration: Add to app/Console/Kernel.php:

    protected $commands = [
        \PhpQuality\Command\AnalyzeCommand::class,
        // ...
    ];
    

    Use case: Run via php artisan phpquality:analyze.

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.
codraw/entity-migrator
codraw/doctrine-extra
codraw/aws-tool-kit
codraw/validator
codraw/workflow
codraw/open-api
codraw/cron-job
codraw/process
codraw/log
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