Skip to content

Latest commit

 

History

History
341 lines (243 loc) · 8.32 KB

File metadata and controls

341 lines (243 loc) · 8.32 KB

Contributing to tmpltool

Thank you for your interest in contributing to tmpltool! This document provides guidelines for contributing to the project.

Table of Contents

Code of Conduct

This project adheres to a code of conduct. By participating, you are expected to uphold this code. Please be respectful and constructive in your interactions.

Getting Started

Prerequisites

  • Rust 1.70 or higher (Install Rust)
  • Node.js 18 or higher (Install Node.js) - for commit validation
  • cargo-make (optional but recommended): cargo install --force cargo-make

Setup

  1. Fork the repository
  2. Clone your fork:
    git clone https://github.com/YOUR_USERNAME/tmpltool.git
    cd tmpltool
  3. Add the upstream repository:
    git remote add upstream https://github.com/bordeux/tmpltool.git
  4. Install Node.js dependencies (for commit validation):
    npm install
    This will:
    • Install commitlint and husky
    • Set up git hooks to validate commit messages
    • Prevent commits that don't follow conventional commit format
  5. Create a new branch:
    git checkout -b feature/my-feature

Development Workflow

Quick Development Cycle

# Build and test
cargo make dev

# Run all quality checks
cargo make qa

# Format code
cargo make format

# Run clippy
cargo make clippy

# Run tests
cargo make test

# Test examples
cargo make test-examples

Making Changes

  1. Make your changes in your feature branch
  2. Add tests for your changes
  3. Ensure all tests pass: cargo make qa
  4. Commit your changes using conventional commits
  5. Push to your fork
  6. Create a pull request

Commit Convention

This project uses Conventional Commits for automated versioning and changelog generation.

Important: Commit messages are automatically validated using commitlint. Invalid commits will be rejected before they're created.

Commit Validation

When you try to commit, a git hook will automatically check your commit message format. If it doesn't follow the conventional commit format, you'll see an error like:

⧗   input: bad commit message
✖   type must be one of [feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert] [type-enum]
✖   found 1 problems, 0 warnings
husky - commit-msg hook exited with code 1 (error)

To fix this, make sure your commit message follows the format below.

Commit Message Format

<type>(<scope>): <subject>

<body>

<footer>

Types

  • feat: A new feature (triggers minor version bump)
  • fix: A bug fix (triggers patch version bump)
  • docs: Documentation only changes (triggers patch version bump)
  • style: Code style changes (formatting, missing semi-colons, etc.)
  • refactor: Code refactoring (triggers patch version bump)
  • perf: Performance improvements (triggers patch version bump)
  • test: Adding or updating tests
  • build: Changes to build system or dependencies (triggers patch version bump)
  • ci: CI/CD configuration changes
  • chore: Other changes that don't modify src or test files
  • revert: Reverts a previous commit (triggers patch version bump)

Breaking Changes

For breaking changes, add BREAKING CHANGE: in the commit body or add ! after the type:

feat!: remove support for direct variable access

BREAKING CHANGE: Environment variables must now be accessed via get_env() function

This will trigger a major version bump.

Examples

# Feature addition (minor version bump)
git commit -m "feat: add slugify filter support"

# Bug fix (patch version bump)
git commit -m "fix: correct multiline template rendering"

# Documentation (patch version bump)
git commit -m "docs: update README with new examples"

# Breaking change (major version bump)
git commit -m "feat!: change default output behavior

BREAKING CHANGE: Output now goes to stdout by default instead of file"

# Multiple changes
git commit -m "feat: add new template filters

- Add uppercase filter
- Add lowercase filter
- Add trim filter"

Scope (Optional)

You can add a scope to provide additional context:

git commit -m "feat(cli): add --version flag"
git commit -m "fix(renderer): handle empty templates correctly"
git commit -m "test(fixtures): add more test cases"

Pull Request Process

  1. Update tests: Add tests for your changes
  2. Update documentation: Update README.md if needed
  3. Run quality checks: cargo make qa
  4. Commit with conventional commits: Follow the commit convention
  5. Create PR: Provide a clear description of your changes
  6. CI checks: Ensure all CI checks pass
  7. Code review: Address any review comments
  8. Merge: Once approved, your PR will be merged

PR Title

PR titles should also follow the conventional commit format:

feat: add support for custom filters
fix: resolve template parsing issue
docs: improve installation instructions

Testing

Running Tests

# Run all tests
cargo test

# Run specific test
cargo test test_successful_rendering

# Run tests with output
cargo test -- --nocapture

# Run tests with cargo-make
cargo make test
cargo make test-verbose

Test Organization

  • All tests are in the tests/ directory
  • Each test is in its own file
  • Test fixtures are in tests/fixtures/
  • Use helper functions from tests/common.rs

Adding Tests

See tests/fixtures/README.md for instructions on adding test fixtures.

Example test:

mod common;

use common::{cleanup_test_file, get_test_file_path, read_fixture_expected, read_fixture_template};
use std::fs;
use tmpltool::render_template;

#[test]
fn test_my_feature() {
    let output_path = get_test_file_path("output.txt");

    // Read template from fixtures
    let template_content = read_fixture_template("my_template.tmpltool");
    let template_path = get_test_file_path("template.txt");
    fs::write(&template_path, template_content).unwrap();

    // Run the function
    let result = render_template(
        Some(template_path.to_str().unwrap()),
        Some(output_path.to_str().unwrap()),
    );

    // Compare with expected output
    assert!(result.is_ok());
    let output = fs::read_to_string(&output_path).unwrap();
    let expected = read_fixture_expected("my_template.txt");
    assert_eq!(output, expected);

    // Cleanup
    cleanup_test_file(&template_path);
    cleanup_test_file(&output_path);
}

Code Style

Formatting

# Format code
cargo fmt

# Check formatting
cargo fmt --check

Linting

# Run clippy
cargo clippy

# Run clippy with all warnings
cargo clippy -- -W clippy::all

Code Guidelines

  • Follow Rust naming conventions
  • Add documentation for public APIs
  • Keep functions small and focused
  • Write descriptive variable names
  • Add comments for complex logic

Release Process

Releases are automated using semantic-release:

  1. Commit changes using conventional commits
  2. Push to master/main branch
  3. CI/CD automatically:
    • Analyzes commits
    • Determines version bump
    • Updates Cargo.toml and CHANGELOG.md
    • Builds binaries for all platforms
    • Creates GitHub release
    • Publishes Docker image

Troubleshooting

Commit Validation Not Working

If commit validation isn't working:

  1. Make sure you ran npm install after cloning the repository
  2. Check that .husky/commit-msg exists and is executable
  3. Reinstall hooks: npm run prepare

Bypassing Commit Validation (NOT Recommended)

In rare cases, you may need to bypass validation (e.g., fixing a broken commit history):

git commit --no-verify -m "your message"

Warning: Only use --no-verify when absolutely necessary, as it will bypass the commit validation.

Testing Commit Messages

You can test a commit message without making a commit:

echo "feat: add new feature" | npx commitlint

Questions?

If you have questions, please:

  • Check existing issues
  • Create a new issue for discussion
  • Ask in pull request comments

Thank you for contributing! 🎉