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