| title | Contributing to Honeymelon |
|---|---|
| description | Guidelines for setting up the project, proposing changes, and collaborating on Honeymelon development. |
Thank you for your interest in contributing to Honeymelon! This guide will help you get started with development and explain our contribution workflow.
We are committed to providing a welcoming and inclusive environment. Please be respectful and constructive in all interactions.
Before you begin, ensure you have:
- macOS 13.0+ (Ventura or later)
- Apple Silicon Mac (M1, M2, M3, M4)
- Node.js 18+ and npm
- Rust (latest stable)
- Xcode Command Line Tools
-
Fork the repository on GitHub
-
Clone your fork:
git clone https://github.com/honeymelon-app/honeymelon.git cd honeymelon -
Install dependencies:
npm install
-
Verify setup:
npm run tauri:devThe app should launch successfully.
main: Stable, production-ready codedevelop: Integration branch for features (if used)feature/feature-name: Individual featuresfix/bug-description: Bug fixes
-
Create a branch:
git checkout -b feature/your-feature-name
-
Make changes with frequent commits:
git add . git commit -m "feat: add new feature"
-
Keep updated:
git fetch origin git rebase origin/main
-
Push and create PR:
git push origin feature/your-feature-nameWe use Conventional Commits:
<type>(<scope>): <subject>
<body>
<footer>
Types:
feat: New featurefix: Bug fixdocs: Documentationstyle: Formatting, no code changerefactor: Code change without adding feature or fixing bugperf: Performance improvementtest: Adding testschore: Maintenance tasks
Examples:
feat(jobs): add pause/resume functionality
fix(ffmpeg): handle spaces in file paths
docs(architecture): update pipeline diagram
test(stores): add job state transition tests
honeymelon/
├── src/ # Vue frontend
│ ├── app.vue # Root component
│ ├── lib/ # Core logic
│ ├── stores/ # Pinia stores
│ ├── composables/ # Vue composables
│ └── components/ # Vue components
│
├── src-tauri/ # Rust backend
│ ├── src/
│ │ ├── lib.rs # Main entry
│ │ ├── ffmpeg_*.rs # FFmpeg integration
│ │ └── ...
│ └── Cargo.toml # Rust dependencies
│
├── docs/ # Documentation
├── e2e/ # E2E tests
└── public/ # Static assets
We use ESLint and Prettier:
# Check linting
npm run lint
# Fix linting issues
npm run lint:fix
# Format code
npm run format
Key conventions:
- Use
<script setup lang="ts">for components - Prefer
constoverlet - Use type inference when possible
- Name components in PascalCase
- Use kebab-case for file names
Example:
<script setup lang="ts">
import { ref, computed } from 'vue';
interface Props {
title: string;
count?: number;
}
const props = withDefaults(defineProps<Props>(), {
count: 0,
});
const doubled = computed(() => props.count * 2);
</script>We use Clippy and rustfmt:
# Check Rust code
npm run lint:rust
# Format Rust code
npm run format:rust
Key conventions:
- Follow Rust API guidelines
- Use
Result<T, E>for error handling - Prefer
async/awaitover callbacks - Document public APIs with
///comments
Example:
/// Probes a media file using FFprobe
///
/// # Arguments
///
/// * `file_path` - Path to the media file
///
/// # Returns
///
/// * `Ok(ProbeResult)` - Parsed metadata
/// * `Err(String)` - Error message
pub async fn probe_media(file_path: &str) -> Result<ProbeResult, String> {
// Implementation
}Run unit tests:
npm run test:unit
Watch mode:
npm run test:unit:watch
Coverage:
npm run test:unit:coverage
Writing tests:
import { describe, it, expect } from 'vitest';
import { mount } from '@vue/test-utils';
import JobQueueItem from '@/components/JobQueueItem.vue';
describe('JobQueueItem', () => {
it('renders job information', () => {
const wrapper = mount(JobQueueItem, {
props: {
job: {
id: '1',
status: 'queued',
sourceFile: '/path/to/file.mp4',
},
},
});
expect(wrapper.text()).toContain('file.mp4');
});
});Run Rust tests:
cd src-tauri
cargo test
Writing tests:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_ffprobe_output() {
let json = r#"{"format": {"duration": "10.5"}}"#;
let result = parse_probe_result(json).unwrap();
assert_eq!(result.duration, 10.5);
}
#[tokio::test]
async fn test_async_function() {
let result = probe_media("test.mp4").await;
assert!(result.is_ok());
}
}Run E2E tests:
npm run test:e2e
UI mode:
npm run test:e2e:ui
Writing E2E tests:
import { test, expect } from '@playwright/test';
test('converts a video file', async ({ page }) => {
await page.goto('http://localhost:1420');
// Add file to queue
await page.click('[data-testid="add-file"]');
// ... interact with app
await expect(page.locator('.job-completed')).toBeVisible();
});- Update tests: Add/update tests for your changes
- Run linters:
npm run lintandnpm run lint:rust - Run tests:
npm run test - Update docs: Document new features or API changes
- Test manually: Ensure the app works as expected
- Code follows style guidelines
- Tests pass locally
- New features have tests
- Documentation is updated
- Commit messages follow convention
- No console errors or warnings
- PR description explains changes
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing
How was this tested?
## Screenshots
If applicable
## Related Issues
Closes #123- Automated checks must pass (linting, tests)
- Code review by maintainer(s)
- Changes requested (if needed)
- Approval from maintainer
- Merge to main branch
- Plan: Discuss the feature in an issue first
- Design: Consider architecture and user experience
- Implement: Write code with tests
- Document: Update relevant documentation
- Review: Submit PR for review
- Reproduce: Ensure you can reproduce the bug
- Write test: Create a failing test that demonstrates the bug
- Fix: Implement the fix
- Verify: Ensure the test passes
- Submit: Create PR with fix
- Tests first: Ensure existing tests pass
- Small changes: Make incremental refactorings
- Test coverage: Maintain or improve test coverage
- Document: Explain why the refactor was needed
- Edit src/lib/presets.ts
- Add preset definition
- Add tests for the preset
- Update documentation
- Update src/lib/container-rules.ts
- Add codec compatibility rules
- Update capability detection if needed
- Add tests
- Update supported formats documentation
Frontend:
npm update
npm audit fix
Backend:
cd src-tauri
cargo update
cargo audit
Verify:
npm run test
npm run build
Browser DevTools:
- Press
Cmd + Option + Iin the app - Use Vue DevTools extension
- Check console for errors
VS Code:
{
"type": "chrome",
"request": "launch",
"name": "Debug Honeymelon",
"url": "http://localhost:1420",
"webRoot": "${workspaceFolder}/src"
}Rust debugging:
// Add debug prints
println!("Debug: {:?}", value);
// Or use dbg! macro
dbg!(value);Logs:
# Run with debug logging
RUST_LOG=debug npm run tauri:dev- Documentation: Check our docs
- Issues: Search existing issues on GitHub
- Discussions: Start a discussion for questions
- Email: tjthavarshan@gmail.com
By contributing, you agree that your contributions will be licensed under the GNU General Public License v3.0 or later (GPL-3.0-or-later), the same license as the project. See LICENSE for the full license text.