Skip to main content

git_spawn/command/
ls_tree.rs

1//! `git ls-tree` — list the contents of a tree object.
2
3use crate::command::{CommandExecutor, CommandOutput, GitCommand};
4use crate::error::{Error, Result};
5use async_trait::async_trait;
6
7/// Builder for `git ls-tree`.
8#[derive(Debug, Clone, Default)]
9pub struct LsTreeCommand {
10    /// Shared executor.
11    pub executor: CommandExecutor,
12    /// Tree-ish to list.
13    pub tree: Option<String>,
14    /// `-r` recurse into subtrees.
15    pub recurse: bool,
16    /// `-t` show trees even with `-r`.
17    pub show_trees: bool,
18    /// `-d` show only trees.
19    pub trees_only: bool,
20    /// `-l` include object size for blobs.
21    pub long: bool,
22    /// `--name-only`.
23    pub name_only: bool,
24    /// `--full-tree`.
25    pub full_tree: bool,
26    /// Pathspecs.
27    pub paths: Vec<String>,
28}
29
30impl LsTreeCommand {
31    /// New command with the given tree-ish.
32    pub fn new(tree: impl Into<String>) -> Self {
33        Self {
34            tree: Some(tree.into()),
35            ..Self::default()
36        }
37    }
38
39    /// `-r`.
40    pub fn recurse(&mut self) -> &mut Self {
41        self.recurse = true;
42        self
43    }
44
45    /// `-t`.
46    pub fn show_trees(&mut self) -> &mut Self {
47        self.show_trees = true;
48        self
49    }
50
51    /// `-d`.
52    pub fn trees_only(&mut self) -> &mut Self {
53        self.trees_only = true;
54        self
55    }
56
57    /// `-l`.
58    pub fn long(&mut self) -> &mut Self {
59        self.long = true;
60        self
61    }
62
63    /// `--name-only`.
64    pub fn name_only(&mut self) -> &mut Self {
65        self.name_only = true;
66        self
67    }
68
69    /// `--full-tree`.
70    pub fn full_tree(&mut self) -> &mut Self {
71        self.full_tree = true;
72        self
73    }
74
75    /// Filter by path.
76    pub fn path(&mut self, p: impl Into<String>) -> &mut Self {
77        self.paths.push(p.into());
78        self
79    }
80}
81
82#[async_trait]
83impl GitCommand for LsTreeCommand {
84    type Output = CommandOutput;
85    fn get_executor(&self) -> &CommandExecutor {
86        &self.executor
87    }
88    fn get_executor_mut(&mut self) -> &mut CommandExecutor {
89        &mut self.executor
90    }
91    fn build_command_args(&self) -> Vec<String> {
92        let mut args = vec!["ls-tree".to_string()];
93        if self.recurse {
94            args.push("-r".into());
95        }
96        if self.show_trees {
97            args.push("-t".into());
98        }
99        if self.trees_only {
100            args.push("-d".into());
101        }
102        if self.long {
103            args.push("-l".into());
104        }
105        if self.name_only {
106            args.push("--name-only".into());
107        }
108        if self.full_tree {
109            args.push("--full-tree".into());
110        }
111        if let Some(t) = &self.tree {
112            args.push(t.clone());
113        }
114        args.extend(self.paths.iter().cloned());
115        args
116    }
117    async fn execute(&self) -> Result<CommandOutput> {
118        if self.tree.is_none() {
119            return Err(Error::invalid_config(
120                "ls-tree requires a tree-ish argument",
121            ));
122        }
123        self.execute_raw().await
124    }
125}