Weave 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 Tools Laravel Package

laranail/package-tools

laranail/package-tools is a toolkit for Laravel package developers, offering helpers and scaffolding for service providers, configuration, migrations, and common package concerns so you can build cleaner, more consistent add-ons with less boilerplate.

Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require laranail/package-tools
    

    Add to composer.json under require-dev if only for package development:

    "require-dev": {
        "laranail/package-tools": "^1.0"
    }
    
  2. First Use Case: Package Scaffolding Run the package:new Artisan command to generate a boilerplate package structure:

    php artisan package:new MyPackage
    

    This creates:

    • src/ (core classes)
    • config/ (package config)
    • resources/ (views, assets)
    • tests/ (package tests)
    • package.json (if applicable)
  3. Key Files to Review

    • PackageServiceProvider.php (entry point)
    • config/package.php (default config)
    • src/Package.php (fluent builder base)

Implementation Patterns

1. Fluent Package Builder

Use the Package class to define package metadata and features declaratively:

use Laranail\PackageTools\Package;

$package = new Package('vendor/package', '1.0.0')
    ->name('My Awesome Package')
    ->description('Does amazing things.')
    ->author('Jane Developer', '[email protected]')
    ->requires('laravel/framework', '^10.0')
    ->conflicts('other/package', '^1.0')
    ->provides('package-feature');

Common Methods:

Method Purpose Example
addConfig() Register package config ->addConfig('package.php')
addView() Register views ->addView('path/to/views')
addAsset() Register assets (JS/CSS) ->addAsset('path/to/assets')
addCommand() Register Artisan commands ->addCommand(\MyCommand::class)
addMacro() Extend Laravel classes ->addMacro(Str::class, ...)

2. Attribute Discovery

Automatically discover and register package features using attributes:

use Laranail\PackageTools\Attributes\PackageFeature;

#[PackageFeature]
class MyFeature {
    public function register(): void {
        // Feature logic here
    }
}

The package scans for classes with [PackageFeature] and registers them automatically.


3. Integration Workflows

A. Config Publishing

Publish package config with:

php artisan vendor:publish --provider="Vendor\Package\PackageServiceProvider" --tag="config"

Override defaults in config/package.php.

B. View/Asset Publishing

Publish views/assets:

php artisan vendor:publish --provider="Vendor\Package\PackageServiceProvider" --tag="views"
php artisan vendor:publish --provider="Vendor\Package\PackageServiceProvider" --tag="assets"

C. Dynamic Feature Loading

Load features conditionally:

if (config('package.feature.enabled')) {
    $this->app->make(\Vendor\Package\Features\MyFeature::class)->register();
}

4. Testing Patterns

Use the PackageTestCase base class for package tests:

use Laranail\PackageTools\Testing\PackageTestCase;

class MyPackageTest extends PackageTestCase {
    protected function getPackageProviders(): array {
        return [\Vendor\Package\PackageServiceProvider::class];
    }

    public function test_feature() {
        $this->assertTrue(config('package.feature.enabled'));
    }
}

Gotchas and Tips

Pitfalls

  1. Attribute Discovery Scope

    • Attributes are only discovered in classes within the src/ directory by default.
    • Fix: Use #[PackageFeature(scan: true)] to force scan outside src/.
  2. Config Caching

    • Published config is cached. Clear it after changes:
      php artisan config:clear
      
  3. Command/Provider Registration Order

    • Ensure PackageServiceProvider is last in config/app.php to avoid conflicts.
  4. Asset Versioning

    • Always version asset filenames (e.g., styles.css?v=1.0.0) to bypass cache:
      $this->package->addAsset('path/to/assets', 'public/path', 'v=' . $this->version);
      

Debugging Tips

  1. Enable Debug Mode Set PACKAGE_TOOLS_DEBUG=true in .env to log discovery and registration steps.

  2. Check Discovery Logs Run with:

    PACKAGE_TOOLS_DEBUG=1 php artisan package:discover
    
  3. Validate Metadata Use the package:validate command to check for issues:

    php artisan package:validate
    

Extension Points

  1. Custom Attributes Extend discovery with your own attributes:

    use Laranail\PackageTools\Contracts\PackageAttribute;
    
    #[Attribute]
    class MyCustomAttribute implements PackageAttribute {
        public function handle(object $subject, Package $package): void {
            // Custom logic
        }
    }
    
  2. Hooks System Register hooks in PackageServiceProvider:

    $this->package->hook('booting', function () {
        // Runs after package boots
    });
    
  3. Dynamic Config Override config dynamically:

    $this->package->config->set('feature.enabled', true);
    

Performance Quirks

  • Lazy Loading: Features marked with #[LazyLoad] are loaded only when accessed.
  • Memoization: Use $this->package->memoize() to cache expensive operations:
    $data = $this->package->memoize('data', function () {
        return Cache::remember('package-data', 60, fn() => DB::table(...));
    });
    
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.
roundly-consulting/kubernetes-api-for-laravel
roundly-consulting/plausible-for-laravel
gvp/gvp-laravel-template
metasyncsite/laravel-metasync-client
roundly-consulting/onboarding-for-laravel
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo