Contributing
Thank you for your interest in contributing to Variant-Linker! This guide will help you get started with contributing to the project, whether you're fixing bugs, adding features, or improving documentation.
Getting Started
Development Setup
Fork and Clone the Repository
bashgit clone https://github.com/your-username/variant-linker.git cd variant-linker
Install Dependencies
bashnpm install
Run Tests
bashnpm test
Check Code Style
bashnpm run lint
Development Workflow
Create a Feature Branch
bashgit checkout -b feature/your-feature-name
Make Your Changes
- Write code following the project's style guidelines
- Add tests for new functionality
- Update documentation as needed
Test Your Changes
bashnpm test npm run lint npm run benchmark # If performance-related changes
Commit Your Changes
bashgit add . git commit -m "feat: add new feature description"
Push and Create Pull Request
bashgit push origin feature/your-feature-name
Code Style & Guidelines
ESLint Configuration
Variant-Linker uses ESLint with the Google JavaScript Style Guide as the base configuration. The linting setup includes:
- Base Configuration: Google JavaScript Style Guide
- Node.js Rules: Node.js specific linting rules
- Test File Overrides: Special rules for test files using Mocha/Chai
Running Linting
# Check for linting issues
npm run lint
# Fix automatically fixable issues
npm run lint:fix
Style Guidelines
When contributing code, please follow these guidelines:
Naming Conventions
- Use camelCase for variable and function names
- Use PascalCase for constructor functions and classes
- Use UPPER_SNAKE_CASE for constants
- Use descriptive names that clearly indicate purpose
Code Structure
- Keep functions small and focused (KISS principle)
- Avoid code duplication (DRY principle)
- Use consistent indentation (2 spaces)
- Maintain line length under 100 characters
Documentation
- Provide clear JSDoc comments for all functions
- Include parameter and return type information
- Document complex algorithms and business logic
- Keep comments up-to-date with code changes
Example Code Style
/**
* Processes a single variant through the annotation pipeline.
* @param {string} variant - The variant identifier (rsID, HGVS, or VCF format)
* @param {Object} options - Configuration options for processing
* @param {string} options.output - Output format (JSON, CSV, TSV, VCF)
* @param {boolean} options.debug - Enable debug logging
* @returns {Promise<Object>} Processed variant annotation data
*/
async function processVariant(variant, options = {}) {
const {output = 'JSON', debug = false} = options;
if (debug) {
console.log(`Processing variant: ${variant}`);
}
try {
const annotation = await getVariantAnnotation(variant);
return formatOutput(annotation, output);
} catch (error) {
throw new Error(`Failed to process variant ${variant}: ${error.message}`);
}
}
Testing
Test Framework
Variant-Linker uses a comprehensive testing stack:
- Mocha (^10.4.0) - Test runner with 30-second timeout
- Chai (^4.3.4) - BDD/TDD assertion library
- Sinon (^18.0.1) - Test spies, stubs, and mocks
- Nock (^13.5.4) - HTTP request mocking
- Proxyquire (^2.1.3) - Module mocking and dependency injection
Running Tests
# Run all tests
npm test
# Run tests with coverage (if configured)
npm run test:coverage
# Run specific test file
npx mocha test/variantLinkerCore.test.js
# Run tests with debugging
npx mocha test/variantLinkerCore.test.js --inspect-brk
Test Structure
Tests are organized in the test/
directory:
test/
├── helpers.js # Common test utilities and mock data
├── apiHelper.test.js # HTTP client and retry logic tests
├── variantLinkerCore.test.js # Core functionality tests
├── variantLinkerProcessor.test.js # Result processing tests
├── scoring.test.js # Scoring system tests
├── inheritance-integration.test.js # Family analysis tests
└── fixtures/ # Test data and expected results
├── README.md
├── test.vcf
└── inheritance/
├── trio_ar_homozygous.ped
└── trio_ar_homozygous.vcf
Writing Tests
Test Patterns
Follow these patterns when writing tests:
describe('Module Name', () => {
let sandbox;
beforeEach(() => {
sandbox = sinon.createSandbox();
});
afterEach(() => {
sandbox.restore();
nock.cleanAll();
});
describe('functionName', () => {
it('should handle normal input correctly', async () => {
// Arrange
const input = 'test-input';
const expected = 'expected-output';
// Act
const result = await functionName(input);
// Assert
expect(result).to.equal(expected);
});
it('should handle error conditions gracefully', async () => {
// Arrange
const invalidInput = null;
// Act & Assert
await expect(functionName(invalidInput)).to.be.rejected;
});
});
});
Mock API Responses
Use Nock for mocking HTTP requests:
const nock = require('nock');
beforeEach(() => {
nock('https://rest.ensembl.org')
.get('/variant_recoder/human/rs6025')
.reply(200, {
"rs6025": [{
"id": "rs6025",
"input": "rs6025",
"vcf_string": "1\t169519049\trs6025\tT\tC\t.\t.\t."
}]
});
});
Adding New Tests
When adding new features:
- Write Tests First (TDD approach when possible)
- Cover Edge Cases - Test boundary conditions and error scenarios
- Mock External Dependencies - Don't make real API calls in tests
- Use Descriptive Names - Test names should clearly describe what's being tested
- Keep Tests Focused - Each test should verify one specific behavior
Commit Message Guidelines
Conventional Commits
This project uses Conventional Commits with semantic-release for automated versioning and releases.
Commit message format:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Commit Types
Type | Description | Version Impact |
---|---|---|
feat | New feature | Minor version bump |
fix | Bug fix | Patch version bump |
perf | Performance improvements | Patch version bump |
revert | Revert previous commit | Patch version bump |
docs | Documentation changes | No release |
style | Code style changes | No release |
refactor | Code refactoring | No release |
test | Test additions/changes | No release |
build | Build system changes | No release |
ci | CI configuration changes | No release |
chore | Other maintenance | No release |
📝 Documentation-Only Changes: Commits with types docs
, style
, chore
, refactor
, test
, build
, or ci
will NOT trigger a new release. This is perfect for documentation updates, code formatting, and development workflow improvements.
Breaking Changes
For breaking changes, add !
after the type or include BREAKING CHANGE:
in the footer:
# With !
git commit -m "feat!: drop support for Node.js 12"
# With footer
git commit -m "feat: update API interface
BREAKING CHANGE: API now requires authentication token"
Examples
# New feature
git commit -m "feat: add support for compound heterozygous analysis"
# Bug fix
git commit -m "fix: resolve VCF parsing issue with multi-allelic variants"
# Documentation
git commit -m "docs: update installation instructions for Windows"
# Performance improvement
git commit -m "perf: optimize batch processing for large variant sets"
Development Guidelines
Architecture Principles
- Modular Design: Keep components focused and loosely coupled
- API First: Design for both CLI and library usage
- Error Handling: Provide clear, actionable error messages
- Performance: Consider performance implications of changes
- Backward Compatibility: Avoid breaking changes when possible
Code Organization
src/
├── main.js # CLI entry point
├── index.js # Library exports
├── variantLinkerCore.js # Core processing logic
├── variantLinkerProcessor.js # Result processing
├── apiHelper.js # HTTP client utilities
├── inheritance/ # Inheritance analysis modules
│ ├── inheritanceAnalyzer.js
│ └── patternDeducer.js
└── scoring.js # Scoring engine
Adding New Features
Design Phase
- Document the feature requirements
- Design the API interface
- Consider backward compatibility
Implementation Phase
- Follow existing patterns and conventions
- Add comprehensive error handling
- Include debug logging where appropriate
Testing Phase
- Write unit tests for all new functions
- Add integration tests for complete workflows
- Test error conditions and edge cases
Documentation Phase
- Update CLI help text if needed
- Add JSDoc comments to all functions
- Update README and guide documentation
Performance Considerations
- API Efficiency: Minimize API calls through batching
- Memory Usage: Consider memory impact of large datasets
- Async Patterns: Use proper async/await patterns
- Error Recovery: Implement retry logic for transient failures
Documentation
Documentation Types
- Code Documentation - JSDoc comments in source code
- API Documentation - Generated from JSDoc comments
- User Guides - Markdown files in
docs/docs/
- README Files - Overview and quick start information
Writing Documentation
- Be Clear and Concise - Explain concepts in simple terms
- Include Examples - Provide practical usage examples
- Keep Updated - Update documentation with code changes
- Consider Audience - Write for both beginners and advanced users
Documentation Build
The documentation site is built with Docusaurus:
# Install documentation dependencies
cd docs && npm install
# Start development server
cd docs && npm start
# Build for production
cd docs && npm run build
Pull Request Process
Before Submitting
Code Quality Checks
bashnpm run lint npm test npm run benchmark # If performance-related
Documentation Updates
- Update relevant documentation
- Add JSDoc comments for new functions
- Update CLI help text if needed
Testing
- Ensure all tests pass
- Add tests for new functionality
- Test edge cases and error conditions
Pull Request Template
When submitting a pull request, include:
- Description - Clear description of changes
- Motivation - Why the change is needed
- Testing - How the changes were tested
- Breaking Changes - Any breaking changes and migration guide
- Checklist - Confirmation of code quality checks
Review Process
- All pull requests require review before merging
- Address reviewer feedback promptly
- Keep pull requests focused and reasonably sized
- Squash commits when merging to maintain clean history
Getting Help
Communication Channels
- GitHub Issues - Bug reports and feature requests
- GitHub Discussions - General questions and community discussions
- Pull Request Comments - Code review and implementation discussions
Common Questions
Q: How do I test my changes against real API data? A: Use the debug mode and small test datasets to validate against live APIs. Avoid making excessive API calls during development.
Q: How do I add support for a new annotation source? A: Follow the existing API helper patterns and add appropriate tests with mocked responses.
Q: How do I handle breaking changes? A: Document breaking changes clearly and provide migration guidance. Use semantic versioning to communicate the impact.
Recognition
Contributors are recognized in:
- GitHub contributor list
- Release notes for significant contributions
- Documentation acknowledgments
Thank you for contributing to Variant-Linker! Your efforts help make genetic variant analysis more accessible and reliable for the research community.