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