Skip to main content

ito_common/
paths.rs

1//! Canonical Ito path builders.
2//!
3//! These helpers consistently build paths under an Ito root directory.
4
5use std::path::{Path, PathBuf};
6
7/// Canonical `.ito/` path builders.
8///
9/// These helpers intentionally take a `ito_path` (the configured ito root directory)
10/// so callers do not duplicate `.join("changes")`, `.join("modules")`, or ad-hoc
11/// string-based path formatting.
12pub fn default_ito_root(workspace_root: &Path) -> PathBuf {
13    workspace_root.join(".ito")
14}
15
16/// Return the `changes/` directory under the Ito root.
17pub fn changes_dir(ito_path: &Path) -> PathBuf {
18    ito_path.join("changes")
19}
20
21/// Return the on-disk directory for a specific change.
22pub fn change_dir(ito_path: &Path, change_id: &str) -> PathBuf {
23    changes_dir(ito_path).join(change_id)
24}
25
26/// Return the path to a change's metadata file.
27pub fn change_meta_path(ito_path: &Path, change_id: &str) -> PathBuf {
28    change_dir(ito_path, change_id).join(".ito.yaml")
29}
30
31/// Return the `specs/` directory within a change directory.
32pub fn change_specs_dir(ito_path: &Path, change_id: &str) -> PathBuf {
33    change_dir(ito_path, change_id).join("specs")
34}
35
36/// Return the archive directory for changes (`changes/archive/`).
37pub fn changes_archive_dir(ito_path: &Path) -> PathBuf {
38    changes_dir(ito_path).join("archive")
39}
40
41/// Return the directory used by `ito archive` for archived change artifacts.
42pub fn archive_changes_dir(ito_path: &Path) -> PathBuf {
43    ito_path.join("archive").join("changes")
44}
45
46/// Return the `modules/` directory under the Ito root.
47pub fn modules_dir(ito_path: &Path) -> PathBuf {
48    ito_path.join("modules")
49}
50
51/// Return the `specs/` directory under the Ito root.
52pub fn specs_dir(ito_path: &Path) -> PathBuf {
53    ito_path.join("specs")
54}
55
56/// Return the canonical path to a spec's markdown file (`spec.md`).
57pub fn spec_markdown_path(ito_path: &Path, spec_id: &str) -> PathBuf {
58    specs_dir(ito_path).join(spec_id).join("spec.md")
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64
65    #[test]
66    fn default_ito_root_is_dot_ito() {
67        let root = PathBuf::from("/repo");
68        assert_eq!(default_ito_root(&root), PathBuf::from("/repo/.ito"));
69    }
70
71    #[test]
72    fn builders_join_expected_paths() {
73        let ito = PathBuf::from("/repo/.ito");
74
75        assert_eq!(changes_dir(&ito), PathBuf::from("/repo/.ito/changes"));
76        assert_eq!(
77            change_dir(&ito, "001-01_test"),
78            PathBuf::from("/repo/.ito/changes/001-01_test")
79        );
80        assert_eq!(
81            change_meta_path(&ito, "001-01_test"),
82            PathBuf::from("/repo/.ito/changes/001-01_test/.ito.yaml")
83        );
84        assert_eq!(
85            change_specs_dir(&ito, "001-01_test"),
86            PathBuf::from("/repo/.ito/changes/001-01_test/specs")
87        );
88        assert_eq!(
89            changes_archive_dir(&ito),
90            PathBuf::from("/repo/.ito/changes/archive")
91        );
92        assert_eq!(
93            archive_changes_dir(&ito),
94            PathBuf::from("/repo/.ito/archive/changes")
95        );
96        assert_eq!(modules_dir(&ito), PathBuf::from("/repo/.ito/modules"));
97        assert_eq!(specs_dir(&ito), PathBuf::from("/repo/.ito/specs"));
98        assert_eq!(
99            spec_markdown_path(&ito, "cli-tasks"),
100            PathBuf::from("/repo/.ito/specs/cli-tasks/spec.md")
101        );
102    }
103}