anas/easy-dev
Interactive Laravel code generator for complete CRUD with repository/service patterns. Auto-detects model relationships and scaffolds policies, DTOs, observers, filters, enums, API resources, routes, and more, with dry-run mode and customizable stubs.
Complete guide to configuring Laravel Easy Dev v2 for your project needs.
The configuration file provides extensive customization options for the package behavior.
php artisan vendor:publish --tag=easy-dev-config
This creates config/easy-dev.php with all available options.
Configure where your models are located:
'model_namespace' => 'App\\Models\\',
// For DDD structure
'model_namespace' => 'Domain\\Models\\',
// For modular structure
'model_namespace' => 'Modules\\{Module}\\Models\\',
Customize output directories for generated files:
'paths' => [
'models' => app_path('Models'),
'controllers' => app_path('Http/Controllers'),
'api_controllers' => app_path('Http/Controllers/Api'),
'requests' => app_path('Http/Requests'),
'repositories' => app_path('Repositories'),
'repository_contracts' => app_path('Repositories/Contracts'),
'services' => app_path('Services'),
'service_contracts' => app_path('Services/Contracts'),
'tests' => base_path('tests'),
'feature_tests' => base_path('tests/Feature'),
'unit_tests' => base_path('tests/Unit'),
'factories' => database_path('factories'),
'seeders' => database_path('seeders'),
'migrations' => database_path('migrations'),
'resources' => app_path('Http/Resources'),
],
For custom project structures:
// Domain-Driven Design
'paths' => [
'models' => base_path('src/Domain/Models'),
'controllers' => base_path('src/Http/Controllers'),
'repositories' => base_path('src/Domain/Repositories'),
'services' => base_path('src/Application/Services'),
// ...
],
// Modular Structure
'paths' => [
'controllers' => app_path('Modules/{Module}/Http/Controllers'),
'models' => app_path('Modules/{Module}/Models'),
// ...
],
Configure route generation behavior:
'routes' => [
'api_prefix' => 'api',
'api_version' => 'v1', // Optional versioning
'api_middleware' => ['api', 'auth:sanctum'],
'web_middleware' => ['web', 'auth'],
'generate_api_routes' => true,
'generate_web_routes' => true,
// Route naming
'route_names' => [
'api_prefix' => 'api.',
'web_prefix' => '',
],
// Custom route files
'route_files' => [
'api' => base_path('routes/api.php'),
'web' => base_path('routes/web.php'),
],
],
Control what gets generated by default:
'generation' => [
'use_repository_pattern' => true,
'use_service_pattern' => true,
'generate_interfaces' => true,
'generate_tests' => true,
'generate_factories' => true,
'generate_form_requests' => true,
'generate_api_resources' => true,
'generate_observers' => false,
'generate_policies' => false,
'generate_events' => false,
// File naming conventions
'naming' => [
'controller_suffix' => 'Controller',
'repository_suffix' => 'Repository',
'service_suffix' => 'Service',
'interface_suffix' => 'Interface',
'request_store_prefix' => 'Store',
'request_update_prefix' => 'Update',
],
],
Configure relationship detection behavior:
'database' => [
'relationship_detection' => true,
'foreign_key_detection' => true,
'polymorphic_detection' => true,
'pivot_table_detection' => true,
'self_referencing_detection' => true,
// Detection patterns
'foreign_key_patterns' => [
'/(\w+)_id$/', // Standard: user_id
'/(\w+)_uuid$/', // UUID: user_uuid
'/(\w+)_foreign_key$/', // Custom: user_foreign_key
],
'polymorphic_patterns' => [
'/(\w+)able_type$/', // Standard: commentable_type
'/(\w+)_type$/', // Alternative: comment_type
],
// Skip these tables during detection
'skip_tables' => [
'migrations',
'password_resets',
'failed_jobs',
'personal_access_tokens',
],
// Skip these columns during detection
'skip_columns' => [
'id',
'created_at',
'updated_at',
'deleted_at',
'email_verified_at',
'remember_token',
],
],
Configure template behavior:
'templates' => [
'controller' => 'default',
'api_controller' => 'default',
'model' => 'default',
'repository' => 'default',
'service' => 'default',
'request' => 'default',
'resource' => 'default',
'test' => 'default',
// Custom template paths
'custom_stubs_path' => resource_path('stubs/custom'),
// Template variables
'variables' => [
'author' => 'Your Name',
'company' => 'Your Company',
'license' => 'MIT',
],
],
Configure command-line interface behavior:
'ui' => [
'use_beautiful_output' => true,
'show_progress_bars' => true,
'use_colors' => true,
'interactive_mode' => true,
'show_file_paths' => true,
'show_success_summary' => true,
// Color scheme
'colors' => [
'primary' => 'cyan',
'success' => 'green',
'warning' => 'yellow',
'error' => 'red',
'info' => 'blue',
],
],
Configure form request generation:
'validation' => [
'generate_rules' => true,
'generate_messages' => true,
'generate_attributes' => true,
// Default validation rules by field type
'field_rules' => [
'string' => ['required', 'string', 'max:255'],
'text' => ['required', 'string'],
'integer' => ['required', 'integer', 'min:0'],
'decimal' => ['required', 'numeric', 'min:0'],
'boolean' => ['boolean'],
'date' => ['date'],
'datetime' => ['date'],
'email' => ['required', 'email', 'unique:users,email'],
'foreign_key' => ['required', 'exists:{table},id'],
],
// Custom validation messages
'custom_messages' => [
'required' => 'The :attribute field is required.',
'unique' => 'The :attribute has already been taken.',
'exists' => 'The selected :attribute is invalid.',
],
],
Override configuration using environment variables:
# Model namespace
EASY_DEV_MODEL_NAMESPACE="Domain\\Models\\"
# Pattern usage
EASY_DEV_USE_REPOSITORY_PATTERN=true
EASY_DEV_USE_SERVICE_PATTERN=true
EASY_DEV_GENERATE_INTERFACES=true
# Generation options
EASY_DEV_GENERATE_TESTS=true
EASY_DEV_GENERATE_API_RESOURCES=true
# Route configuration
EASY_DEV_API_PREFIX="v1"
EASY_DEV_GENERATE_API_ROUTES=true
# UI preferences
EASY_DEV_USE_BEAUTIFUL_OUTPUT=true
EASY_DEV_INTERACTIVE_MODE=true
# Database detection
EASY_DEV_RELATIONSHIP_DETECTION=true
EASY_DEV_FOREIGN_KEY_DETECTION=true
php artisan vendor:publish --tag=easy-dev-stubs
Stubs are published to resources/stubs/vendor/easy-dev/.
resources/stubs/vendor/easy-dev/
├── controller.stub # Web controller
├── controller.api.stub # API controller
├── controller.repository.stub # Controller with repository
├── controller.api.service.stub # API controller with service
├── controller.web.service.stub # Web controller with service
├── model.stub # Eloquent model
├── repository.stub # Repository implementation
├── repository.interface.stub # Repository interface
├── repository.enhanced.stub # Enhanced repository
├── service.stub # Service implementation
├── service.interface.stub # Service interface
├── request.store.stub # Store request
├── request.update.stub # Update request
├── request.enhanced.stub # Enhanced request
├── factory.stub # Model factory
├── api.resource.stub # API resource
├── api.collection.stub # API collection
└── relations/ # Relationship stubs
├── belongsTo.stub
├── hasMany.stub
├── hasOne.stub
├── belongsToMany.stub
├── morphTo.stub
├── morphOne.stub
└── morphMany.stub
Available variables in stubs:
// Basic variables
{{ ModelName }} // Product
{{ ModelVariable }} // product
{{ ModelPlural }} // products
{{ ModelNamespace }} // App\Models\Product
// Controller variables
{{ ControllerName }} // ProductController
{{ ControllerNamespace }} // App\Http\Controllers
// Repository variables
{{ RepositoryName }} // ProductRepository
{{ RepositoryInterface }} // ProductRepositoryInterface
{{ RepositoryNamespace }} // App\Repositories
// Service variables
{{ ServiceName }} // ProductService
{{ ServiceInterface }} // ProductServiceInterface
{{ ServiceNamespace }} // App\Services
// Request variables
{{ StoreRequest }} // StoreProductRequest
{{ UpdateRequest }} // UpdateProductRequest
{{ RequestNamespace }} // App\Http\Requests
// Database variables
{{ TableName }} // products
{{ PrimaryKey }} // id
{{ FillableFields }} // ['name', 'price', 'description']
// Route variables
{{ RoutePrefix }} // products
{{ RouteMiddleware }} // ['web', 'auth']
// Relationship variables
{{ RelationshipMethods }} // Generated relationship methods
// resources/stubs/vendor/easy-dev/controller.stub
<?php
namespace {{ ControllerNamespace }};
use {{ ModelNamespace }};
use {{ RequestNamespace }}\{{ StoreRequest }};
use {{ RequestNamespace }}\{{ UpdateRequest }};
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Resources\{{ ModelName }}Resource;
/**
* {{ ModelName }} Controller
*
* Handles CRUD operations for {{ ModelName }} model.
*
* [@author](https://github.com/author) {{ Author }}
* [@created](https://github.com/created) {{ Date }}
*/
class {{ ControllerName }} extends Controller
{
/**
* Display a listing of {{ ModelVariable }}s.
*/
public function index(Request $request)
{
${{ ModelVariable }}s = {{ ModelName }}::query()
->when($request->search, function ($query, $search) {
$query->where('name', 'like', "%{$search}%");
})
->paginate($request->per_page ?? 15);
return view('{{ ViewPath }}.index', compact('{{ ModelVariable }}s'));
}
// ... rest of the methods
}
Different configurations for different environments:
// config/easy-dev.php
return [
'generation' => [
'generate_tests' => env('EASY_DEV_GENERATE_TESTS', app()->environment('local')),
'use_repository_pattern' => env('EASY_DEV_USE_REPOSITORY', true),
],
'paths' => [
'controllers' => env('APP_ENV') === 'testing'
? base_path('tests/Fixtures/Controllers')
: app_path('Http/Controllers'),
],
];
Modify configuration at runtime:
// In a service provider
public function boot()
{
if (app()->environment('production')) {
config(['easy-dev.generation.generate_tests' => false]);
}
if (config('app.locale') === 'ar') {
config(['easy-dev.templates.direction' => 'rtl']);
}
}
Create a custom service provider for advanced configuration:
<?php
namespace App\Providers;
use AnasNashat\EasyDev\Services\CodeWriter;
use AnasNashat\EasyDev\Services\FileGenerator;
use Illuminate\Support\ServiceProvider;
class CustomEasyDevServiceProvider extends ServiceProvider
{
public function register(): void
{
// Merge custom configuration
$this->mergeConfigFrom(
base_path('config/custom-easy-dev.php'),
'easy-dev'
);
// Override services
$this->app->bind(CodeWriter::class, CustomCodeWriter::class);
}
public function boot(): void
{
// Runtime configuration
config([
'easy-dev.paths.controllers' => app_path('Custom/Controllers'),
'easy-dev.generation.use_custom_templates' => true,
]);
}
}
Configure based on project structure:
// config/easy-dev.php
return [
'paths' => [
'models' => file_exists(app_path('Domain'))
? app_path('Domain/Models')
: app_path('Models'),
'repositories' => class_exists('App\\Repositories\\BaseRepository')
? app_path('Repositories')
: app_path('Services/Repositories'),
],
'generation' => [
'use_repository_pattern' => interface_exists('App\\Repositories\\BaseRepositoryInterface'),
'use_service_pattern' => class_exists('App\\Services\\BaseService'),
],
];
Add configuration to version control but allow local overrides:
# Don't ignore main config
config/easy-dev.php
# Ignore local overrides
config/easy-dev.local.php
Use environment variables for settings that change between environments:
'generation' => [
'generate_tests' => env('EASY_DEV_GENERATE_TESTS', true),
'use_repository_pattern' => env('EASY_DEV_USE_REPOSITORY', false),
],
Document your configuration choices:
// config/easy-dev.php
/**
* Easy Dev Configuration
*
* This configuration is set up for our project's architecture:
* - We use Repository pattern for data access
* - We use Service pattern for business logic
* - Controllers are kept thin
* - All models have factories for testing
*/
return [
// Configuration options...
];
For large projects, consider:
'database' => [
// Disable detection for large schemas
'relationship_detection' => env('EASY_DEV_DETECT_RELATIONS', false),
// Skip system tables
'skip_tables' => [
'migrations',
'failed_jobs',
'telescope_*',
'pulse_*',
],
],
The configuration system provides complete flexibility to adapt Laravel Easy Dev v2 to any project structure or development workflow!
How can I help you explore Laravel packages today?