Skip to content

Contributing

Marco Breveglieri edited this page Jul 21, 2026 · 3 revisions

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

# 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

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:

// Use XML documentation comments
/// <summary>
///  Brief description of what this does.
/// </summary>
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

type
  IYourPolicy = interface(IPolicy)
    ['{GENERATE-NEW-GUID}']
    procedure Execute(AProc: TProc);
    function ConfigMethod(AValue: Integer): IYourPolicy;
  end;

2. Implement the Policy

type
  TYourPolicy = class(TPolicy, IYourPolicy)
  private
    FConfigValue: Integer;
  public
    constructor Create(AExceptionTypes: TArray<ExceptClass>); override;
    procedure Execute(AProc: TProc);
    function ConfigMethod(AValue: Integer): IYourPolicy;
  end;

3. Create the Builder

type
  TYourPolicyBuilder = class sealed(TPolicyBuilder<IYourPolicy>)
  public
    class function Handle(AExceptionTypes: TArray<ExceptClass>): IYourPolicy; override;
  end;

4. Add Tests

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

[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

# Open Murphy.Tests.dpr
# Run all tests
# Ensure all tests pass

Documentation Requirements

Code Comments

/// <summary>
///  Executes the provided procedure with your pattern logic.
/// </summary>
/// <param name="AProc">The procedure to execute</param>
/// <remarks>
///  Additional details about behavior, exceptions, or usage.
/// </remarks>
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

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

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)

Clone this wiki locally