Thank you for your interest in contributing to EnvValidator! This guide will help you understand how to contribute effectively to this project.
- Getting Started
- Development Setup
- Code Architecture
- Adding New Rule Types
- Writing Tests
- Code Style
- Submitting Changes
EnvValidator is a Laravel package for validating environment variables with support for standalone usage (without Laravel). The package is designed with extensibility and maintainability in mind.
- PHP 8.2 or higher
- Composer 2.2+
- Basic understanding of Laravel validation concepts
- Git for version control
-
Clone the repository:
git clone https://github.com/your-username/env-validator.git cd env-validator -
Install dependencies:
composer install
-
Run tests:
./vendor/bin/pest
-
Run static analysis:
./vendor/bin/phpstan analyse
The project follows SOLID principles and is organized into several key components:
AbstractRule: Base class for all validation rulesStandaloneValidator: Main validator for non-Laravel environmentsRuleRegistry: Manages and organizes validation rulesRuleFactory: Creates rule instances dynamically
The standalone validator uses a pluggable system with dedicated validators:
StringRuleValidator: Handles string-based rules like'in:value1,value2'ValidationRuleValidator: Handles LaravelValidationRuleobjectsBuiltInRuleValidator: Handles package's built-in rules
Rules are organized by category:
StringRules/: String validation rules (BooleanRule, KeyRule, PatternRule)NumericRules/: Numeric validation rules (NumericRule, IntegerRule)NetworkRules/: Network-related rules (UrlRule, IpRule)
-
Create the rule class:
<?php namespace EnvValidator\Collections\YourCategory; use EnvValidator\Core\AbstractRule; final class YourRule extends AbstractRule { public function passes($attribute, $value) { // Your validation logic here return true; } public function message() { return 'The :attribute validation failed.'; } }
-
Register the rule (optional):
// In a service provider or configuration $ruleRegistry = app(RuleRegistry::class); $ruleRegistry->register('your-category', 'your-rule', YourRule::class);
-
Add tests:
test('it validates with YourRule', function () { $validator = new EnvValidator; $validator->setRules(['TEST_VAR' => [new YourRule()]]); $env = ['TEST_VAR' => 'valid-value']; expect($validator->validate($env))->toBeTrue(); });
If you need to handle a completely new type of rule format:
-
Implement the interface:
<?php namespace Your\Namespace; use EnvValidator\Contracts\RuleValidatorInterface; final class YourCustomValidator implements RuleValidatorInterface { public function validate(string $key, mixed $rule, mixed $value, array $messages, array &$errors): void { // Your validation logic } public function canHandle(mixed $rule): bool { // Return true if this validator can handle the rule return false; } }
-
Register with the validator:
$validator = new StandaloneValidator(); $validator->addValidator(new YourCustomValidator());
We use Pest for testing. Tests should be comprehensive and cover:
- Happy path scenarios (valid inputs)
- Error scenarios (invalid inputs)
- Edge cases (empty values, null values, etc.)
- Integration scenarios (multiple rules together)
test('it validates valid environment variables', function () {
$validator = new EnvValidator;
$env = [
'APP_NAME' => 'Test App',
'APP_ENV' => 'production',
'APP_DEBUG' => 'false',
];
expect($validator->validate($env))->toBeTrue();
});
test('it fails with invalid values', function () {
$validator = new EnvValidator;
$env = ['APP_DEBUG' => 'invalid-boolean'];
expect(fn () => $validator->validate($env))
->toThrow(InvalidEnvironmentException::class);
});- Follow PSR-12 coding standards
- Use strict types:
declare(strict_types=1); - Type hint everything (parameters, return types, properties)
- Use readonly properties where appropriate
- All public methods must have PHPDoc comments
- Include
@paramand@returntags with proper types - Add
@throwstags for exceptions - Include usage examples for complex rules
/**
* Validate that a value matches a specific pattern.
*
* @param string $pattern The regular expression pattern
* @param string|null $customMessage A custom error message
*
* @example
* ```php
* // Validate an IP address
* $rule = new PatternRule('/^(\d{1,3}\.){3}\d{1,3}$/');
* ```
*/
public function __construct(
private readonly string $pattern,
private readonly ?string $customMessage = null
) {}- Classes:
PascalCase(e.g.,BooleanRule) - Methods:
camelCase(e.g.,validateField) - Variables:
camelCase(e.g.,$ruleRegistry) - Constants:
SCREAMING_SNAKE_CASE(e.g.,DEFAULT_MESSAGE)
- Run tests:
./vendor/bin/pest - Run static analysis:
./vendor/bin/phpstan analyse - Check code style: Ensure PSR-12 compliance
- Update documentation: If adding new features
-
Fork the repository
-
Create a feature branch:
git checkout -b feature/your-feature-name -
Make your changes
-
Add tests for your changes
-
Commit with clear messages:
feat: add support for custom validation patterns - Add PatternRule for regex-based validation - Include comprehensive tests - Update documentation with examples -
Push to your fork:
git push origin feature/your-feature-name -
Create a Pull Request
Use conventional commits:
feat:for new featuresfix:for bug fixesdocs:for documentation changestest:for adding testsrefactor:for code refactoringperf:for performance improvements
- Issues: Use GitHub issues for bug reports and feature requests
- Discussions: Use GitHub discussions for questions and general discussion
- Documentation: Check the README and code comments
Contributors will be added to the contributors list in the README. Significant contributions may be recognized in release notes.
Thank you for contributing to EnvValidator!