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