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

Package Versions Laravel Package

ocramius/package-versions

Fast, zero-I/O access to installed Composer package versions from composer.lock. Get dependency versions at runtime via PackageVersions\Versions::getVersion(), with versions compiled during install/update—ideal for building assets or artifacts based on dependency versions.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require ocramius/package-versions
    

    Ensure composer.json includes:

    "config": {
        "optimize-autoloader": true
    }
    

    Run:

    composer dump-autoload --optimize
    
  2. First Use Case: Access a package version in your Laravel application:

    use PackageVersions\Versions;
    
    $version = Versions::getVersion('laravel/framework');
    // Returns: e.g., "10.0.0@sha256hash"
    

Where to Look First

  • Documentation: Focus on the README for installation and basic usage.
  • API: The core class is PackageVersions\Versions with static methods like getVersion().
  • Composer Lock: The package reads from composer.lock (generated during composer install or composer update).

Implementation Patterns

Core Workflows

  1. Version Lookup in Controllers/Blades:

    // In a Laravel controller or Blade template
    $laravelVersion = Versions::getVersion('laravel/framework');
    return view('app', ['version' => $laravelVersion]);
    

    Render in Blade:

    <p>Laravel Version: {{ $version }}</p>
    
  2. Dependency-Aware Artifacts: Generate version-specific assets (e.g., config files, API docs) during deployment:

    $version = Versions::getVersion('vendor/package');
    file_put_contents(
        storage_path("app/versioned-config/{$version}.json"),
        json_encode(['version' => $version])
    );
    
  3. CI/CD Integration: Use in GitHub Actions or GitLab CI to validate dependencies:

    # .github/workflows/validate-versions.yml
    jobs:
      validate:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - run: composer install --optimize-autoloader
          - run: php -r "echo \PackageVersions\Versions::getVersion('laravel/framework');"
    
  4. Dynamic Configuration: Load environment-specific configs based on dependency versions:

    $phpVersion = Versions::getVersion('php');
    config([
        'app.php_compatibility' => [
            '8.2' => require __DIR__.'/config/php82.php',
            '8.3' => require __DIR__.'/config/php83.php',
        ][$phpVersion],
    ]);
    

Integration Tips

  • Service Providers: Register a service provider to preload versions into the container:

    // app/Providers/PackageVersionsServiceProvider.php
    public function register()
    {
        $this->app->singleton('package.versions', function () {
            return new class {
                public function get($package) {
                    return Versions::getVersion($package);
                }
            };
        });
    }
    

    Use in controllers:

    $version = app('package.versions')->get('laravel/framework');
    
  • Artisan Commands: Create a custom command to dump versions:

    php artisan package:versions
    
    // app/Console/Commands/DumpPackageVersions.php
    public function handle()
    {
        $versions = collect(Versions::getAllVersions());
        $this->info($versions->toJson());
    }
    
  • Testing: Mock versions in tests using PackageVersions\Versions::setVersions() (if available) or reset composer.lock between tests.


Gotchas and Tips

Pitfalls

  1. Missing composer.lock:

    • Error: Class 'PackageVersions\Versions' not found or composer.lock not generated.
    • Fix: Ensure composer install or composer update runs before accessing versions. Avoid running in --no-scripts mode unless configured (see changelog/1.1.0).
  2. Autoloader Issues:

    • Error: Class not found despite installation.
    • Fix: Run composer dump-autoload --optimize and clear Laravel cache:
      php artisan config:clear
      php artisan cache:clear
      
  3. Root Package Confusion:

    • Gotcha: Versions::rootPackageName() returns the root package name (e.g., your project name), not a dependency.
    • Fix: Use Versions::getVersion('vendor/package') for dependencies.
  4. Concurrent Autoloader Regeneration:

    • Issue: Multiple plugins (including this one) may regenerate the autoloader during composer update, causing race conditions.
    • Fix: Use --no-plugins or ensure plugins run sequentially.
  5. HHVM Incompatibility:

    • Error: Fails on HHVM due to classmap generation.
    • Fix: Avoid using this package on HHVM (see changelog/1.1.1).
  6. Version Format:

    • Gotcha: Returns version@hash (e.g., 10.0.0@abc123). Trim the hash if only the version is needed:
      $version = explode('@', Versions::getVersion('package'))[0];
      

Debugging Tips

  • Verify composer.lock:

    cat composer.lock | grep 'laravel/framework'
    

    Ensure the package exists in the lock file.

  • Check Autoloader:

    composer show --installed | grep package-versions
    composer dump-autoload --optimize --verbose
    
  • Log Versions: Add a temporary route to debug:

    Route::get('/debug/versions', function () {
        return Versions::getAllVersions();
    });
    

Extension Points

  1. Custom Version Sources: Extend PackageVersions\Versions by overriding the getVersion() logic (though this is not officially supported). Create a decorator:

    class CustomVersions extends Versions {
        public static function getVersion($package) {
            $version = parent::getVersion($package);
            return $version ? "custom-{$version}" : null;
        }
    }
    
  2. Event Listeners: Hook into Composer events to react to version changes (e.g., trigger rebuilds):

    // In a Composer plugin or Laravel service provider
    $composer = new \Composer\Composer();
    $composer->getEventDispatcher()->addListener(
        \Composer\Script\ScriptEvents::POST_INSTALL_CMD,
        function () {
            // Rebuild assets based on new versions
        }
    );
    
  3. Performance Optimization:

    • Cache versions in Redis or the app cache for high-traffic routes:
      $cacheKey = 'package_versions:laravel/framework';
      $version = cache()->remember($cacheKey, 3600, function () {
          return Versions::getVersion('laravel/framework');
      });
      
  4. Testing: Use PackageVersions\Versions::setVersions() (if available in future versions) or mock the composer.lock file in tests:

    // Example using Laravel's filesystem
    Storage::fake('composer');
    Storage::put('composer.lock', file_get_contents(__DIR__.'/tests/fixtures/composer.lock'));
    

Config Quirks

  • optimize-autoloader:

    • Why: Without this, Versions::getVersion() may trigger slow I/O operations.
    • Fix: Always include it in composer.json and run composer dump-autoload --optimize.
  • --classmap-authoritative:

  • Dev Dependencies:

    • Behavior: Dev dependencies (under require-dev) are not included by default. Use Versions::getDevVersion() if available (check latest docs).

Laravel-Specific Tips

  1. Publish Config: If you need to expose versions via config:

    // config/package_versions.php
    return [
        'versions' => Versions::getAllVersions(),
    ];
    

    Publish the config:

    php artisan vendor:publish --tag=config
    
  2. API Responses: Include versions in API responses:

    return response()->json([
        'data' => $resource,
        'metadata' => [
            'laravel_version' => Versions::getVersion('laravel/framework'),
        ],
    
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