Contributing to Batin
Thank you for your interest in contributing to Batin! This guide explains how to get started.
Development Setup
Prerequisites
- Rust 1.75+ (rustup recommended)
- Git for version control
- Cargo for building and testing
Clone and Build
# Clone the repository
git clone https://github.com/ahmeddwalid/batin.git
cd batin
# Build in debug mode
cargo build
# Run tests
cargo test --all-features
# Run clippy lints
cargo clippy --all-features -- -D warnings
# Check formatting
cargo fmt --all -- --check
Project Structure
batin/
├── src/ # Source code
│ ├── lib.rs # Library entry point
│ ├── main.rs # CLI binary
│ └── ... # Modules
├── tests/ # Integration tests
├── examples/ # Usage examples
├── benches/ # Performance benchmarks
├── fuzz/ # Fuzz testing targets
└── docs/ # This documentation
Contribution Workflow
1. Find an Issue
- Browse open issues
- Look for
good first issuelabels - Or open a new issue to discuss your idea
2. Fork and Branch
# Fork on GitHub, then clone your fork
git clone https://github.com/YOUR_USERNAME/batin.git
cd batin
# Create a feature branch
git checkout -b feature/your-feature-name
3. Make Changes
- Follow the code style (run
cargo fmt) - Add tests for new functionality
- Update documentation if needed
- Run the full test suite
4. Commit
git add .
git commit -m "feat: add support for XYZ format"
Commit message format:
feat:- New featurefix:- Bug fixdocs:- Documentation onlytest:- Adding testsrefactor:- Code refactoringperf:- Performance improvement
5. Push and Open PR
git push origin feature/your-feature-name
Then open a Pull Request on GitHub.
Code Style
Rust Style
- Follow standard Rust conventions
- Run
cargo fmtbefore committing - Fix all
clippywarnings
Documentation
Every public item should have:
- A doc comment (
///) - Example code where helpful
- Parameter descriptions
/// Detect file type from byte slice.
///
/// # Arguments
/// * `data` - The file content as bytes
/// * `config` - Detection configuration
///
/// # Returns
/// `Result<FileType>` with detection results
///
/// # Example
/// ```
/// let data = std::fs::read("file.pdf")?;
/// let result = FileType::from_bytes(&data, &config)?;
/// ```
pub fn from_bytes(data: &[u8], config: &DetectionConfig) -> Result<Self>
Adding New File Signatures
Step 1: Research
- Find the format's specification
- Identify magic bytes and offset
- Check for similar formats that need disambiguation
Step 2: Add Signature
In src/detection/signatures.rs:
FileSignature {
magic: &[0x00, 0x00, 0x01, 0x00],
offset: 0,
additional_magic: None,
extensions: vec!["ico".to_string()],
mime_type: "image/x-icon",
category: FileCategory::Image,
},
Step 3: Add Test
#[test]
fn test_detect_ico() {
let ico_data = include_bytes!("../test_files/sample.ico");
let db = SignatureDatabase::default();
let matches = db.match_signatures(ico_data);
assert!(!matches.is_empty());
}
Step 4: Update Documentation
Add the new format to CHANGELOG.md and README.
Testing
Unit Tests
# Run all tests
cargo test --all-features
# Run specific test
cargo test test_detect_ico
# Run with output
cargo test -- --nocapture
Fuzz Testing
# Install cargo-fuzz
cargo install cargo-fuzz
# Run fuzz tests
cargo +nightly fuzz run fuzz_detect
Benchmarks
# Run benchmarks
cargo bench
Pull Request Checklist
- Code compiles without warnings
- All tests pass
-
cargo clippypasses -
cargo fmt --checkpasses - New code has tests
- Documentation updated
- CHANGELOG updated (if applicable)
Release Process
For maintainers only
- Update version in
Cargo.toml - Update
CHANGELOG.md - Commit:
git commit -m "release: v0.2.0" - Tag:
git tag v0.2.0 - Push:
git push && git push --tags - GitHub Actions handles the rest
Getting Help
- Questions? Open a Discussion
- Found a bug? Open an Issue
- Security issue? See SECURITY.md
License
By contributing, you agree that your contributions will be licensed under the GPL-3.0 license.
First Time Contributing?
Look for issues labeled good first issue - they're specifically chosen to be approachable for new contributors!