use std::ffi::OsString;
use std::path::{Path, PathBuf};
use clap::builder::TypedValueParser as _;
use clap::{Args, Parser, Subcommand, ValueEnum, ValueHint};
use clap_complete::Shell as ClapCompleteShell;
use derive_more::{Display, Error, From, IsVariant};
use distant_core::net::common::{ConnectionId, Destination, Map, PortRange};
use distant_core::net::server::Shutdown;
use distant_core::protocol::ChangeKind;
use service_manager::ServiceManagerKind;
use crate::constants;
use crate::constants::user::CACHE_FILE_PATH_STR;
mod common;
mod config;
pub use common::*;
pub use self::config::*;
#[derive(Debug, PartialEq, Parser)]
#[clap(author, version, about)]
#[clap(name = "distant")]
pub struct Options {
#[clap(flatten)]
pub logging: LoggingSettings,
#[clap(long = "config", global = true, value_parser)]
config_path: Option<PathBuf>,
#[clap(subcommand)]
pub command: DistantSubcommand,
}
#[derive(Debug, Display, From, Error)]
pub enum OptionsError {
Config(#[error(not(source))] anyhow::Error),
Options(#[error(not(source))] clap::Error),
}
impl Options {
pub fn load() -> Result<Self, OptionsError> {
Self::load_from(std::env::args_os())
}
pub fn load_from<I, T>(args: I) -> Result<Self, OptionsError>
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
let mut this = Self::try_parse_from(args)?;
let config = Config::load_multi(this.config_path.take())?;
this.merge(config);
if this.logging.log_file.is_none() {
this.logging.log_file = Some(match &this.command {
DistantSubcommand::Client(_) => constants::user::CLIENT_LOG_FILE_PATH.to_path_buf(),
DistantSubcommand::Server(_) => constants::user::SERVER_LOG_FILE_PATH.to_path_buf(),
DistantSubcommand::Generate(_) => {
constants::user::GENERATE_LOG_FILE_PATH.to_path_buf()
}
DistantSubcommand::Manager(cmd) if cmd.is_listen() => {
constants::user::MANAGER_LOG_FILE_PATH.to_path_buf()
}
DistantSubcommand::Manager(_) => {
constants::user::CLIENT_LOG_FILE_PATH.to_path_buf()
}
});
}
Ok(this)
}
fn merge(&mut self, config: Config) {
macro_rules! update_logging {
($kind:ident) => {{
self.logging.log_file = self
.logging
.log_file
.take()
.or(config.$kind.logging.log_file);
self.logging.log_level = self.logging.log_level.or(config.$kind.logging.log_level);
}};
}
match &mut self.command {
DistantSubcommand::Client(cmd) => {
update_logging!(client);
match cmd {
ClientSubcommand::Api {
network, timeout, ..
} => {
network.merge(config.client.network);
*timeout = timeout.take().or(config.client.api.timeout);
}
ClientSubcommand::Connect {
network, options, ..
} => {
network.merge(config.client.network);
options.merge(config.client.connect.options, true);
}
ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Copy { network, .. }
| ClientFileSystemSubcommand::Exists { network, .. }
| ClientFileSystemSubcommand::MakeDir { network, .. }
| ClientFileSystemSubcommand::Metadata { network, .. }
| ClientFileSystemSubcommand::Read { network, .. }
| ClientFileSystemSubcommand::Remove { network, .. }
| ClientFileSystemSubcommand::Rename { network, .. }
| ClientFileSystemSubcommand::Search { network, .. }
| ClientFileSystemSubcommand::SetPermissions { network, .. }
| ClientFileSystemSubcommand::Watch { network, .. }
| ClientFileSystemSubcommand::Write { network, .. },
) => {
network.merge(config.client.network);
}
ClientSubcommand::Launch {
distant_args,
distant_bin,
distant_bind_server,
network,
options,
..
} => {
network.merge(config.client.network);
options.merge(config.client.launch.options, true);
*distant_args = distant_args.take().or(config.client.launch.distant.args);
*distant_bin = distant_bin.take().or(config.client.launch.distant.bin);
*distant_bind_server =
distant_bind_server
.take()
.or(config.client.launch.distant.bind_server);
}
ClientSubcommand::Shell { network, .. } => {
network.merge(config.client.network);
}
ClientSubcommand::Spawn { network, .. } => {
network.merge(config.client.network);
}
ClientSubcommand::SystemInfo { network, .. } => {
network.merge(config.client.network);
}
ClientSubcommand::Version { network, .. } => {
network.merge(config.client.network);
}
}
}
DistantSubcommand::Generate(_) => {
update_logging!(generate);
}
DistantSubcommand::Manager(cmd) => {
update_logging!(manager);
match cmd {
ManagerSubcommand::Version { network, .. } => {
network.merge(config.manager.network);
}
ManagerSubcommand::Info { network, .. } => {
network.merge(config.manager.network);
}
ManagerSubcommand::Kill { network, .. } => {
network.merge(config.manager.network);
}
ManagerSubcommand::List { network, .. } => {
network.merge(config.manager.network);
}
ManagerSubcommand::Listen {
access, network, ..
} => {
*access = access.take().or(config.manager.access);
network.merge(config.manager.network);
}
ManagerSubcommand::Select { network, .. } => {
network.merge(config.manager.network);
}
ManagerSubcommand::Service(_) => (),
}
}
DistantSubcommand::Server(cmd) => {
update_logging!(server);
match cmd {
ServerSubcommand::Listen {
current_dir,
host,
port,
shutdown,
use_ipv6,
watch,
..
} => {
*current_dir = current_dir.take().or(config.server.listen.current_dir);
if host.is_default() && config.server.listen.host.is_some() {
*host = Value::Explicit(config.server.listen.host.unwrap());
}
if port.is_default() && config.server.listen.port.is_some() {
*port = Value::Explicit(config.server.listen.port.unwrap());
}
if shutdown.is_default() && config.server.listen.shutdown.is_some() {
*shutdown = Value::Explicit(config.server.listen.shutdown.unwrap());
}
if !*use_ipv6 && config.server.listen.use_ipv6 {
*use_ipv6 = true;
}
if !watch.watch_polling && !config.server.watch.native {
watch.watch_polling = true;
}
watch.watch_poll_interval = watch
.watch_poll_interval
.take()
.or(config.server.watch.poll_interval);
if !watch.watch_compare_contents && config.server.watch.compare_contents {
watch.watch_compare_contents = true;
}
if watch.watch_debounce_timeout.is_default()
&& config.server.watch.debounce_timeout.is_some()
{
watch.watch_debounce_timeout =
Value::Explicit(config.server.watch.debounce_timeout.unwrap());
}
watch.watch_debounce_tick_rate = watch
.watch_debounce_tick_rate
.take()
.or(config.server.watch.debounce_tick_rate);
}
}
}
}
}
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug, PartialEq, Subcommand, IsVariant)]
pub enum DistantSubcommand {
#[clap(flatten)]
Client(ClientSubcommand),
#[clap(subcommand)]
Manager(ManagerSubcommand),
#[clap(subcommand)]
Server(ServerSubcommand),
#[clap(subcommand)]
Generate(GenerateSubcommand),
}
impl DistantSubcommand {
#[inline]
pub fn format(&self) -> Format {
match self {
Self::Client(x) => x.format(),
Self::Manager(x) => x.format(),
Self::Server(x) => x.format(),
Self::Generate(x) => x.format(),
}
}
}
#[derive(Debug, PartialEq, Subcommand, IsVariant)]
pub enum ClientSubcommand {
Api {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(long)]
timeout: Option<Seconds>,
#[clap(long)]
connection: Option<ConnectionId>,
#[clap(flatten)]
network: NetworkSettings,
},
Connect {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(long, default_value_t)]
options: Map,
#[clap(flatten)]
network: NetworkSettings,
#[clap(short, long, default_value_t, value_enum)]
format: Format,
destination: Box<Destination>,
},
#[clap(subcommand, name = "fs")]
FileSystem(ClientFileSystemSubcommand),
Launch {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(name = "distant", long)]
distant_bin: Option<String>,
#[clap(name = "distant-bind-server", long, value_name = "ssh|any|IP")]
distant_bind_server: Option<BindAddress>,
#[clap(name = "distant-args", long, allow_hyphen_values(true))]
distant_args: Option<String>,
#[clap(long, default_value_t)]
options: Map,
#[clap(flatten)]
network: NetworkSettings,
#[clap(short, long, default_value_t, value_enum)]
format: Format,
destination: Box<Destination>,
},
Shell {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(long)]
connection: Option<ConnectionId>,
#[clap(flatten)]
network: NetworkSettings,
#[clap(long)]
current_dir: Option<PathBuf>,
#[clap(long, default_value_t)]
environment: Map,
#[clap(name = "CMD", last = true)]
cmd: Option<Vec<String>>,
},
Spawn {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(long)]
connection: Option<ConnectionId>,
#[clap(flatten)]
network: NetworkSettings,
#[clap(long, name = "SCHEME")]
lsp: Option<Option<String>>,
#[clap(long)]
pty: bool,
#[clap(long, name = "SHELL")]
shell: Option<Option<Shell>>,
#[clap(long)]
current_dir: Option<PathBuf>,
#[clap(long, default_value_t)]
environment: Map,
#[clap(short = 'c', long = "cmd", conflicts_with = "CMD")]
cmd_str: Option<String>,
#[clap(
name = "CMD",
num_args = 1..,
last = true,
conflicts_with = "cmd_str"
)]
cmd: Vec<String>,
},
SystemInfo {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(long)]
connection: Option<ConnectionId>,
#[clap(flatten)]
network: NetworkSettings,
},
Version {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(long)]
connection: Option<ConnectionId>,
#[clap(flatten)]
network: NetworkSettings,
#[clap(short, long, default_value_t, value_enum)]
format: Format,
},
}
impl ClientSubcommand {
pub fn cache_path(&self) -> &Path {
match self {
Self::Connect { cache, .. } => cache.as_path(),
Self::FileSystem(fs) => fs.cache_path(),
Self::Launch { cache, .. } => cache.as_path(),
Self::Api { cache, .. } => cache.as_path(),
Self::Shell { cache, .. } => cache.as_path(),
Self::Spawn { cache, .. } => cache.as_path(),
Self::SystemInfo { cache, .. } => cache.as_path(),
Self::Version { cache, .. } => cache.as_path(),
}
}
pub fn network_settings(&self) -> &NetworkSettings {
match self {
Self::Connect { network, .. } => network,
Self::FileSystem(fs) => fs.network_settings(),
Self::Launch { network, .. } => network,
Self::Api { network, .. } => network,
Self::Shell { network, .. } => network,
Self::Spawn { network, .. } => network,
Self::SystemInfo { network, .. } => network,
Self::Version { network, .. } => network,
}
}
#[inline]
pub fn format(&self) -> Format {
match self {
Self::Api { .. } => Format::Json,
Self::Connect { format, .. } => *format,
Self::FileSystem(fs) => fs.format(),
Self::Launch { format, .. } => *format,
Self::Shell { .. } => Format::Shell,
Self::Spawn { .. } => Format::Shell,
Self::SystemInfo { .. } => Format::Shell,
Self::Version { format, .. } => *format,
}
}
}
#[derive(Debug, PartialEq, Eq, Subcommand, IsVariant)]
pub enum ClientFileSystemSubcommand {
Copy {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(long)]
connection: Option<ConnectionId>,
#[clap(flatten)]
network: NetworkSettings,
src: PathBuf,
dst: PathBuf,
},
Exists {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(long)]
connection: Option<ConnectionId>,
#[clap(flatten)]
network: NetworkSettings,
path: PathBuf,
},
MakeDir {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(long)]
connection: Option<ConnectionId>,
#[clap(flatten)]
network: NetworkSettings,
#[clap(long)]
all: bool,
path: PathBuf,
},
Metadata {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(long)]
connection: Option<ConnectionId>,
#[clap(flatten)]
network: NetworkSettings,
#[clap(long)]
canonicalize: bool,
#[clap(long)]
resolve_file_type: bool,
path: PathBuf,
},
Read {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(long)]
connection: Option<ConnectionId>,
#[clap(flatten)]
network: NetworkSettings,
#[clap(long, default_value_t = 1)]
depth: usize,
#[clap(long)]
absolute: bool,
#[clap(long)]
canonicalize: bool,
#[clap(long)]
include_root: bool,
path: PathBuf,
},
Remove {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(long)]
connection: Option<ConnectionId>,
#[clap(flatten)]
network: NetworkSettings,
#[clap(long)]
force: bool,
path: PathBuf,
},
Rename {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(long)]
connection: Option<ConnectionId>,
#[clap(flatten)]
network: NetworkSettings,
src: PathBuf,
dst: PathBuf,
},
Search {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(long)]
connection: Option<ConnectionId>,
#[clap(flatten)]
network: NetworkSettings,
#[clap(long, value_enum, default_value_t = CliSearchQueryTarget::Contents)]
target: CliSearchQueryTarget,
#[clap(name = "pattern")]
condition: CliSearchQueryCondition,
#[clap(flatten)]
options: CliSearchQueryOptions,
#[clap(default_value = ".")]
paths: Vec<PathBuf>,
},
SetPermissions {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(long)]
connection: Option<ConnectionId>,
#[clap(flatten)]
network: NetworkSettings,
#[clap(short = 'R', long)]
recursive: bool,
#[clap(short = 'L', long)]
follow_symlinks: bool,
mode: String,
path: PathBuf,
},
Watch {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(long)]
connection: Option<ConnectionId>,
#[clap(flatten)]
network: NetworkSettings,
#[clap(long)]
recursive: bool,
#[
clap(
long,
value_parser = clap::builder::PossibleValuesParser::new(ChangeKind::variants())
.map(|s| s.parse::<ChangeKind>().unwrap()),
)
]
only: Vec<ChangeKind>,
#[
clap(
long,
value_parser = clap::builder::PossibleValuesParser::new(ChangeKind::variants())
.map(|s| s.parse::<ChangeKind>().unwrap()),
)
]
except: Vec<ChangeKind>,
path: PathBuf,
},
Write {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
#[clap(long)]
connection: Option<ConnectionId>,
#[clap(flatten)]
network: NetworkSettings,
#[clap(long)]
append: bool,
path: PathBuf,
data: Option<OsString>,
},
}
impl ClientFileSystemSubcommand {
pub fn cache_path(&self) -> &Path {
match self {
Self::Copy { cache, .. } => cache.as_path(),
Self::Exists { cache, .. } => cache.as_path(),
Self::MakeDir { cache, .. } => cache.as_path(),
Self::Metadata { cache, .. } => cache.as_path(),
Self::Read { cache, .. } => cache.as_path(),
Self::Remove { cache, .. } => cache.as_path(),
Self::Rename { cache, .. } => cache.as_path(),
Self::Search { cache, .. } => cache.as_path(),
Self::SetPermissions { cache, .. } => cache.as_path(),
Self::Watch { cache, .. } => cache.as_path(),
Self::Write { cache, .. } => cache.as_path(),
}
}
pub fn network_settings(&self) -> &NetworkSettings {
match self {
Self::Copy { network, .. } => network,
Self::Exists { network, .. } => network,
Self::MakeDir { network, .. } => network,
Self::Metadata { network, .. } => network,
Self::Read { network, .. } => network,
Self::Remove { network, .. } => network,
Self::Rename { network, .. } => network,
Self::Search { network, .. } => network,
Self::SetPermissions { network, .. } => network,
Self::Watch { network, .. } => network,
Self::Write { network, .. } => network,
}
}
#[inline]
pub fn format(&self) -> Format {
Format::Shell
}
}
#[derive(Debug, PartialEq, Eq, Subcommand, IsVariant)]
pub enum GenerateSubcommand {
Config {
#[clap(short, long, value_name = "FILE")]
output: Option<PathBuf>,
},
Completion {
#[clap(long, value_name = "FILE")]
output: Option<PathBuf>,
#[clap(value_enum, value_parser)]
shell: ClapCompleteShell,
},
}
impl GenerateSubcommand {
#[inline]
pub fn format(&self) -> Format {
Format::Shell
}
}
#[derive(Debug, PartialEq, Eq, Subcommand, IsVariant)]
pub enum ManagerSubcommand {
Select {
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
connection: Option<ConnectionId>,
#[clap(short, long, default_value_t, value_enum)]
format: Format,
#[clap(flatten)]
network: NetworkSettings,
},
#[clap(subcommand)]
Service(ManagerServiceSubcommand),
Listen {
#[clap(long, value_enum)]
access: Option<AccessControl>,
#[clap(long)]
daemon: bool,
#[clap(long)]
user: bool,
#[clap(flatten)]
network: NetworkSettings,
},
Version {
#[clap(short, long, default_value_t, value_enum)]
format: Format,
#[clap(flatten)]
network: NetworkSettings,
},
Info {
#[clap(short, long, default_value_t, value_enum)]
format: Format,
id: ConnectionId,
#[clap(flatten)]
network: NetworkSettings,
},
List {
#[clap(short, long, default_value_t, value_enum)]
format: Format,
#[clap(flatten)]
network: NetworkSettings,
#[clap(
long,
value_hint = ValueHint::FilePath,
value_parser,
default_value = CACHE_FILE_PATH_STR.as_str()
)]
cache: PathBuf,
},
Kill {
#[clap(short, long, default_value_t, value_enum)]
format: Format,
#[clap(flatten)]
network: NetworkSettings,
id: ConnectionId,
},
}
impl ManagerSubcommand {
#[inline]
pub fn format(&self) -> Format {
match self {
Self::Select { format, .. } => *format,
Self::Service(_) => Format::Shell,
Self::Listen { .. } => Format::Shell,
Self::Version { format, .. } => *format,
Self::Info { format, .. } => *format,
Self::List { format, .. } => *format,
Self::Kill { format, .. } => *format,
}
}
}
#[derive(Debug, PartialEq, Eq, Subcommand, IsVariant)]
pub enum ManagerServiceSubcommand {
Start {
#[clap(long, value_enum)]
kind: Option<ServiceManagerKind>,
#[clap(long)]
user: bool,
},
Stop {
#[clap(long, value_enum)]
kind: Option<ServiceManagerKind>,
#[clap(long)]
user: bool,
},
Install {
#[clap(long, value_enum)]
kind: Option<ServiceManagerKind>,
#[clap(long)]
user: bool,
#[clap(name = "ARGS", last = true)]
args: Vec<String>,
},
Uninstall {
#[clap(long, value_enum)]
kind: Option<ServiceManagerKind>,
#[clap(long)]
user: bool,
},
}
#[derive(Debug, PartialEq, Subcommand, IsVariant)]
pub enum ServerSubcommand {
Listen {
#[clap(long, value_name = "ssh|any|IP", default_value_t = Value::Default(BindAddress::Any))]
host: Value<BindAddress>,
#[clap(long, value_name = "PORT[:PORT2]", default_value_t = Value::Default(PortRange::EPHEMERAL))]
port: Value<PortRange>,
#[clap(short = '6', long)]
use_ipv6: bool,
#[clap(long, default_value_t = Value::Default(Shutdown::Never))]
shutdown: Value<Shutdown>,
#[clap(long)]
current_dir: Option<PathBuf>,
#[clap(long)]
daemon: bool,
#[clap(flatten)]
watch: ServerListenWatchOptions,
#[clap(long)]
key_from_stdin: bool,
#[clap(long, help = None, long_help = None)]
output_to_local_pipe: Option<std::ffi::OsString>,
},
}
impl ServerSubcommand {
#[inline]
pub fn format(&self) -> Format {
Format::Shell
}
}
#[derive(Args, Debug, PartialEq)]
pub struct ServerListenWatchOptions {
#[clap(long)]
pub watch_polling: bool,
#[clap(long)]
pub watch_poll_interval: Option<Seconds>,
#[clap(long)]
pub watch_compare_contents: bool,
#[clap(long, default_value_t = Value::Default(Seconds::try_from(0.5).unwrap()))]
pub watch_debounce_timeout: Value<Seconds>,
#[clap(long)]
pub watch_debounce_tick_rate: Option<Seconds>,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, ValueEnum)]
#[clap(rename_all = "snake_case")]
pub enum Format {
Json,
Shell,
}
impl Format {
pub fn is_json(self) -> bool {
matches!(self, Self::Json)
}
}
impl Default for Format {
fn default() -> Self {
Self::Shell
}
}
#[cfg(test)]
mod tests {
use std::time::Duration;
use distant_core::net::common::Host;
use distant_core::net::map;
use super::*;
#[test]
fn distant_api_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Client(ClientSubcommand::Api {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
timeout: None,
}),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
api: ClientApiConfig {
timeout: Some(Seconds::from(5u32)),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Client(ClientSubcommand::Api {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
timeout: Some(Seconds::from(5u32)),
}),
}
);
}
#[test]
fn distant_api_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::Api {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
timeout: Some(Seconds::from(99u32)),
}),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
api: ClientApiConfig {
timeout: Some(Seconds::from(5u32)),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::Api {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
timeout: Some(Seconds::from(99u32)),
}),
}
);
}
#[test]
fn distant_capabilities_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Client(ClientSubcommand::Version {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
format: Format::Json,
}),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
connect: ClientConnectConfig {
options: map!("hello" -> "world"),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Client(ClientSubcommand::Version {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
format: Format::Json,
}),
}
);
}
#[test]
fn distant_capabilities_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::Version {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
format: Format::Json,
}),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
connect: ClientConnectConfig {
options: map!("hello" -> "world", "config" -> "value"),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::Version {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
format: Format::Json,
}),
}
);
}
#[test]
fn distant_connect_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Client(ClientSubcommand::Connect {
cache: PathBuf::new(),
options: map!(),
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
format: Format::Json,
destination: Box::new("test://destination".parse().unwrap()),
}),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
connect: ClientConnectConfig {
options: map!("hello" -> "world"),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Client(ClientSubcommand::Connect {
cache: PathBuf::new(),
options: map!("hello" -> "world"),
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
format: Format::Json,
destination: Box::new("test://destination".parse().unwrap()),
}),
}
);
}
#[test]
fn distant_connect_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::Connect {
cache: PathBuf::new(),
options: map!("hello" -> "test", "cli" -> "value"),
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
format: Format::Json,
destination: Box::new("test://destination".parse().unwrap()),
}),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
connect: ClientConnectConfig {
options: map!("hello" -> "world", "config" -> "value"),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::Connect {
cache: PathBuf::new(),
options: map!("hello" -> "test", "cli" -> "value", "config" -> "value"),
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
format: Format::Json,
destination: Box::new("test://destination".parse().unwrap()),
}),
}
);
}
#[test]
fn distant_launch_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Client(ClientSubcommand::Launch {
cache: PathBuf::new(),
distant_bin: None,
distant_bind_server: None,
distant_args: None,
options: map!(),
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
format: Format::Json,
destination: Box::new("test://destination".parse().unwrap()),
}),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
launch: ClientLaunchConfig {
distant: ClientLaunchDistantConfig {
args: Some(String::from("config-args")),
bin: Some(String::from("config-bin")),
bind_server: Some(BindAddress::Host(Host::Name(String::from(
"config-host",
)))),
},
options: map!("hello" -> "world"),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Client(ClientSubcommand::Launch {
cache: PathBuf::new(),
distant_args: Some(String::from("config-args")),
distant_bin: Some(String::from("config-bin")),
distant_bind_server: Some(BindAddress::Host(Host::Name(String::from(
"config-host",
)))),
options: map!("hello" -> "world"),
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
format: Format::Json,
destination: Box::new("test://destination".parse().unwrap()),
}),
}
);
}
#[test]
fn distant_launch_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::Launch {
cache: PathBuf::new(),
distant_args: Some(String::from("cli-args")),
distant_bin: Some(String::from("cli-bin")),
distant_bind_server: Some(BindAddress::Host(Host::Name(String::from("cli-host")))),
options: map!("hello" -> "test", "cli" -> "value"),
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
format: Format::Json,
destination: Box::new("test://destination".parse().unwrap()),
}),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
launch: ClientLaunchConfig {
distant: ClientLaunchDistantConfig {
args: Some(String::from("config-args")),
bin: Some(String::from("config-bin")),
bind_server: Some(BindAddress::Host(Host::Name(String::from(
"config-host",
)))),
},
options: map!("hello" -> "world", "config" -> "value"),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::Launch {
cache: PathBuf::new(),
distant_args: Some(String::from("cli-args")),
distant_bin: Some(String::from("cli-bin")),
distant_bind_server: Some(BindAddress::Host(Host::Name(String::from(
"cli-host",
)))),
options: map!("hello" -> "test", "config" -> "value", "cli" -> "value"),
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
format: Format::Json,
destination: Box::new("test://destination".parse().unwrap()),
}),
}
);
}
#[test]
fn distant_shell_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Client(ClientSubcommand::Shell {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
current_dir: None,
environment: Default::default(),
cmd: None,
}),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Client(ClientSubcommand::Shell {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
current_dir: None,
environment: map!(),
cmd: None,
}),
}
);
}
#[test]
fn distant_shell_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::Shell {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
current_dir: None,
environment: map!(),
cmd: None,
}),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::Shell {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
current_dir: None,
environment: map!(),
cmd: None,
}),
}
);
}
#[test]
fn distant_spawn_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Client(ClientSubcommand::Spawn {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
current_dir: None,
environment: map!(),
lsp: Some(None),
shell: Some(None),
pty: true,
cmd_str: None,
cmd: vec![String::from("cmd")],
}),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Client(ClientSubcommand::Spawn {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
current_dir: None,
environment: map!(),
lsp: Some(None),
shell: Some(None),
pty: true,
cmd_str: None,
cmd: vec![String::from("cmd")],
}),
}
);
}
#[test]
fn distant_spawn_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::Spawn {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
current_dir: None,
environment: map!(),
lsp: Some(None),
shell: Some(None),
pty: true,
cmd_str: None,
cmd: vec![String::from("cmd")],
}),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::Spawn {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
current_dir: None,
environment: map!(),
lsp: Some(None),
shell: Some(None),
pty: true,
cmd_str: None,
cmd: vec![String::from("cmd")],
}),
}
);
}
#[test]
fn distant_system_info_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Client(ClientSubcommand::SystemInfo {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
}),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Client(ClientSubcommand::SystemInfo {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
}),
}
);
}
#[test]
fn distant_system_info_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::SystemInfo {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
}),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::SystemInfo {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
}),
}
);
}
#[test]
fn distant_fs_copy_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Copy {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
src: PathBuf::from("src"),
dst: PathBuf::from("dst"),
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Copy {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
src: PathBuf::from("src"),
dst: PathBuf::from("dst"),
}
)),
}
);
}
#[test]
fn distant_fs_copy_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Copy {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
src: PathBuf::from("src"),
dst: PathBuf::from("dst"),
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Copy {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
src: PathBuf::from("src"),
dst: PathBuf::from("dst"),
}
)),
}
);
}
#[test]
fn distant_fs_exists_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Exists {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
path: PathBuf::from("path"),
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Exists {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
path: PathBuf::from("path"),
}
)),
}
);
}
#[test]
fn distant_fs_exists_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Exists {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
path: PathBuf::from("path"),
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Exists {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
path: PathBuf::from("path"),
}
)),
}
);
}
#[test]
fn distant_fs_makedir_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::MakeDir {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
path: PathBuf::from("path"),
all: true,
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::MakeDir {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
path: PathBuf::from("path"),
all: true,
}
)),
}
);
}
#[test]
fn distant_fs_makedir_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::MakeDir {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
path: PathBuf::from("path"),
all: true,
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::MakeDir {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
path: PathBuf::from("path"),
all: true,
}
)),
}
);
}
#[test]
fn distant_fs_metadata_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Metadata {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
canonicalize: true,
resolve_file_type: true,
path: PathBuf::from("path"),
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Metadata {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
canonicalize: true,
resolve_file_type: true,
path: PathBuf::from("path"),
}
)),
}
);
}
#[test]
fn distant_fs_metadata_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Metadata {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
canonicalize: true,
resolve_file_type: true,
path: PathBuf::from("path"),
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Metadata {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
canonicalize: true,
resolve_file_type: true,
path: PathBuf::from("path"),
}
)),
}
);
}
#[test]
fn distant_fs_read_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Read {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
path: PathBuf::from("path"),
depth: 1,
absolute: true,
canonicalize: true,
include_root: true,
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Read {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
path: PathBuf::from("path"),
depth: 1,
absolute: true,
canonicalize: true,
include_root: true,
}
)),
}
);
}
#[test]
fn distant_fs_read_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Read {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
path: PathBuf::from("path"),
depth: 1,
absolute: true,
canonicalize: true,
include_root: true,
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Read {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
path: PathBuf::from("path"),
depth: 1,
absolute: true,
canonicalize: true,
include_root: true,
}
)),
}
);
}
#[test]
fn distant_fs_remove_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Remove {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
path: PathBuf::from("path"),
force: true,
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Remove {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
path: PathBuf::from("path"),
force: true,
}
)),
}
);
}
#[test]
fn distant_fs_remove_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Remove {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
path: PathBuf::from("path"),
force: true,
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Remove {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
path: PathBuf::from("path"),
force: true,
}
)),
}
);
}
#[test]
fn distant_fs_rename_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Rename {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
src: PathBuf::from("src"),
dst: PathBuf::from("dst"),
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Rename {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
src: PathBuf::from("src"),
dst: PathBuf::from("dst"),
}
)),
}
);
}
#[test]
fn distant_fs_rename_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Rename {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
src: PathBuf::from("src"),
dst: PathBuf::from("dst"),
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Rename {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
src: PathBuf::from("src"),
dst: PathBuf::from("dst"),
}
)),
}
);
}
#[test]
fn distant_fs_search_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Search {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
target: CliSearchQueryTarget::Contents,
condition: CliSearchQueryCondition::regex(".*"),
options: Default::default(),
paths: vec![PathBuf::from(".")],
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Search {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
target: CliSearchQueryTarget::Contents,
condition: CliSearchQueryCondition::regex(".*"),
options: Default::default(),
paths: vec![PathBuf::from(".")],
}
)),
}
);
}
#[test]
fn distant_fs_search_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Search {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
target: CliSearchQueryTarget::Contents,
condition: CliSearchQueryCondition::regex(".*"),
options: Default::default(),
paths: vec![PathBuf::from(".")],
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Search {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
target: CliSearchQueryTarget::Contents,
condition: CliSearchQueryCondition::regex(".*"),
options: Default::default(),
paths: vec![PathBuf::from(".")],
}
)),
}
);
}
#[test]
fn distant_fs_watch_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Watch {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
recursive: true,
only: ChangeKind::all(),
except: ChangeKind::all(),
path: PathBuf::from("path"),
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Watch {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
recursive: true,
only: ChangeKind::all(),
except: ChangeKind::all(),
path: PathBuf::from("path"),
}
)),
}
);
}
#[test]
fn distant_fs_watch_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Watch {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
recursive: true,
only: ChangeKind::all(),
except: ChangeKind::all(),
path: PathBuf::from("path"),
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Watch {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
recursive: true,
only: ChangeKind::all(),
except: ChangeKind::all(),
path: PathBuf::from("path"),
}
)),
}
);
}
#[test]
fn distant_fs_write_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Write {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
append: false,
path: PathBuf::from("path"),
data: None,
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Write {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
append: false,
path: PathBuf::from("path"),
data: None,
}
)),
}
);
}
#[test]
fn distant_fs_write_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Write {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
append: false,
path: PathBuf::from("path"),
data: None,
},
)),
};
options.merge(Config {
client: ClientConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Client(ClientSubcommand::FileSystem(
ClientFileSystemSubcommand::Write {
cache: PathBuf::new(),
connection: None,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
append: false,
path: PathBuf::from("path"),
data: None,
}
)),
}
);
}
#[test]
fn distant_generate_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Generate(GenerateSubcommand::Completion {
output: None,
shell: ClapCompleteShell::Bash,
}),
};
options.merge(Config {
generate: GenerateConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Generate(GenerateSubcommand::Completion {
output: None,
shell: ClapCompleteShell::Bash,
}),
}
);
}
#[test]
fn distant_generate_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Generate(GenerateSubcommand::Completion {
output: None,
shell: ClapCompleteShell::Bash,
}),
};
options.merge(Config {
generate: GenerateConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Generate(GenerateSubcommand::Completion {
output: None,
shell: ClapCompleteShell::Bash,
}),
}
);
}
#[test]
fn distant_manager_capabilities_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Manager(ManagerSubcommand::Version {
format: Format::Json,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
}),
};
options.merge(Config {
manager: ManagerConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Version {
format: Format::Json,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
}),
}
);
}
#[test]
fn distant_manager_capabilities_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Version {
format: Format::Json,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
}),
};
options.merge(Config {
manager: ManagerConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Version {
format: Format::Json,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
}),
}
);
}
#[test]
fn distant_manager_info_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Manager(ManagerSubcommand::Info {
id: 0,
format: Format::Json,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
}),
};
options.merge(Config {
manager: ManagerConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Info {
id: 0,
format: Format::Json,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
}),
}
);
}
#[test]
fn distant_manager_info_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Info {
id: 0,
format: Format::Json,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
}),
};
options.merge(Config {
manager: ManagerConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Info {
id: 0,
format: Format::Json,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
}),
}
);
}
#[test]
fn distant_manager_kill_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Manager(ManagerSubcommand::Kill {
id: 0,
format: Format::Json,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
}),
};
options.merge(Config {
manager: ManagerConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Kill {
id: 0,
format: Format::Json,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
}),
}
);
}
#[test]
fn distant_manager_kill_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Kill {
id: 0,
format: Format::Json,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
}),
};
options.merge(Config {
manager: ManagerConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Kill {
id: 0,
format: Format::Json,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
}),
}
);
}
#[test]
fn distant_manager_list_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Manager(ManagerSubcommand::List {
cache: PathBuf::new(),
format: Format::Json,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
}),
};
options.merge(Config {
manager: ManagerConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Manager(ManagerSubcommand::List {
cache: PathBuf::new(),
format: Format::Json,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
}),
}
);
}
#[test]
fn distant_manager_list_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Manager(ManagerSubcommand::List {
cache: PathBuf::new(),
format: Format::Json,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
}),
};
options.merge(Config {
manager: ManagerConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Manager(ManagerSubcommand::List {
cache: PathBuf::new(),
format: Format::Json,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
}),
}
);
}
#[test]
fn distant_manager_listen_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Manager(ManagerSubcommand::Listen {
access: None,
daemon: false,
user: false,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
}),
};
options.merge(Config {
manager: ManagerConfig {
access: Some(AccessControl::Group),
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Listen {
access: Some(AccessControl::Group),
daemon: false,
user: false,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
}),
}
);
}
#[test]
fn distant_manager_listen_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Listen {
access: Some(AccessControl::Owner),
daemon: false,
user: false,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
}),
};
options.merge(Config {
manager: ManagerConfig {
access: Some(AccessControl::Group),
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Listen {
access: Some(AccessControl::Owner),
daemon: false,
user: false,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
}),
}
);
}
#[test]
fn distant_manager_select_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Manager(ManagerSubcommand::Select {
cache: PathBuf::new(),
connection: None,
format: Format::Json,
network: NetworkSettings {
unix_socket: None,
windows_pipe: None,
},
}),
};
options.merge(Config {
manager: ManagerConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Select {
cache: PathBuf::new(),
connection: None,
format: Format::Json,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
}),
}
);
}
#[test]
fn distant_manager_select_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Select {
cache: PathBuf::new(),
connection: None,
format: Format::Json,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
}),
};
options.merge(Config {
manager: ManagerConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
network: NetworkSettings {
unix_socket: Some(PathBuf::from("config-unix-socket")),
windows_pipe: Some(String::from("config-windows-pipe")),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Select {
cache: PathBuf::new(),
connection: None,
format: Format::Json,
network: NetworkSettings {
unix_socket: Some(PathBuf::from("cli-unix-socket")),
windows_pipe: Some(String::from("cli-windows-pipe")),
},
}),
}
);
}
#[test]
fn distant_manager_service_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Manager(ManagerSubcommand::Service(
ManagerServiceSubcommand::Install {
kind: None,
user: false,
args: Vec::new(),
},
)),
};
options.merge(Config {
manager: ManagerConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Service(
ManagerServiceSubcommand::Install {
kind: None,
user: false,
args: Vec::new(),
},
)),
}
);
}
#[test]
fn distant_manager_service_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Service(
ManagerServiceSubcommand::Install {
kind: None,
user: false,
args: Vec::new(),
},
)),
};
options.merge(Config {
manager: ManagerConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
..Default::default()
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Manager(ManagerSubcommand::Service(
ManagerServiceSubcommand::Install {
kind: None,
user: false,
args: Vec::new(),
},
)),
}
);
}
#[test]
fn distant_server_listen_should_support_merging_with_config() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: None,
log_level: None,
},
command: DistantSubcommand::Server(ServerSubcommand::Listen {
host: Value::Default(BindAddress::Any),
port: Value::Default(PortRange::single(123)),
use_ipv6: false,
shutdown: Value::Default(Shutdown::After(Duration::from_secs(123))),
current_dir: None,
watch: ServerListenWatchOptions {
watch_polling: false,
watch_poll_interval: None,
watch_compare_contents: false,
watch_debounce_timeout: Value::Default(Seconds::try_from(0.5).unwrap()),
watch_debounce_tick_rate: None,
},
daemon: false,
key_from_stdin: false,
output_to_local_pipe: None,
}),
};
options.merge(Config {
server: ServerConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
listen: ServerListenConfig {
host: Some(BindAddress::Ssh),
port: Some(PortRange::single(456)),
use_ipv6: true,
shutdown: Some(Shutdown::Lonely(Duration::from_secs(456))),
current_dir: Some(PathBuf::from("config-dir")),
},
watch: ServerWatchConfig {
native: false,
poll_interval: Some(Seconds::from(100u32)),
compare_contents: true,
debounce_timeout: Some(Seconds::from(200u32)),
debounce_tick_rate: Some(Seconds::from(300u32)),
},
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
command: DistantSubcommand::Server(ServerSubcommand::Listen {
host: Value::Explicit(BindAddress::Ssh),
port: Value::Explicit(PortRange::single(456)),
use_ipv6: true,
shutdown: Value::Explicit(Shutdown::Lonely(Duration::from_secs(456))),
current_dir: Some(PathBuf::from("config-dir")),
watch: ServerListenWatchOptions {
watch_polling: true,
watch_poll_interval: Some(Seconds::from(100u32)),
watch_compare_contents: true,
watch_debounce_timeout: Value::Explicit(Seconds::from(200u32)),
watch_debounce_tick_rate: Some(Seconds::from(300u32)),
},
daemon: false,
key_from_stdin: false,
output_to_local_pipe: None,
}),
}
);
}
#[test]
fn distant_server_listen_should_prioritize_explicit_cli_options_when_merging() {
let mut options = Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Server(ServerSubcommand::Listen {
host: Value::Explicit(BindAddress::Any),
port: Value::Explicit(PortRange::single(123)),
use_ipv6: true,
shutdown: Value::Explicit(Shutdown::After(Duration::from_secs(123))),
current_dir: Some(PathBuf::from("cli-dir")),
watch: ServerListenWatchOptions {
watch_polling: true,
watch_poll_interval: Some(Seconds::from(10u32)),
watch_compare_contents: true,
watch_debounce_timeout: Value::Explicit(Seconds::from(20u32)),
watch_debounce_tick_rate: Some(Seconds::from(30u32)),
},
daemon: false,
key_from_stdin: false,
output_to_local_pipe: None,
}),
};
options.merge(Config {
server: ServerConfig {
logging: LoggingSettings {
log_file: Some(PathBuf::from("config-log-file")),
log_level: Some(LogLevel::Trace),
},
listen: ServerListenConfig {
host: Some(BindAddress::Ssh),
port: Some(PortRange::single(456)),
use_ipv6: false,
shutdown: Some(Shutdown::Lonely(Duration::from_secs(456))),
current_dir: Some(PathBuf::from("config-dir")),
},
watch: ServerWatchConfig {
native: true,
poll_interval: Some(Seconds::from(100u32)),
compare_contents: false,
debounce_timeout: Some(Seconds::from(200u32)),
debounce_tick_rate: Some(Seconds::from(300u32)),
},
},
..Default::default()
});
assert_eq!(
options,
Options {
config_path: None,
logging: LoggingSettings {
log_file: Some(PathBuf::from("cli-log-file")),
log_level: Some(LogLevel::Info),
},
command: DistantSubcommand::Server(ServerSubcommand::Listen {
host: Value::Explicit(BindAddress::Any),
port: Value::Explicit(PortRange::single(123)),
use_ipv6: true,
shutdown: Value::Explicit(Shutdown::After(Duration::from_secs(123))),
current_dir: Some(PathBuf::from("cli-dir")),
watch: ServerListenWatchOptions {
watch_polling: true,
watch_poll_interval: Some(Seconds::from(10u32)),
watch_compare_contents: true,
watch_debounce_timeout: Value::Explicit(Seconds::from(20u32)),
watch_debounce_tick_rate: Some(Seconds::from(30u32)),
},
daemon: false,
key_from_stdin: false,
output_to_local_pipe: None,
}),
}
);
}
}