Contributing to ExkPasswd

View Source

Thank you for considering contributing to ExkPasswd! This document provides guidelines and information to help you get started.


Interactive Developer Guide

We've created an interactive Livebook notebook to help you understand the codebase and experiment with changes in real-time:

Run in Livebook

Why use the interactive notebook?

  • Immediate feedback - Test your changes without running the full test suite
  • Explore architecture - See how Dictionary, Password, Config, and Transforms work together
  • Run examples live - Execute code while reading documentation
  • Safe experimentation - Try ideas without modifying the actual codebase
  • Performance testing - Verify O(1) lookups and benchmark your changes

The notebook covers:

  • Project structure and architecture
  • Key design patterns (schema-driven config, Transform protocol, O(1) lookups)
  • Security verification (cryptographic randomness, entropy analysis)
  • Creating custom presets and transforms
  • Testing edge cases
  • Performance benchmarking

How Can I Contribute?

Reporting Bugs

Before creating bug reports, please check existing issues as you might find out that you don't need to create one. When you are creating a bug report, please include as many details as possible:

  • Use a clear and descriptive title
  • Describe the exact steps to reproduce the problem
  • Provide specific examples to demonstrate the steps
  • Describe the behavior you observed and what behavior you expected
  • Include your environment details (Elixir version, OS, etc.)

Suggesting Enhancements

Enhancement suggestions are tracked as GitHub issues. When creating an enhancement suggestion, please include:

  • Use a clear and descriptive title
  • Provide a detailed description of the suggested enhancement
  • Provide specific examples to demonstrate the enhancement
  • Describe the current behavior and expected behavior
  • Explain why this enhancement would be useful

Pull Requests

  1. Fork the repo and create your branch from main
  2. Add tests for any new functionality
  3. Ensure the test suite passes (mix test)
  4. Make sure your code follows the style guidelines (mix format and mix credo)
  5. Write clear, descriptive commit messages
  6. Issue that pull request!

Development Setup

  1. Fork and clone the repository

    git clone https://github.com/futhr/exk_passwd.git
    cd exk_passwd
    
  2. Install dependencies

    mix deps.get
    
  3. Run tests to ensure everything is working

    mix test
    

Development Workflow

Running Tests

# Run all tests
mix test

# Run tests with coverage
mix coveralls.html

# Run tests in watch mode
mix test.watch

# Run specific test file
mix test test/exk_passwd/password_test.exs

Code Quality

# Format code
mix format

# Run Credo for style consistency
mix credo --strict

# Run Dialyzer for type checking
mix dialyzer

# Run all checks
mix check

Building Documentation

# Generate docs
mix docs

# View docs
open doc/index.html

Project Structure

lib/exk_passwd/
 config/               # Configuration system
    presets.ex       # Built-in presets (Agent-based)
    schema.ex        # Configuration validation
 transform/            # Transform protocol implementations
    case_transform.ex
    substitution.ex
 config.ex            # Configuration struct (schema-driven)
 dictionary.ex        # ETS-backed word storage (O(1) lookups)
 password.ex          # Core password generation engine
 batch.ex             # Optimized batch generation
 token.ex             # Random number/symbol generation
 buffer.ex            # Buffered random bytes for performance
 entropy.ex           # Entropy calculation
 strength.ex          # Password strength analysis
 transform.ex         # Transform protocol definition
 validator.ex         # Configuration validation
 random.ex            # Cryptographically secure random utilities

Testing Guidelines

Writing Tests

  • Write tests for all public functions
  • Include both success and error cases
  • Use descriptive test names
  • Aim for 95%+ test coverage (100% for security-critical code)
  • Test randomness and uniqueness for password generation

Example test structure:

describe "generate/1" do
  test "generates password with default settings" do
    password = ExkPasswd.generate()
    assert is_binary(password)
    assert String.length(password) > 0
  end

  test "generates different passwords each time" do
    passwords = for _ <- 1..10, do: ExkPasswd.generate()
    assert length(Enum.uniq(passwords)) == 10
  end

  test "generates unique passwords at scale" do
    passwords = for _ <- 1..1000, do: ExkPasswd.generate()
    unique_count = passwords |> Enum.uniq() |> length()
    # Allow tiny collision chance
    assert unique_count > 995
  end
end

Coding Style

Elixir Style Guide

  • Use pattern matching over conditionals when possible
  • Keep functions under 20 lines
  • Use descriptive variable and function names
  • Write comprehensive @moduledoc and @doc documentation
  • Include doctests in documentation
  • Prefer pipelines over nested calls

Commit Messages

We follow conventional commits:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • style: Formatting, missing semicolons, etc.
  • refactor: Code restructuring
  • test: Adding tests
  • chore: Maintenance tasks

Examples:

feat: add passphrase generation
fix: handle edge case in strength checker
docs: update README with examples
test: add integration tests for validator

Project Principles

ExkPasswd follows these core principles:

1. Security First

2. Zero Runtime Dependencies

  • Only use Elixir stdlib and :crypto
  • Dev/test dependencies are acceptable
  • No external dependencies for core functionality

3. Well-Tested

  • Maintain 95%+ overall test coverage
  • 100% coverage for security-critical code
  • All public API functions must be tested

4. Performance Matters

  • Dictionary uses O(1) lookups (tuple-based)
  • Batch generation uses buffered random bytes
  • Run benchmarks to verify performance

Documentation

  • All public modules must have @moduledoc
  • All public functions must have @doc with examples
  • Include doctests where appropriate
  • Update README.md for user-facing changes
  • Update CHANGELOG.md following Keep a Changelog format

Release Process

Releases are managed by maintainers using git_ops:

  1. Ensure all tests pass: mix check
  2. Run mix release (alias for mix git_ops.release) — updates changelog, bumps version, commits, and tags
  3. Push with tags: git push --follow-tags
  4. CI will publish to Hex.pm on the v* tag

Resources

Documentation

  • README - Project overview
  • AGENTS.md (in repository root) - Agent guidelines and best practices
  • Hex Docs - Published documentation

Interactive Notebooks

References


Questions?

  • Open an issue on GitHub
  • Check existing issues and discussions
  • Review the interactive contributing notebook

Thank you for contributing to ExkPasswd! 🎉