This commit is contained in:
21
.gitea/workflows/ci.yml
Normal file
21
.gitea/workflows/ci.yml
Normal 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
2
Cargo.lock
generated
@@ -2934,7 +2934,9 @@ dependencies = [
|
||||
"dirs",
|
||||
"serde",
|
||||
"serde_yaml",
|
||||
"tempfile",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
26
justfile
Normal file
26
justfile
Normal 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
2
rust-toolchain.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "stable"
|
||||
@@ -9,3 +9,7 @@ serde = { workspace = true }
|
||||
serde_yaml = "0.9"
|
||||
dirs = "6"
|
||||
tracing = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3"
|
||||
tracing-subscriber = { workspace = true }
|
||||
|
||||
@@ -164,15 +164,33 @@ fn default_organization_format() -> String {
|
||||
"{artist}/{album}/{track_number} - {title}.{ext}".to_string()
|
||||
}
|
||||
|
||||
fn default_port() -> u16 { 8085 }
|
||||
fn default_bind() -> String { "0.0.0.0".to_string() }
|
||||
fn default_confidence() -> f64 { 0.8 }
|
||||
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 }
|
||||
fn default_port() -> u16 {
|
||||
8085
|
||||
}
|
||||
fn default_bind() -> String {
|
||||
"0.0.0.0".to_string()
|
||||
}
|
||||
fn default_confidence() -> f64 {
|
||||
0.8
|
||||
}
|
||||
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 ---
|
||||
|
||||
@@ -223,8 +241,8 @@ impl AppConfig {
|
||||
std::fs::create_dir_all(parent)
|
||||
.map_err(|e| format!("failed to create config directory: {e}"))?;
|
||||
}
|
||||
let yaml = serde_yaml::to_string(self)
|
||||
.map_err(|e| format!("failed to serialize config: {e}"))?;
|
||||
let yaml =
|
||||
serde_yaml::to_string(self).map_err(|e| format!("failed to serialize config: {e}"))?;
|
||||
std::fs::write(&config_path, yaml)
|
||||
.map_err(|e| format!("failed to write config to {}: {e}", config_path.display()))?;
|
||||
tracing::info!(path = %config_path.display(), "config saved");
|
||||
@@ -241,11 +259,11 @@ impl AppConfig {
|
||||
if let Ok(v) = std::env::var("SHANTY_DOWNLOAD_PATH") {
|
||||
config.download_path = PathBuf::from(v);
|
||||
}
|
||||
if let Ok(v) = std::env::var("SHANTY_WEB_PORT") {
|
||||
if let Ok(port) = v.parse() {
|
||||
if let Ok(v) = std::env::var("SHANTY_WEB_PORT")
|
||||
&& let Ok(port) = v.parse()
|
||||
{
|
||||
config.web.port = port;
|
||||
}
|
||||
}
|
||||
if let Ok(v) = std::env::var("SHANTY_WEB_BIND") {
|
||||
config.web.bind = v;
|
||||
}
|
||||
|
||||
55
shanty-config/tests/integration.rs
Normal file
55
shanty-config/tests/integration.rs
Normal 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"));
|
||||
}
|
||||
Submodule shanty-db updated: 37410ce216...c6452609d6
Submodule shanty-dl updated: a57df38eb1...2592651c9a
Submodule shanty-index updated: 1d1674e3a1...3494de1133
Submodule shanty-org updated: 3159ee51ad...a2152cbf8d
Submodule shanty-search updated: d09557d953...d358b79a6b
Submodule shanty-tag updated: 4400cbc1cb...5957d69e7d
Submodule shanty-watch updated: 3d01fa85c9...0b336789da
Submodule shanty-web updated: 1f36374394...93392db27c
@@ -1,5 +1,5 @@
|
||||
use actix_cors::Cors;
|
||||
use actix_web::{web, App, HttpServer};
|
||||
use actix_web::{App, HttpServer, web};
|
||||
use clap::Parser;
|
||||
use tracing_actix_web::TracingLogger;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
@@ -79,9 +79,8 @@ async fn main() -> anyhow::Result<()> {
|
||||
static_dir
|
||||
} else {
|
||||
// Check next to shanty-web crate root (for development)
|
||||
let dev_path = std::path::PathBuf::from(
|
||||
concat!(env!("CARGO_MANIFEST_DIR"), "/shanty-web/static"),
|
||||
);
|
||||
let dev_path =
|
||||
std::path::PathBuf::from(concat!(env!("CARGO_MANIFEST_DIR"), "/shanty-web/static"));
|
||||
if dev_path.is_dir() {
|
||||
dev_path
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user