pub const NO_OPTIONAL_LOCKS: &str = "--no-optional-locks";
pub const STATUS_SUBCOMMAND: &str = "status";
pub const HUMAN_READABLE_STATUS_ARGS: &[&str] = &[];
pub const PORCELAIN_STATUS_ARGS: &[&str] = &["--porcelain"];
pub const DIRTY_STATE_STATUS_ARGS: &[&str] =
&["--porcelain", "--untracked-files=normal", "--ignored=no"];
pub const PORCELAIN_UNTRACKED_STATUS_ARGS: &[&str] = &["--porcelain", "--untracked-files=normal"];
pub const CHANGE_MONITOR_STATUS_ARGS: &[&str] = &["--porcelain", "-u"];
pub const PATH_SCOPED_PORCELAIN_STATUS_ARGS: &[&str] = &["--porcelain", "--"];
pub const PORCELAIN_V2_STATUS_ARGS: &[&str] = &["--porcelain=v2"];
pub fn read_only_status_argv<'a>(status_args: &[&'a str]) -> Vec<&'a str> {
let mut argv = Vec::with_capacity(status_args.len() + 2);
argv.push(NO_OPTIONAL_LOCKS);
argv.push(STATUS_SUBCOMMAND);
argv.extend_from_slice(status_args);
argv
}
pub fn read_only_status_command_display(status_args: &[&str]) -> String {
let mut rendered = String::from("git");
for arg in read_only_status_argv(status_args) {
rendered.push(' ');
rendered.push_str(arg);
}
rendered
}
#[cfg(test)]
#[path = "status_policy_repository_tests.rs"]
mod native_git_status_optional_locks_repository;
#[cfg(test)]
mod native_git_status_optional_locks {
use super::*;
fn assert_read_only_status_shape(argv: &[&str]) {
let option_index = argv
.iter()
.position(|arg| *arg == NO_OPTIONAL_LOCKS)
.unwrap_or_else(|| panic!("{argv:?} must disable optional index locks"));
let subcommand_index = argv
.iter()
.position(|arg| *arg == STATUS_SUBCOMMAND)
.unwrap_or_else(|| panic!("{argv:?} must run the status subcommand"));
assert!(
option_index < subcommand_index,
"`{NO_OPTIONAL_LOCKS}` is a Git global option and must precede `status`: {argv:?}"
);
assert_eq!(
option_index, 0,
"the global option belongs before every other argument: {argv:?}"
);
}
#[test]
fn policy_builder_puts_the_global_option_before_the_subcommand() {
assert_eq!(
read_only_status_argv(&["--porcelain"]),
vec!["--no-optional-locks", "status", "--porcelain"]
);
assert_eq!(
read_only_status_argv(&[]),
vec!["--no-optional-locks", "status"]
);
assert_read_only_status_shape(&read_only_status_argv(&["--porcelain"]));
assert_read_only_status_shape(&read_only_status_argv(&[]));
}
#[test]
fn every_declared_observation_keeps_its_exact_argv() {
let cases: [(&str, &[&str], &[&str]); 7] = [
(
"human readable",
HUMAN_READABLE_STATUS_ARGS,
&["--no-optional-locks", "status"],
),
(
"porcelain",
PORCELAIN_STATUS_ARGS,
&["--no-optional-locks", "status", "--porcelain"],
),
(
"dirty state",
DIRTY_STATE_STATUS_ARGS,
&[
"--no-optional-locks",
"status",
"--porcelain",
"--untracked-files=normal",
"--ignored=no",
],
),
(
"porcelain untracked",
PORCELAIN_UNTRACKED_STATUS_ARGS,
&[
"--no-optional-locks",
"status",
"--porcelain",
"--untracked-files=normal",
],
),
(
"change monitor",
CHANGE_MONITOR_STATUS_ARGS,
&["--no-optional-locks", "status", "--porcelain", "-u"],
),
(
"path scoped",
PATH_SCOPED_PORCELAIN_STATUS_ARGS,
&["--no-optional-locks", "status", "--porcelain", "--"],
),
(
"porcelain v2",
PORCELAIN_V2_STATUS_ARGS,
&["--no-optional-locks", "status", "--porcelain=v2"],
),
];
for (name, args, expected) in cases {
let argv = read_only_status_argv(args);
assert_eq!(argv, expected, "{name} observation argv drifted");
assert_read_only_status_shape(&argv);
}
}
#[test]
fn command_display_matches_the_argv_it_describes() {
assert_eq!(
read_only_status_command_display(DIRTY_STATE_STATUS_ARGS),
"git --no-optional-locks status --porcelain --untracked-files=normal --ignored=no"
);
assert_eq!(
read_only_status_command_display(HUMAN_READABLE_STATUS_ARGS),
"git --no-optional-locks status"
);
}
#[test]
fn suppression_is_never_delivered_through_process_environment() {
assert!(
std::env::var_os("GIT_OPTIONAL_LOCKS").is_none(),
"optional-lock suppression must stay child-command-local"
);
}
}