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        let commit_range = self.commit_range.as_deref().unwrap_or("HEAD");
25
26        // Open git repository
27        let repo = GitRepository::open()
28            .context("Failed to open git repository. Make sure you're in a git repository.")?;
29
30        // Get working directory status
31        let wd_status = repo.get_working_directory_status()?;
32        let working_directory = WorkingDirectoryInfo {
33            clean: wd_status.clean,
34            untracked_changes: wd_status
35                .untracked_changes
36                .into_iter()
37                .map(|fs| FileStatusInfo {
38                    status: fs.status,
39                    file: fs.file,
40                })
41                .collect(),
42        };
43
44        // Get remote information
45        let remotes = RemoteInfo::get_all_remotes(repo.repository())?;
46
47        // Parse commit range and get commits
48        let commits = repo.get_commits_in_range(commit_range)?;
49
50        // Create version information
51        let versions = Some(VersionInfo {
52            omni_dev: env!("CARGO_PKG_VERSION").to_string(),
53        });
54
55        // Get AI scratch directory
56        let ai_scratch_path =
57            ai_scratch::get_ai_scratch_dir().context("Failed to determine AI scratch directory")?;
58        let ai_info = AiInfo {
59            scratch: ai_scratch_path.to_string_lossy().to_string(),
60        };
61
62        // Build repository view
63        let mut repo_view = RepositoryView {
64            versions,
65            explanation: FieldExplanation::default(),
66            working_directory,
67            remotes,
68            ai: ai_info,
69            branch_info: None,
70            pr_template: None,
71            pr_template_location: None,
72            branch_prs: None,
73            commits,
74        };
75
76        // Update field presence based on actual data
77        repo_view.update_field_presence();
78
79        // Output as YAML
80        let yaml_output = crate::data::to_yaml(&repo_view)?;
81        println!("{}", yaml_output);
82
83        Ok(())
84    }
85}