This guide provides comprehensive instructions for setting up a development environment and contributing to MIDIMon.
# Clone the repository
git clone https://github.com/amiable-dev/midimon.git
cd midimon
# Run automated setup
./scripts/dev-setup.sh
# Build and run
cargo build --release
cargo run --release- Rust: 1.75.0 or later (install via rustup)
- Git: For version control
- MIDI Device: For testing (or use virtual MIDI ports)
macOS:
- Xcode Command Line Tools:
xcode-select --install - Input Monitoring permission for HID access
Linux (future):
- ALSA development libraries:
sudo apt-get install libasound2-dev - udev rules for device access
Windows (future):
- Visual Studio Build Tools
# Fork on GitHub, then clone your fork
git clone https://github.com/YOUR_USERNAME/midimon.git
cd midimon
# Add upstream remote
git remote add upstream https://github.com/amiable-dev/midimon.git# Install rustup (if not already installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install required components
rustup component add rustfmt clippy
# Verify installation
cargo --version
rustc --version# Automated development environment setup
chmod +x scripts/dev-setup.sh
./scripts/dev-setup.shThis script will:
- Verify Rust installation
- Install cargo extensions
- Set up git hooks
- Check system dependencies
# Fast compilation, includes debug symbols
cargo build
# Run with debug build
cargo run# Optimized build (3-5MB binary)
cargo build --release
# Run with release build (recommended for testing)
cargo run --release
# Connect to MIDI port 2
cargo run --release 2# Enable debug logging
DEBUG=1 cargo run --release 2
# With LED scheme
cargo run --release 2 --led reactive
# With device profile
cargo run --release 2 --profile mikro.ncmm3# Run full test suite
cargo test --all
# Run with output
cargo test -- --nocapture
# Run specific test
cargo test test_name
# Run tests in specific module
cargo test mappings::# Run clippy (linter)
cargo clippy -- -D warnings
# Run formatter check
cargo fmt --check
# Apply formatting
cargo fmt
# Run all quality checks
./scripts/test.sh# MIDI event visualizer
cargo run --bin midi_diagnostic 2
# LED testing
cargo run --bin led_diagnostic
cargo run --bin led_tester
# Pad mapping utility
cargo run --bin pad_mappermidimon/
├── src/
│ ├── main.rs # Entry point, MIDI connection, event loop
│ ├── config.rs # Configuration structures (TOML parsing)
│ ├── event_processor.rs # MidiEvent → ProcessedEvent (timing detection)
│ ├── mappings.rs # ProcessedEvent → Action (mapping engine)
│ ├── actions.rs # Action execution (keyboard, shell, etc.)
│ ├── feedback.rs # LED feedback trait and factory
│ ├── mikro_leds.rs # HID-based RGB LED control
│ ├── midi_feedback.rs # MIDI-based LED control fallback
│ └── device_profile.rs # NI Controller Editor profile parser
├── docs/ # Additional documentation
├── scripts/ # Build and development scripts
├── .github/ # CI/CD workflows and templates
└── config.toml # Example configuration
- main.rs: MIDI input →
MidiEvent - event_processor.rs:
MidiEvent→ProcessedEvent(detect velocity, timing, chords) - mappings.rs:
ProcessedEvent→Action(match against config) - actions.rs:
Action→ execution (simulate input, run commands)
New Trigger Type:
- Add variant to
Triggerenum inconfig.rs - Add variant to
ProcessedEventenum inevent_processor.rs - Add detection logic in
EventProcessor::process() - Add matching case in
MappingEngine::trigger_matches_processed()
New Action Type:
- Add variant to
ActionConfigenum inconfig.rs - Add variant to
Actionenum inactions.rs - Add execution logic in
ActionExecutor::execute() - Update
compile_action()inmappings.rs
New LED Scheme:
- Add variant to
LightingSchemeenum infeedback.rs - Implement in
MikroMK3LEDs::run_scheme()(mikro_leds.rs) - Add fallback in
MidiFeedback::run_scheme()(midi_feedback.rs)
- Use
rustfmt(automatically applied by pre-commit hook) - 4-space indentation
- 100-character line limit
- All
clippywarnings must be resolved - Run
cargo clippy -- -D warningsbefore committing
/// Brief description of function
///
/// # Arguments
///
/// * `param` - Description of parameter
///
/// # Returns
///
/// Description of return value
///
/// # Example
///
/// ```
/// let result = function(arg);
/// ```
pub fn function(param: Type) -> Result<ReturnType, Error> {
// Implementation
}- Use
Result<T, E>for operations that can fail - Provide context with error messages
- Avoid
unwrap()in production code (useexpect()with clear message)
# Set DEBUG environment variable
DEBUG=1 cargo run --release 2Use the provided launch configurations in .vscode/launch.json:
- Debug Main: Run main application with debugger
- Debug Diagnostic: Run MIDI diagnostic tool
- Run Tests: Debug specific tests
MIDI device not found:
# Check USB connection
system_profiler SPUSBDataType | grep -i mikro
# List available ports
cargo run --releasePermission denied (HID):
- Grant Input Monitoring permission on macOS
- System Settings → Privacy & Security → Input Monitoring
Build errors:
# Clean build artifacts
cargo clean
# Update dependencies
cargo update- Feature:
feature/short-descriptionorusername/feature-name - Bug fix:
fix/issue-number-description - Docs:
docs/what-changed
Follow conventional commits format:
type(scope): brief description
Longer description if needed
Fixes #123
Types: feat, fix, docs, style, refactor, test, chore
- Create feature branch
- Make changes with clear commits
- Run
./scripts/test.shto ensure quality - Push to your fork
- Open PR with comprehensive description
- Address review feedback
- Merge once approved
Automated checks run before each commit:
# Install hooks
./scripts/dev-setup.sh
# Manually run checks
cargo fmt --check
cargo clippy -- -D warnings
cargo test --allTo bypass hooks (emergency only):
git commit --no-verifyInstall extensions (.vscode/extensions.json):
- rust-analyzer
- CodeLLDB (debugging)
- Even Better TOML
- Error Lens
Settings are pre-configured in .vscode/settings.json.
- Install Rust plugin
- Import project as Cargo project
- Run configurations provided
cargo install flamegraph
sudo cargo flamegraph# Run benchmarks (if implemented)
cargo benchThe release profile in Cargo.toml:
[profile.release]
opt-level = 3
lto = true
codegen-units = 1
strip = trueResults in:
- Binary size: 3-5MB
- Response latency: <1ms
- Memory usage: 5-10MB
See CONTRIBUTING.md for full guidelines.
- Code follows style guidelines
- All tests pass
- Documentation updated
- CHANGELOG.md updated (for features)
- Commit messages are clear
- No new clippy warnings
- Documentation: https://amiable-dev.github.io/midimon/
- Discussions: GitHub Discussions
- Issues: GitHub Issues
Happy coding! Thank you for contributing to MIDIMon.