Skip to content

Instantly share code, notes, and snippets.

@macarthuror
Created October 21, 2025 22:58
Show Gist options
  • Select an option

  • Save macarthuror/d8d412726e3f6d581cefaa3aee5c2cbd to your computer and use it in GitHub Desktop.

Select an option

Save macarthuror/d8d412726e3f6d581cefaa3aee5c2cbd to your computer and use it in GitHub Desktop.
<?php
/**
* =================================================================
* Laravel Project Init
* =================================================================
*
* A powerful command to kickstart new Laravel projects.
* Command: project:init
*
* Author: @macarthuror
*
*/
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
class InitProjectCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'project:init
{--force : Force overwrite existing .env file}
{--db-connection=sqlite : Database connection type (sqlite, mysql)}
{--no-seed : Skip running seeders}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Initialize a new project: create .env, generate key, setup database, and run migrations with seeders (Development only - cannot run in production)';
/**
* Execute the console command.
*/
public function handle()
{
// Prevent running in production environment
if (app()->environment('production')) {
$this->error('❌ This command cannot be run in production environment for security reasons.');
$this->error('Please run this command only in local, testing');
return self::FAILURE;
}
$this->info('🚀 Starting project initialization...');
$this->newLine();
// Additional safety checks
if (!$this->option('force') && $this->hasExistingData()) {
if (!$this->confirm('⚠️ This operation may overwrite existing data. Are you sure you want to continue?')) {
$this->info('Operation cancelled.');
return self::SUCCESS;
}
}
// Check if .env exists
if (File::exists(base_path('.env')) && !$this->option('force')) {
if (!$this->confirm('The .env file already exists. Do you want to overwrite it?')) {
$this->info('Skipping .env file creation.');
goto skipEnv;
}
}
// Create .env file from .env.example
$this->createEnvFile();
skipEnv:
// Generate application key
$this->generateAppKey();
// Setup database
$this->setupDatabase();
// Run migrations
$this->runMigrations();
// Run seeders (unless --no-seed is specified)
if (!$this->option('no-seed')) {
$this->runSeeders();
}
$this->newLine();
$this->info('✅ Project initialization completed successfully!');
$this->info('Your application is ready to use.');
return self::SUCCESS;
}
/**
* Create .env file from .env.example
*/
protected function createEnvFile()
{
$this->info('📄 Creating .env file from .env.example...');
if (!File::exists(base_path('.env.example'))) {
$this->error('.env.example file not found!');
return;
}
File::copy(base_path('.env.example'), base_path('.env'));
$this->info('✓ .env file created successfully');
}
/**
* Generate application key
*/
protected function generateAppKey()
{
$this->info('🔑 Generating application key...');
Artisan::call('key:generate', ['--force' => true]);
$this->info('✓ Application key generated successfully');
}
/**
* Setup database based on connection type
*/
protected function setupDatabase()
{
$dbConnection = $this->option('db-connection');
$this->info("🗄️ Setting up {$dbConnection} database...");
if ($dbConnection === 'sqlite') {
$this->setupSqliteDatabase();
} elseif ($dbConnection === 'mysql') {
$this->setupMysqlDatabase();
} else {
$this->warn("Database connection '{$dbConnection}' not specifically handled, proceeding with default configuration.");
}
}
/**
* Setup SQLite database
*/
protected function setupSqliteDatabase()
{
$databasePath = database_path('database.sqlite');
if (!File::exists($databasePath)) {
File::put($databasePath, '');
$this->info('✓ SQLite database file created at: database/database.sqlite');
} else {
$this->info('✓ SQLite database file already exists');
}
// Update .env file to use SQLite
$this->updateEnvFile([
'DB_CONNECTION' => 'sqlite',
]);
}
/**
* Setup MySQL database configuration
*/
protected function setupMysqlDatabase()
{
$host = $this->ask('Database host', '127.0.0.1');
$port = $this->ask('Database port', '3306');
$database = $this->ask('Database name', 'laravel');
$username = $this->ask('Database username', 'root');
$password = $this->secret('Database password');
// Update .env file with MySQL configuration
$this->updateEnvFile([
'DB_CONNECTION' => 'mysql',
'DB_HOST' => $host,
'DB_PORT' => $port,
'DB_DATABASE' => $database,
'DB_USERNAME' => $username,
'DB_PASSWORD' => $password,
]);
$this->info('✓ MySQL database configuration updated');
}
/**
* Update .env file with new values
*/
protected function updateEnvFile(array $values)
{
$envPath = base_path('.env');
$envContent = File::get($envPath);
foreach ($values as $key => $value) {
$pattern = "/^{$key}=.*$/m";
$replacement = "{$key}={$value}";
if (preg_match($pattern, $envContent)) {
$envContent = preg_replace($pattern, $replacement, $envContent);
} else {
$envContent .= "\n{$replacement}";
}
}
File::put($envPath, $envContent);
}
/**
* Run database migrations
*/
protected function runMigrations()
{
$this->info('📊 Running database migrations...');
try {
// Test database connection first
DB::connection()->getPdo();
Artisan::call('migrate', ['--force' => true]);
$this->info('✓ Database migrations completed successfully');
} catch (\Exception $e) {
$this->error('Database connection failed: ' . $e->getMessage());
$this->error('Please check your database configuration and try again.');
return false;
}
return true;
}
/**
* Run database seeders
*/
protected function runSeeders()
{
$this->info('🌱 Running database seeders...');
try {
Artisan::call('db:seed', ['--force' => true]);
$this->info('✓ Database seeders completed successfully');
} catch (\Exception $e) {
$this->warn('Seeders failed: ' . $e->getMessage());
$this->warn('This is not critical - your application will still work.');
}
}
/**
* Check if there's existing data that could be overwritten
*/
protected function hasExistingData(): bool
{
// Check if .env file exists
$hasEnv = File::exists(base_path('.env'));
// Check if database file exists and has content
$hasDatabase = false;
if (File::exists(database_path('database.sqlite'))) {
$hasDatabase = File::size(database_path('database.sqlite')) > 0;
}
return $hasEnv || $hasDatabase;
}
}

Supercharge Your Laravel Setup with project:init 🚀

Tired of the same old setup dance every time you start a new Laravel project? Me too. That's why I built this handy Artisan command project:init takes care of all the boring stuff for you—creating the .env file, generating a key, setting up the database, and running migrations—all with one simple command.

This lets you skip the boilerplate and get straight to the fun part: coding.

php artisan project:init

What's it do? 🤔

  • One-Command Setup: Kicks off your entire project setup with php artisan project:init.
  • No More .env Hassles: Automatically copies your .env.example to .env.
  • Key Generation on Autopilot: Runs php artisan key:generate so you don't have to.
  • Dead-Simple DB Setup:
    • Handles SQLite out-of-the-box (it'll even create the file for you).
    • For MySQL, it'll just ask you for your credentials. Easy peasy.
  • Migrate & Seed: Runs your migrations and can even seed the database with test data.
  • Plays it Safe:
    • It will always ask for your permission before overwriting an existing .env file.
    • Got your back with a --force flag if you're feeling brave.
    • Don't need seeders? Just use the --no-seed flag.
  • Production-Proof: It literally won't let you run this command on a production server, preventing any "oops" moments. You're welcome 😉.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment