Skip to content

Instantly share code, notes, and snippets.

@blashbrook
Created September 16, 2025 22:14
Show Gist options
  • Select an option

  • Save blashbrook/eef613bb60e10fb7723d32a03ae67c0a to your computer and use it in GitHub Desktop.

Select an option

Save blashbrook/eef613bb60e10fb7723d32a03ae67c0a to your computer and use it in GitHub Desktop.
Laravel Package Creator
#!/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