capo_agent/session/
paths.rs1#![cfg_attr(test, allow(clippy::expect_used, clippy::unwrap_used))]
2
3use std::path::{Path, PathBuf};
6
7use crate::error::{AppError, Result};
8use crate::session::encode_cwd;
9
10#[derive(Debug, Clone)]
12pub struct SessionPaths {
13 pub agent_dir: PathBuf,
15 pub bucket_dir: PathBuf,
18}
19
20impl SessionPaths {
21 pub fn for_cwd(agent_dir: PathBuf, cwd: &Path) -> Self {
23 let bucket_dir = agent_dir.join("sessions").join(encode_cwd(cwd));
24 Self {
25 agent_dir,
26 bucket_dir,
27 }
28 }
29
30 pub fn ensure_bucket(&self) -> Result<()> {
32 std::fs::create_dir_all(&self.bucket_dir).map_err(|err| {
33 AppError::Config(format!(
34 "failed to create {}: {err}",
35 self.bucket_dir.display()
36 ))
37 })
38 }
39
40 pub fn sessions_root(&self) -> PathBuf {
42 self.agent_dir.join("sessions")
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49 use tempfile::tempdir;
50
51 #[test]
52 fn for_cwd_produces_encoded_bucket() {
53 let agent = PathBuf::from("/x/agent");
54 let cwd = PathBuf::from("/Users/wade/proj/capo");
55 let p = SessionPaths::for_cwd(agent.clone(), &cwd);
56 assert_eq!(p.agent_dir, agent);
57 assert_eq!(
58 p.bucket_dir,
59 PathBuf::from("/x/agent/sessions/--Users-wade-proj-capo--")
60 );
61 }
62
63 #[test]
64 fn ensure_bucket_creates_nested_dirs() {
65 let dir = tempdir().unwrap();
66 let p = SessionPaths::for_cwd(dir.path().to_path_buf(), &PathBuf::from("/tmp/x"));
67 assert!(!p.bucket_dir.exists());
68 p.ensure_bucket().unwrap();
69 assert!(p.bucket_dir.exists());
70 }
71}