#![allow(dead_code)]
use assert_cmd::Command as Cli;
use std::io::Write;
use std::process::{Command as Sys, Stdio};
use tempfile::TempDir;
pub fn git(dir: &TempDir) -> Sys {
let mut cmd = Sys::new("git");
cmd.current_dir(dir.path());
cmd.env(
"GIT_CONFIG_GLOBAL",
dir.path().join("absent-global-gitconfig"),
);
cmd.env(
"GIT_CONFIG_SYSTEM",
dir.path().join("absent-system-gitconfig"),
);
hunkpick::gitenv::insulate_repo_location(&mut cmd);
cmd
}
pub fn git_with_stdin(dir: &TempDir, args: &[&str], stdin_bytes: &[u8]) -> std::process::Output {
let mut child = git(dir)
.args(args)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.unwrap();
let mut stdin = child.stdin.take().expect("stdin was configured as piped");
std::thread::scope(|scope| {
scope.spawn(move || stdin.write_all(stdin_bytes));
child.wait_with_output().unwrap()
})
}
pub fn repo_with(old_files: &[(&str, &str)]) -> TempDir {
let dir = tempfile::tempdir().unwrap();
sys(&dir, &["init", "-q"]);
sys(&dir, &["config", "user.email", "t@t"]);
sys(&dir, &["config", "user.name", "t"]);
sys(&dir, &["config", "core.autocrlf", "false"]);
if old_files.is_empty() {
sys(&dir, &["commit", "-q", "-m", "init", "--allow-empty"]);
} else {
for (p, c) in old_files {
let full = dir.path().join(p);
std::fs::create_dir_all(full.parent().unwrap()).unwrap();
std::fs::write(full, c).unwrap();
}
sys(&dir, &["add", "."]);
sys(&dir, &["commit", "-q", "-m", "init"]);
}
dir
}
pub fn sys(dir: &TempDir, args: &[&str]) {
let ok = git(dir).args(args).status().unwrap().success();
assert!(ok, "git {args:?} failed");
}
pub fn git_output(dir: &TempDir, args: &[&str]) -> String {
String::from_utf8(git_output_bytes(dir, args)).unwrap()
}
pub fn git_output_bytes(dir: &TempDir, args: &[&str]) -> Vec<u8> {
git(dir).args(args).output().unwrap().stdout
}
pub fn diff_after(dir: &TempDir, new_files: &[(&str, &str)]) -> String {
for (p, c) in new_files {
std::fs::write(dir.path().join(p), c).unwrap();
}
git_output(dir, &["diff"])
}
pub fn diff_staged(dir: &TempDir) -> String {
git_output(dir, &["diff", "--staged"])
}
pub fn revert(dir: &TempDir) {
sys(dir, &["checkout", "--", "."]);
}
pub fn apply_cached(dir: &TempDir, diff: &[u8]) {
apply_diff(dir, &["apply", "--cached"], diff, "git apply --cached");
}
pub fn apply_diff(dir: &TempDir, args: &[&str], diff: &[u8], what: &str) {
let out = git_with_stdin(dir, args, diff);
assert!(
out.status.success(),
"{what} failed: {}",
String::from_utf8_lossy(&out.stderr).trim()
);
}
pub fn run_ok(args: &[&str], stdin: &str) -> Vec<u8> {
Cli::cargo_bin("hunkpick")
.unwrap()
.args(args)
.write_stdin(stdin.to_string())
.assert()
.success()
.get_output()
.stdout
.clone()
}
pub fn run_ok_text(args: &[&str], stdin: &str) -> String {
String::from_utf8(run_ok(args, stdin)).unwrap()
}
pub fn select_checked(dir: &TempDir, diff: &str, selectors: &[&str]) -> assert_cmd::assert::Assert {
let mut cmd = Cli::cargo_bin("hunkpick").unwrap();
cmd.arg("select");
cmd.args(selectors);
cmd.args([
"--verify-result-diff-git",
"-C",
dir.path().to_str().unwrap(),
]);
cmd.write_stdin(diff.to_string()).assert()
}
pub fn select_checked_ok(dir: &TempDir, diff: &str, selectors: &[&str]) -> String {
let out = select_checked(dir, diff, selectors)
.success()
.get_output()
.stdout
.clone();
String::from_utf8(out).unwrap()
}