Skip to main content

steer_workspace/utils/
environment.rs

1use std::path::Path;
2
3/// Common environment utilities for workspaces
4pub struct EnvironmentUtils;
5
6impl EnvironmentUtils {
7    /// Get the current platform string
8    pub fn get_platform() -> &'static str {
9        if cfg!(target_os = "windows") {
10            "windows"
11        } else if cfg!(target_os = "macos") {
12            "macos"
13        } else if cfg!(target_os = "linux") {
14            "linux"
15        } else {
16            "unknown"
17        }
18    }
19
20    /// Get the current date in YYYY-MM-DD format
21    pub fn get_current_date() -> String {
22        use chrono::Local;
23        Local::now().format("%Y-%m-%d").to_string()
24    }
25
26    /// Check if a directory is a git repository
27    pub fn is_git_repo(path: &Path) -> bool {
28        gix::discover(path).is_ok()
29    }
30
31    /// Read README.md if it exists
32    pub fn read_readme(path: &Path) -> Option<String> {
33        let readme_path = path.join("README.md");
34        std::fs::read_to_string(readme_path).ok()
35    }
36
37    /// Read AGENTS.md if it exists, otherwise fall back to CLAUDE.md.
38    pub fn read_memory_file(path: &Path) -> Option<(String, String)> {
39        const PRIMARY_MEMORY_FILE_NAME: &str = "AGENTS.md";
40        const FALLBACK_MEMORY_FILE_NAME: &str = "CLAUDE.md";
41
42        let agents_path = path.join(PRIMARY_MEMORY_FILE_NAME);
43        if let Ok(content) = std::fs::read_to_string(agents_path) {
44            return Some((PRIMARY_MEMORY_FILE_NAME.to_string(), content));
45        }
46
47        let claude_path = path.join(FALLBACK_MEMORY_FILE_NAME);
48        std::fs::read_to_string(claude_path)
49            .ok()
50            .map(|content| (FALLBACK_MEMORY_FILE_NAME.to_string(), content))
51    }
52
53    /// Read AGENTS.md (preferred) or CLAUDE.md and return only the content.
54    pub fn read_claude_md(path: &Path) -> Option<String> {
55        Self::read_memory_file(path).map(|(_, content)| content)
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62    use tempfile::tempdir;
63
64    #[test]
65    fn test_platform_detection() {
66        let platform = EnvironmentUtils::get_platform();
67        assert!(["windows", "macos", "linux", "unknown"].contains(&platform));
68    }
69
70    #[test]
71    fn test_date_format() {
72        let date = EnvironmentUtils::get_current_date();
73        // Basic check for YYYY-MM-DD format
74        assert_eq!(date.len(), 10);
75        assert_eq!(date.chars().nth(4), Some('-'));
76        assert_eq!(date.chars().nth(7), Some('-'));
77    }
78
79    #[test]
80    fn test_git_repo_detection() {
81        let temp_dir = tempdir().unwrap();
82        assert!(!EnvironmentUtils::is_git_repo(temp_dir.path()));
83
84        // Create a git repo
85        gix::init(temp_dir.path()).unwrap();
86        assert!(EnvironmentUtils::is_git_repo(temp_dir.path()));
87    }
88}