use std::{
ffi::OsStr,
path::{Path, PathBuf},
process::{Child, Command, Stdio},
};
use super::{ExclusiveOption, SubCommand, Unselected};
use crate::global::GlobalOpts;
use crate::spawn::ParameterizedSpawn;
pub mod delete;
pub mod inout;
pub mod userorvis;
pub use delete::{DeleteMode, LocalDeleteMode, TransferDeleteMode};
#[cfg(not(feature = "lt2015_2"))]
pub use delete::{RemoteDeleteMode, TransferRemoteDeleteMode};
pub use userorvis::{TransferUVMode, UserOrVisibilityMode};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Visibility {
Public,
Restricted,
}
impl Visibility {
pub fn as_str(&self) -> &'static str {
match self {
Visibility::Public => "public",
Visibility::Restricted => "restricted",
}
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct RegularOperationMode;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct StdoutMode;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct StdinMode;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct ForceOperationMode;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct UpdateOperationMode;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct OnlyForceOperationMode;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct OnlyUpdateOperationMode;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct OriginalChangeListMode;
#[cfg(not(feature = "lt2022_1"))]
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct IdentityChangeListMode;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct OnlyOriginalChangeListMode;
#[cfg(not(feature = "lt2015_2"))]
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct OnlyIdentityChangeListMode;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct ArbitraryJobStatus;
impl ExclusiveOption for ForceOperationMode {
fn inject_args(&self, command: &mut Command) {
command.arg("-f");
}
}
impl ExclusiveOption for UpdateOperationMode {
fn inject_args(&self, command: &mut Command) {
command.arg("-u");
}
}
impl ExclusiveOption for OnlyForceOperationMode {
fn inject_args(&self, command: &mut Command) {
command.arg("-f");
}
}
impl ExclusiveOption for OnlyUpdateOperationMode {
fn inject_args(&self, command: &mut Command) {
command.arg("-u");
}
}
impl ExclusiveOption for OriginalChangeListMode {
fn inject_args(&self, command: &mut Command) {
command.arg("-O");
}
}
#[cfg(not(feature = "lt2022_1"))]
impl ExclusiveOption for IdentityChangeListMode {
fn inject_args(&self, command: &mut Command) {
command.arg("-I");
}
}
impl ExclusiveOption for OnlyOriginalChangeListMode {
fn inject_args(&self, command: &mut Command) {
command.arg("-O");
}
}
#[cfg(not(feature = "lt2015_2"))]
impl ExclusiveOption for OnlyIdentityChangeListMode {
fn inject_args(&self, command: &mut Command) {
command.arg("-I");
}
}
impl ExclusiveOption for ArbitraryJobStatus {
fn inject_args(&self, command: &mut Command) {
command.arg("-s");
}
}
impl ExclusiveOption for RegularOperationMode {}
impl ExclusiveOption for StdoutMode {
fn inject_args(&self, command: &mut Command) {
command.arg("-o");
}
}
impl ExclusiveOption for StdinMode {
fn inject_args(&self, command: &mut Command) {
command.arg("-i");
}
}
#[doc(hidden)]
pub trait TakesChangeList {}
impl TakesChangeList for RegularOperationMode {}
impl TakesChangeList for StdoutMode {}
#[cfg_attr(
not(feature = "lt2022_1"),
doc = " / [`IdentityChangeListMode`], or their"
)]
#[cfg_attr(feature = "lt2022_1", doc = " , or its")]
#[cfg_attr(not(feature = "lt2022_1"), doc = "[`Self::identity`]/")]
#[derive(Debug, Clone, Default)]
pub struct Change<M = Unselected, P = Unselected, C = Unselected, S = Unselected> {
bin: PathBuf,
global_opts: GlobalOpts,
mode: M,
permission_mode: P,
changelist_mode: C,
job_status_mode: S,
}
impl Change<Unselected, Unselected, Unselected, Unselected> {
pub fn new(bin: impl Into<PathBuf>, global_opts: GlobalOpts) -> Self {
Self {
bin: bin.into(),
global_opts,
mode: Unselected,
permission_mode: Unselected,
changelist_mode: Unselected,
job_status_mode: Unselected,
}
}
pub fn delete(self) -> Change<DeleteMode<LocalDeleteMode>, Unselected, Unselected, Unselected> {
self.with_mode(DeleteMode {
loc: LocalDeleteMode,
})
}
#[cfg(not(feature = "lt2015_2"))]
pub fn server_id(
self,
server_id: impl Into<String>,
) -> Change<DeleteMode<RemoteDeleteMode>, Unselected, Unselected, Unselected> {
self.with_mode(DeleteMode {
loc: RemoteDeleteMode {
server_id: server_id.into(),
},
})
}
pub fn stdout(self) -> Change<StdoutMode, Unselected, Unselected, Unselected> {
self.with_mode(StdoutMode)
}
pub fn stdin(self) -> Change<StdinMode, Unselected, Unselected, Unselected> {
self.with_mode(StdinMode)
}
pub fn visibility(
self,
visibility: Visibility,
) -> Change<UserOrVisibilityMode, Unselected, Unselected, Unselected> {
self.with_mode(UserOrVisibilityMode {
visibility: Some(visibility),
user: None,
})
}
pub fn user(
self,
user: impl Into<String>,
) -> Change<UserOrVisibilityMode, Unselected, Unselected, Unselected> {
self.with_mode(UserOrVisibilityMode {
user: Some(user.into()),
visibility: None,
})
}
pub fn arbitrary_job_status(
self,
) -> Change<RegularOperationMode, Unselected, Unselected, ArbitraryJobStatus> {
Change {
bin: self.bin,
global_opts: self.global_opts,
mode: RegularOperationMode,
permission_mode: Unselected,
changelist_mode: Unselected,
job_status_mode: ArbitraryJobStatus,
}
}
pub fn force(self) -> Change<RegularOperationMode, ForceOperationMode, Unselected, Unselected> {
Change {
bin: self.bin,
global_opts: self.global_opts,
mode: RegularOperationMode,
permission_mode: ForceOperationMode,
changelist_mode: Unselected,
job_status_mode: Unselected,
}
}
pub fn update(
self,
) -> Change<RegularOperationMode, UpdateOperationMode, Unselected, Unselected> {
Change {
bin: self.bin,
global_opts: self.global_opts,
mode: RegularOperationMode,
permission_mode: UpdateOperationMode,
changelist_mode: Unselected,
job_status_mode: Unselected,
}
}
pub fn original(
self,
) -> Change<RegularOperationMode, Unselected, OriginalChangeListMode, Unselected> {
Change {
bin: self.bin,
global_opts: self.global_opts,
mode: RegularOperationMode,
permission_mode: Unselected,
changelist_mode: OriginalChangeListMode,
job_status_mode: Unselected,
}
}
#[cfg(not(feature = "lt2022_1"))]
pub fn identity(
self,
) -> Change<RegularOperationMode, Unselected, IdentityChangeListMode, Unselected> {
Change {
bin: self.bin,
global_opts: self.global_opts,
mode: RegularOperationMode,
permission_mode: Unselected,
changelist_mode: IdentityChangeListMode,
job_status_mode: Unselected,
}
}
}
impl<M, P, C, S> Change<M, P, C, S> {
fn with_mode<OTHERMODE>(self, mode: OTHERMODE) -> Change<OTHERMODE, P, C, S> {
Change {
bin: self.bin,
global_opts: self.global_opts,
mode,
permission_mode: self.permission_mode,
changelist_mode: self.changelist_mode,
job_status_mode: self.job_status_mode,
}
}
}
impl<M, P, C, S> Change<M, P, C, S> {
pub fn get_bin(&self) -> &Path {
&self.bin
}
pub fn set_bin(&mut self, bin: impl Into<PathBuf>) -> &mut Self {
self.bin = bin.into();
self
}
pub fn bin(mut self, bin: impl Into<PathBuf>) -> Self {
self.set_bin(bin);
self
}
pub fn get_global_opts(&self) -> &GlobalOpts {
&self.global_opts
}
pub fn set_global_opts(&mut self, v: GlobalOpts) -> &mut Self {
self.global_opts = v;
self
}
pub fn global_opts(mut self, v: GlobalOpts) -> Self {
self.global_opts = v;
self
}
}
#[doc(hidden)]
pub trait TransferStdoutMode {}
impl TransferStdoutMode for Unselected {}
impl TransferStdoutMode for ForceOperationMode {}
impl<P, C, S> Change<RegularOperationMode, P, C, S> {
pub fn delete(self) -> Change<DeleteMode<LocalDeleteMode>, P, C, S>
where
P: TransferDeleteMode,
C: TransferDeleteMode,
{
Change {
bin: self.bin,
global_opts: self.global_opts,
mode: DeleteMode {
loc: LocalDeleteMode,
},
permission_mode: self.permission_mode,
changelist_mode: self.changelist_mode,
job_status_mode: self.job_status_mode,
}
}
pub fn stdout(self) -> Change<StdoutMode, P, C, S>
where
P: TransferStdoutMode,
{
Change {
bin: self.bin,
global_opts: self.global_opts,
mode: StdoutMode,
permission_mode: self.permission_mode,
changelist_mode: self.changelist_mode,
job_status_mode: self.job_status_mode,
}
}
}
#[cfg(not(feature = "lt2015_2"))]
impl<P: TransferRemoteDeleteMode> Change<RegularOperationMode, P, Unselected, Unselected> {
pub fn server_id(
self,
server_id: impl Into<String>,
) -> Change<DeleteMode<RemoteDeleteMode>, Unselected, Unselected, Unselected> {
Change {
bin: self.bin,
global_opts: self.global_opts,
mode: DeleteMode {
loc: RemoteDeleteMode {
server_id: server_id.into(),
},
},
permission_mode: Unselected,
changelist_mode: Unselected,
job_status_mode: Unselected,
}
}
}
impl<O, S> Change<RegularOperationMode, O, Unselected, S> {
pub fn stdin(self) -> Change<StdinMode, O, Unselected, S> {
Change {
bin: self.bin,
global_opts: self.global_opts,
mode: StdinMode,
permission_mode: self.permission_mode,
changelist_mode: Unselected,
job_status_mode: self.job_status_mode,
}
}
}
impl<O, C> Change<RegularOperationMode, O, C, Unselected> {
pub fn arbitrary_job_status(self) -> Change<RegularOperationMode, O, C, ArbitraryJobStatus> {
Change {
bin: self.bin,
global_opts: self.global_opts,
mode: self.mode,
permission_mode: self.permission_mode,
changelist_mode: self.changelist_mode,
job_status_mode: ArbitraryJobStatus,
}
}
}
impl<C, S> Change<RegularOperationMode, Unselected, C, S> {
pub fn force(self) -> Change<RegularOperationMode, ForceOperationMode, C, S> {
Change {
bin: self.bin,
global_opts: self.global_opts,
mode: self.mode,
permission_mode: ForceOperationMode,
changelist_mode: self.changelist_mode,
job_status_mode: self.job_status_mode,
}
}
pub fn update(self) -> Change<RegularOperationMode, UpdateOperationMode, C, S> {
Change {
bin: self.bin,
global_opts: self.global_opts,
mode: self.mode,
permission_mode: UpdateOperationMode,
changelist_mode: self.changelist_mode,
job_status_mode: self.job_status_mode,
}
}
}
impl<O, S> Change<RegularOperationMode, O, Unselected, S> {
pub fn original(self) -> Change<RegularOperationMode, O, OriginalChangeListMode, S> {
Change {
bin: self.bin,
global_opts: self.global_opts,
mode: self.mode,
permission_mode: self.permission_mode,
changelist_mode: OriginalChangeListMode,
job_status_mode: self.job_status_mode,
}
}
#[cfg(not(feature = "lt2022_1"))]
pub fn identity(self) -> Change<RegularOperationMode, O, IdentityChangeListMode, S> {
Change {
bin: self.bin,
global_opts: self.global_opts,
mode: self.mode,
permission_mode: self.permission_mode,
changelist_mode: IdentityChangeListMode,
job_status_mode: self.job_status_mode,
}
}
}
impl<O, C> Change<RegularOperationMode, O, C, Unselected> {
#[allow(clippy::type_complexity)]
pub fn visibility(
self,
visibility: Visibility,
) -> Change<
UserOrVisibilityMode,
<(O, C) as TransferUVMode>::P,
<(O, C) as TransferUVMode>::C,
Unselected,
>
where
(O, C): TransferUVMode,
{
let (operation, change_ref) = (self.permission_mode, self.changelist_mode).transfer();
Change {
bin: self.bin,
global_opts: self.global_opts,
mode: UserOrVisibilityMode {
visibility: Some(visibility),
user: None,
},
permission_mode: operation,
changelist_mode: change_ref,
job_status_mode: Unselected,
}
}
#[allow(clippy::type_complexity)]
pub fn user(
self,
user: impl Into<String>,
) -> Change<
UserOrVisibilityMode,
<(O, C) as TransferUVMode>::P,
<(O, C) as TransferUVMode>::C,
Unselected,
>
where
(O, C): TransferUVMode,
{
let (operation, change_ref) = (self.permission_mode, self.changelist_mode).transfer();
Change {
bin: self.bin,
global_opts: self.global_opts,
mode: UserOrVisibilityMode {
user: Some(user.into()),
visibility: None,
},
permission_mode: operation,
changelist_mode: change_ref,
job_status_mode: Unselected,
}
}
}
impl<M, O, C, S> SubCommand for Change<M, O, C, S>
where
M: ExclusiveOption,
O: ExclusiveOption,
C: ExclusiveOption,
S: ExclusiveOption,
{
fn name(&self) -> &str {
"change"
}
fn inject_local_args(&self, command: &mut Command) {
self.mode.inject_args(command);
self.job_status_mode.inject_args(command);
self.permission_mode.inject_args(command);
self.changelist_mode.inject_args(command);
}
fn global_opts(&self) -> Option<&GlobalOpts> {
Some(&self.global_opts)
}
}
impl<M, O, C, S, I> ParameterizedSpawn<(I,)> for Change<M, O, C, S>
where
M: ExclusiveOption + TakesChangeList,
O: ExclusiveOption,
C: ExclusiveOption,
S: ExclusiveOption,
I: AsRef<OsStr>,
{
type Output = Child;
type Error = std::io::Error;
fn spawn_with(&mut self, (changelist,): (I,)) -> Result<Self::Output, Self::Error> {
self.setup_command(&self.bin)
.arg(changelist)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
}
}
impl<O, C, S> ParameterizedSpawn<()> for Change<RegularOperationMode, O, C, S>
where
O: ExclusiveOption,
C: ExclusiveOption,
S: ExclusiveOption,
{
type Output = Child;
type Error = std::io::Error;
fn spawn_with(&mut self, _: ()) -> Result<Self::Output, Self::Error> {
self.setup_command(&self.bin)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
}
}
impl<O, C, S> ParameterizedSpawn<()> for Change<StdoutMode, O, C, S>
where
O: ExclusiveOption,
C: ExclusiveOption,
S: ExclusiveOption,
{
type Output = Child;
type Error = std::io::Error;
fn spawn_with(&mut self, _: ()) -> Result<Self::Output, Self::Error> {
self.setup_command(&self.bin)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
}
}
impl<O, S> ParameterizedSpawn<()> for Change<StdinMode, O, Unselected, S>
where
O: ExclusiveOption,
S: ExclusiveOption,
{
type Output = Child;
type Error = std::io::Error;
fn spawn_with(&mut self, _: ()) -> Result<Self::Output, Self::Error> {
self.setup_command(&self.bin)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
}
}
impl<O, S> ParameterizedSpawn<(Stdio,)> for Change<StdinMode, O, Unselected, S>
where
O: ExclusiveOption,
S: ExclusiveOption,
{
type Output = Child;
type Error = std::io::Error;
fn spawn_with(&mut self, (stdio,): (Stdio,)) -> Result<Self::Output, Self::Error> {
self.setup_command(&self.bin)
.stdin(stdio)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::cmd::args_of;
#[test]
fn bin_accessors_update_executable_path() {
let mut command = Change::new("p4", GlobalOpts::new());
assert_eq!(command.get_bin(), Path::new("p4"));
command.set_bin("/usr/local/bin/p4");
assert_eq!(command.get_bin(), Path::new("/usr/local/bin/p4"));
let command = command.bin("p4.exe");
assert_eq!(command.get_bin(), Path::new("p4.exe"));
}
#[test]
fn regular_form_injects_all_options() {
let change = Change::new("p4", GlobalOpts::new())
.arbitrary_job_status()
.force()
.original();
assert_eq!(
args_of(&change.setup_command("p4")),
["change", "-s", "-f", "-O"]
);
}
#[test]
#[cfg(not(feature = "lt2022_1"))]
fn regular_form_update_and_identity() {
let change = Change::new("p4", GlobalOpts::new())
.arbitrary_job_status()
.update()
.identity();
assert_eq!(
args_of(&change.setup_command("p4")),
["change", "-s", "-u", "-I"]
);
}
#[test]
fn entry_points_select_form_flags() {
let delete = Change::new("p4", GlobalOpts::new()).delete();
assert_eq!(args_of(&delete.setup_command("p4")), ["change", "-d"]);
let stdout = Change::new("p4", GlobalOpts::new()).stdout();
assert_eq!(args_of(&stdout.setup_command("p4")), ["change", "-o"]);
let stdin = Change::new("p4", GlobalOpts::new()).stdin();
assert_eq!(args_of(&stdin.setup_command("p4")), ["change", "-i"]);
#[cfg(not(feature = "lt2015_2"))]
{
let remote = Change::new("p4", GlobalOpts::new()).server_id("remote-1");
#[cfg(feature = "lt2022_1")]
assert_eq!(
args_of(&remote.setup_command("p4")),
["change", "-d", "-f", "--server=remote-1"]
);
#[cfg(not(feature = "lt2022_1"))]
assert_eq!(
args_of(&remote.setup_command("p4")),
["change", "-d", "-f", "--serverid=remote-1"]
);
}
}
#[test]
fn arbitrary_job_status_carries_into_delete_stdout_stdin() {
let delete = Change::new("p4", GlobalOpts::new())
.arbitrary_job_status()
.delete();
assert_eq!(args_of(&delete.setup_command("p4")), ["change", "-d", "-s"]);
let stdout = Change::new("p4", GlobalOpts::new())
.arbitrary_job_status()
.stdout();
assert_eq!(args_of(&stdout.setup_command("p4")), ["change", "-o", "-s"]);
let stdin = Change::new("p4", GlobalOpts::new())
.arbitrary_job_status()
.stdin();
assert_eq!(args_of(&stdin.setup_command("p4")), ["change", "-i", "-s"]);
}
#[test]
fn regular_to_delete_preserves_compatible_options() {
let change = Change::new("p4", GlobalOpts::new())
.arbitrary_job_status()
.force()
.original()
.delete();
assert_eq!(
args_of(&change.setup_command("p4")),
["change", "-d", "-s", "-f", "-O"]
);
}
#[test]
#[cfg(not(feature = "lt2022_1"))]
fn regular_to_stdout_preserves_identity() {
let change = Change::new("p4", GlobalOpts::new())
.arbitrary_job_status()
.force()
.identity()
.stdout();
assert_eq!(
args_of(&change.setup_command("p4")),
["change", "-o", "-s", "-f", "-I"]
);
}
#[test]
fn regular_to_stdin_preserves_update() {
let change = Change::new("p4", GlobalOpts::new())
.arbitrary_job_status()
.update()
.stdin();
assert_eq!(
args_of(&change.setup_command("p4")),
["change", "-i", "-s", "-u"]
);
}
#[test]
#[cfg(not(feature = "lt2015_2"))]
fn regular_to_remote_delete_folds_force_into_builtin() {
let change = Change::new("p4", GlobalOpts::new())
.force()
.server_id("remote-1");
#[cfg(feature = "lt2022_1")]
assert_eq!(
args_of(&change.setup_command("p4")),
["change", "-d", "-f", "--server=remote-1"]
);
#[cfg(not(feature = "lt2022_1"))]
assert_eq!(
args_of(&change.setup_command("p4")),
["change", "-d", "-f", "--serverid=remote-1"]
);
}
#[test]
fn regular_visibility_maps_to_only_states() {
let forced = Change::new("p4", GlobalOpts::new())
.force()
.visibility(Visibility::Restricted);
assert_eq!(
args_of(&forced.setup_command("p4")),
["change", "-t", "restricted", "-f"]
);
#[cfg(not(feature = "lt2022_1"))]
{
let identity = Change::new("p4", GlobalOpts::new())
.identity()
.visibility(Visibility::Public);
assert_eq!(
args_of(&identity.setup_command("p4")),
["change", "-t", "public", "-I"]
);
}
let plain = Change::new("p4", GlobalOpts::new())
.visibility(Visibility::Restricted)
.user("maria");
assert_eq!(
args_of(&plain.setup_command("p4")),
["change", "-t", "restricted", "-U", "maria"]
);
}
#[test]
fn regular_user_maps_single_option() {
let change = Change::new("p4", GlobalOpts::new())
.force()
.user("maria")
.visibility(Visibility::Public);
assert_eq!(
args_of(&change.setup_command("p4")),
["change", "-t", "public", "-U", "maria", "-f"]
);
let original = Change::new("p4", GlobalOpts::new())
.original()
.user("maria");
assert_eq!(
args_of(&original.setup_command("p4")),
["change", "-U", "maria", "-O"]
);
}
#[test]
fn user_or_visibility_form_sets_values_and_selects_one_option() {
let both = Change::new("p4", GlobalOpts::new())
.user("maria")
.visibility(Visibility::Public);
assert_eq!(
args_of(&both.setup_command("p4")),
["change", "-t", "public", "-U", "maria"]
);
let forced = Change::new("p4", GlobalOpts::new())
.visibility(Visibility::Restricted)
.force();
assert_eq!(
args_of(&forced.setup_command("p4")),
["change", "-t", "restricted", "-f"]
);
let updated = Change::new("p4", GlobalOpts::new()).user("maria").update();
assert_eq!(
args_of(&updated.setup_command("p4")),
["change", "-U", "maria", "-u"]
);
let original = Change::new("p4", GlobalOpts::new())
.user("maria")
.original();
assert_eq!(
args_of(&original.setup_command("p4")),
["change", "-U", "maria", "-O"]
);
#[cfg(not(feature = "lt2015_2"))]
{
let identity = Change::new("p4", GlobalOpts::new())
.visibility(Visibility::Public)
.identity();
assert_eq!(
args_of(&identity.setup_command("p4")),
["change", "-t", "public", "-I"]
);
}
}
#[test]
fn options_can_be_selected_inside_forms() {
let delete = Change::new("p4", GlobalOpts::new())
.delete()
.arbitrary_job_status()
.force()
.original();
assert_eq!(
args_of(&delete.setup_command("p4")),
["change", "-d", "-s", "-f", "-O"]
);
#[cfg(not(feature = "lt2022_1"))]
{
let stdout = Change::new("p4", GlobalOpts::new())
.stdout()
.arbitrary_job_status()
.identity();
assert_eq!(
args_of(&stdout.setup_command("p4")),
["change", "-o", "-s", "-I"]
);
}
#[cfg(feature = "lt2022_1")]
{
let stdout = Change::new("p4", GlobalOpts::new())
.stdout()
.arbitrary_job_status()
.original();
assert_eq!(
args_of(&stdout.setup_command("p4")),
["change", "-o", "-s", "-O"]
);
}
let stdin = Change::new("p4", GlobalOpts::new())
.stdin()
.arbitrary_job_status()
.update();
assert_eq!(
args_of(&stdin.setup_command("p4")),
["change", "-i", "-s", "-u"]
);
}
#[test]
fn global_opts_are_injected_once() {
let change = Change::new("p4", GlobalOpts::new()).delete();
assert_eq!(args_of(&change.setup_command("p4")), ["change", "-d"]);
}
#[test]
fn spawn_argument_counts_per_form() {
let plain = Change::new("p4", GlobalOpts::new())
.arbitrary_job_status()
.force();
assert_eq!(args_of(&plain.setup_command("p4")), ["change", "-s", "-f"]);
let mut with_cl = plain.setup_command("p4");
with_cl.arg("1234");
assert_eq!(args_of(&with_cl), ["change", "-s", "-f", "1234"]);
let delete = Change::new("p4", GlobalOpts::new())
.delete()
.arbitrary_job_status()
.force()
.original();
let mut delete_cl = delete.setup_command("p4");
delete_cl.arg("1234");
assert_eq!(
args_of(&delete_cl),
["change", "-d", "-s", "-f", "-O", "1234"]
);
#[cfg(not(feature = "lt2015_2"))]
{
let remote = Change::new("p4", GlobalOpts::new()).server_id("edge-1");
let mut remote_cl = remote.setup_command("p4");
remote_cl.arg("1234");
#[cfg(feature = "lt2022_1")]
assert_eq!(
args_of(&remote_cl),
["change", "-d", "-f", "--server=edge-1", "1234"]
);
#[cfg(not(feature = "lt2022_1"))]
assert_eq!(
args_of(&remote_cl),
["change", "-d", "-f", "--serverid=edge-1", "1234"]
);
}
#[cfg(not(feature = "lt2022_1"))]
{
let stdout = Change::new("p4", GlobalOpts::new())
.stdout()
.arbitrary_job_status()
.force()
.identity();
assert_eq!(
args_of(&stdout.setup_command("p4")),
["change", "-o", "-s", "-f", "-I"]
);
let mut stdout_cl = stdout.setup_command("p4");
stdout_cl.arg("1234");
assert_eq!(
args_of(&stdout_cl),
["change", "-o", "-s", "-f", "-I", "1234"]
);
}
#[cfg(feature = "lt2022_1")]
{
let stdout = Change::new("p4", GlobalOpts::new())
.stdout()
.arbitrary_job_status()
.force()
.original();
assert_eq!(
args_of(&stdout.setup_command("p4")),
["change", "-o", "-s", "-f", "-O"]
);
let mut stdout_cl = stdout.setup_command("p4");
stdout_cl.arg("1234");
assert_eq!(
args_of(&stdout_cl),
["change", "-o", "-s", "-f", "-O", "1234"]
);
}
let stdin = Change::new("p4", GlobalOpts::new())
.stdin()
.arbitrary_job_status()
.update();
assert_eq!(
args_of(&stdin.setup_command("p4")),
["change", "-i", "-s", "-u"]
);
let uov = Change::new("p4", GlobalOpts::new())
.visibility(Visibility::Restricted)
.user("maria")
.force();
let mut uov_cl = uov.setup_command("p4");
uov_cl.arg("1234");
assert_eq!(
args_of(&uov_cl),
["change", "-t", "restricted", "-U", "maria", "-f", "1234"]
);
}
}