Skip to main content

perforce_cli/
lib.rs

1use std::path::{Path, PathBuf};
2
3use crate::cmd::Add;
4use crate::cmd::AdminEntry;
5#[cfg(not(feature = "lt2016_1"))]
6use crate::cmd::Aliases;
7use crate::cmd::Annotate;
8use crate::cmd::Archive;
9use crate::cmd::Attribute;
10use crate::cmd::Changes;
11use crate::cmd::Describe;
12use crate::cmd::Diff;
13use crate::cmd::Diff2;
14use crate::cmd::Edit;
15use crate::cmd::FileLog;
16use crate::cmd::Print;
17use crate::cmd::Sync;
18use crate::cmd::Where;
19use crate::global::GlobalOpts;
20
21pub mod cmd;
22pub mod global;
23pub mod spawn;
24
25pub mod prelude {
26    pub use crate::cmd::*;
27    pub use crate::global::*;
28    pub use crate::spawn::*;
29}
30
31#[derive(Debug, Clone)]
32pub struct P4Cli {
33    bin: PathBuf,
34
35    global_opts: GlobalOpts,
36}
37
38impl Default for P4Cli {
39    fn default() -> Self {
40        Self {
41            bin: PathBuf::from("p4"),
42            global_opts: GlobalOpts::default(),
43        }
44    }
45}
46
47impl P4Cli {
48    /// Create a new Perforce command-line client.
49    ///
50    /// `bin` is the path to the Perforce command-line executable.
51    pub fn new(bin: impl Into<PathBuf>, global_opts: GlobalOpts) -> Self {
52        Self {
53            bin: bin.into(),
54            global_opts,
55        }
56    }
57
58    /// Set the Perforce command path.
59    pub fn bin(mut self, bin: impl Into<PathBuf>) -> Self {
60        self.set_bin(bin);
61        self
62    }
63
64    /// Set the global options.
65    pub fn global_opts(mut self, global_opts: GlobalOpts) -> Self {
66        self.set_global_opts(global_opts);
67        self
68    }
69
70    /// Get the Perforce command path.
71    pub fn get_bin(&self) -> &Path {
72        &self.bin
73    }
74
75    /// Get the global options.
76    pub fn get_global_opts(&self) -> &GlobalOpts {
77        &self.global_opts
78    }
79
80    /// Set the Perforce command path.
81    pub fn set_bin(&mut self, bin: impl Into<PathBuf>) {
82        self.bin = bin.into();
83    }
84
85    /// Set the global options.
86    pub fn set_global_opts(&mut self, global_opts: GlobalOpts) {
87        self.global_opts = global_opts;
88    }
89
90    /// Open files in a client workspace for addition to the depot.
91    pub fn add(&self) -> Add {
92        Add::new(self.bin.clone(), self.global_opts.clone())
93    }
94
95    /// Perform administrative operations on the server.
96    pub fn admin(&self) -> AdminEntry {
97        AdminEntry::new(self.bin.clone(), self.global_opts.clone())
98    }
99
100    /// Display command aliases that are currently defined in a .p4aliases file.
101    #[cfg(not(feature = "lt2016_1"))]
102    pub fn aliases(&self) -> Aliases {
103        Aliases::new(self.bin.clone(), self.global_opts.clone())
104    }
105
106    /// Print file lines along with their revisions.
107    pub fn annotate(&self) -> Annotate {
108        Annotate::new(self.bin.clone(), self.global_opts.clone())
109    }
110
111    /// Archive obsolete revisions to an archive depot.
112    pub fn archive(&self) -> Archive {
113        Archive::new(self.bin.clone(), self.global_opts.clone())
114    }
115
116    /// Set per-revision attributes on file revisions.
117    pub fn attribute(&self) -> Attribute {
118        Attribute::new(self.bin.clone(), self.global_opts.clone())
119    }
120
121    /// List submitted and pending changelists.
122    pub fn changes(&self) -> Changes {
123        Changes::new(self.bin.clone(), self.global_opts.clone())
124    }
125
126    /// List submitted and pending changelists.
127    ///
128    /// This is an alias for [`Self::changes`], corresponding to the `p4
129    /// changelists` command.
130    pub fn changelists(&self) -> Changes {
131        Changes::new(self.bin.clone(), self.global_opts.clone())
132    }
133
134    /// Display the details of one or more changelists.
135    pub fn describe(&self) -> Describe {
136        Describe::new(self.bin.clone(), self.global_opts.clone())
137    }
138
139    /// Diff workspace content against depot content, or diff stream specs.
140    pub fn diff(&self) -> Diff {
141        Diff::new(self.bin.clone(), self.global_opts.clone())
142    }
143
144    /// Compare the content at two depot paths, or compare two stream specs.
145    pub fn diff2(&self) -> Diff2 {
146        Diff2::new(self.bin.clone(), self.global_opts.clone())
147    }
148
149    /// Open files in a client workspace for edit.
150    pub fn edit(&self) -> Edit {
151        Edit::new(self.bin.clone(), self.global_opts.clone())
152    }
153
154    /// Print detailed information about the revisions of files.
155    pub fn filelog(&self) -> FileLog {
156        FileLog::new(self.bin.clone(), self.global_opts.clone())
157    }
158
159    /// Print the contents of depot file revisions.
160    pub fn print(&self) -> Print {
161        Print::new(self.bin.clone(), self.global_opts.clone())
162    }
163
164    /// Update the client workspace to reflect the contents of the depot.
165    pub fn sync(&self) -> Sync {
166        Sync::new(self.bin.clone(), self.global_opts.clone())
167    }
168
169    /// Show where a particular file is located, as determined by the client view.
170    pub fn r#where(&self) -> Where {
171        Where::new(self.bin.clone(), self.global_opts.clone())
172    }
173}
174
175#[cfg(test)]
176mod tests {
177    use super::*;
178
179    #[test]
180    fn default_uses_p4_from_path() {
181        let p4 = P4Cli::default();
182
183        assert_eq!(p4.get_bin(), Path::new("p4"));
184    }
185
186    #[test]
187    fn accepts_custom_bin_path() {
188        let p4 = P4Cli::new("C:\\tools\\p4.exe", GlobalOpts::default());
189
190        assert_eq!(p4.get_bin(), Path::new("C:\\tools\\p4.exe"));
191    }
192}