use std::path::{Path, PathBuf};
use anyhow::{Context, Result};
use scrybe_application::{ConfigService, ScrybeApplication, StorageRoot};
use scrybe_core::config::Config;
pub fn expand_root(root: &Path) -> PathBuf {
scrybe_application::recording::expand_tilde(root, dirs_home().as_deref())
}
fn dirs_home() -> Option<PathBuf> {
directories::BaseDirs::new().map(|b| b.home_dir().to_path_buf())
}
pub fn config_service() -> Result<ConfigService> {
Ok(ConfigService::new(
Config::discover_path().context("resolving config path")?,
))
}
pub fn application(root_override: Option<&Path>) -> Result<ScrybeApplication> {
let config = config_service()?;
let path = match root_override {
Some(path) => expand_root(path),
None => expand_root(&config.load()?.storage.root),
};
Ok(ScrybeApplication::new(
StorageRoot::new(path),
config.path(),
))
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
use std::sync::Arc;
#[test]
fn test_expand_root_returns_input_path_for_absolute_path() {
let p = PathBuf::from("/var/scrybe");
let expanded = expand_root(&p);
assert_eq!(expanded, p);
}
#[test]
fn test_expand_root_returns_input_path_for_relative_path() {
let p = PathBuf::from("relative/dir");
let expanded = expand_root(&p);
assert_eq!(expanded, p);
}
#[test]
fn test_expand_root_substitutes_tilde_prefix_with_home() {
let p = PathBuf::from("~/scrybe");
let expanded = expand_root(&p);
if let Some(home) = dirs_home() {
assert_eq!(expanded, home.join("scrybe"));
}
}
#[test]
fn test_expand_root_returns_home_for_bare_tilde() {
let p = PathBuf::from("~");
let expanded = expand_root(&p);
if let Some(home) = dirs_home() {
assert_eq!(expanded, home);
}
}
#[test]
fn test_the_application_is_the_only_source_of_a_recording_controller() {
let dir = tempfile::tempdir().unwrap();
let app = application(Some(dir.path())).unwrap();
let from_cli = Arc::clone(app.recording());
assert!(Arc::ptr_eq(&from_cli, app.recording()));
from_cli.begin_preparing().unwrap();
assert_eq!(
app.recording().snapshot().state,
scrybe_application::recording::RecordingState::Preparing,
"a second instance would leave the application reading Idle forever"
);
}
#[test]
fn test_the_config_service_returns_the_default_when_no_file_exists() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("no-such-config.toml");
std::env::set_var("SCRYBE_CONFIG", &path);
let service = config_service().unwrap();
assert_eq!(service.path(), path);
assert_eq!(
service.load().unwrap(),
scrybe_core::config::Config::default()
);
}
}