Created
September 16, 2025 22:14
-
-
Save blashbrook/eef613bb60e10fb7723d32a03ae67c0a to your computer and use it in GitHub Desktop.
Laravel Package Creator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Package Creator - Fixed Version | |
| # Creates Laravel packages with proper composer.json structure | |
| read -p "Enter vendor name (default: Dcplibrary): " vendor | |
| vendor=${vendor:-Dcplibrary} | |
| read -p "Enter package name: " package | |
| read -p "Enter Laravel project directory path (optional, press enter to skip): " laravel_path | |
| echo "Creating package: $vendor/$package" | |
| # Create directory | |
| package_dir=$(echo $package | tr '[:upper:]' '[:lower:]') | |
| mkdir "$package_dir" | |
| cd "$package_dir" | |
| # Initialize basic composer project | |
| composer init --no-interaction --name="$(echo $vendor | tr '[:upper:]' '[:lower:]')/$(echo $package | tr '[:upper:]' '[:lower:]')" | |
| # Create proper composer.json with jq | |
| jq --arg vendor "$vendor" --arg package "$package" '. + { | |
| "type": "library", | |
| "description": "Laravel package for \($package)", | |
| "keywords": ["laravel", "package", "papi", "account"], | |
| "license": "MIT", | |
| "require": { | |
| "php": "^8.1", | |
| "illuminate/support": "^9.0||^10.0||^11.0||^12.0", | |
| "blashbrook/papiclient": "^2.0" | |
| }, | |
| "require-dev": { | |
| "phpunit/phpunit": "^10.0||^11.0", | |
| "orchestra/testbench": "^9.0||^10.0", | |
| "mockery/mockery": "^1.6" | |
| }, | |
| "authors": [{ | |
| "name": "Brian Lashbrook", | |
| "email": "[email protected]" | |
| }], | |
| "homepage": "https://www.dcplibrary.org", | |
| "autoload": { | |
| "psr-4": { | |
| "\($vendor)\\\($package)\\": "src/", | |
| "\($vendor)\\\($package)\\App\\": "src/app" | |
| } | |
| }, | |
| "autoload-dev": { | |
| "psr-4": { | |
| "\($vendor)\\\($package)\\Tests\\": "src/tests/" | |
| } | |
| }, | |
| "extra": { | |
| "branch-alias": { | |
| "dev-main": "1.0.x-dev" | |
| }, | |
| "laravel": { | |
| "providers": [ | |
| "\($vendor)\\\($package)\\App\\Providers\\\($package)ServiceProvider" | |
| ], | |
| "aliases": { | |
| "\($package)": "\($vendor)\\\($package)\\Facades\\\($package)" | |
| } | |
| } | |
| }, | |
| "scripts": { | |
| "test": "phpunit", | |
| "format": "php-cs-fixer fix", | |
| "analyse": "phpstan analyse" | |
| }, | |
| "config": { | |
| "allow-plugins": { | |
| "pestphp/pest-plugin": true | |
| } | |
| }, | |
| "minimum-stability": "dev", | |
| "prefer-stable": true | |
| }' composer.json > temp.json && mv temp.json composer.json | |
| echo "β Valid composer.json created!" | |
| composer validate | |
| echo "Installing Composer dependencies..." | |
| composer install --no-interaction | |
| echo "Initializing npm package..." | |
| npm init -y | |
| echo "Installing npm dev dependencies..." | |
| npm install semantic-release @semantic-release/changelog @semantic-release/git @semantic-release/github --save-dev | |
| echo "Creating Laravel package structure..." | |
| # Create directory structure following user's preferred layout | |
| mkdir -p src/app/Http/Controllers | |
| mkdir -p src/app/Http/Middleware | |
| mkdir -p src/app/Http/Requests | |
| mkdir -p src/app/Providers | |
| mkdir -p src/app/Models | |
| mkdir -p src/config | |
| mkdir -p src/database/Factories | |
| mkdir -p src/database/Migrations | |
| mkdir -p src/database/Seeders | |
| mkdir -p src/Facades | |
| mkdir -p src/resources/views | |
| mkdir -p src/resources/lang | |
| mkdir -p src/resources/assets/css | |
| mkdir -p src/resources/assets/js | |
| mkdir -p src/routes | |
| mkdir -p src/tests/Feature | |
| mkdir -p src/tests/Unit | |
| echo "Creating basic package files..." | |
| # Create main package class | |
| cat > src/${package}.php << EOF | |
| <?php | |
| namespace ${vendor}\\${package}; | |
| class ${package} | |
| { | |
| /** | |
| * Create a new ${package} instance. | |
| */ | |
| public function __construct() | |
| { | |
| // | |
| } | |
| /** | |
| * Get the package version. | |
| */ | |
| public function version(): string | |
| { | |
| return '1.0.0'; | |
| } | |
| /** | |
| * Get the package name. | |
| */ | |
| public function name(): string | |
| { | |
| return '${package}'; | |
| } | |
| } | |
| EOF | |
| # Create Service Provider | |
| cat > src/app/Providers/${package}ServiceProvider.php << EOF | |
| <?php | |
| namespace ${vendor}\\${package}\\App\\Providers; | |
| use Illuminate\\Support\\ServiceProvider; | |
| class ${package}ServiceProvider extends ServiceProvider | |
| { | |
| /** | |
| * Register services. | |
| */ | |
| public function register(): void | |
| { | |
| // Register package services | |
| \$this->app->singleton('${package}', function (\$app) { | |
| return new \\${vendor}\\${package}\\${package}(); | |
| }); | |
| } | |
| /** | |
| * Bootstrap services. | |
| */ | |
| public function boot(): void | |
| { | |
| // Load package routes | |
| \$this->loadRoutesFrom(__DIR__.'/../../routes/web.php'); | |
| // Load package views | |
| \$this->loadViewsFrom(__DIR__.'/../../resources/views', '$(echo $package | tr '[:upper:]' '[:lower:]')'); | |
| // Load package migrations | |
| \$this->loadMigrationsFrom(__DIR__.'/../../database/Migrations'); | |
| // Load package config | |
| \$this->mergeConfigFrom(__DIR__.'/../../config/$(echo $package | tr '[:upper:]' '[:lower:]').php', '$(echo $package | tr '[:upper:]' '[:lower:]')'); | |
| // Register package commands | |
| if (\$this->app->runningInConsole()) { | |
| // Publish package config | |
| \$this->publishes([ | |
| __DIR__.'/../../config/$(echo $package | tr '[:upper:]' '[:lower:]').php' => config_path('$(echo $package | tr '[:upper:]' '[:lower:]').php'), | |
| ], '$(echo $package | tr '[:upper:]' '[:lower:]')-config'); | |
| // Publish package views | |
| \$this->publishes([ | |
| __DIR__.'/../../resources/views' => resource_path('views/vendor/$(echo $package | tr '[:upper:]' '[:lower:]')'), | |
| ], '$(echo $package | tr '[:upper:]' '[:lower:]')-views'); | |
| } | |
| } | |
| } | |
| EOF | |
| # Create package config | |
| cat > src/config/$(echo $package | tr '[:upper:]' '[:lower:]').php << EOF | |
| <?php | |
| return [ | |
| /* | |
| |-------------------------------------------------------------------------- | |
| | ${package} Configuration | |
| |-------------------------------------------------------------------------- | |
| | | |
| | Configuration options for the ${package} package. | |
| | | |
| */ | |
| 'enabled' => env('$(echo $package | tr '[:lower:]' '[:upper:]')_ENABLED', true), | |
| 'debug' => env('$(echo $package | tr '[:lower:]' '[:upper:]')_DEBUG', false), | |
| ]; | |
| EOF | |
| # Create routes | |
| cat > src/routes/web.php << EOF | |
| <?php | |
| use Illuminate\\Support\\Facades\\Route; | |
| use ${vendor}\\${package}\\App\\Http\\Controllers\\${package}Controller; | |
| /* | |
| |-------------------------------------------------------------------------- | |
| | ${package} Routes | |
| |-------------------------------------------------------------------------- | |
| */ | |
| Route::group([ | |
| 'prefix' => '$(echo $package | tr '[:upper:]' '[:lower:]')', | |
| 'middleware' => ['web'], | |
| ], function () { | |
| Route::get('/', [${package}Controller::class, 'index'])->name('$(echo $package | tr '[:upper:]' '[:lower:]').index'); | |
| }); | |
| EOF | |
| # Create controller | |
| cat > src/app/Http/Controllers/${package}Controller.php << EOF | |
| <?php | |
| namespace ${vendor}\\${package}\\App\\Http\\Controllers; | |
| use Illuminate\\Http\\Request; | |
| use Illuminate\\Routing\\Controller; | |
| class ${package}Controller extends Controller | |
| { | |
| /** | |
| * Display the ${package} index page. | |
| */ | |
| public function index() | |
| { | |
| return view('$(echo $package | tr '[:upper:]' '[:lower:]')::index'); | |
| } | |
| } | |
| EOF | |
| # Create facade | |
| cat > src/Facades/${package}.php << EOF | |
| <?php | |
| namespace ${vendor}\\${package}\\Facades; | |
| use Illuminate\\Support\\Facades\\Facade; | |
| /** | |
| * @see \\${vendor}\\${package}\\${package} | |
| */ | |
| class ${package} extends Facade | |
| { | |
| /** | |
| * Get the registered name of the component. | |
| */ | |
| protected static function getFacadeAccessor(): string | |
| { | |
| return '${package}'; | |
| } | |
| } | |
| EOF | |
| # Create view | |
| cat > src/resources/views/index.blade.php << EOF | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>${package}</title> | |
| <style> | |
| body { | |
| font-family: Arial, sans-serif; | |
| max-width: 800px; | |
| margin: 50px auto; | |
| padding: 20px; | |
| background-color: #f8f9fa; | |
| } | |
| .header { | |
| text-align: center; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| color: white; | |
| padding: 2rem; | |
| border-radius: 10px; | |
| margin-bottom: 2rem; | |
| } | |
| .content { | |
| background: white; | |
| padding: 2rem; | |
| border-radius: 10px; | |
| box-shadow: 0 2px 10px rgba(0,0,0,0.1); | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="header"> | |
| <h1>π ${package}</h1> | |
| <p>Laravel Package by ${vendor}</p> | |
| </div> | |
| <div class="content"> | |
| <h2>Welcome to ${package}!</h2> | |
| <p>This is the default view for your Laravel package.</p> | |
| <h3>Package Information:</h3> | |
| <ul> | |
| <li><strong>Vendor:</strong> ${vendor}</li> | |
| <li><strong>Package:</strong> ${package}</li> | |
| <li><strong>Route:</strong> /$(echo $package | tr '[:upper:]' '[:lower:]')</li> | |
| </ul> | |
| <p>Happy coding! π</p> | |
| </div> | |
| </body> | |
| </html> | |
| EOF | |
| # Create basic tests | |
| cat > src/tests/TestCase.php << EOF | |
| <?php | |
| namespace ${vendor}\\${package}\\Tests; | |
| use Orchestra\\Testbench\\TestCase as Orchestra; | |
| use ${vendor}\\${package}\\App\\Providers\\${package}ServiceProvider; | |
| abstract class TestCase extends Orchestra | |
| { | |
| protected function setUp(): void | |
| { | |
| parent::setUp(); | |
| } | |
| protected function getPackageProviders(\$app): array | |
| { | |
| return [ | |
| ${package}ServiceProvider::class, | |
| ]; | |
| } | |
| } | |
| EOF | |
| cat > src/tests/Unit/${package}Test.php << EOF | |
| <?php | |
| namespace ${vendor}\\${package}\\Tests\\Unit; | |
| use ${vendor}\\${package}\\Tests\\TestCase; | |
| use ${vendor}\\${package}\\${package}; | |
| class ${package}Test extends TestCase | |
| { | |
| /** @test */ | |
| public function it_can_be_instantiated(): void | |
| { | |
| \$instance = new ${package}(); | |
| \$this->assertInstanceOf(${package}::class, \$instance); | |
| } | |
| /** @test */ | |
| public function it_returns_correct_name(): void | |
| { | |
| \$instance = new ${package}(); | |
| \$this->assertEquals('${package}', \$instance->name()); | |
| } | |
| } | |
| EOF | |
| # Create Git repository | |
| echo "Initializing Git repository..." | |
| git init | |
| gh repo create "$(echo $vendor | tr '[:upper:]' '[:lower:]')/$(echo $package | tr '[:upper:]' '[:lower:]')" --public | |
| git remote add origin "https://github.com/$(echo $vendor | tr '[:upper:]' '[:lower:]')/$(echo $package | tr '[:upper:]' '[:lower:]').git" | |
| # Create .gitignore | |
| cat > .gitignore << 'EOF' | |
| # Dependencies | |
| /vendor/ | |
| /node_modules/ | |
| # IDE | |
| .idea/ | |
| .vscode/ | |
| # OS | |
| .DS_Store | |
| Thumbs.db | |
| # Testing | |
| .phpunit.result.cache | |
| coverage/ | |
| # Environment | |
| .env* | |
| !.env.example | |
| EOF | |
| git add . | |
| git commit -m "Initial commit" | |
| git push -u origin main | |
| echo "β Laravel package created successfully!" | |
| echo "π Package directory: $(pwd)" | |
| echo "π Repository: https://github.com/$(echo $vendor | tr '[:upper:]' '[:lower:]')/$(echo $package | tr '[:upper:]' '[:lower:]')" | |
| # Configure Laravel project if provided | |
| if [ -n "$laravel_path" ] && [ -d "$laravel_path" ]; then | |
| echo "Configuring Laravel project at $laravel_path..." | |
| package_path=$(pwd) | |
| cd "$laravel_path" | |
| if [ -f "composer.json" ]; then | |
| echo "Adding local repository configuration..." | |
| composer config repositories.$(echo $package | tr '[:upper:]' '[:lower:]') '{"type": "path", "url": "'$package_path'"}' | |
| echo "Adding package as dev dependency..." | |
| composer require "$(echo $vendor | tr '[:upper:]' '[:lower:]')/$(echo $package | tr '[:upper:]' '[:lower:]'):@dev" --dev | |
| echo "β Laravel project configured!" | |
| else | |
| echo "β No composer.json found in $laravel_path" | |
| fi | |
| cd "$package_path" | |
| fi | |
| echo "π All done! Your package is ready for development." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment