Libation is a cross-platform .NET desktop/CLI app for downloading and de-DRMing Audible
audiobooks. The core product is the Avalonia GUI (LibationAvalonia, assembly name Libation)
plus a headless CLI (LibationCli) that shares the same config and SQLite library database.
- Requires the .NET 10 SDK pinned by
global.json(10.0.101). It is preinstalled at~/.dotnet;~/.bashrcexportsDOTNET_ROOTand adds~/.dotnet(and~/.dotnet/tools) toPATH. New non-login shells may not have it — usedotnetafter a login shell, or call~/.dotnet/dotnetdirectly. - The startup update script runs
dotnet tool restore(restoresdotnet-ef) anddotnet restore Source/Libation.slnx. No other setup is needed. - The solution file is the new XML format:
Source/Libation.slnx(there is no classic.sln).
dotnet build Source/Libation.slnxsucceeds on Linux with 0 errors. So doLibationWinForms,HangoverWinFormsand theLoadByOS/{Windows,MacOS}ConfigApphelpers, individually: they targetnet10.0-windows7.0but setEnableWindowsTargeting, which is what makes a non-Windows SDK build them. Always compile-check a change to the WinForms projects — an earlier version of this file said they could not be built here, and a whole PR's worth of WinForms edits went out unverified on the strength of that.- Compiling is not running. WinForms has no Linux runtime, so behaviour and layout in
LibationWinForms/HangoverWinFormsstill need a human on Windows. Say so explicitly rather than implying a WinForms change was tested. - Build the runnable cross-platform apps directly:
dotnet build Source/LibationAvalonia/LibationAvalonia.csprojdotnet build Source/LibationCli/LibationCli.csproj
- There is no dedicated lint step; the repo's
.editorconfigis minimal and CI (.github/workflows/validate.yml) only builds and tests. The compiler/analyzer warnings from a normal build serve as the static-analysis check. (A known transitiveNU1903SQLite vulnerability warning is expected and harmless.)
- Test projects live under
Source/_Tests/and use MSTest on Microsoft.Testing.Platform (configured viaglobal.jsontest.runner). Because of this runner,dotnet testrequires--projectfor a single project (a positional project path is rejected):dotnet test --project Source/_Tests/FileManager.Tests/FileManager.Tests.csproj - CI runs
dotnet testfromSource/on every platform, Linux included, and it works here too: the restore covers the whole solution but only the test projects and their references are compiled, so the Windows-only projects never break the run. Naming one project is simply quicker. - Manual UI testing:
dotnet run Scripts/seed-demo-library.csfills the library with fake books covering every Liberate-column icon and prints the expected result for each row (-- --cleanremoves them). Readdocs/development/testing.mdbefore seeding library state by hand: the yellow lamp is an.aaxcfile on disk rather than a stored status,AudioExistsis a database check so green/error need no files, and a podcast's series is keyed off the parent book's own ASIN or the grid silently drops the parent row. - GNOME Keyring / OS secret store: Libation's default
TokenStorageMethodisEncrypted, and the AES-GCM master key is stored via the OS secret store (OsSecretStore/IdentityTokenStorageWiring). On Linux that is GNOME Keyring (Secret Service), which blocks indefinitely here: the login keyring is locked with a password nobody has, and the D-Bus call hangs even with no prompt on screen. Probing availability does not help - the probe is the blocking call. Every test project should finish in about a second. If one runs for minutes, assume something reached the OS secret store; do not sit through it and do not re-run it hoping for a different result.ResolveSecretStoreshort-circuits onLIBATION_MASTER_KEY_FILE, an existinglibation-master.keyunder the Libation files dir, orLIBATION_MASTER_KEY, so setting one of those keeps a test off the OS store entirely. The tests that deliberately exercise the real store are opt-in viaLIBATION_TEST_OS_SECRET_STORE=1and are skipped otherwise. Leave them skipped on Linux; they will hang if enabled. Always run tests undertimeoutso a regression here cannot stall a session.
- GUI: a display is available on
DISPLAY=:1. Run withcd Source/LibationAvalonia && dotnet run. First launch shows a Welcome/walkthrough and creates config under~/.local/share/Libation/(Settings.json,AccountsSettings.json,LibationContext.db). The same keyring note above applies when the GUI/CLI first encrypts account tokens. - CLI:
cd Source/LibationCli && dotnet run -- <command>(e.g.version,get-setting,list-accounts,scan,liberate). The CLI reads the same~/.local/share/Libation/config and database as the GUI. - Actually scanning/downloading a library requires signing into a real Audible account, so full end-to-end liberation cannot be exercised without credentials.