michel a127dd97bf ci: run soulfind e2e tests on GitHub Actions
Extend the existing CI workflow with an ubuntu-only "End-to-end (soulfind)"
job that builds soulfind from source (LDC + `dub build :server`), points
SOULFIND_BIN at it, and runs the e2e suite with SOULSEEK_E2E_REQUIRED=1.
Also widen the clippy job to the whole workspace.

The e2e harness gains SOULSEEK_E2E_REQUIRED: when set, a missing/unstartable
server is a hard failure instead of a silent skip, so CI genuinely exercises
the client end-to-end. Add e2e coverage for two existing behaviours a single
server can verify: wrong-password rejection and concurrent logins.
2026-07-19 13:19:46 +02:00
2025-11-12 15:38:29 +01:00
2024-09-09 08:32:51 +02:00
2026-04-26 12:00:24 +02:00
2025-07-31 20:06:41 +02:00

Soulseek-rs 🦀

⚠️WARNING THIS IS UNDER DEVELOPMENT AND NOT READY FOR USE ⚠️

Souleek-rs is an experimental Soulseek library and client built in Rust. It's under development and not yet ready for use. Soulseek is a closed-source P2P file-sharing network from the 2000s. It's still used by music enthusiasts around the world to share niche music.

🎥 Demo

CLI Demo

Project Goals

This project is a learning exercise to explore Rust. I've been using Soulseek since the early 2000s, so it's close to my heart, and the Soulseek protocol is a closed-source network protocol that provides a great opportunity to learn about asynchronous and concurrent network programming and reverse engineering

It's not intended to be a production-ready client (yet).

Since it's a learning project, I have a self-imposed restriction not to use external dependencies in the library. This means I can't use any external crates that are not part of the Rust standard library. This is a good challenge to learn how to build complex systems with only the standard library.

In the client crate, external dependencies are allowed for building a rich experience. For me, this is a good balance between learning and practicality.

Planned Features

  • Search for files
  • Download files
  • Configure credentials
  • TUI for searching and downloading files
  • Configure download & upload directories
  • Share files
  • Browse user(s) files
  • Chat in chatrooms
  • Private messaging
  • Headless mode daemon mode with remote control

Project Structure

This project is organized as a Cargo workspace with two crates:

  • soulseek-rs-lib - The core library implementing the Soulseek protocol
  • soulseek-rs - A CLI client built on top of the library

This structure allows:

  • Other developers to build custom Soulseek clients using soulseek-rs-lib
  • Users to install the ready-made client via cargo install soulseek-rs
  • Clean separation of concerns between protocol implementation and user interface

Installation

For Users

cargo install soulseek-rs

For Developers

Clone and build from source:

git clone git@github.com:michel/soulseek-rs.git
cd soulseek-rs
cargo build --release

The binary will be available at target/release/soulseek-rs.

For Library Users

To build your own Soulseek client, add to your Cargo.toml:

[dependencies]
soulseek-rs-lib = "0.1.0"

Usage

./target/release/soulseek-rs "the weeknd Blinding Lights"

Development

To run the project in development mode with debug output and trace output:

RUST_LOG=trace cargo run

Development

To run the tests:

cargo test

To run the linter:

cargo clippy

To run the formatter:

cargo fmt

End-to-end tests

The soulseek-rs-lib/tests/e2e.rs suite exercises the client against a real Soulseek server using soulfind, a local server implementation. The tests are server-optional: they run when a server is available and otherwise skip (so cargo test stays green everywhere).

They locate a server in this order:

  1. SOULSEEK_TEST_SERVER=host:port — connect to an already-running server, or
  2. SOULFIND_BIN=/path/to/soulfind (or a soulfind/bin/soulfind checkout in a parent directory) — spawn soulfind on an ephemeral port with a throwaway database.
# Build soulfind once (see its BUILDING.md), then:
SOULFIND_BIN=/path/to/soulfind/bin/soulfind \
  cargo test -p soulseek-rs-lib --test e2e -- --nocapture

On macOS, soulfind's SQLITE_CONFIG_SINGLETHREAD optimization is rejected by the system SQLite; building soulfind with that call made non-fatal lets it run locally. It is only a mutex optimization and does not affect the server.

Set SOULSEEK_E2E_REQUIRED=1 to turn a missing server into a hard failure instead of a skip. Continuous integration sets it so the e2e suite genuinely runs against a freshly built soulfind rather than silently skipping.

Continuous integration

.github/workflows/ci.yml runs on every push and pull request:

  • Format & Clippy — cargo fmt --all --check and cargo clippy --workspace --all-targets -- -D warnings.
  • Test — builds soulfind from source (LDC + dub build :server), points SOULFIND_BIN at it, and runs cargo test --workspace with SOULSEEK_E2E_REQUIRED=1, so unit and end-to-end tests both run.

License

This project is licensed under the MIT License — see the LICENSE file for details.

S
Description
repo for improving soulseek-rs with qol features.
Readme MIT
5.2 MiB
Languages
Rust 92.5%
TypeScript 6%
Shell 1.1%
CSS 0.2%