mit_hook_test_helper/
lib.rs1#![warn(clippy::nursery)]
4#![deny(
5 unused,
6 nonstandard_style,
7 future_incompatible,
8 missing_copy_implementations,
9 missing_debug_implementations,
10 missing_docs,
11 clippy::cargo,
12 clippy::complexity,
13 clippy::correctness,
14 clippy::perf,
15 clippy::style,
16 clippy::suspicious,
17 clippy::pedantic,
18 non_fmt_panics
19)]
20#![allow(clippy::multiple_crate_versions)]
21
22use std::{
23 env,
24 error::Error,
25 fmt,
26 fmt::{Display, Formatter},
27 path::{Path, PathBuf},
28 process::{Command, Output},
29 str,
30 time::Duration,
31};
32
33use git2::{Config, Repository};
34use tempfile::TempDir;
35
36#[must_use]
42pub fn run_hook(working_dir: &Path, package: &str, arguments: Vec<&str>) -> Output {
43 let toml_path = calculate_cargo_toml_path(package);
44 let mut cargo_arguments = vec![
45 "run",
46 "--locked",
47 "--quiet",
48 "--manifest-path",
49 &toml_path,
50 "--",
51 ];
52 cargo_arguments.extend(arguments);
53
54 Command::new("cargo")
55 .current_dir(working_dir)
56 .args(cargo_arguments)
57 .output()
58 .expect("failed to execute process")
59}
60
61#[derive(Debug)]
62struct PathError;
63
64impl Error for PathError {}
65
66impl Display for PathError {
67 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
68 write!(f, "Path not found")
69 }
70}
71pub fn set_co_author(working_dir: &Path, author_name: &str, author_email: &str, index: i64) {
78 Command::new("git")
79 .current_dir(working_dir)
80 .arg("config")
81 .arg("--local")
82 .arg(format!("mit.author.coauthors.{index}.name"))
83 .arg(author_name)
84 .output()
85 .expect("failed to execute process");
86 Command::new("git")
87 .current_dir(working_dir)
88 .arg("config")
89 .arg("--local")
90 .arg(format!("mit.author.coauthors.{index}.email"))
91 .arg(author_email)
92 .output()
93 .expect("failed to execute process");
94}
95
96pub fn set_author_expires(expiration_time: Duration, working_dir: &Path) {
103 let now = format!("{}", expiration_time.as_secs());
104 Command::new("git")
105 .current_dir(working_dir)
106 .arg("config")
107 .arg("--local")
108 .arg("--type")
109 .arg("expiry-date")
110 .arg("mit.author.expires")
111 .arg(now)
112 .output()
113 .expect("failed to execute process");
114}
115
116#[must_use]
120pub fn calculate_cargo_toml_path(package: &str) -> String {
121 let boxed_path_error = || Box::from(PathError);
122 let parent_directory = |x: PathBuf| x.parent().ok_or_else(boxed_path_error).map(PathBuf::from);
123 let bin_root = |x: PathBuf| x.join(package);
124 let cargo_toml = |x: PathBuf| x.join("Cargo.toml");
125 let path_buf_to_string = |x: PathBuf| x.to_str().ok_or_else(boxed_path_error).map(String::from);
126
127 env::current_exe()
128 .map_err(Box::<dyn Error>::from)
129 .and_then(parent_directory)
130 .and_then(parent_directory)
131 .and_then(parent_directory)
132 .and_then(parent_directory)
133 .map(bin_root)
134 .map(cargo_toml)
135 .and_then(path_buf_to_string)
136 .unwrap()
137}
138
139#[must_use]
147pub fn make_config() -> Config {
148 let add_repository_to_path = |x: PathBuf| x.join("repository");
149 TempDir::new()
150 .map(TempDir::keep)
151 .map(add_repository_to_path)
152 .map(Repository::init)
153 .expect("Failed to initialise the repository")
154 .expect("Failed create temporary directory")
155 .config()
156 .expect("Failed to get configuration")
157}
158
159pub fn assert_output(
163 output: &Output,
164 expected_stdout: &str,
165 expected_stderr: &str,
166 expect_success: bool,
167) {
168 let stdout = str::from_utf8(&output.stdout).expect("stdout couldn't be parsed");
169 let stderr = str::from_utf8(&output.stderr).expect("stderr couldn't be parsed");
170 assert_eq!(
171 stdout,
172 expected_stdout,
173 "Expected stdout to be {:?}, instead it contained {:?} stderr {:?} status {:?}",
174 expected_stdout,
175 stdout,
176 stderr,
177 output.status.code()
178 );
179 assert_eq!(
180 stderr,
181 expected_stderr,
182 "Expected stderr to {:?}, instead it contained {:?} stderr {:?} status {:?}",
183 expected_stderr,
184 stderr,
185 stdout,
186 output.status.code()
187 );
188 assert_eq!(
189 output.status.success(),
190 expect_success,
191 "Expected status to be {:?}, instead it was {:?} stdout {:?} stderr {:?}",
192 expect_success,
193 &output.status.code(),
194 stdout,
195 stderr
196 );
197}
198
199#[must_use]
208pub fn setup_working_dir() -> PathBuf {
209 let add_repository = |x: PathBuf| x.join("repository");
210 let temp = TempDir::new()
211 .map(TempDir::keep)
212 .map(add_repository)
213 .expect("Unable to make path");
214 Repository::init(&temp).expect("Couldn't create repo");
215
216 temp
217}