Formatting and CI
Some checks failed
CI / check (push) Failing after 10s

This commit is contained in:
Connor Johnstone
2026-03-18 15:37:30 -04:00
parent 1b7c10ea9e
commit 82c82ae46a
16 changed files with 154 additions and 27 deletions

21
.gitea/workflows/ci.yml Normal file
View File

@@ -0,0 +1,21 @@
name: CI
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: dtolnay/rust-toolchain@stable
- run: cargo fmt --check
- run: cargo clippy --workspace -- -D warnings
- run: cargo build --workspace
- run: cargo test --workspace

2
Cargo.lock generated
View File

@@ -2934,7 +2934,9 @@ dependencies = [
"dirs", "dirs",
"serde", "serde",
"serde_yaml", "serde_yaml",
"tempfile",
"tracing", "tracing",
"tracing-subscriber",
] ]
[[package]] [[package]]

26
justfile Normal file
View File

@@ -0,0 +1,26 @@
default:
@just --list
build:
cargo build --workspace
test:
cargo test --workspace
lint:
cargo clippy --workspace -- -D warnings
fmt:
cargo fmt
check: fmt lint test
run:
cargo run --bin shanty
frontend:
cd shanty-web/frontend && trunk build
dev: frontend run
ci: check build

2
rust-toolchain.toml Normal file
View File

@@ -0,0 +1,2 @@
[toolchain]
channel = "stable"

View File

@@ -9,3 +9,7 @@ serde = { workspace = true }
serde_yaml = "0.9" serde_yaml = "0.9"
dirs = "6" dirs = "6"
tracing = { workspace = true } tracing = { workspace = true }
[dev-dependencies]
tempfile = "3"
tracing-subscriber = { workspace = true }

View File

@@ -164,15 +164,33 @@ fn default_organization_format() -> String {
"{artist}/{album}/{track_number} - {title}.{ext}".to_string() "{artist}/{album}/{track_number} - {title}.{ext}".to_string()
} }
fn default_port() -> u16 { 8085 } fn default_port() -> u16 {
fn default_bind() -> String { "0.0.0.0".to_string() } 8085
fn default_confidence() -> f64 { 0.8 } }
fn default_format() -> String { "opus".to_string() } fn default_bind() -> String {
fn default_search_source() -> String { "ytmusic".to_string() } "0.0.0.0".to_string()
fn default_true() -> bool { true } }
fn default_rate_limit() -> u32 { 450 } fn default_confidence() -> f64 {
fn default_rate_limit_auth() -> u32 { 1800 } 0.8
fn default_concurrency() -> usize { 4 } }
fn default_format() -> String {
"opus".to_string()
}
fn default_search_source() -> String {
"ytmusic".to_string()
}
fn default_true() -> bool {
true
}
fn default_rate_limit() -> u32 {
450
}
fn default_rate_limit_auth() -> u32 {
1800
}
fn default_concurrency() -> usize {
4
}
// --- Loading and Saving --- // --- Loading and Saving ---
@@ -223,8 +241,8 @@ impl AppConfig {
std::fs::create_dir_all(parent) std::fs::create_dir_all(parent)
.map_err(|e| format!("failed to create config directory: {e}"))?; .map_err(|e| format!("failed to create config directory: {e}"))?;
} }
let yaml = serde_yaml::to_string(self) let yaml =
.map_err(|e| format!("failed to serialize config: {e}"))?; serde_yaml::to_string(self).map_err(|e| format!("failed to serialize config: {e}"))?;
std::fs::write(&config_path, yaml) std::fs::write(&config_path, yaml)
.map_err(|e| format!("failed to write config to {}: {e}", config_path.display()))?; .map_err(|e| format!("failed to write config to {}: {e}", config_path.display()))?;
tracing::info!(path = %config_path.display(), "config saved"); tracing::info!(path = %config_path.display(), "config saved");
@@ -241,11 +259,11 @@ impl AppConfig {
if let Ok(v) = std::env::var("SHANTY_DOWNLOAD_PATH") { if let Ok(v) = std::env::var("SHANTY_DOWNLOAD_PATH") {
config.download_path = PathBuf::from(v); config.download_path = PathBuf::from(v);
} }
if let Ok(v) = std::env::var("SHANTY_WEB_PORT") { if let Ok(v) = std::env::var("SHANTY_WEB_PORT")
if let Ok(port) = v.parse() { && let Ok(port) = v.parse()
{
config.web.port = port; config.web.port = port;
} }
}
if let Ok(v) = std::env::var("SHANTY_WEB_BIND") { if let Ok(v) = std::env::var("SHANTY_WEB_BIND") {
config.web.bind = v; config.web.bind = v;
} }

View File

@@ -0,0 +1,55 @@
use shanty_config::AppConfig;
#[test]
fn test_default_config() {
let config = AppConfig::default();
assert_eq!(config.web.port, 8085);
assert_eq!(config.web.bind, "0.0.0.0");
assert_eq!(config.tagging.confidence, 0.8);
assert!(config.tagging.write_tags);
assert!(!config.tagging.auto_tag);
assert_eq!(config.download.format, "opus");
assert_eq!(config.download.search_source, "ytmusic");
assert_eq!(config.download.rate_limit, 450);
assert_eq!(config.download.rate_limit_auth, 1800);
assert_eq!(config.indexing.concurrency, 4);
assert!(config.allowed_secondary_types.is_empty());
}
#[test]
fn test_load_missing_file() {
// Loading from a nonexistent path should return defaults
let config = AppConfig::load(Some("/tmp/shanty-test-nonexistent-config.yaml"));
assert_eq!(config.web.port, 8085);
}
#[test]
fn test_save_and_load_roundtrip() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("config.yaml");
let path_str = path.to_string_lossy().to_string();
let mut config = AppConfig::default();
config.web.port = 9999;
config.tagging.confidence = 0.95;
config.download.format = "flac".to_string();
config.indexing.concurrency = 8;
config.save(Some(&path_str)).unwrap();
let loaded = AppConfig::load(Some(&path_str));
assert_eq!(loaded.web.port, 9999);
assert_eq!(loaded.tagging.confidence, 0.95);
assert_eq!(loaded.download.format, "flac");
assert_eq!(loaded.indexing.concurrency, 8);
}
#[test]
fn test_config_path_resolution() {
let path = AppConfig::config_path(Some("/custom/path.yaml"));
assert_eq!(path.to_string_lossy(), "/custom/path.yaml");
// Default path should end with config.yaml
let default = AppConfig::config_path(None);
assert!(default.to_string_lossy().ends_with("config.yaml"));
}

View File

@@ -1,5 +1,5 @@
use actix_cors::Cors; use actix_cors::Cors;
use actix_web::{web, App, HttpServer}; use actix_web::{App, HttpServer, web};
use clap::Parser; use clap::Parser;
use tracing_actix_web::TracingLogger; use tracing_actix_web::TracingLogger;
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
@@ -79,9 +79,8 @@ async fn main() -> anyhow::Result<()> {
static_dir static_dir
} else { } else {
// Check next to shanty-web crate root (for development) // Check next to shanty-web crate root (for development)
let dev_path = std::path::PathBuf::from( let dev_path =
concat!(env!("CARGO_MANIFEST_DIR"), "/shanty-web/static"), std::path::PathBuf::from(concat!(env!("CARGO_MANIFEST_DIR"), "/shanty-web/static"));
);
if dev_path.is_dir() { if dev_path.is_dir() {
dev_path dev_path
} else { } else {