Repository navigation
development
This page is for developers who want to build, test, or contribute to Retro Game Cover Downloader.
| Tool | Notes |
|---|---|
| Windows, Linux, or macOS | The application and tests target net10.0 and use Avalonia |
| .NET 10 SDK | The repository pins SDK 10.0.0 with a latestMajor roll-forward policy in global.json
|
| Git | To clone the repository |
| IDE (optional) | JetBrains Rider, Visual Studio 2022+, or VS Code with the Avalonia extension |
git clone https://github.com/purelogiccode/RetroGameCoverDownloader.git
cd CSharp_RetroGameCoverDownloader# Restore and build
dotnet restore CSharp_RetroGameCoverDownloader.sln
dotnet build CSharp_RetroGameCoverDownloader.sln -c Release
# Run the application
dotnet run --project RetroGameCoverDownloader
# Run the full unit test suite
dotnet test CSharp_RetroGameCoverDownloader.slnThe solution builds with zero warnings. The test suite is fully offline and does not require a GitHub token. CI runs the same build and tests on Windows, Linux, and macOS.
The release script builds self-contained single-file bundles for all six targets:
# All targets
./scripts/package-release.ps1 -Version 2.0.0
# One target at a time
./scripts/package-release.ps1 -Version 2.0.0 -Runtimes linux-arm64 -SkipTestsSupported RIDs are win-x64, win-arm64, linux-x64, linux-arm64, osx-x64, and osx-arm64.
Windows bundles are zip files, Linux bundles are tar.gz files, and macOS bundles contain a .app directory.
Run the script on the target operating system when you need to preserve Unix executable permissions.
| Project / folder | Contents |
|---|---|
RetroGameCoverDownloader |
The Avalonia application. Key folders: Assets, Commands, Converters, Helpers, Managers, Models, Services, ViewModels, Views
|
RetroGameCoverDownloader.Tests |
xUnit tests (also net10.0) mirroring the application's folder structure (Helpers, Managers, Services, ViewModels, ...) |
docs |
This documentation. Sources are plain Markdown plus toc.yml and docfx.json; docs/template customizes the DocFX modern template (dark theme, logo, styling) |
scripts |
package-release.ps1 (release bundles) and publish-wiki.ps1 (wiki sync) |
.github |
workflows/ci.yml (build + test), workflows/codeql.yml (code scanning), workflows/release.yml (approval-gated release), workflows/docs.yml (Pages + Wiki), and dependabot.yml
|
-
xUnit with
Microsoft.NET.Test.Sdk,xunit, andcoverlet.collectorfor coverage. - A
[ModuleInitializer]replacesBugReportServicewith an in-memoryMockBugReportService, so unit tests never call the bug report API. -
MainViewModelexposesprotected virtualseams (InvokeOnDispatcher,GetFiles,WriteAllBytesAsync,GetAvailableFreeSpace, ...) that tests override to run without touching the file system, network, or UI. -
IGitHubServiceis fakeable; tests inject an in-memory implementation to simulate repository data, rate limits, timeouts, and failures. - A
CollectingLogSinkcaptures Serilog events so tests can assert log levels (for example, that transient network failures are logged as information rather than errors).
Run a single test class or test with the usual filters:
dotnet test --filter "FullyQualifiedName~GitHubServiceTests"
dotnet test --filter "DisplayName~RateLimit"CodeQL runs in CI for the application and the workflows. You can also run JetBrains InspectCode locally:
jb inspectcode CSharp_RetroGameCoverDownloader.sln `
--output=inspectcode.sarif --format=Sarif --severity=WARNING --sweaThe solution should report no warnings or errors. The SARIF report is for local review only and is ignored by Git.
The codebase is C# with nullable reference types enabled, file-scoped namespaces, and structured logging through Serilog. The following analyzers enforce quality and are part of every build:
- Meziantou.Analyzer
- Roslynator.Analyzers, Roslynator.CodeAnalysis.Analyzers, Roslynator.Formatting.Analyzers
Contributions are expected to build with no warnings; a handful of analyzer rules are intentionally disabled
in .editorconfig for this codebase.
Guidelines used throughout the project:
- Prefer
async/awaitend to end; never block the UI thread. - Marshal UI updates through
MainViewModel's dispatcher seams. - Log with structured message templates (
Log.Information("Loaded {Count} files", count)). - Classify failures: transient network problems are expected and logged as information; real defects are
logged as errors so they reach
error.logand the bug report endpoint. - Keep services testable: inject or virtualize external dependencies.
The Markdown files in docs/ feed two outputs, each with its own lateral menu:
-
GitHub Pages — built with DocFX using
docs/docfx.json.docs/toc.ymldefines the top navigation bar, anddocs/guide/toc.ymldefines the left sidebar shown on every documentation page. -
GitHub Wiki — the same pages are synced by
scripts/publish-wiki.ps1, which renamesindex.mdtoHome.md, flattens folder prefixes, converts.mdlinks to wiki-style links, and generates_Sidebar.mdfrom the navigation file.
When adding a page:
- Create
docs/guide/<page-name>.md. - Add an entry to
docs/guide/toc.ymlso DocFX adds it to the left sidebar and the wiki_Sidebar.md. - Link to other pages with relative Markdown links (for example
[User Guide](user-guide)); the wiki sync strips folder prefixes and the.mdextension automatically.
Build the site locally to verify:
dotnet tool install --global docfx --version 2.81.0
docfx docs/docfx.json
# Output is written to docs/_siteThe site uses a dark theme by default. The customization lives in docs/template:
-
public/main.jssetsdefaultTheme: 'dark'and adds the GitHub icon link. -
public/main.cssoverrides the Bootstrap color-mode variables and adds the branding accents. -
public/logo.pngis the navbar logo. -
docs/docfx.jsonsetsfileMetadata._disableTocforindex.mdso the landing page keeps the lateral menu; without it, DocFX hides the sidebar on pages linked directly from the roottoc.yml.
- Architecture — how the components fit together.
- Release Process — CI, packaging, and publishing.