Custom Rules

GitHub

Custom Rules

Learn how to create custom analysis rules for Codementor-AI to match your project's specific requirements and coding standards.

Overview

Codementor-AI's extensible rule system allows you to create custom analysis rules that can:

  • Enforce project-specific coding standards
  • Detect domain-specific patterns
  • Validate business logic requirements
  • Ensure architectural consistency
  • Check for security vulnerabilities specific to your application

Rule Structure

Custom rules are PHP classes that extend the base rule class:

<?php

namespace CodementorAI\Rules\Custom;

use CodementorAI\Rules\BaseRule;
use PhpParser\Node;

class MyCustomRule extends BaseRule
{
    public function getDescription(): string
    {
        return 'Description of what this rule checks for';
    }

    public function getSeverity(): string
    {
        return 'medium'; // critical, high, medium, low
    }

    public function getCategory(): string
    {
        return 'custom'; // security, performance, laravel, style, custom
    }

    public function analyze(Node $node): array
    {
        $issues = [];

        // Your analysis logic here
        if ($this->hasIssue($node)) {
            $issues[] = [
                'message' => 'Issue description',
                'line' => $node->getLine(),
                'file' => $this->getCurrentFile(),
                'suggestion' => 'How to fix this issue'
            ];
        }

        return $issues;
    }

    private function hasIssue(Node $node): bool
    {
        // Your detection logic
        return false;
    }
}

Creating Your First Rule

Step 1: Create the Rule File

Create a new file in your custom rules directory:

mkdir -p codementor-ai/rules/custom
touch codementor-ai/rules/custom/MyCustomRule.php

Step 2: Implement the Rule

Here's a simple example that checks for hardcoded database credentials:

<?php

namespace CodementorAI\Rules\Custom;

use CodementorAI\Rules\BaseRule;
use PhpParser\Node;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\Array_;

class HardcodedCredentialsRule extends BaseRule
{
    public function getDescription(): string
    {
        return 'Detects hardcoded database credentials in configuration files';
    }

    public function getSeverity(): string
    {
        return 'critical';
    }

    public function getCategory(): string
    {
        return 'security';
    }

    public function analyze(Node $node): array
    {
        $issues = [];

        if ($node instanceof Array_) {
            foreach ($node->items as $item) {
                if ($item instanceof ArrayItem) {
                    $issues = array_merge($issues, $this->checkArrayItem($item));
                }
            }
        }

        return $issues;
    }

    private function checkArrayItem(ArrayItem $item): array
    {
        $issues = [];

        if ($item->key && $this->isCredentialKey($item->key)) {
            if ($item->value && $this->isHardcodedValue($item->value)) {
                $issues[] = [
                    'message' => 'Hardcoded credential detected: ' . $item->key->value,
                    'line' => $item->getLine(),
                    'file' => $this->getCurrentFile(),
                    'suggestion' => 'Use environment variables instead of hardcoded values'
                ];
            }
        }

        return $issues;
    }

    private function isCredentialKey($key): bool
    {
        $credentialKeys = ['password', 'secret', 'key', 'token', 'api_key'];
        return in_array(strtolower($key->value), $credentialKeys);
    }

    private function isHardcodedValue($value): bool
    {
        // Check if value is a string literal (not a variable or function call)
        return $value instanceof \PhpParser\Node\Scalar\String_;
    }
}

Rule Categories

Organize your rules into categories for better management:

🔒 Security Rules

Rules that detect security vulnerabilities and enforce secure coding practices.

  • SQL injection detection
  • XSS prevention
  • Authentication bypass
  • Hardcoded credentials

⚡ Performance Rules

Rules that identify performance bottlenecks and optimization opportunities.

  • N+1 query detection
  • Memory leak detection
  • Inefficient algorithms
  • Resource usage optimization

🏗️ Laravel Rules

Framework-specific rules for Laravel best practices.

  • Controller method validation
  • Model relationship checks
  • Service layer patterns
  • Middleware usage

