Skip to main content

omni_dev/cli/git/
view.rs

1//! View command — outputs repository information in YAML format.
2
3use anyhow::{Context, Result};
4use clap::Parser;
5
6/// View command options.
7#[derive(Parser)]
8pub struct ViewCommand {
9    /// Commit range to analyze (e.g., HEAD~3..HEAD, abc123..def456).
10    #[arg(value_name = "COMMIT_RANGE")]
11    pub commit_range: Option<String>,
12}
13
14impl ViewCommand {
15    /// Executes the view command.
16    pub fn execute(self) -> Result<()> {
17        use crate::data::{
18            AiInfo, FieldExplanation, FileStatusInfo, RepositoryView, VersionInfo,
19            WorkingDirectoryInfo,
20        };
21        use crate::git::{GitRepository, RemoteInfo};
22        use crate::utils::ai_scratch;
23
24        // Preflight check: validate git repository before any processing
25        crate::utils::check_git_repository()?;
26
27        let commit_range = self.commit_range.as_deref().unwrap_or("HEAD");
28
29        // Open git repository
30        let repo = GitRepository::open()
31            .context("Failed to open git repository. Make sure you're in a git repository.")?;
32
33        // Get working directory status
34        let wd_status = repo.get_working_directory_status()?;
35        let working_directory = WorkingDirectoryInfo {
36            clean: wd_status.clean,
37            untracked_changes: wd_status
38                .untracked_changes
39                .into_iter()
40                .map(|fs| FileStatusInfo {
41                    status: fs.status,
42                    file: fs.file,
43                })
44                .collect(),
45        };
46
47        // Get remote information
48        let remotes = RemoteInfo::get_all_remotes(repo.repository())?;
49
50        // Parse commit range and get commits
51        let commits = repo.get_commits_in_range(commit_range)?;
52
53        // Create version information
54        let versions = Some(VersionInfo {
55            omni_dev: env!("CARGO_PKG_VERSION").to_string(),
56        });
57
58        // Get AI scratch directory
59        let ai_scratch_path =
60            ai_scratch::get_ai_scratch_dir().context("Failed to determine AI scratch directory")?;
61        let ai_info = AiInfo {
62            scratch: ai_scratch_path.to_string_lossy().to_string(),
63        };
64
65        // Build repository view
66        let mut repo_view = RepositoryView {
67            versions,
68            explanation: FieldExplanation::default(),
69            working_directory,
70            remotes,
71            ai: ai_info,
72            branch_info: None,
73            pr_template: None,
74            pr_template_location: None,
75            branch_prs: None,
76            commits,
77        };
78
79        let yaml_output = repo_view.to_yaml_output()?;
80        println!("{yaml_output}");
81
82        Ok(())
83    }
84}