Contributing to Flort¶
Thank you for your interest in contributing to Flort! This guide will help you get started with development and explain our contribution process.
๐ Getting Started¶
Development Setup¶
- Fork and Clone
- Create Virtual Environment
# Create environment
python -m venv venv
# Activate (Linux/macOS)
source venv/bin/activate
# Activate (Windows)
venv\Scripts\activate
- Install Development Dependencies
# Install in development mode
pip install -e .
# Install development dependencies
pip install -e .[dev]
# Install documentation dependencies
pip install -r docs/requirements.txt
- Verify Installation
๐ ๏ธ Development Workflow¶
Making Changes¶
- Create Feature Branch
- Make Your Changes
Follow the coding standards and add tests for new functionality.
- Test Your Changes
# Run all tests
make test
# Run specific tests
python -m pytest tests/test_specific.py -v
# Test with coverage
python -m pytest tests/ --cov=flort --cov-report=html
- Update Documentation
# Update relevant documentation
# docs/usage.md, docs/examples.md, etc.
# Test documentation locally
make docs
# Check documentation build
make docs-build
- Commit and Push
- Create Pull Request
Open a pull request on GitHub with a clear description of your changes.
๐ Contribution Types¶
๐ Bug Fixes¶
- Find or Create Issue
- Search existing issues
-
Create new issue with bug report template
-
Fix the Bug
- Write a failing test that reproduces the bug
- Fix the bug
- Ensure the test now passes
-
Add regression test if appropriate
-
Example Bug Fix
# tests/test_bug_fix.py
def test_extension_filtering_bug():
"""Test that extensions with dots are handled correctly."""
# This test would fail before the fix
result = parse_extensions([".py", "js"])
assert result == ["py", "js"] # Should normalize extensions
โจ New Features¶
- Discussion First
- Open a feature request
-
Discuss the approach before implementing
-
Implementation Guidelines
- Follow existing patterns and architecture
- Add comprehensive tests
- Update documentation
-
Consider backward compatibility
-
Example Feature Addition
# flort/new_feature.py
def new_filtering_option(file_list, criteria):
"""
New filtering functionality.
Args:
file_list: List of file dictionaries
criteria: Filtering criteria
Returns:
Filtered file list
"""
# Implementation here
pass
# tests/test_new_feature.py
def test_new_filtering_option():
"""Test the new filtering functionality."""
# Test implementation
pass
๐ Documentation¶
- Types of Documentation
- Code comments and docstrings
- User guides and examples
- API documentation
-
README and setup instructions
-
Documentation Standards
- Use clear, concise language
- Include code examples
- Update relevant sections
- Test documentation builds
๐งช Testing¶
- Test Types
- Unit tests for individual functions
- Integration tests for workflows
- UI tests for interactive features
-
Performance tests for large files
-
Writing Tests
# tests/test_example.py
import pytest
from pathlib import Path
from flort.utils import example_function
class TestExampleFunction:
"""Test suite for example_function."""
def test_basic_functionality(self):
"""Test basic use case."""
result = example_function("input")
assert result == "expected_output"
def test_edge_cases(self):
"""Test edge cases and error conditions."""
with pytest.raises(ValueError):
example_function("")
def test_with_fixtures(self, tmp_path):
"""Test using pytest fixtures."""
test_file = tmp_path / "test.txt"
test_file.write_text("content")
result = example_function(test_file)
assert result is not None
๐ Coding Standards¶
Python Style¶
We follow PEP 8 with some modifications:
# Use snake_case for functions and variables
def process_file_list(file_list):
processed_count = 0
return processed_count
# Use descriptive names
def get_filtered_files(extensions, exclude_patterns):
# Not: get_files(ext, exc)
pass
# Add type hints where helpful
def count_tokens(text: str) -> int:
"""Count tokens in text."""
return len(text.split())
# Use docstrings for public functions
def public_function(param: str) -> bool:
"""
Brief description of what this function does.
Args:
param: Description of parameter
Returns:
Description of return value
Example:
```python
result = public_function("value")
```
"""
pass
Code Formatting¶
We use automated tools for consistent formatting:
# Format code with black
black flort/ tests/
# Sort imports with isort
isort flort/ tests/
# Check style with flake8
flake8 flort/ tests/
# Type checking with mypy
mypy flort/ --ignore-missing-imports
# Run all checks
make check-all
Commit Messages¶
Use Conventional Commits:
# Feature addition
git commit -m "feat: add new file filtering option"
# Bug fix
git commit -m "fix: handle empty directory gracefully"
# Documentation
git commit -m "docs: update installation guide"
# Tests
git commit -m "test: add tests for file filtering"
# Refactoring
git commit -m "refactor: simplify path handling logic"
๐งช Testing Guidelines¶
Test Structure¶
tests/
โโโ __init__.py
โโโ test_utils.py # Test utility functions
โโโ test_traverse.py # Test file discovery
โโโ test_concatenate.py # Test file concatenation
โโโ test_cli.py # Test command-line interface
โโโ test_ui.py # Test interactive UI
โโโ fixtures/ # Test data and fixtures
โโโ sample_project/
โโโ test_files/
Writing Good Tests¶
# Good test example
def test_file_filtering_with_extensions(tmp_path):
"""Test file filtering with specific extensions."""
# Setup
(tmp_path / "main.py").write_text("print('hello')")
(tmp_path / "style.css").write_text("body { }")
(tmp_path / "README.md").write_text("# Project")
# Execute
file_list = get_paths(
directories=[str(tmp_path)],
extensions=['py', 'md']
)
# Verify
files = [f for f in file_list if f['type'] == 'file']
file_names = [f['path'].name for f in files]
assert 'main.py' in file_names
assert 'README.md' in file_names
assert 'style.css' not in file_names
Test Coverage¶
Aim for high test coverage, especially for:
- Core functionality
- Error handling
- Edge cases
- User-facing APIs
# Run tests with coverage
python -m pytest tests/ --cov=flort --cov-report=html
# View coverage report
open htmlcov/index.html
๐ Documentation Guidelines¶
Code Documentation¶
def complex_function(param1: str, param2: List[int], param3: bool = False) -> Dict[str, Any]:
"""
Brief one-line description.
Longer description explaining the purpose, behavior, and any important
details about the function.
Args:
param1: Description of first parameter
param2: Description of second parameter
param3: Description of optional parameter (default: False)
Returns:
Description of return value and its structure
Raises:
ValueError: When param1 is empty
IOError: When file operations fail
Example:
```python
result = complex_function("input", [1, 2, 3], True)
print(result['status'])
```
Note:
Any additional notes or warnings
"""
pass
User Documentation¶
- Keep it practical - Focus on real-world usage
- Include examples - Show working code snippets
- Explain why - Not just how, but when and why to use features
- Update together - Update docs with code changes
Documentation Testing¶
# Test documentation builds
make docs-build
# Test documentation locally
make docs
# Check for broken links
make docs-check
๐ Code Review Process¶
Submitting Pull Requests¶
- Clear Description
- Explain what changes you made and why
- Reference any related issues
-
Include screenshots for UI changes
-
Checklist Before Submitting
- Tests pass locally
- New tests added for new functionality
- Documentation updated
- Code follows style guidelines
-
Commit messages follow convention
-
Pull Request Template
## Description
Brief description of changes made.
## Related Issues
Fixes #123
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Documentation update
- [ ] Refactoring
## Testing
- [ ] All tests pass
- [ ] New tests added
- [ ] Manual testing completed
## Checklist
- [ ] Code follows style guidelines
- [ ] Self-review completed
- [ ] Documentation updated
Review Process¶
- Automated Checks
- Tests must pass
- Code style checks
-
Documentation builds
-
Human Review
- Code quality and clarity
- Test coverage and quality
- Documentation accuracy
-
User experience impact
-
Addressing Feedback
- Respond to review comments
- Make requested changes
- Update based on suggestions
๐๏ธ Architecture Guidelines¶
Project Structure¶
flort/
โโโ flort/ # Main package
โ โโโ __init__.py # Public API exports
โ โโโ cli.py # Command-line interface
โ โโโ traverse.py # File discovery logic
โ โโโ concatenate_files.py # File processing
โ โโโ utils.py # Utility functions
โ โโโ ...
โโโ tests/ # Test suite
โโโ docs/ # Documentation
โโโ examples/ # Usage examples
Design Principles¶
- Modularity - Keep functions and classes focused
- Testability - Design for easy testing
- Extensibility - Allow for future enhancements
- User-Friendly - Prioritize user experience
- Performance - Consider efficiency for large projects
Adding New Features¶
- Plan the Architecture
- Where does the feature fit?
- What existing code needs changes?
-
How will it be tested?
-
Implement Incrementally
- Start with core functionality
- Add tests early
-
Build up complexity gradually
-
Consider Backward Compatibility
- Don't break existing APIs
- Deprecate features gracefully
- Document breaking changes
๐ฏ Specific Areas for Contribution¶
High-Priority Areas¶
- Performance Optimization
- Large file handling
- Memory usage optimization
-
Faster file discovery
-
Platform Support
- Windows-specific improvements
- macOS compatibility
-
Linux distribution testing
-
New File Types
- Additional language support
- Binary file handling improvements
-
Custom file processors
-
User Experience
- Interactive UI enhancements
- Better error messages
- Progress indicators
Good First Issues¶
Look for issues labeled: - good first issue
- help wanted
- documentation
- tests
๐ Getting Help¶
Communication Channels¶
- GitHub Issues - Bug reports and feature requests
- GitHub Discussions - Questions and general discussion
- Code Reviews - Feedback on pull requests
Questions?¶
- Check existing documentation first
- Search closed issues for similar questions
- Ask in GitHub Discussions
- Be specific about what you're trying to do
๐ License¶
By contributing to Flort, you agree that your contributions will be licensed under the BSD 3-Clause License.
Thank you for contributing to Flort! Every contribution, no matter how small, helps make the project better for everyone. ๐