📝 Style Rules

Code style and formatting rules.

  • Naming conventions
  • Code formatting
  • Documentation requirements
  • Comment standards

Advanced Rule Features

Context-Aware Analysis

Rules can access context about the current file and project:

public function analyze(Node $node): array
{
    $issues = [];

    // Check if we're in a Laravel controller
    if ($this->isLaravelController()) {
        $issues = array_merge($issues, $this->analyzeController($node));
    }

    // Check if we're in a configuration file
    if ($this->isConfigFile()) {
        $issues = array_merge($issues, $this->analyzeConfig($node));
    }

    return $issues;
}

private function isLaravelController(): bool
{
    $file = $this->getCurrentFile();
    return strpos($file, 'app/Http/Controllers/') !== false;
}

private function isConfigFile(): bool
{
    $file = $this->getCurrentFile();
    return strpos($file, 'config/') !== false;
}

Configuration Options

Rules can accept configuration parameters:

class ConfigurableRule extends BaseRule
{
    private array $config;

    public function __construct(array $config = [])
    {
        $this->config = array_merge([
            'max_method_length' => 50,
            'allowed_exceptions' => [],
            'severity_threshold' => 'medium'
        ], $config);
    }

    public function analyze(Node $node): array
    {
        $issues = [];

        if ($node instanceof \PhpParser\Node\Stmt\ClassMethod) {
            if (strlen($node->name->name) > $this->config['max_method_length']) {
                $issues[] = [
                    'message' => "Method name too long: {$node->name->name}",
                    'line' => $node->getLine(),
                    'file' => $this->getCurrentFile(),
                    'suggestion' => 'Use shorter, more descriptive method names'
                ];
            }
        }

        return $issues;
    }
}

Registering Custom Rules

Add your custom rules to the configuration:

// config/codementor-ai.php
return [
    'rules' => [
        'custom' => [
            'CodementorAI\Rules\Custom\HardcodedCredentialsRule',
            'CodementorAI\Rules\Custom\MyCustomRule',
        ],
        'enabled' => ['security', 'performance', 'laravel', 'custom'],
    ],
];

Testing Custom Rules

Create test cases for your custom rules:

<?php

namespace Tests\Rules\Custom;

use CodementorAI\Rules\Custom\HardcodedCredentialsRule;
use PHPUnit\Framework\TestCase;

class HardcodedCredentialsRuleTest extends TestCase
{
    private HardcodedCredentialsRule $rule;

    protected function setUp(): void
    {
        $this->rule = new HardcodedCredentialsRule();
    }

    public function testDetectsHardcodedPassword()
    {
        $code = '<?php return ["password" => "secret123"];';
        $nodes = $this->parseCode($code);
        
        $issues = $this->rule->analyze($nodes[0]);
        
        $this->assertCount(1, $issues);
        $this->assertEquals('Hardcoded credential detected: password', $issues[0]['message']);
    }

    private function parseCode(string $code): array
    {
        $parser = new \PhpParser\Parser\Php7(new \PhpParser\Lexer\Emulative());
        return $parser->parse($code);
    }
}

Best Practices

  • Keep rules focused: Each rule should check for one specific issue
  • Provide clear messages: Include actionable suggestions in issue descriptions
  • Use appropriate severity: Match severity to the impact of the issue
  • Test thoroughly: Create comprehensive test cases for your rules
  • Document your rules: Explain what each rule checks and why it's important
  • Consider performance: Ensure rules don't significantly slow down analysis

Sharing Rules

Share your custom rules with the community:

  • Create a GitHub repository for your rules
  • Document installation and usage instructions
  • Provide examples and test cases
  • Submit to the Codementor-AI rules registry

Next Steps

Now that you understand custom rules:

  • Create your first custom rule
  • Set up testing for your rules
  • Integrate rules into your development workflow
  • Share useful rules with your team