api_testing_core/
cli_history.rs1use std::io::Write;
2use std::path::{Path, PathBuf};
3
4use crate::{Result, cli_util, history};
5
6pub fn resolve_history_file<F>(
7 cwd: &Path,
8 config_dir: Option<&Path>,
9 file_override_arg: Option<&str>,
10 env_override_var: &str,
11 resolve_setup_dir: F,
12 default_filename: &str,
13) -> Result<PathBuf>
14where
15 F: FnOnce(&Path, Option<&Path>) -> Result<PathBuf>,
16{
17 let setup_dir = resolve_setup_dir(cwd, config_dir)?;
18 let file_override = file_override_arg
19 .and_then(cli_util::trim_non_empty)
20 .or_else(|| {
21 std::env::var(env_override_var)
22 .ok()
23 .and_then(|s| cli_util::trim_non_empty(&s))
24 });
25 let file_override = file_override.as_deref().map(Path::new);
26
27 Ok(history::resolve_history_file(
28 &setup_dir,
29 file_override,
30 default_filename,
31 ))
32}
33
34pub fn run_history_command(
35 history_file: &Path,
36 tail: Option<u32>,
37 command_only: bool,
38 stdout: &mut dyn Write,
39 stderr: &mut dyn Write,
40) -> i32 {
41 if !history_file.is_file() {
42 let _ = writeln!(stderr, "History file not found: {}", history_file.display());
43 return 1;
44 }
45
46 let records = match history::read_records(history_file) {
47 Ok(v) => v,
48 Err(err) => {
49 let _ = writeln!(stderr, "{err}");
50 return 1;
51 }
52 };
53 if records.is_empty() {
54 return 3;
55 }
56
57 let n = tail.unwrap_or(1).max(1) as usize;
58 let start = records.len().saturating_sub(n);
59 for record in &records[start..] {
60 if command_only && record.starts_with('#') {
61 let trimmed = record
62 .split_once('\n')
63 .map(|(_first, rest)| rest)
64 .unwrap_or_default();
65 let _ = stdout.write_all(trimmed.as_bytes());
66 if trimmed.is_empty() {
67 let _ = stdout.write_all(b"\n\n");
68 }
69 } else {
70 let _ = stdout.write_all(record.as_bytes());
71 }
72 }
73
74 0
75}