1use std::{
2 ffi::OsStr,
3 path::{Path, PathBuf},
4 process::{Child, Command, Stdio},
5};
6
7use super::{DiffOptions, ExclusiveOption, SubCommand, Unselected};
8
9use crate::global::GlobalOpts;
10use crate::spawn::ParameterizedSpawn;
11
12#[derive(Debug, Clone, Copy, Default)]
17pub struct ShortSummaryMode;
18
19impl ExclusiveOption for ShortSummaryMode {
20 fn inject_args(&self, command: &mut Command) {
21 command.arg("-s");
22 }
23}
24
25#[cfg_attr(
26 feature = "lt2017_2",
27 doc = "Detail diff output of `p4 describe` (`-d`).",
28 doc = "",
29 doc = "Entered with [`Describe::diff_options`]."
30)]
31#[cfg_attr(
32 not(feature = "lt2017_2"),
33 doc = "Detail diff output of `p4 describe` (`-a` and `-d`).",
34 doc = "",
35 doc = "Entered with [`Describe::display_added_text_content`] or",
36 doc = "[`Describe::diff_options`]."
37)]
38#[derive(Debug, Clone, Default)]
39pub struct DetailDiffMode {
40 diff_options: Option<DiffOptions>,
41
42 #[cfg(not(feature = "lt2017_2"))]
43 display_added_text_content: bool,
44}
45
46impl ExclusiveOption for DetailDiffMode {
47 fn inject_args(&self, command: &mut Command) {
48 #[cfg(not(feature = "lt2017_2"))]
49 if self.display_added_text_content {
50 command.arg("-a");
51 }
52
53 if let Some(diff_options) = &self.diff_options {
54 diff_options.inject_arg(command);
55 }
56 }
57}
58
59#[cfg_attr(
60 feature = "lt2014_2",
61 doc = "`p4 [g-opts] describe [ -dflags -s -S -f -O ] changelist...`"
62)]
63#[cfg_attr(
64 all(feature = "lt2015_1", not(feature = "lt2014_2")),
65 doc = "`p4 [g-opts] describe [ -doptions -s -S -f -O ] changelist...`"
66)]
67#[cfg_attr(
68 all(feature = "lt2015_2", not(feature = "lt2015_1")),
69 doc = "`p4 [g-opts] describe [-doptions] [-s -S -f -O] changelist …`"
70)]
71#[cfg_attr(
72 all(feature = "lt2016_1", not(feature = "lt2015_2")),
73 doc = "`p4 [g-opts] describe [-doptions] [-s -S -f -O -I] changelist …`"
74)]
75#[cfg_attr(
76 all(feature = "lt2017_1", not(feature = "lt2016_1")),
77 doc = "`p4 [g-opts] describe [-doptions] [-s -S -f -O -I] changelist ...`"
78)]
79#[cfg_attr(
80 all(feature = "lt2017_2", not(feature = "lt2017_1")),
81 doc = "`p4 [g-opts] describe [-doptions] [-f -I -m -O -s -S] changelist ...`"
82)]
83#[cfg_attr(
84 not(feature = "lt2017_2"),
85 doc = "`p4 [g-opts] describe [-doptions] [-a -f -I -m -O -s -S] changelist ...`"
86)]
87#[cfg_attr(
89 feature = "lt2017_2",
90 doc = "Provides information about changelists and the changelists' files."
91)]
92#[cfg_attr(
93 all(feature = "lt2019_1", not(feature = "lt2017_2")),
94 doc = "Provides information about changelists and files in the changelists."
95)]
96#[cfg_attr(
97 not(feature = "lt2019_1"),
98 doc = "Provides information about changelists, as well as files in the",
99 doc = "changelists, and the path of the open stream, if a stream is open."
100)]
101#[cfg_attr(
102 all(feature = "lt2018_1", not(feature = "lt2017_2")),
103 doc = "",
104 doc = "# Note",
105 doc = "",
106 doc = "If the depot is of type `graph`, displays a commit description. See",
107 doc = "the command-line help for `p4 help-graph describe`."
108)]
109#[cfg_attr(
113 feature = "lt2017_2",
114 doc = "`-d`; [`Self::short_summary_output`] transitions to the [`ShortSummaryMode`] state, while [`Self::diff_options`] transitions to the [`DetailDiffMode`] state."
115)]
116#[cfg_attr(
117 not(feature = "lt2017_2"),
118 doc = "`-a`/`-d`; [`Self::short_summary_output`] transitions to the [`ShortSummaryMode`] state, while [`Self::display_added_text_content`] and [`Self::diff_options`] transition to the [`DetailDiffMode`] state."
119)]
120#[derive(Debug, Clone, Default)]
121pub struct Describe<M = Unselected> {
122 bin: PathBuf,
123
124 global_opts: GlobalOpts,
125
126 force_restricted: bool,
127
128 #[cfg(not(feature = "lt2015_2"))]
129 use_identity: bool,
130
131 #[cfg(not(feature = "lt2017_1"))]
132 limit: Option<u64>,
133
134 use_original_number: bool,
135
136 include_shelved_files: bool,
137
138 mode: M,
139}
140
141impl Describe<Unselected> {
142 pub fn new(bin: impl Into<PathBuf>, global_opts: GlobalOpts) -> Self {
146 Self {
147 bin: bin.into(),
148 global_opts,
149 force_restricted: false,
150 #[cfg(not(feature = "lt2015_2"))]
151 use_identity: false,
152 #[cfg(not(feature = "lt2017_1"))]
153 limit: None,
154 use_original_number: false,
155 include_shelved_files: false,
156 mode: Unselected,
157 }
158 }
159
160 #[cfg_attr(feature = "lt2017_1", doc = "the files' diffs.")]
166 #[cfg_attr(not(feature = "lt2017_1"), doc = "the diffs of the files.")]
167 pub fn short_summary_output(self) -> Describe<ShortSummaryMode> {
170 Describe {
171 bin: self.bin,
172 global_opts: self.global_opts,
173 force_restricted: self.force_restricted,
174 #[cfg(not(feature = "lt2015_2"))]
175 use_identity: self.use_identity,
176 #[cfg(not(feature = "lt2017_1"))]
177 limit: self.limit,
178 use_original_number: self.use_original_number,
179 include_shelved_files: self.include_shelved_files,
180 mode: ShortSummaryMode,
181 }
182 }
183
184 #[cfg(not(feature = "lt2017_2"))]
196 pub fn display_added_text_content(self, v: bool) -> Describe<DetailDiffMode> {
197 Describe {
198 bin: self.bin,
199 global_opts: self.global_opts,
200 force_restricted: self.force_restricted,
201 #[cfg(not(feature = "lt2015_2"))]
202 use_identity: self.use_identity,
203 #[cfg(not(feature = "lt2017_1"))]
204 limit: self.limit,
205 use_original_number: self.use_original_number,
206 include_shelved_files: self.include_shelved_files,
207 mode: DetailDiffMode {
208 diff_options: None,
209 display_added_text_content: v,
210 },
211 }
212 }
213
214 #[cfg_attr(feature = "lt2014_2", doc = "-dflags")]
217 #[cfg_attr(not(feature = "lt2014_2"), doc = "-doptions")]
218 #[cfg_attr(
221 feature = "lt2014_2",
222 doc = "flags. See the Usage Notes below for a flag listing."
223 )]
224 #[cfg_attr(
225 all(feature = "lt2015_1", not(feature = "lt2014_2")),
226 doc = "options. See the Usage Notes below for a option listing."
227 )]
228 #[cfg_attr(
229 all(feature = "lt2024_1", not(feature = "lt2015_1")),
230 doc = "options. See Usage Notes for an option listing."
231 )]
232 #[cfg_attr(
233 not(feature = "lt2024_1"),
234 doc = "options. See Usage notes for an option listing."
235 )]
236 pub fn diff_options(self, v: impl Into<DiffOptions>) -> Describe<DetailDiffMode> {
240 Describe {
241 bin: self.bin,
242 global_opts: self.global_opts,
243 force_restricted: self.force_restricted,
244 #[cfg(not(feature = "lt2015_2"))]
245 use_identity: self.use_identity,
246 #[cfg(not(feature = "lt2017_1"))]
247 limit: self.limit,
248 use_original_number: self.use_original_number,
249 include_shelved_files: self.include_shelved_files,
250 mode: DetailDiffMode {
251 diff_options: Some(v.into()),
252 #[cfg(not(feature = "lt2017_2"))]
253 display_added_text_content: false,
254 },
255 }
256 }
257}
258
259impl<M: ExclusiveOption, S, I> ParameterizedSpawn<(S,)> for Describe<M>
260where
261 S: IntoIterator<Item = I>,
262 I: AsRef<OsStr>,
263{
264 type Output = Child;
265 type Error = std::io::Error;
266
267 fn spawn_with(&mut self, (changelists,): (S,)) -> Result<Self::Output, Self::Error> {
271 self.setup_command(&self.bin)
272 .args(changelists)
273 .stdout(Stdio::piped())
274 .stderr(Stdio::piped())
275 .spawn()
276 }
277}
278
279impl<M: ExclusiveOption> Describe<M> {
280 pub fn get_bin(&self) -> &Path {
282 &self.bin
283 }
284
285 pub fn set_bin(&mut self, bin: impl Into<PathBuf>) -> &mut Self {
287 self.bin = bin.into();
288 self
289 }
290
291 pub fn bin(mut self, bin: impl Into<PathBuf>) -> Self {
293 self.set_bin(bin);
294 self
295 }
296
297 #[cfg_attr(
302 feature = "lt2014_2",
303 doc = "See the [Global Options](GlobalOpts) section."
304 )]
305 #[cfg_attr(
306 all(feature = "lt2015_1", not(feature = "lt2014_2")),
307 doc = "See the [“Global Options”](GlobalOpts) section."
308 )]
309 #[cfg_attr(
310 all(feature = "lt2017_1", not(feature = "lt2015_1")),
311 doc = "See [“Global Options”](GlobalOpts)."
312 )]
313 #[cfg_attr(
314 all(feature = "lt2018_2", not(feature = "lt2017_1")),
315 doc = "See [Global Options](GlobalOpts)."
316 )]
317 #[cfg_attr(not(feature = "lt2018_2"), doc = "See [Global options](GlobalOpts).")]
318 pub fn get_global_opts(&self) -> &GlobalOpts {
319 &self.global_opts
320 }
321
322 #[cfg_attr(
327 feature = "lt2014_2",
328 doc = "See the [Global Options](GlobalOpts) section."
329 )]
330 #[cfg_attr(
331 all(feature = "lt2015_1", not(feature = "lt2014_2")),
332 doc = "See the [“Global Options”](GlobalOpts) section."
333 )]
334 #[cfg_attr(
335 all(feature = "lt2017_1", not(feature = "lt2015_1")),
336 doc = "See [“Global Options”](GlobalOpts)."
337 )]
338 #[cfg_attr(
339 all(feature = "lt2018_2", not(feature = "lt2017_1")),
340 doc = "See [Global Options](GlobalOpts)."
341 )]
342 #[cfg_attr(not(feature = "lt2018_2"), doc = "See [Global options](GlobalOpts).")]
343 pub fn set_global_opts(&mut self, v: GlobalOpts) -> &mut Self {
344 self.global_opts = v;
345 self
346 }
347
348 #[cfg_attr(
353 feature = "lt2014_2",
354 doc = "See the [Global Options](GlobalOpts) section."
355 )]
356 #[cfg_attr(
357 all(feature = "lt2015_1", not(feature = "lt2014_2")),
358 doc = "See the [“Global Options”](GlobalOpts) section."
359 )]
360 #[cfg_attr(
361 all(feature = "lt2017_1", not(feature = "lt2015_1")),
362 doc = "See [“Global Options”](GlobalOpts)."
363 )]
364 #[cfg_attr(
365 all(feature = "lt2018_2", not(feature = "lt2017_1")),
366 doc = "See [Global Options](GlobalOpts)."
367 )]
368 #[cfg_attr(not(feature = "lt2018_2"), doc = "See [Global options](GlobalOpts).")]
369 pub fn global_opts(mut self, v: GlobalOpts) -> Self {
370 self.global_opts = v;
371 self
372 }
373
374 #[cfg_attr(feature = "lt2014_2", doc = "flag requires `admin` permission.")]
380 #[cfg_attr(not(feature = "lt2014_2"), doc = "option requires `admin` permission.")]
381 pub fn get_force_restricted(&self) -> bool {
382 self.force_restricted
383 }
384
385 #[cfg_attr(feature = "lt2014_2", doc = "flag requires `admin` permission.")]
391 #[cfg_attr(not(feature = "lt2014_2"), doc = "option requires `admin` permission.")]
392 pub fn set_force_restricted(&mut self, v: bool) -> &mut Self {
393 self.force_restricted = v;
394 self
395 }
396
397 #[cfg_attr(feature = "lt2014_2", doc = "flag requires `admin` permission.")]
403 #[cfg_attr(not(feature = "lt2014_2"), doc = "option requires `admin` permission.")]
404 pub fn force_restricted(mut self, v: bool) -> Self {
405 self.force_restricted = v;
406 self
407 }
408
409 #[cfg_attr(feature = "lt2017_1", doc = "Identity field of a changelist.")]
415 #[cfg_attr(not(feature = "lt2017_1"), doc = "`Identity` field of a changelist.")]
416 #[cfg(not(feature = "lt2015_2"))]
417 pub fn get_use_identity(&self) -> bool {
418 self.use_identity
419 }
420
421 #[cfg_attr(feature = "lt2017_1", doc = "Identity field of a changelist.")]
427 #[cfg_attr(not(feature = "lt2017_1"), doc = "`Identity` field of a changelist.")]
428 #[cfg(not(feature = "lt2015_2"))]
429 pub fn set_use_identity(&mut self, v: bool) -> &mut Self {
430 self.use_identity = v;
431 self
432 }
433
434 #[cfg_attr(feature = "lt2017_1", doc = "Identity field of a changelist.")]
440 #[cfg_attr(not(feature = "lt2017_1"), doc = "`Identity` field of a changelist.")]
441 #[cfg(not(feature = "lt2015_2"))]
442 pub fn use_identity(mut self, v: bool) -> Self {
443 self.use_identity = v;
444 self
445 }
446
447 #[cfg(not(feature = "lt2017_1"))]
456 pub fn get_limit(&self) -> Option<u64> {
457 self.limit
458 }
459
460 #[cfg(not(feature = "lt2017_1"))]
469 pub fn set_limit(&mut self, v: u64) -> &mut Self {
470 self.limit = Some(v);
471 self
472 }
473
474 #[cfg(not(feature = "lt2017_1"))]
483 pub fn limit(mut self, v: u64) -> Self {
484 self.limit = Some(v);
485 self
486 }
487
488 pub fn get_use_original_number(&self) -> bool {
496 self.use_original_number
497 }
498
499 pub fn set_use_original_number(&mut self, v: bool) -> &mut Self {
507 self.use_original_number = v;
508 self
509 }
510
511 pub fn use_original_number(mut self, v: bool) -> Self {
519 self.use_original_number = v;
520 self
521 }
522
523 #[cfg_attr(
528 feature = "lt2017_1",
529 doc = "Display files shelved for the specified changelist, including",
530 doc = "diffs of those files against their previous depot revision."
531 )]
532 #[cfg_attr(
533 all(feature = "lt2020_2", not(feature = "lt2017_1")),
534 doc = "Display the names of files shelved for the specified changelist,",
535 doc = "including the diff of each file against its previous depot",
536 doc = "revision."
537 )]
538 #[cfg_attr(
539 not(feature = "lt2020_2"),
540 doc = "Lists files that are shelved for the pending changelist and",
541 doc = "displays diffs of the files against their previous revision."
542 )]
543 pub fn get_include_shelved_files(&self) -> bool {
544 self.include_shelved_files
545 }
546
547 #[cfg_attr(
552 feature = "lt2017_1",
553 doc = "Display files shelved for the specified changelist, including",
554 doc = "diffs of those files against their previous depot revision."
555 )]
556 #[cfg_attr(
557 all(feature = "lt2020_2", not(feature = "lt2017_1")),
558 doc = "Display the names of files shelved for the specified changelist,",
559 doc = "including the diff of each file against its previous depot",
560 doc = "revision."
561 )]
562 #[cfg_attr(
563 not(feature = "lt2020_2"),
564 doc = "Lists files that are shelved for the pending changelist and",
565 doc = "displays diffs of the files against their previous revision."
566 )]
567 pub fn set_include_shelved_files(&mut self, v: bool) -> &mut Self {
568 self.include_shelved_files = v;
569 self
570 }
571
572 #[cfg_attr(
577 feature = "lt2017_1",
578 doc = "Display files shelved for the specified changelist, including",
579 doc = "diffs of those files against their previous depot revision."
580 )]
581 #[cfg_attr(
582 all(feature = "lt2020_2", not(feature = "lt2017_1")),
583 doc = "Display the names of files shelved for the specified changelist,",
584 doc = "including the diff of each file against its previous depot",
585 doc = "revision."
586 )]
587 #[cfg_attr(
588 not(feature = "lt2020_2"),
589 doc = "Lists files that are shelved for the pending changelist and",
590 doc = "displays diffs of the files against their previous revision."
591 )]
592 pub fn include_shelved_files(mut self, v: bool) -> Self {
593 self.include_shelved_files = v;
594 self
595 }
596}
597
598impl Describe<DetailDiffMode> {
599 #[cfg_attr(feature = "lt2014_2", doc = "-dflags")]
602 #[cfg_attr(not(feature = "lt2014_2"), doc = "-doptions")]
603 #[cfg_attr(
606 feature = "lt2014_2",
607 doc = "flags. See the Usage Notes below for a flag listing."
608 )]
609 #[cfg_attr(
610 all(feature = "lt2015_1", not(feature = "lt2014_2")),
611 doc = "options. See the Usage Notes below for a option listing."
612 )]
613 #[cfg_attr(
614 all(feature = "lt2024_1", not(feature = "lt2015_1")),
615 doc = "options. See Usage Notes for an option listing."
616 )]
617 #[cfg_attr(
618 not(feature = "lt2024_1"),
619 doc = "options. See Usage notes for an option listing."
620 )]
621 pub fn get_diff_options(&self) -> Option<&DiffOptions> {
622 self.mode.diff_options.as_ref()
623 }
624
625 #[cfg_attr(feature = "lt2014_2", doc = "-dflags")]
628 #[cfg_attr(not(feature = "lt2014_2"), doc = "-doptions")]
629 #[cfg_attr(
632 feature = "lt2014_2",
633 doc = "flags. See the Usage Notes below for a flag listing."
634 )]
635 #[cfg_attr(
636 all(feature = "lt2015_1", not(feature = "lt2014_2")),
637 doc = "options. See the Usage Notes below for a option listing."
638 )]
639 #[cfg_attr(
640 all(feature = "lt2024_1", not(feature = "lt2015_1")),
641 doc = "options. See Usage Notes for an option listing."
642 )]
643 #[cfg_attr(
644 not(feature = "lt2024_1"),
645 doc = "options. See Usage notes for an option listing."
646 )]
647 pub fn set_diff_options(&mut self, v: impl Into<DiffOptions>) -> &mut Self {
648 self.mode.diff_options = Some(v.into());
649 self
650 }
651
652 #[cfg(not(feature = "lt2017_2"))]
661 pub fn get_display_added_text_content(&self) -> bool {
662 self.mode.display_added_text_content
663 }
664
665 #[cfg(not(feature = "lt2017_2"))]
674 pub fn set_display_added_text_content(&mut self, v: bool) -> &mut Self {
675 self.mode.display_added_text_content = v;
676 self
677 }
678}
679
680impl<M: ExclusiveOption> SubCommand for Describe<M> {
681 fn name(&self) -> &str {
682 "describe"
683 }
684
685 fn inject_local_args(&self, command: &mut Command) {
686 self.mode.inject_args(command);
687
688 if self.force_restricted {
689 command.arg("-f");
690 }
691
692 #[cfg(not(feature = "lt2015_2"))]
693 if self.use_identity {
694 command.arg("-I");
695 }
696
697 #[cfg(not(feature = "lt2017_1"))]
698 if let Some(max) = self.limit {
699 command.arg("-m").arg(max.to_string());
700 }
701
702 if self.use_original_number {
703 command.arg("-O");
704 }
705
706 if self.include_shelved_files {
707 command.arg("-S");
708 }
709 }
710
711 fn global_opts(&self) -> Option<&GlobalOpts> {
712 Some(&self.global_opts)
713 }
714}
715
716#[cfg(test)]
717mod tests {
718 use super::*;
719 use crate::cmd::DiffOptionsBuilder;
720 use crate::cmd::args_of;
721
722 #[test]
723 fn bin_accessors_update_executable_path() {
724 let mut command = Describe::new("p4", GlobalOpts::new());
725 assert_eq!(command.get_bin(), Path::new("p4"));
726
727 command.set_bin("/usr/local/bin/p4");
728 assert_eq!(command.get_bin(), Path::new("/usr/local/bin/p4"));
729
730 let command = command.bin("p4.exe");
731 assert_eq!(command.get_bin(), Path::new("p4.exe"));
732 }
733
734 #[test]
737 fn without_options() {
738 let describe = Describe::new("p4", GlobalOpts::new());
739
740 assert_eq!(args_of(&describe.setup_command("p4")), ["describe"]);
741 }
742
743 #[test]
744 fn unselected_with_generic_options() {
745 let mut describe = Describe::new("p4", GlobalOpts::new());
746 describe.set_force_restricted(true);
747 #[cfg(not(feature = "lt2015_2"))]
748 describe.set_use_identity(true);
749 #[cfg(not(feature = "lt2017_1"))]
750 describe.set_limit(2);
751 describe
752 .set_use_original_number(true)
753 .set_include_shelved_files(true);
754
755 let mut expected = vec!["describe"];
756 expected.push("-f");
757 #[cfg(not(feature = "lt2015_2"))]
758 expected.push("-I");
759 #[cfg(not(feature = "lt2017_1"))]
760 expected.extend(["-m", "2"]);
761 expected.extend(["-O", "-S"]);
762
763 assert_eq!(args_of(&describe.setup_command("p4")), expected);
764 }
765
766 #[test]
767 fn short_summary_mode() {
768 let describe = Describe::new("p4", GlobalOpts::new())
769 .force_restricted(true)
770 .short_summary_output();
771
772 assert_eq!(
773 args_of(&describe.setup_command("p4")),
774 ["describe", "-s", "-f"]
775 );
776 }
777
778 #[test]
779 fn mode_transition_preserves_generic_options() {
780 let mut describe = Describe::new("p4", GlobalOpts::new());
781 describe.set_force_restricted(true);
782 #[cfg(not(feature = "lt2017_1"))]
783 describe.set_limit(3);
784
785 let describe = describe.short_summary_output().include_shelved_files(true);
786
787 let mut expected = vec!["describe", "-s", "-f"];
788 #[cfg(not(feature = "lt2017_1"))]
789 expected.extend(["-m", "3"]);
790 expected.push("-S");
791
792 assert_eq!(args_of(&describe.setup_command("p4")), expected);
793 }
794
795 #[test]
796 fn detail_diff_mode_via_diff_options() {
797 let describe =
798 Describe::new("p4", GlobalOpts::new()).diff_options(DiffOptionsBuilder::unified(None));
799
800 assert!(describe.get_diff_options().is_some());
801 assert_eq!(args_of(&describe.setup_command("p4")), ["describe", "-du"]);
802 }
803
804 #[test]
805 fn detail_diff_mode_set_diff_options() {
806 let mut describe =
807 Describe::new("p4", GlobalOpts::new()).diff_options(DiffOptionsBuilder::unified(None));
808 describe.set_diff_options(DiffOptionsBuilder::summary());
809
810 assert_eq!(
811 describe.get_diff_options(),
812 Some(&DiffOptions::from(DiffOptionsBuilder::summary()))
813 );
814 assert_eq!(args_of(&describe.setup_command("p4")), ["describe", "-ds"]);
815 }
816
817 #[cfg(not(feature = "lt2017_2"))]
818 #[test]
819 fn detail_diff_mode_via_display_added_text_content() {
820 let describe = Describe::new("p4", GlobalOpts::new()).display_added_text_content(true);
821
822 assert!(describe.get_display_added_text_content());
823 assert_eq!(describe.get_diff_options(), None);
824 assert_eq!(args_of(&describe.setup_command("p4")), ["describe", "-a"]);
825 }
826
827 #[cfg(not(feature = "lt2017_2"))]
828 #[test]
829 fn detail_diff_mode_combines_a_and_d() {
830 let mut describe = Describe::new("p4", GlobalOpts::new()).display_added_text_content(true);
831 describe.set_diff_options(DiffOptionsBuilder::unified(None));
832
833 assert_eq!(
834 args_of(&describe.setup_command("p4")),
835 ["describe", "-a", "-du"]
836 );
837 }
838
839 #[cfg(not(feature = "lt2017_1"))]
840 #[test]
841 fn limit_is_injected_as_separate_args() {
842 let mut describe = Describe::new("p4", GlobalOpts::new());
843 describe.set_limit(5);
844
845 assert_eq!(
846 args_of(&describe.setup_command("p4")),
847 ["describe", "-m", "5"]
848 );
849 }
850}