From 5d0cbae5d567ac2ab91a156342022e22c48f22e2 Mon Sep 17 00:00:00 2001 From: antomfdez Date: Wed, 27 Nov 2024 12:24:06 +0100 Subject: [PATCH 1/2] Show supported features and audio backend in --version --- Cargo.lock | 5 ++-- Cargo.toml | 1 + src/config.rs | 81 +++++++++++++++++++++++++++++++++++++++++++++++---- src/main.rs | 7 +++++ 4 files changed, 86 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c7533d3a..256a1ff0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2197,9 +2197,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "opaque-debug" @@ -3032,6 +3032,7 @@ dependencies = [ "librespot-discovery", "librespot-playback", "log", + "once_cell", "pledge", "rspotify", "serde", diff --git a/Cargo.toml b/Cargo.toml index 4ecf0fdf..57b29008 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,7 @@ librespot-connect = { version = "0.4" } toml = "0.7" color-eyre = "0.6" directories = "5.0.1" +once_cell = "1.20.2" [target."cfg(unix)".dependencies] daemonize = "0.5" diff --git a/src/config.rs b/src/config.rs index 048e4558..3b91c73d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -13,6 +13,7 @@ use librespot_playback::{ dither::{mk_ditherer, DithererBuilder, TriangularDitherer}, }; use log::{error, info, warn}; +use once_cell::sync::Lazy; use serde::{de::Error, de::Unexpected, Deserialize, Deserializer}; use sha1::{Digest, Sha1}; use std::{fmt, fs, path::Path, path::PathBuf, str::FromStr}; @@ -332,27 +333,83 @@ impl From for LSAudioFormat { } } -#[derive(Debug, Default, StructOpt)] +pub static ABOUT_INFO: Lazy = Lazy::new(format_features_info); + +// Features functionality +fn format_features_info() -> String { + let features = get_enabled_features(); + let backends = get_enabled_backends(); + + let features_str = if features.is_empty() { + "No features enabled".to_string() + } else { + features.join(", ") + }; + + // Get the version from the Cargo environment variable + let version = env!("CARGO_PKG_VERSION"); + + // Format the string with version under the title, and avoid repeating version elsewhere + format!( + "A Spotify daemon\nspotifyd {}\nfeatures: {}\naudio backends: {}", + version, + features_str, + backends.join(", ") + ) +} + +pub fn get_enabled_backends() -> Vec<&'static str> { + let backends = vec![ + #[cfg(feature = "alsa_backend")] + "alsa", + #[cfg(feature = "pulseaudio_backend")] + "pulseaudio", + #[cfg(feature = "rodio_backend")] + "rodio", + #[cfg(feature = "portaudio_backend")] + "portaudio", + #[cfg(feature = "rodiojack_backend")] + "rodiojack", + #[cfg(feature = "pipe_backend")] + "pipe", + ]; + + backends +} + +pub fn get_enabled_features() -> Vec<&'static str> { + let mut features = Vec::new(); + + #[cfg(feature = "dbus_mpris")] + features.push("MPRIS"); + + #[cfg(feature = "dbus_keyring")] + features.push("keyring"); + + features +} + +#[derive(Debug, StructOpt)] #[structopt( - about = "A Spotify daemon", + about = &**ABOUT_INFO, // Use double dereference to get `&str` author, name = "spotifyd", setting(AppSettings::ColoredHelp) )] pub struct CliConfig { - /// The path to the config file to use + // The path to the config file to use #[structopt(long, value_name = "string")] pub config_path: Option, - /// If set, starts spotifyd without detaching + // If set, starts spotifyd without detaching #[structopt(long)] pub no_daemon: bool, - /// Prints more verbose output + // Prints more verbose output #[structopt(long)] pub verbose: bool, - /// Path to PID file. + // Path to PID file. #[structopt(long)] pub pid: Option, @@ -360,6 +417,18 @@ pub struct CliConfig { pub shared_config: SharedConfigValues, } +impl Default for CliConfig { + fn default() -> Self { + CliConfig { + config_path: None, + no_daemon: false, + verbose: false, + pid: None, + shared_config: SharedConfigValues::default(), + } + } +} + // A struct that holds all allowed config fields. // The actual config file is made up of two sections, spotifyd and global. #[derive(Clone, Default, Deserialize, PartialEq, StructOpt)] diff --git a/src/main.rs b/src/main.rs index deb36d88..b8d2a388 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ use crate::config::CliConfig; +use crate::config::ABOUT_INFO; #[cfg(unix)] use color_eyre::eyre::eyre; use color_eyre::{ @@ -98,6 +99,12 @@ fn main() -> eyre::Result<()> { color_eyre::install().wrap_err("Couldn't initialize error reporting")?; + // Handle --version explicitly + if std::env::args().any(|arg| arg == "--version") { + println!("{}", &**ABOUT_INFO); + return Ok(()); + } + let mut cli_config: CliConfig = CliConfig::from_args(); let is_daemon = !cli_config.no_daemon; From 76734c36c237cf249516041acb780b9f7bd734d6 Mon Sep 17 00:00:00 2001 From: antomfdez <126808009+antomfdez@users.noreply.github.com> Date: Thu, 16 Jan 2025 15:07:44 +0100 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: eladyn <59307989+eladyn@users.noreply.github.com> --- src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.rs b/src/config.rs index 3b91c73d..76be0b30 100644 --- a/src/config.rs +++ b/src/config.rs @@ -341,7 +341,7 @@ fn format_features_info() -> String { let backends = get_enabled_backends(); let features_str = if features.is_empty() { - "No features enabled".to_string() + "none".to_string() } else { features.join(", ") };