1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
use std::fs;
use tools::{println_cargo_style, run_cmd};
const OUTPUT_DIR: &str = "docs/cov-test";
fn main() {
let repo_root = find_git_repo().expect("Failed to find git repository root");
let output_path = repo_root.join(OUTPUT_DIR);
// Read features from [package.metadata.docs.rs]
let features = tools::read_features().unwrap_or_else(|e| {
eprintln!("Error: {}", e);
std::process::exit(1);
});
let features_arg = features.join(",");
// Ensure output directory exists
std::fs::create_dir_all(&output_path).expect("Failed to create output directory");
let cmd = format!(
"cargo llvm-cov --html --output-dir \"{}\" --workspace --features \"{}\" --color always",
output_path.to_string_lossy(),
features_arg,
);
println_cargo_style!("Features: {}", features_arg);
println_cargo_style!("Coverage: {}", output_path.display());
println_cargo_style!("Running: cargo llvm-cov --html");
run_cmd!(&cmd).unwrap_or_else(|code| {
eprintln!("Error: cargo llvm-cov failed with exit code {}", code);
std::process::exit(code);
});
// Move files from <output_path>/html/ to <output_path>
let html_dir = output_path.join("html");
if html_dir.exists() && html_dir.is_dir() {
println_cargo_style!("Moving files from {}/html/ to {}/", OUTPUT_DIR, OUTPUT_DIR);
// Move each entry in html_dir up one level
for entry in fs::read_dir(&html_dir).expect("Failed to read html directory") {
let entry = entry.expect("Failed to read entry");
let entry_path = entry.path();
let file_name = entry
.file_name()
.to_str()
.expect("Invalid filename")
.to_owned();
let dest_path = output_path.join(&file_name);
// Remove existing file/directory at destination if any
if dest_path.exists() {
if dest_path.is_dir() {
fs::remove_dir_all(&dest_path).unwrap_or_else(|e| {
eprintln!(
"Warning: could not remove directory {}: {}",
dest_path.display(),
e
);
});
} else {
fs::remove_file(&dest_path).unwrap_or_else(|e| {
eprintln!(
"Warning: could not remove file {}: {}",
dest_path.display(),
e
);
});
}
}
fs::rename(&entry_path, &dest_path).unwrap_or_else(|e| {
eprintln!("Warning: could not move {}: {}", entry_path.display(), e);
});
}
// Remove the now-empty html directory
fs::remove_dir(&html_dir).unwrap_or_else(|e| {
eprintln!("Warning: could not remove html directory: {}", e);
});
println_cargo_style!("Files moved successfully.");
}
println_cargo_style!(
"Done: coverage report generated at {}/index.html",
OUTPUT_DIR
);
}
fn find_git_repo() -> Option<std::path::PathBuf> {
let mut current_dir = std::env::current_dir().ok()?;
loop {
let git_dir = current_dir.join(".git");
if git_dir.exists() && git_dir.is_dir() {
return Some(current_dir);
}
if !current_dir.pop() {
break;
}
}
None
}
|