Skip to content

Instantly share code, notes, and snippets.

@gnugat
Created August 13, 2025 18:41
Show Gist options
  • Save gnugat/be172cef02229673694803ee4e6f1cbc to your computer and use it in GitHub Desktop.
Save gnugat/be172cef02229673694803ee4e6f1cbc to your computer and use it in GitHub Desktop.
Makefile vs Castor
<?php
use Castor\Attribute\AsTask;
use Castor\Attribute\AsOption;
use Castor\Attribute\AsArgument;
use function Castor\io;
use function Castor\run;
use function Castor\variable;
use function Castor\get_context;
// Global variables
$phpService = 'app';
$dockerRun = 'docker run -it -v "' . getcwd() . '":/app --user ' . trim(`id -u`) . ':' . trim(`id -g`);
// Helper functions for command execution
function dockerExec(string $service, string $command, ?string $env = null): string
{
$envFlag = $env ? "-e APP_ENV={$env}" : '';
return "docker compose exec {$envFlag} {$service} symfony {$command}";
}
function php(string $command = '', ?string $env = null): string
{
global $phpService;
return dockerExec($phpService, "php {$command}", $env);
}
function composer(string $command = ''): string
{
global $phpService;
return dockerExec($phpService, "composer {$command}");
}
function console(string $command = '', ?string $env = null): string
{
global $phpService;
return dockerExec($phpService, "console {$command}", $env ?: 'test');
}
function phinx(string $command = '', ?string $env = null): string
{
global $phpService;
return dockerExec($phpService, "php vendor/bin/phinx {$command}", $env ?: 'test');
}
function phpunit(string $command = ''): string
{
global $phpService;
return dockerExec($phpService, "php vendor/bin/phpunit {$command}");
}
function phpCsFixer(string $command = ''): string
{
global $phpService;
return dockerExec($phpService, "php vendor/bin/php-cs-fixer {$command}");
}
function phpstan(string $command = ''): string
{
global $phpService;
return dockerExec($phpService, "php vendor/bin/phpstan {$command}");
}
// β€”β€” Docker 🐳 β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
#[AsTask(description: 'Builds the Docker images')]
function build(): void
{
run('docker compose build --pull');
}
#[AsTask(description: 'Starts Docker Compose services, in detached mode (no logs)')]
function up(): void
{
run('docker compose up --detach');
}
#[AsTask(description: 'Show live logs')]
function logs(): void
{
run('docker compose logs --tail=0 --follow');
}
#[AsTask(description: 'Stops Docker Compose services')]
function down(): void
{
run('docker compose down --remove-orphans');
}
#[AsTask(description: 'Connect to the container via bash')]
function bash(): void
{
global $phpService;
run("docker compose exec {$phpService} bash", tty: true);
}
// β€”β€” PHP 🐘 β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
#[AsTask(description: 'Runs Composer')]
function composerCmd(
#[AsArgument(description: 'Composer command and options (e.g., "install --optimize-autoloader")')]
string $command = ''
): void
{
run(composer($command));
}
#[AsTask(description: 'Runs bin/console')]
function consoleCmd(
#[AsArgument(description: 'Console command (e.g., "cache:clear")')]
string $command = '',
#[AsOption(description: 'Environment (default: test)')]
string $env = 'test'
): void
{
run(console($command, $env));
}
#[AsTask(description: 'Runs Phinx')]
function phinxCmd(
#[AsArgument(description: 'Phinx command (e.g., "create MyMigration")')]
string $command = '',
#[AsOption(description: 'Environment (default: test)')]
string $env = 'test'
): void
{
run(phinx($command, $env));
}
#[AsTask(description: 'Runs DB migrations')]
function migrate(
#[AsArgument(description: 'Additional migration options')]
string $options = '',
#[AsOption(description: 'Environment (default: test)')]
string $env = 'test'
): void
{
run(phinx("migrate --environment={$env} {$options}", $env));
}
// β€”β€” Quality πŸ›‚ β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
#[AsTask(description: 'Resets test database (drop, create, migrate, fixtures)')]
function dbReset(
#[AsOption(description: 'Environment (default: test)')]
string $env = 'test'
): void
{
io()->title('Resetting database...');
run(console('doctrine:database:drop --force --if-exists', $env));
run(console('doctrine:database:create --if-not-exists', $env));
run(phinx("migrate --environment={$env}", $env));
run(phinx("seed:run --environment={$env}", $env));
io()->success('Database reset complete!');
}
#[AsTask(description: 'Runs the tests with PHPUnit')]
function test(
#[AsArgument(description: 'Test path or options (e.g., "./tests/Unit")')]
string $options = ''
): void
{
run(phpunit($options));
}
#[AsTask(description: 'Static Analysis with PHPStan')]
function staticAnalysis(
#[AsArgument(description: 'Path to analyze (e.g., "./src/")')]
string $path = ''
): void
{
run(phpstan("analyze {$path}"));
}
#[AsTask(description: 'Checks CS with PHP-CS-Fixer')]
function csCheck(
#[AsArgument(description: 'Path to check (e.g., "./src")')]
string $path = ''
): void
{
run(phpCsFixer("check --verbose {$path}"));
}
#[AsTask(description: 'Fixes CS with PHP-CS-Fixer')]
function csFix(
#[AsArgument(description: 'Path to fix (e.g., "./src")')]
string $path = ''
): void
{
run(phpCsFixer("fix --verbose {$path}"));
}
#[AsTask(description: 'Quality Assurance: runs cs-check, static-analysis, and test')]
function qa(): void
{
io()->title('Running Quality Assurance checks...');
io()->section('Checking code style...');
csCheck();
io()->section('Running static analysis...');
staticAnalysis();
io()->section('Running tests...');
test();
io()->success('All QA checks passed!');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment