# Contributing to Murphy Thank you for your interest in contributing to Murphy for Delphi! This guide will help you get started. ## Ways to Contribute - Report bugs and issues - Suggest new features or patterns - Improve documentation - Submit bug fixes - Add new resilience patterns - Write tests - Share usage examples ## Getting Started ### 1. Fork and Clone ```bash # Fork the repository on GitHub # Clone your fork git clone https://github.com/YOUR_USERNAME/murphy-delphi.git cd murphy-delphi ``` ### 2. Create a Branch ```bash git checkout -b feature/my-new-feature # or git checkout -b fix/bug-description ``` ### 3. Set Up Development Environment - Delphi 11 Alexandria or later - Install Blocks package manager (optional but recommended) - Load `Murphy.dpk` or the demo project ## Code Standards ### Coding Style Murphy follows standard Delphi conventions: ```pascal // Use XML documentation comments /// /// Brief description of what this does. /// function MyFunction: Integer; // Use meaningful names var RetryCount: Integer; // Good var i: Integer; // Bad for non-loop variables // Use inline variables (Delphi 11+) procedure Example; begin var LocalVar := 'value'; end; ``` ### File Organization ``` Source/ Murphy.Base.Policy.pas # Base classes Murphy.Policy.YourPattern.pas # New pattern Murphy.Services.*.pas # Support services Tests/ Murphy.Tests.YourPattern.pas # Unit tests Demos/ Samples.YourPattern.pas # Usage examples ``` ## Adding a New Pattern ### 1. Create the Interface ```pascal type IYourPolicy = interface(IPolicy) ['{GENERATE-NEW-GUID}'] procedure Execute(AProc: TProc); function ConfigMethod(AValue: Integer): IYourPolicy; end; ``` ### 2. Implement the Policy ```pascal type TYourPolicy = class(TPolicy, IYourPolicy) private FConfigValue: Integer; public constructor Create(AExceptionTypes: TArray); override; procedure Execute(AProc: TProc); function ConfigMethod(AValue: Integer): IYourPolicy; end; ``` ### 3. Create the Builder ```pascal type TYourPolicyBuilder = class sealed(TPolicyBuilder) public class function Handle(AExceptionTypes: TArray): IYourPolicy; override; end; ``` ### 4. Add Tests ```pascal unit Murphy.Tests.YourPattern; interface uses DUnitX.TestFramework, Murphy.Policy.YourPattern; type [TestFixture] TYourPolicyTests = class public [Test] procedure TestBasicFunctionality; [Test] procedure TestExceptionHandling; end; implementation // Implementation... end. ``` ### 5. Add Demo Create a sample in `Demos/00_Primer/Samples.YourPattern.pas` ### 6. Update Documentation - Add pattern guide in `Docs/Patterns/YourPattern.md` - Add API reference in `Docs/API-Reference/YourPattern-Policy.md` - Update main README.md ## Testing Requirements ### All Contributions Must Include Tests ```pascal [Test] procedure TYourTests.TestYourFeature; begin MurphyTestModeEnabled := True; try // Arrange var Policy := TYourBuilder.Handle(Exception).Build; // Act Policy.Execute(procedure begin ... end); // Assert Assert.IsTrue(...); finally MurphyTestModeEnabled := False; end; end; ``` ### Test Coverage - Happy path (successful execution) - Failure scenarios - Exception handling - Edge cases - Configuration validation ### Run All Tests Before Submitting ```bash # Open Murphy.Tests.dpr # Run all tests # Ensure all tests pass ``` ## Documentation Requirements ### Code Comments ```pascal /// /// Executes the provided procedure with your pattern logic. /// /// The procedure to execute /// /// Additional details about behavior, exceptions, or usage. /// procedure Execute(AProc: TProc); ``` ### Markdown Documentation For new patterns, create: - Pattern guide (`Docs/Patterns/YourPattern.md`) - API reference (`Docs/API-Reference/YourPattern-Policy.md`) Include: - Description and purpose - When to use / when not to use - Quick start example - Common scenarios (3-5 examples) - Best practices ## Submitting Changes ### 1. Commit Your Changes ```bash git add . git commit -m "Add: New timeout pattern implementation" # Use conventional commit messages: # Add: New feature # Fix: Bug fix # Update: Improvements to existing feature # Docs: Documentation changes # Test: Test additions or changes ``` ### 2. Push to Your Fork ```bash git push origin feature/my-new-feature ``` ### 3. Create Pull Request - Go to GitHub and create a pull request - Fill in the PR template (if provided) - Describe your changes clearly - Reference any related issues ### PR Checklist - [ ] Code compiles without warnings - [ ] All existing tests pass - [ ] New tests added for new functionality - [ ] Documentation updated - [ ] Code follows Murphy conventions - [ ] Commit messages are clear - [ ] No unnecessary changes (whitespace, formatting) ## Reporting Issues ### Bug Reports Include: - Delphi version - Murphy version - Steps to reproduce - Expected behavior - Actual behavior - Code sample (minimal reproducible example) Example: ``` ## Bug Report **Environment:** - Delphi 11.3 - Murphy v1.0.0 - Windows 11 **Description:** Retry policy doesn't respect wait delay in specific scenario... **To Reproduce:** ```pascal var Policy := TRetryBuilder .Handle(Exception) .Retry(3) .Wait(TTimeSpan.FromSeconds(5)) .Build; // Steps... ``` **Expected:** Should wait 5 seconds between retries **Actual:** No delay observed ``` ### Feature Requests Include: - Use case description - Proposed API - Example usage - Benefits ## Code Review Process - Maintainers will review your PR - You may be asked to make changes - Once approved, your PR will be merged - Your contribution will be credited ## Community Guidelines - Be respectful and constructive - Help others in discussions - Share your Murphy usage experiences - Report issues you encounter ## Recognition Contributors will be: - Listed in CONTRIBUTORS.md (if created) - Credited in release notes - Mentioned in the project README ## Questions? - Open an issue for questions - Check existing documentation - Look at existing patterns for examples ## License By contributing, you agree that your contributions will be licensed under the MIT License. --- Thank you for contributing to Murphy for Delphi! 🎉 [Back to Index](../Home.md)