Contributing to Cantus¶
Thank you for your interest in contributing to Cantus! We welcome contributions of all kinds—from reporting bugs and improving documentation to submitting bug fixes and proposing new features.
Code of Conduct¶
Cantus is an open-source project that thrives on respectful, constructive collaboration. Please ensure that all interactions across discussions, issues, and pull requests remain professional and welcoming to developers of all backgrounds.
Ways to Contribute¶
You can contribute to Cantus in several ways:
- Bug Reports: Open an issue if you discover a timing bug, rendering defect, or crash.
- Feature Requests: Share ideas for new UI visualizers, additional lyrics providers, or platform targets.
- Code Contributions: Submit pull requests for bug fixes, performance optimizations, or new capabilities.
- Documentation: Help improve guides, clarify setup steps, or fix typos.
Development Setup & Prerequisites¶
Prerequisites¶
To build and run Cantus locally, ensure you have the following installed:
- .NET 10 SDK (
v10.0.100or higher): - Uno Platform WebAssembly Workload (if developing for the Web client):
- Spotify Developer Account (Free):
- Create a free developer application at developer.spotify.com/dashboard to obtain a Client ID.
- Add
http://localhost:5000/api/auth/spotify/callbackandhttp://127.0.0.1:5000/api/auth/spotify/callbackto your Spotify App's Redirect URIs. - Docker (Optional): For running containerized tests or smoke tests.
Getting the Code¶
- Fork the Cantus repository on GitHub.
- Clone your fork locally:
- Create a descriptive feature branch:
Local Environment Configuration¶
Copy the example environment configuration:
Edit .env to include your Spotify Client ID:
Solution Structure & Architecture¶
Cantus is structured following Clean Architecture across four primary solution projects in Cantus.slnx:
flowchart TB
Client["Cantus.Client (Uno Platform)<br/>Desktop (Skia/WinUI) & WebAssembly"]
Server["Cantus.Server (ASP.NET Core 10)<br/>SignalR PlaybackHub & REST APIs"]
Infra["Cantus.Infrastructure<br/>Spotify PKCE, LRCLIB, SQLite, Crypto"]
Core["Cantus.Core<br/>Domain Entities, LRC Parser, Engine Contracts"]
Client --> Core
Server --> Infra
Server --> Core
Infra --> Core
src/Cantus.Core: Pure .NET standard domain models (PlaybackState,SyncedLyrics,LyricLine),LrcParser, and interface definitions. Zero external framework dependencies.src/Cantus.Infrastructure: Implementation of Spotify Web API client, LRCLIB integration, SQLite caching (CantusDbContext), and Data Protection encryption.src/Cantus.Server: ASP.NET Core application hosting the SignalRPlaybackHub, backgroundActiveUsersPlaybackMonitor, and Minimal API endpoints.src/Cantus.Client: Cross-platform MVVM client targeting Desktop (Linux Skia, Windows WinUI 3) and WebAssembly.
Building and Running Locally¶
1. Build the Entire Solution¶
2. Run the ASP.NET Core Server¶
Start the backend server on http://localhost:5000:
To enable detailed debug or trace logs in the terminal:
3. Run the Desktop Client¶
Launch the Uno Platform Skia desktop window:
4. Run the WebAssembly Client¶
To build and serve the WebAssembly client through the ASP.NET Core server:
# Publish WASM assets
dotnet publish src/Cantus.Client/Cantus.Client/Cantus.Client.csproj -f net10.0-browserwasm -c Release -o ./src/Cantus.Server/wwwroot
# Start server and navigate to http://localhost:5000
dotnet run --project src/Cantus.Server
Running Automated Tests¶
Before opening a pull request, ensure all unit and integration test suites pass:
# Run all tests
dotnet test Cantus.slnx
# Run tests with detailed console logger
dotnet test Cantus.slnx --logger "console;verbosity=normal"
Unit and integration tests reside in tests/:
- tests/Cantus.Core.Tests: LRC parser, time calculations, domain model logic.
- tests/Cantus.Infrastructure.Tests: Caching layers, token encryption, SQLite persistence.
- tests/Cantus.Client.Tests: MVVM ViewModels, auto-scrolling logic, theme manager, and responsive layout calculation.
- tests/Cantus.Server.Tests: SignalR hub broadcasting, REST API endpoints, adaptive poller state transitions.
Coding Standards & Style Conventions¶
Cantus follows strict C# code quality guidelines. Please keep the following rules in mind:
1. Explicit Types over var¶
Do not use var for local variable declarations. Always use the explicit type:
// Correct
string trackTitle = "Never Gonna Give You Up";
int durationMs = 213000;
List<LyricLine> lines = new();
// Avoid
var trackTitle = "Never Gonna Give You Up";
2. Target-Typed new()¶
When the explicit type is declared on the left-hand side, use target-typed new():
// Correct
Dictionary<string, CachedTrack> cache = new();
PlaybackState state = new(trackId, progressMs);
// Avoid
Dictionary<string, CachedTrack> cache = new Dictionary<string, CachedTrack>();
3. File-Scoped Namespaces¶
Always use file-scoped namespace declarations:
4. Allman Bracing Style¶
Place opening braces { on their own line:
5. Structured Logging¶
Never use string interpolation inside ILogger calls. Use semantic message templates:
// Correct
_logger.LogInformation("User {UserId} joined room {RoomCode}", userId, roomCode);
// Avoid
_logger.LogInformation($"User {userId} joined room {roomCode}");
6. Code Formatting¶
Format your code before committing using dotnet format:
Submitting a Pull Request (PR)¶
PR Checklist¶
Before submitting your pull request, verify that:
- [ ] Code builds without errors or warnings (
dotnet build Cantus.slnx --configuration Release). - [ ] All unit and integration tests pass (
dotnet test Cantus.slnx). - [ ] Code conforms to repository formatting standards (
dotnet format). - [ ] New functionality or bug fixes include corresponding unit or integration tests.
- [ ] Commit messages and PR titles are clear, descriptive, and follow conventional commit formats (e.g.
feat: ...,fix: ...,docs: ...).
Opening the PR¶
- Push your branch to your GitHub fork:
- Navigate to github.com/jav76/Cantus and click Compare & pull request.
- Fill out the PR template with a clear explanation of what changed, why, and how it was tested.
- If your PR resolves an existing issue, link it in the description (e.g.
Closes #12). - Automated CI checks will validate formatting, compilation, and test execution.
Reporting Issues¶
If you find a bug or experience unexpected behavior:
- Check existing GitHub Issues to see if the issue has already been reported.
- Open a new issue with:
- A clear, descriptive title.
- Exact steps to reproduce the behavior.
- Expected vs. actual behavior.
- Relevant environment details (OS, browser/client type, Docker setup).
- Server or client logs (use
--log-configuration debugor open the Diagnostics HUD by pressing D in the client).