14 KiB
14 KiB
Contributing to YAMS
Thank you for your interest in contributing to YAMS! This guide provides everything you need to know to contribute effectively to the project.
🚀 Quick Start for Contributors
- Set up your development environment
- Find an issue to work on
- Fork and clone the repository
- Make your changes
- Run tests and ensure quality
- Submit a pull request
Development Environment Setup
Prerequisites
- C++20 compatible compiler (GCC 11+, Clang 14+, or MSVC 2022+)
- CMake 3.20+
- Git 2.20+
- Platform-specific dependencies (see Installation Guide)
Quick Setup
# 1. Fork the repository on GitHub
# 2. Clone your fork
git clone https://github.com/YOUR_USERNAME/yams.git
cd yams
# 3. Add upstream remote
git remote add upstream https://github.com/trvon/yams.git
# 4. Install dependencies (macOS example)
brew install cmake openssl@3 protobuf sqlite3 gcovr
# 5. Create development build
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Debug \
-DYAMS_ENABLE_COVERAGE=ON \
-DYAMS_ENABLE_SANITIZERS=ON \
-DYAMS_BUILD_TESTS=ON \
..
# 6. Build and test
make -j$(nproc) && ctest --output-on-failure
🎯 Ways to Contribute
Code Contributions
- Bug fixes: Fix issues reported in GitHub Issues
- New features: Implement features from the roadmap
- Performance improvements: Optimize critical code paths
- Test coverage: Add tests for untested code
- Code quality: Refactor and improve existing code
Documentation Contributions
- API documentation: Improve code comments and API docs
- User guides: Create tutorials and usage examples
- Developer docs: Document architecture and design decisions
- Translations: Translate documentation to other languages
Community Contributions
- Issue triage: Help categorize and reproduce bug reports
- Code reviews: Review pull requests from other contributors
- Community support: Answer questions in discussions
- Testing: Test pre-release versions and report issues
📋 Development Workflow
Finding Issues to Work On
Good First Issues
Look for issues labeled with:
good first issue- Beginner-friendly taskshelp wanted- Issues where we need helpbug- Bug fixes (usually well-defined)documentation- Documentation improvements
Feature Development
- Check the project roadmap
- Review Product Backlog Items
- Discuss new features in GitHub Discussions
Forking and Cloning
# 1. Fork on GitHub (click Fork button)
# 2. Clone your fork
git clone https://github.com/YOUR_USERNAME/yams.git
cd yams
# 3. Add upstream remote
git remote add upstream https://github.com/trvon/yams.git
# 4. Verify remotes
git remote -v
# origin https://github.com/YOUR_USERNAME/yams.git (fetch)
# origin https://github.com/YOUR_USERNAME/yams.git (push)
# upstream https://github.com/trvon/yams.git (fetch)
# upstream https://github.com/trvon/yams.git (push)
Branch Management
# Always work on feature branches
git checkout -b feature/your-feature-name
# Keep your main branch up to date
git checkout main
git pull upstream main
git push origin main
# Rebase your feature branch regularly
git checkout feature/your-feature-name
git rebase main
Making Changes
Code Style and Standards
- C++ Standard: Use C++20 features appropriately
- Naming Conventions:
- Classes:
PascalCase(e.g.,ContentStore) - Functions/Variables:
camelCase(e.g.,storeContent) - Constants:
UPPER_SNAKE_CASE(e.g.,MAX_CHUNK_SIZE) - Files:
snake_case(e.g.,content_store.h)
- Classes:
- Formatting: Use
.clang-formatconfiguration - Comments: Document public APIs with Doxygen-style comments
Code Quality Rules
// Good: Clear, descriptive names
Result<ContentInfo> ContentStore::storeContent(
const std::filesystem::path& filePath,
const ContentMetadata& metadata) {
// Good: Use early returns
if (!std::filesystem::exists(filePath)) {
return Error{ErrorCode::FileNotFound, "File does not exist"};
}
// Good: RAII and smart pointers
auto hasher = crypto::createSHA256Hasher();
auto hash = hasher->hashFile(filePath);
// Good: Modern C++ features
return ContentInfo{
.hash = std::move(hash),
.size = std::filesystem::file_size(filePath),
.createdAt = std::chrono::system_clock::now()
};
}
Testing Requirements
Every contribution must include appropriate tests:
// Unit test example
TEST(ContentStoreTest, StoreValidFile) {
ContentStore store("/tmp/test_store");
ContentMetadata metadata{.tags = {"test", "document"}};
auto result = store.storeContent("test_file.txt", metadata);
ASSERT_TRUE(result.has_value());
EXPECT_FALSE(result.value().hash.empty());
EXPECT_GT(result.value().size, 0);
}
// Integration test example
TEST(ContentStoreIntegrationTest, StoreAndRetrieveWorkflow) {
// Test complete workflow from storage to retrieval
ContentStore store("/tmp/integration_test");
// Store a file
auto storeResult = store.storeContent("input.txt", {});
ASSERT_TRUE(storeResult.has_value());
// Retrieve the file
auto retrieveResult = store.retrieveContent(
storeResult.value().hash, "output.txt");
ASSERT_TRUE(retrieveResult.has_value());
// Verify contents match
EXPECT_TRUE(filesAreIdentical("input.txt", "output.txt"));
}
Commit Guidelines
Commit Message Format
type(scope): brief description
Detailed explanation of the change, including:
- What was changed and why
- Any breaking changes
- Related issue numbers
Fixes #123
Commit Types
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style/formatting changesrefactor: Code refactoringtest: Adding or modifying testsperf: Performance improvementsbuild: Build system changesci: CI/CD changes
Examples
git commit -m "feat(storage): add compression support for large files
Implement Zstandard compression for files larger than 1MB to reduce
storage requirements. Compression is applied automatically based on
configurable size thresholds.
- Add ZstandardCompressor class
- Integrate compression into storage pipeline
- Add configuration options for compression settings
- Include comprehensive tests for compression scenarios
Fixes #456"
🧪 Testing and Quality Assurance
Running Tests
# Run all tests
ctest --output-on-failure
# Run specific test categories
ctest -L unit
ctest -L integration
ctest -L performance
# Run tests with coverage
make coverage
# Run specific test executable
./tests/unit/storage/storage_tests
./tests/integration/full_system_test
Code Coverage
# Generate coverage report
make coverage-html
# View coverage report
open build/coverage/html/index.html # macOS
xdg-open build/coverage/html/index.html # Linux
# Coverage requirements
# - New code: 90%+ line coverage
# - Modified code: No decrease in coverage
# - Critical paths: 100% coverage
Static Analysis
# Run clang-tidy
clang-tidy src/**/*.cpp -- -I include
# Run cppcheck
cppcheck --enable=all src/ include/
# Run AddressSanitizer (if enabled)
ASAN_OPTIONS=abort_on_error=1 ./tests/unit/all_tests
Performance Testing
# Run performance benchmarks
./benchmarks/yams_benchmarks
# Measure specific operations
./benchmarks/storage_benchmark --size=1GB
./benchmarks/search_benchmark --queries=10000
# Performance requirements:
# - No regressions >10% in critical paths
# - Memory usage should not increase significantly
# - Startup time should remain under 1 second
🔄 Submitting Pull Requests
Pre-Submission Checklist
- Tests pass: All tests pass locally
- Coverage maintained: Code coverage meets requirements
- Documentation updated: API docs and user guides updated
- Changelog entry: Added entry to CHANGELOG.md
- Commit messages: Follow conventional commit format
- Branch up-to-date: Rebased against latest main
- Self-review: Code has been self-reviewed
Pull Request Process
# 1. Push your feature branch
git push origin feature/your-feature-name
# 2. Create PR on GitHub
# - Use descriptive title and description
# - Link related issues
# - Add appropriate labels
# - Request reviews from relevant maintainers
# 3. Address feedback
# - Make changes based on review comments
# - Push additional commits
# - Request re-review when ready
# 4. Merge
# - Maintainer will merge after approval
# - Delete your feature branch after merge
Pull Request Template
## Description
Brief description of the changes and their purpose.
## Type of Change
- [ ] Bug fix (non-breaking change fixing an issue)
- [ ] New feature (non-breaking change adding functionality)
- [ ] Breaking change (fix or feature causing existing functionality to change)
- [ ] Documentation update
## Testing
- [ ] Unit tests added/updated
- [ ] Integration tests added/updated
- [ ] All tests pass locally
- [ ] Coverage requirements met
## Checklist
- [ ] Code follows project style guidelines
- [ ] Self-review completed
- [ ] Documentation updated
- [ ] Changelog entry added
## Related Issues
Fixes #(issue_number)
🏗️ Architecture Guidelines
Design Principles
- Modularity: Components should be loosely coupled
- Performance: Optimize for common use cases
- Safety: Use RAII, smart pointers, and proper error handling
- Testability: Design for easy unit testing
- Documentation: Self-documenting code with clear APIs
Module Structure
// Example module structure
namespace yams::storage {
// Interface (pure virtual)
class IStorageEngine {
public:
virtual ~IStorageEngine() = default;
virtual Result<Hash> store(ByteSpan data) = 0;
virtual Result<ByteVector> retrieve(const Hash& hash) = 0;
};
// Implementation
class StorageEngine : public IStorageEngine {
public:
explicit StorageEngine(Config config);
Result<Hash> store(ByteSpan data) override;
Result<ByteVector> retrieve(const Hash& hash) override;
private:
class Impl; // Pimpl idiom for stable ABI
std::unique_ptr<Impl> pImpl;
};
// Factory function
std::unique_ptr<IStorageEngine> createStorageEngine(Config config);
}
Error Handling
// Use Result<T> type for operations that can fail
Result<ContentInfo> storeContent(const std::filesystem::path& path) {
if (!std::filesystem::exists(path)) {
return Error{ErrorCode::FileNotFound, "File does not exist"};
}
try {
// Actual implementation
return ContentInfo{/* ... */};
} catch (const std::exception& e) {
return Error{ErrorCode::InternalError, e.what()};
}
}
// Usage
auto result = storeContent("file.txt");
if (!result) {
spdlog::error("Failed to store content: {}", result.error().message);
return;
}
auto info = result.value();
📝 Documentation Standards
Code Documentation
/**
* @brief Stores content with automatic deduplication
*
* This function stores the given content using SHA-256 content addressing.
* If identical content already exists, no duplicate storage occurs.
*
* @param data The content to store
* @param metadata Associated metadata for the content
* @return Result containing the content hash or error information
*
* @throws std::bad_alloc If memory allocation fails
*
* @example
* ```cpp
* ContentStore store("/path/to/storage");
* auto result = store.storeContent(fileData, {.tags = {"document"}});
* if (result) {
* std::cout << "Stored with hash: " << result.value().hash << std::endl;
* }
* ```
*/
Result<ContentInfo> storeContent(ByteSpan data, const ContentMetadata& metadata);
Markdown Documentation
- Use clear headings and sections
- Include code examples for all features
- Add diagrams for complex concepts
- Link between related documents
- Keep language concise but complete
🤝 Community Guidelines
Communication
- Be respectful: Treat all community members with respect
- Be constructive: Provide helpful feedback and suggestions
- Be patient: Remember that contributors have different experience levels
- Be inclusive: Welcome contributors from all backgrounds
Code Review Guidelines
- Focus on code, not the person: Comment on the code, not the author
- Be specific: Provide clear, actionable feedback
- Explain reasoning: Help others learn by explaining your suggestions
- Approve quickly: Don't delay approval for minor style issues
- Test thoroughly: Verify that changes work as intended
Issue Reporting
- Search first: Check if the issue already exists
- Use templates: Follow the provided issue templates
- Provide details: Include reproduction steps, system info, and logs
- Be responsive: Reply to requests for additional information
🎖️ Recognition
Contributors
All contributors are recognized in:
- CONTRIBUTORS.md file
- GitHub contributors page
- Release notes for their contributions
- Special recognition for significant contributions
Maintainer Path
Regular contributors may be invited to become maintainers:
- Consistent contributions over 6+ months
- Code quality and adherence to guidelines
- Community engagement through reviews and discussions
- Domain expertise in specific areas of the codebase
📚 Additional Resources
Development Resources
External Resources
Questions?
- Join GitHub Discussions
- Check the FAQ
- Review existing issues and PRs
Thank you for contributing to YAMS! 🚀