Practical Guide: AI-Assisted XP with Symfony & Roo Code in VSCode
This guide provides step-by-step instructions for setting up your development environment and a cheat sheet for common tasks when implementing Extreme Programming (XP) practices with Symfony, Roo Code (AI Assistant), and a specific PHP quality toolchain in VSCode.
(Assumption: Roo Code extension is already installed and configured with API keys/default models).
1. Initial Environment Setup
(Prerequisite: VSCode & Roo Code Installed/Configured)
Step 1.1: Recommend/Install VSCode Extensions
A consistent set of VSCode extensions is crucial for this workflow. You can ensure this in two ways:
- (Recommended) Project Recommendations: Create a
.vscode/extensions.jsonfile in your project root (see Step 2.4 below or Appendix A for script). This prompts anyone opening the project to install the necessary extensions. - (Manual Installation): If needed, install extensions manually via the Extensions view (Ctrl+Shift+X).
Core Recommended Extensions:
bmewburn.vscode-intelephense-client(PHP IntelliSense)TheNouillet.symfony-vscode(Symfony Support)mblode.twig-language-2(Twig Support)xdebug.php-debug(PHP Debugging)eamodio.gitlens(GitLens)RooVeterinaryInc.roo-cline(Roo Code - listed for completeness)- (Optional)
azdanov.vscode-easy-coding-standard,swordev.phpstan(for deeper IDE integration) - (Optional)
GitLab.gitlab-workflow,GitHub.vscode-pull-request-github(CI/CD)
Troubleshooting Tip: If extensions like PHP Intelephense, PHPStan, or ECS report errors finding tools, ensure VSCode can locate your PHP executable. You might need to configure the php.executablePath setting in VSCode or specific path settings within the extensions themselves, especially if using Docker or custom PHP installations.
2. Project Setup & Quality Toolchain (PHP)
(Prerequisite: Symfony Project Created)
Follow these steps to manually set up the PHP quality toolchain and related configurations.
(Note: Steps 2.1, 2.3, 2.4, 2.5, and 2.6 are largely automated by the optional script provided in Appendix A. Step 2.2 requires manual configuration regardless of using the script.)
Step 2.1: Install PHP Quality Tools & MakerBundle
Navigate to your project directory in the terminal and run:
composer require --dev symfony/maker-bundle rector/rector symplify/easy-coding-standard phpstan/phpstan nunomaduro/phpinsights phpunit/phpunit phpro/grumphp
Step 2.2: Configure PHP Tool Configuration Files
(Required even if you use the script in Appendix A)
Create or modify the configuration files for each tool in your project root:
rector.php(Define Rector rules)ecs.php(Define ECS rules, e.g., PSR-12)phpstan.neon(Define PHPStan level, paths, rules)phpinsights.php(Define PHPInsights checks and thresholds)
(Crucial Step): Remember that you must manually define your specific rules, standards, analysis levels, and configurations within rector.php, ecs.php, phpstan.neon, and phpinsights.php according to your project's needs. Refer to the official documentation for each tool.
Step 2.3: Define Composer Scripts (composer.json)
Add/modify the scripts section in your composer.json:
{
"scripts": {
"rector": "rector process --dry-run",
"ecs": "ecs check src tests",
"ecs-fix": "ecs fix src tests",
"phpstan": "phpstan analyse --error-format=table",
"phpstan-baseline": "phpstan analyse --generate-baseline",
"insights": "phpinsights --no-interaction --ansi --min-quality=85",
"insights-baseline": "phpinsights --baseline",
"rector-upgrade": "rector process --config rector.php",
"phpunit": "phpunit",
"quality": [
"@rector",
"@ecs",
"@phpstan",
"@insights",
"@phpunit"
]
}
}
(Run composer install if you modified composer.json)
Step 2.4: Configure VSCode Workspace (.vscode/)
Create the .vscode directory if it doesn't exist. Inside it, create/edit:
-
extensions.json(Recommended Extensions):{ "recommendations": [ "bmewburn.vscode-intelephense-client", "TheNouillet.symfony-vscode", "mblode.twig-language-2", "xdebug.php-debug", "eamodio.gitlens", "RooVeterinaryInc.roo-cline", "GitLab.gitlab-workflow", "GitHub.vscode-pull-request-github" // Optional: Add azdanov.vscode-easy-coding-standard, swordev.phpstan here too ] } -
settings.json(Workspace Settings):{ "[php]": { "editor.defaultFormatter": "azdanov.vscode-easy-coding-standard", // Assumes extension is installed "editor.formatOnSave": true }, "easyCodingStandard.executablePath": "./vendor/bin/ecs", // Path for ECS extension "phpstan.executablePath": "./vendor/bin/phpstan", // Path for PHPStan extension "phpstan.level": 6, // Match your phpstan.neon level "phpstan.autoAnalysis": "onSave", // Enable live analysis (requires PHPStan extension) "phpstan.memoryLimit": "1G", // Adjust as needed "editor.formatOnSave": true // Enable format on save globally }
Step 2.5: Configure VSCode Tasks (.vscode/tasks.json)
Create/edit .vscode/tasks.json to provide easy access to run Composer scripts via the Command Palette (Ctrl+Shift+P > Run Task):
{
"version": "2.0.0",
"tasks": [
{ "label": "rector-dry-run", "type": "shell", "command": "composer", "args": ["rector"], "problemMatcher": [] },
{ "label": "ecs-check", "type": "shell", "command": "composer", "args": ["ecs"], "problemMatcher": [] },
{ "label": "ecs-fix", "type": "shell", "command": "composer", "args": ["ecs-fix"],"problemMatcher": [] },
{ "label": "phpstan", "type": "shell", "command": "composer", "args": ["phpstan"],"problemMatcher": [] },
{ "label": "phpinsights", "type": "shell", "command": "composer", "args": ["insights"],"problemMatcher": [] },
{ "label": "phpunit", "type": "shell", "command": "composer", "args": ["phpunit"],"problemMatcher": [] },
{
"label": "quality-all",
"dependsOn": ["rector-dry-run","ecs-check","phpstan","phpinsights", "phpunit"],
"dependsOrder": "sequence",
"group": { "kind": "build", "isDefault": true }, // Default build task (Ctrl+Shift+B)
"problemMatcher": []
}
]
}
Step 2.6: Set Up Git Hooks with GrumPHP
-
Configure GrumPHP: Run
vendor/bin/grumphp configureto creategrumphp.yml. -
Edit
grumphp.yml: Add tasks for your quality tools.# grumphp.yml grumphp: tasks: rector: config: rector.php triggered_by: ['php'] ecs: config: ecs.php triggered_by: ['php'] phpstan: configuration: phpstan.neon level: 6 triggered_by: ['php'] phpinsights: config: phpinsights.php min_quality: 85 triggered_by: ['php'] phpunit: ~ -
Initialize Hooks: Run
vendor/bin/grumphp git:init.
3. Configuring Roo Code for XP Tasks
Tailor Roo Code's behavior for specific XP workflows using Custom Modes and Instructions.
Step 3.1: Create Custom Modes
Choose one method:
- Ask Roo: In the Roo Code chat, type: "Create a new mode called 'XP TDD Assistant (PHPUnit)'. It should focus on PHPUnit testing and be able to read, edit, and run commands." Roo Code will guide you.
- Use Prompts Tab: Click the Prompts icon in Roo Code's menu bar, click "+" next to Modes, fill in details (Name, Slug, Role Definition, Tool Groups). Note: File restrictions (
fileRegex) require manual JSON editing. - Manual JSON: Edit
custom_modes.json(global) or.roomodes(project-level) via the Prompts Tab ("Edit Global/Project Modes").
Detailed Example Mode Definitions:
Here are more detailed configurations for the example modes:
XP TDD Assistant (PHPUnit)
- Slug:
xp-tdd-assistant-phpunit - Name:
XP TDD Assistant (PHPUnit) - Role Definition:
"You are a meticulous test engineer focused on PHPUnit. Your primary goal is to assist with Test-Driven Development using PHPUnit in a Symfony project." - Groups:
["read", "edit", "command"](Potentially restrict edit totests/directory usingfileRegexin the JSON:"fileRegex": "\\\\tests\\\\.*\\.php$")
Example Instructions (Place in .roo/rules-xp-tdd-assistant-phpunit/01-phpunit-guidelines.md):
- Given a class/method or user story, generate concise, failing PHPUnit test stubs focusing on one behavior at a time.
- When given a failing test, provide the *simplest possible* PHP code to make it pass.
- Suggest relevant edge cases or assertions.
- Adhere strictly to project coding standards (enforced by ECS, defined in ecs.php).
- Use `composer phpunit` or `vendor/bin/phpunit` to run tests when requested via the terminal tool.
XP Refactoring Helper (PHP/Rector)
- Slug:
xp-refactoring-helper-php - Name:
XP Refactoring Helper (PHP/Rector) - Role Definition:
"You are a code quality expert focused on improving PHP code structure using Rector and general principles like DRY and SOLID." - Groups:
["read", "edit", "command"]
Example Instructions (Place in .roo/rules-xp-refactoring-helper-php/01-refactoring-rules.md):
- Analyze the provided PHP/Symfony code and identify opportunities for refactoring based on principles like DRY, SOLID, and simple design.
- Suggest specific refactorings (e.g., extract method, simplify conditional, introduce dependency injection).
- Identify applicable Rector rules for automated refactoring (referencing rector.php).
- Explain the rationale for each suggestion.
- If requested to perform a manual refactoring, provide a diff preview before modifying files.
- Ensure refactored code passes existing tests and PHPStan checks (assume tests/checks will be run manually using `composer phpunit` and `composer phpstan`).
Symfony Best Practice Advisor
- Slug:
symfony-advisor - Name:
Symfony Best Practice Advisor - Role Definition:
"You are an experienced Symfony developer providing guidance on best practices." - Groups:
["read"](Read-only access is often sufficient for advisory roles)
Example Instructions (Place in .roo/rules-symfony-advisor/01-symfony-focus.md):
- Answer questions and review code related to Symfony best practices.
- Focus on correct usage of the service container, Doctrine ORM patterns, controller design, security components, form handling, Twig templating, and MakerBundle usage.
- Explain concepts clearly with reference to Symfony documentation principles.
- Ensure suggestions align with PHPStan level 6+ checks (referencing phpstan.neon).
Coding Standards Enforcer (ECS)
- Slug:
ecs-enforcer - Name:
Coding Standards Enforcer (ECS) - Role Definition:
"You are an automated code style tool ensuring compliance with the project's Easy Coding Standard (ECS) rules." - Groups:
["read", "edit", "command"]
Example Instructions (Place in .roo/rules-ecs-enforcer/01-ecs-tasks.md):
- Format the provided PHP code according to the project's ECS configuration (ecs.php).
- Identify and report any style violations based on configured ECS rules.
- Use `composer ecs-fix` to apply fixes when requested via the terminal tool.
Step 3.2: Set Custom Instructions
Provide specific guidelines for Roo Code beyond the mode definitions.
- Location:
- Global: Prompts Tab > "Custom Instructions for All Modes".
- Workspace: Create
.roo/rules/directory in project root, add.md/.txtinstruction files. (Recommended for team standards). - Mode-Specific: Prompts Tab > Edit Mode > "Mode-specific Custom Instructions" OR create
.roo/rules-{modeSlug}/directory (e.g.,.roo/rules-xp-tdd-assistant-phpunit/) and add instruction files (as shown in the examples above).
- Content: Use markdown files (
.md) or text files (.txt) within the.roo/rules…directories to list specific rules, preferences, or context for the AI.
(Store team-wide instructions in .roo/rules/ under version control.)
Step 3.3: Configure MCP Servers (Optional Advanced)
Model Context Protocol (MCP) allows Roo Code to connect to external tools and services. This is an advanced feature; configure it if you have specific MCP servers you need to integrate.
-
Find/Install Servers: Roo Code doesn't come with MCP servers. You need to find community servers (e.g., on GitHub) or build your own using the MCP SDK.
-
Configure:
- Global: Edit
mcp_settings.jsonvia Roo Code MCP settings (⚙️ icon). - Project: Create/edit
.roo/mcp.jsonin your project root (also accessible via Roo Code MCP settings). Project settings override global ones.
- Global: Edit
-
Settings Format (JSON):
{ "mcpServers": { "your-server-name": { // --- STDIO (Local Server) Example --- // "command": "node", // "args": ["/path/to/server.js"], // "cwd": "/optional/working/dir", // "env": { "API_KEY": "some_key" }, // --- SSE (Remote Server) Example --- "url": "https://your-remote-server.com/mcp", "headers": { "Authorization": "Bearer your-token" }, // --- Common Settings --- "alwaysAllow": ["tool1_from_this_server"], // Tools to auto-approve "disabled": false // Set to true to disable } // Add more server configurations here } } -
Enable/Disable: You can enable/disable MCP globally or per-server via the Roo Code MCP settings view (⚙️ icon). Disabling reduces token usage if MCP is not needed.
(Refer to the Roo Code documentation for detailed MCP configuration, transport types (STDIO/SSE), and SDK information.)
4. XP Workflow Cheat Sheet with Roo Code
Use Roo Code and your configured tools to streamline XP practices.
Generating Boilerplate (MakerBundle + Roo Code)
- Prompt (Generate): Use a general mode with
commandaccess. Prompt:Run the command 'php bin/console make:controller ProductController' to create a new controller.(Roo Code executes the command). MakerBundle might ask interactive questions in the terminal; you may need to answer them there or pre-configure defaults. - Prompt (Flesh Out): After MakerBundle creates the file, prompt Roo Code (e.g., using 'code' mode):
In the generated ProductController.php, implement the 'index' action to fetch all products from the ProductRepository and render the 'product/index.html.twig' template with the products. - Action (Review): Review the combined result (MakerBundle structure + Roo Code logic).
TDD Cycle (PHPUnit)
- Prompt (Red): Select the 'XP TDD Assistant (PHPUnit)' mode. Prompt:
Generate a failing PHPUnit test for [behavior] in [TestClass.php]. - Action (Verify Fail): Run the specific test using VSCode Test Explorer or terminal (
composer phpunit --filter=…). - Prompt (Green): Prompt:
The test [testName] is failing. Write the simplest code in [SourceClass.php] to make it pass. - Action (Review/Format): Review AI code. Save the file (
Ctrl+S) - ECS formats, PHPStan analyzes (check Problems panel). - Action (Verify Pass): Re-run the test.
- Prompt/Action (Refactor):
- Prompt (using 'XP Refactoring Helper' mode):
Review the new code in [SourceClass.php] and test in [TestClass.php]. Suggest refactorings for simplicity/clarity. - OR Perform manual refactoring.
- OR Use Rector (
composer rector-upgrade).
- Prompt (using 'XP Refactoring Helper' mode):
- Action (Verify Refactor): Run all relevant tests (
composer phpunit).
Refactoring
- Prompt (Suggest): Select 'XP Refactoring Helper' mode. Prompt:
Analyze [ClassOrMethod] for refactoring opportunities based on SOLID/DRY principles. - Prompt (Perform): Prompt:
Extract the selected logic into a new private method named [newMethodName].orRename the variable $oldName to $newName throughout this class.(Roo Code will show diffs). - Action (Automate): Run
composer rector-upgradeto apply configured Rector rules. - Action (Verify): Crucially, run tests (
composer phpunit) and static analysis (composer phpstan) after any refactoring.
Coding Standards (ECS/PHPStan)
- Action (Auto-Format): Save PHP files (
Ctrl+S) - ECS formats automatically if configured viasettings.json. - Prompt (Format File): Select 'Coding Standards Enforcer (ECS)' mode. Prompt:
Format the file [FilePath.php] according to ecs.php. - Action (Check): Run
composer ecsandcomposer phpstanmanually or via VSCode Tasks (Ctrl+Shift+B ifquality-allis default). - Action (Fix Style): Run
composer ecs-fixto automatically fix ECS violations. - Action (Pre-commit):
git commit- GrumPHP hook runs checks automatically.
Debugging
- Action (Identify): Run code/tests, get the exact error message and stack trace.
- Prompt (Fix): Use a general Roo Code mode (like 'code' or 'debug'). Prompt:
Fix this error in [FilePath.php]: [Paste full error message and stack trace]. The error occurs when [describe action triggering error]. Check if [suggest specific area, e.g., variable is initialized]. - Action (Review & Test): Review the proposed fix (diff). Apply it. Re-run the code/test to verify. Iterate prompt if needed.
Generating Code (Simple Design - Post-MakerBundle)
(Assuming MakerBundle created the initial file)
- Prompt (Iterate): Use a general mode. Prompt:
In the 'ProductController' created by MakerBundle, add validation to the 'new' and 'edit' actions. Ensure the 'name' field is not blank using Symfony's Validator component.(Build incrementally on the boilerplate). - Action (Review): Review generated code for correctness, adherence to Symfony practices, and simplicity.
Understanding Code
- Prompt (Explain): Use the 'ask' mode or a general mode. Select code or reference a file/method. Prompt:
Explain what this code does: [paste snippet or reference file/method].orExplain the purpose of the [ClassName] class.
Complex Workflow (Orchestrator Mode / Boomerang Tasks)
Use the built-in 🪃 Orchestrator mode to break down complex tasks and delegate to specialized modes.
- Prompt (Overall Goal): Select the
🪃 Orchestratormode. Prompt:Implement a new feature: Allow users to upload a profile picture. This involves updating the User entity, creating a controller action, handling the file upload, saving the path, and writing tests. - Action (Approve Subtask 1 - Test): Roo Code (Orchestrator) might suggest a subtask: "Create failing tests for profile picture upload using PHPUnit." It will propose delegating this to the
XP TDD Assistant (PHPUnit)mode. Approve the subtask. - Action (Interact with Subtask 1): The context switches to the TDD Assistant mode. Interact with it (provide details, review generated tests) until the tests are created. Approve completion when done.
- Action (Resume Orchestrator): The Orchestrator mode resumes, receiving a summary (e.g., "Tests created in tests/Controller/ProfileControllerTest.php").
- Action (Approve Subtask 2 - Implementation): Orchestrator suggests the next subtask: "Implement the controller action and upload logic." It proposes delegating to the
codemode (or a custom Symfony implementation mode). Approve. - Action (Interact with Subtask 2): Context switches to
codemode. Guide the implementation (review code, provide specifics). Approve completion. - Action (Resume & Continue): Orchestrator resumes with a summary. It might suggest further subtasks (e.g., updating the entity using
codemode, refactoring usingXP Refactoring Helpermode) until the overall goal is achieved.
Key Points for Orchestrator Mode:
- Breaks down complexity.
- Uses the best mode for each sub-job.
- Parent task stays clean, receiving only summaries from subtasks.
- Context is isolated; information passed explicitly via initial instructions and final summary.
- Requires approval steps (unless automated in settings).
5. Key Reminders & Best Practices
- Review Critically: Always review AI-generated code. Don't blindly trust it.
- Understand: Make sure you understand the code being generated. Ask the AI to explain.
- Provide Context: Give the AI enough information (code snippets, errors, requirements) in your prompts.
- Iterate: Use short, focused prompts and build features step-by-step. Refine AI output.
- Test Rigorously: Use TDD (PHPUnit) and run tests frequently, especially after refactoring or complex generation.
- Use Quality Tools: Leverage Rector, ECS, PHPStan, phpinsights continuously (local + CI).
- MakerBundle First: Consider using
php bin/console make:…(manually or via Roo Code terminal) for initial file structures, then use Roo Code to implement the logic within those structures. - Orchestrate Complex Tasks: Use the
🪃 Orchestratormode for multi-step features involving different types of work (testing, coding, refactoring). - Explore MCP: If you need to integrate external tools or services (e.g., custom linters, API checkers, deployment tools), investigate configuring them via Roo Code's MCP capabilities (see Step 3.3).
- Maintain XP Values: Use AI to support communication, simplicity, feedback, courage, and respect, not replace them. You are the lead developer.
This guide provides a starting point. Adapt the configurations and workflows to your specific project needs and team practices. Happy AI-assisted XP development!
Appendix A: Automated Setup Script
This script automates the installation and configuration of the PHP quality tools, Symfony MakerBundle, Composer scripts, VSCode settings (including recommended extensions), GrumPHP, and a basic GitHub Actions workflow. Use this as an alternative to the manual steps in Section 2.
Prerequisites for Script: bash, composer, jq, awk.
Script:
#!/usr/bin/env bash
#
# Automate the “PHP Quality Toolchain – Rector → ECS → PHPStan → phpinsights” + MakerBundle + VSCode Recs
# Safe to run repeatedly: skips steps that are already in place.
# ---------------------------------------------------------------
set -euo pipefail
IFS=
### How to Use the Script
1. Save the script content to a file in your project root, for example, `setup_quality_tools.sh`.
2. Make it executable: `chmod +x setup_quality_tools.sh`.
3. Run it from your project root: `./setup_quality_tools.sh`.
### Important Notes
- **Review Before Running:** Understand what the script does before executing it.
- **Project Root:** Run the script from the root directory of your Symfony project (where `composer.json` is located).
- **Idempotent:** The script tries to be safe to run multiple times (it checks if configurations exist before adding them), but it might overwrite `grumphp.yml` if it exists but wasn't created by the script initially. It skips creating `tasks.json`, `extensions.json`, and the GitHub workflow if they already exist.
- **Tool Configuration:** The script _does not_ configure the specific rules within `rector.php`, `ecs.php`, `phpstan.neon`, or `phpinsights.php`. You still need to define your desired rulesets and configurations in these files manually (Step 2.2).
- **PHPUnit:** The script includes `phpunit/phpunit` in composer require, adds a `phpunit` script to `composer.json`, includes it in the `quality` script, adds a VSCode task for it, includes it in `grumphp.yml`, and adds a step to the GitHub workflow.
- **MakerBundle:** The script adds `symfony/maker-bundle` to the dev dependencies.
- _**Script Logic:**_ _The script uses `jq` to check if certain key configurations already exist before attempting to add them. If you have unusual partial configurations, review the script's additions manually._
\n\t'
## ---------- helpers ---------------------------------------------------------
log() { printf "\e[36m▶ %s\e[0m\n" "$*"; }
warn(){ printf "\e[33m⚠ %s\e[0m\n" "$*"; }
die() { printf "\e[31m✖ %s\e[0m\n" "$*" ; exit 1; }
require_cmd() {
command -v "$1" >/dev/null 2>&1 || die "Missing dependency: $1"
}
json_add_if_missing() {
# $1=file $2=jq filter to test $3=jq snippet to add $4=description
# Check if the specific key exists using the filter $2
if jq -e "$2" "$1" >/dev/null; then
log "$4 already present or structure exists"
else
log "Adding $4"
tmp=$(mktemp)
# Apply the addition using the snippet $3
jq "$3" "$1" >"$tmp" && mv "$tmp" "$1" || { rm "$tmp"; die "Failed to update $1"; }
fi
}
## ---------- sanity checks ----------------------------------------------------
require_cmd composer
require_cmd jq
require_cmd awk
[ -f composer.json ] || die "Run from project root (composer.json not found)"
## ---------- 1. Composer dev tools -------------------------------------------
log "1. Ensuring dev dependencies (Quality Tools + MakerBundle)"
composer require --no-interaction --dev \
symfony/maker-bundle \
rector/rector \
symplify/easy-coding-standard \
phpstan/phpstan \
nunomaduro/phpinsights \
phpunit/phpunit \
phpro/grumphp
## ---------- 2. Composer scripts ---------------------------------------------
log "2. Patching composer.json scripts"
# Check specifically for the 'quality' script key
json_add_if_missing composer.json \
'.scripts.quality' \
'.scripts += {
"rector": "rector process --dry-run",
"ecs": "ecs check src tests",
"ecs-fix": "ecs fix src tests",
"phpstan": "phpstan analyse --error-format=table",
"phpstan-baseline":"phpstan analyse --generate-baseline",
"insights": "phpinsights --no-interaction --ansi --min-quality=85",
"insights-baseline":"phpinsights --baseline",
"rector-upgrade":"rector process --config rector.php",
"phpunit": "phpunit",
"quality": [
"@rector",
"@ecs",
"@phpstan",
"@insights",
"@phpunit"
]
}' \
"composer scripts (rector, ecs, phpstan, insights, phpunit, quality)"
## ---------- 3. VS Code configuration -------------------------------------
log "3. VS Code configuration (.vscode/)"
mkdir -p .vscode
# extensions.json
EXTENSIONS=.vscode/extensions.json
if [ ! -f "$EXTENSIONS" ]; then echo '{"recommendations":[]}' > "$EXTENSIONS"; fi # Ensure base object exists
# Check if recommendations array exists and add if not
json_add_if_missing "$EXTENSIONS" \
'.recommendations' \
'.recommendations = [
"bmewburn.vscode-intelephense-client",
"TheNouillet.symfony-vscode",
"mblode.twig-language-2",
"xdebug.php-debug",
"eamodio.gitlens",
"RooVeterinaryInc.roo-cline",
"GitLab.gitlab-workflow",
"GitHub.vscode-pull-request-github"
// Optional: Add azdanov.vscode-easy-coding-standard, swordev.phpstan here too
]' \
"VS Code recommended extensions"
# settings.json
SETTINGS=.vscode/settings.json
if [ ! -f "$SETTINGS" ]; then echo '{}' > "$SETTINGS"; fi
# Check specifically for the ECS formatter setting within [php]
json_add_if_missing "$SETTINGS" \
'."[php]".editor.defaultFormatter == "azdanov.vscode-easy-coding-standard"' \
'. += {
"[php]": {
"editor.defaultFormatter": "azdanov.vscode-easy-coding-standard",
"editor.formatOnSave": true
},
"easyCodingStandard.executablePath": "./vendor/bin/ecs",
"phpstan.executablePath": "./vendor/bin/phpstan",
"phpstan.level": 6,
"phpstan.autoAnalysis": "onSave",
"phpstan.memoryLimit": "1G",
"editor.formatOnSave": true # Ensure global formatOnSave is also considered
}' \
"VS Code PHP formatter & PHPStan settings"
# tasks.json
TASKS=.vscode/tasks.json
if [ ! -f "$TASKS" ]; then
log "Creating VS Code tasks.json"
cat > "$TASKS" <<'JSON'
{
"version": "2.0.0",
"tasks": [
{ "label": "rector-dry-run", "type": "shell", "command": "composer", "args": ["rector"], "problemMatcher": [] },
{ "label": "ecs-check", "type": "shell", "command": "composer", "args": ["ecs"], "problemMatcher": [] },
{ "label": "ecs-fix", "type": "shell", "command": "composer", "args": ["ecs-fix"],"problemMatcher": [] },
{ "label": "phpstan", "type": "shell", "command": "composer", "args": ["phpstan"],"problemMatcher": [] },
{ "label": "phpinsights", "type": "shell", "command": "composer", "args": ["insights"],"problemMatcher": [] },
{ "label": "phpunit", "type": "shell", "command": "composer", "args": ["phpunit"],"problemMatcher": [] },
{
"label": "quality-all",
"dependsOn": ["rector-dry-run","ecs-check","phpstan","phpinsights", "phpunit"], # Added phpunit
"dependsOrder": "sequence",
"group": { "kind": "build", "isDefault": true },
"problemMatcher": []
}
]
}
JSON
else
warn "VS Code tasks.json exists – skipped (merge manually if needed)"
fi
## ---------- 4. GrumPHP git hook --------------------------------------------
log "4. GrumPHP pre-commit hook"
if [ ! -f grumphp.yml ]; then
# Run configure first to create basic structure if needed
vendor/bin/grumphp configure --no-interaction || true
# Overwrite with desired tasks
cat > grumphp.yml <<'YAML'
# grumphp.yml
grumphp:
tasks:
rector:
config: rector.php
triggered_by: ['php']
ecs:
config: ecs.php
triggered_by: ['php']
phpstan:
configuration: phpstan.neon
level: 6 # Match VSCode setting
triggered_by: ['php']
phpinsights:
config: phpinsights.php
min_quality: 85 # Match composer script/CI
triggered_by: ['php']
phpunit: ~ # Basic PHPUnit task
YAML
# Initialize git hooks
vendor/bin/grumphp git:init
log "GrumPHP configured and hooks initialized"
else
warn "grumphp.yml already present – skipped GrumPHP setup"
fi
## ---------- 5. GitHub Actions workflow --------------------------------------
# Note: This workflow assumes a reusable action '.github/actions/composer-install' exists.
# You might need to replace that with direct PHP setup and composer install steps.
log "5. GitHub Actions workflow"
WF_DIR=".github/workflows"
WF_FILE="$WF_DIR/quality-gate.yml"
if [ ! -f "$WF_FILE" ]; then
mkdir -p "$WF_DIR"
log "Creating GitHub workflow $WF_FILE"
cat > "$WF_FILE" <<'YML'
name: Quality-Gate
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Replace this with actual PHP setup + composer install if needed
# Example using shivammathur/setup-php:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2' # Adjust version as needed
extensions: mbstring, xml, ctype, iconv, intl, gd, zip # Add necessary extensions
tools: composer:v2
- name: Install Dependencies
run: composer install --prefer-dist --no-progress --no-interaction
- name: Rector (Dry Run)
run: vendor/bin/rector process --dry-run
- name: Easy Coding Standard (ECS)
run: vendor/bin/ecs check src tests # Adjust paths
- name: PHPStan
run: vendor/bin/phpstan analyse --error-format=github --no-progress
- name: PHP Insights
run: |
mkdir -p build # Ensure build directory exists
vendor/bin/phpinsights \
--no-interaction \
--min-quality=85 \
--min-complexity=90 \
--min-architecture=80 \
--format=json > build/phpinsights.json # Adjust thresholds
- name: Upload PHP Insights Artifact
uses: actions/upload-artifact@v4
with:
name: insights-${{ github.sha }}
path: build/phpinsights.json
- name: PHPUnit Tests # Added PHPUnit step
run: vendor/bin/phpunit
YML
else
warn "Workflow $WF_FILE already exists – skipped"
fi
## ---------- 6. Final advice --------------------------------------------------
log "Setup script finished!"
log "Review generated/modified files: composer.json, .vscode/, grumphp.yml, $WF_FILE"
log "Configure tool specifics in: rector.php, ecs.php, phpstan.neon, phpinsights.php"
log "Run \`composer quality\` or press Ctrl+Shift+B in VS Code to validate."
How to Use the Script
- Save the script content to a file in your project root, for example,
setup_quality_tools.sh. - Make it executable:
chmod +x setup_quality_tools.sh. - Run it from your project root:
./setup_quality_tools.sh.
Important Notes
- Review Before Running: Understand what the script does before executing it.
- Project Root: Run the script from the root directory of your Symfony project (where
composer.jsonis located). - Idempotent: The script tries to be safe to run multiple times (it checks if configurations exist before adding them), but it might overwrite
grumphp.ymlif it exists but wasn't created by the script initially. It skips creatingtasks.json,extensions.json, and the GitHub workflow if they already exist. - Tool Configuration: The script does not configure the specific rules within
rector.php,ecs.php,phpstan.neon, orphpinsights.php. You still need to define your desired rulesets and configurations in these files manually (Step 2.2). - PHPUnit: The script includes
phpunit/phpunitin composer require, adds aphpunitscript tocomposer.json, includes it in thequalityscript, adds a VSCode task for it, includes it ingrumphp.yml, and adds a step to the GitHub workflow. - MakerBundle: The script adds
symfony/maker-bundleto the dev dependencies. - Script Logic: The script uses
jqto check if certain key configurations already exist before attempting to add them. If you have unusual partial configurations, review the script's additions manually.