-
Notifications
You must be signed in to change notification settings - Fork 2
/
build.rs
151 lines (132 loc) · 5.48 KB
/
build.rs
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
use std::env;
use std::fs;
use std::io::Write;
use std::path::Path;
#[allow(clippy::doc_markdown)]
/// Create a separate test for each individual script in demo/, to ensure that it builds
/// successfully. We don't try to run them for logistical reasons, but at least we
/// identify abandoned scripts. Given that there are so many of these scripts, avoid
/// Cargo's default behaviour of running all tests in parallel. --test-threads=3 seems
/// to work best on my MacBook Air M1.
/// Suggested command: `RUST_LOG=thag=debug cargo test --features=debug-logs -- --nocapture --test-threads=3
/// You may want to adjust the test-threads value further depending on your hardware.
fn main() {
// Get the OUT_DIR environment variable
let out_dir = env::var("OUT_DIR").expect("OUT_DIR not set");
// Note: Cargo suppresses build output. I've tried log and env_logger, ChatGPT, Gemini, Stack Overflow etc.
// The only way it seems that it will display is looking in a *output file for
// println! and a *stderr file for eprintln! afterwards. -vv is suggested but
// doesn't seem to work. `find . -mtime 0 -name "*output" (or "*stderr") -ls`.
// https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script
eprintln!("OUT_DIR={out_dir}");
fs::create_dir_all(&out_dir).expect("Failed to create destination directory");
let out_dir_path = &Path::new(&out_dir);
let dest_path = out_dir_path.join("generated_tests.rs");
let mut file = fs::File::create(dest_path).expect("Failed to create generated_tests.rs");
let demo_dir = Path::new("demo");
eprintln!("source_path = demo_dir = {:#?}", demo_dir.canonicalize());
assert!(
demo_dir.exists() && demo_dir.is_dir(),
"demo directory does not exist"
);
// Define the source and destination paths
let dest_dir = &out_dir_path.join("demo");
// Create the destination directory if it doesn't exist
fs::create_dir_all(dest_dir).expect("Failed to create demo directory");
let skip_scripts_on_windows = [
"crossbeam_channel_stopwatch.rs",
"factorial_main_rug.rs",
"factorial_main_rug_product.rs",
"fib_4784969_cpp_rug.rs",
"fib_big_clap_rug.rs",
"fib_doubling_iterative_purge_rug.rs",
"fib_fac_rug.rs",
"fib_matrix_rug.rs",
"rug_arbitrary_precision_nums.rs",
];
let multimain = ["flume_async.rs", "flume_select.rs"];
let stable_only = [
"duration_main.rs",
"duration_snippet.rs",
"displayable_nightly.rs",
"displayable_nightly1.rs",
];
/*
let source_stem: &str = source_name
.strip_suffix(thag_rs::RS_SUFFIX)
.expect("Problem stripping Rust suffix");
let target_dir_path = TMPDIR
.join("thag_rs")
.join(source_stem)
.join("target/debug");
let target_path = #[cfg(windows) {
target_dir_path.join(source_stem.to_string() + ".exe")
} #[cfg(Not(windows)) {
target_dir_path.join(&source_stem)
};
*/
for entry in fs::read_dir(demo_dir).expect("Failed to read demo directory") {
let entry = entry.expect("Failed to get directory entry");
let path = entry.path();
if path.extension().and_then(|s| s.to_str()) == Some("rs") {
let source_name = path
.file_name()
.and_then(|s| s.to_str())
.expect("Failed to get source file name");
// Skip scripts on Windows
if cfg!(target_os = "windows") && skip_scripts_on_windows.contains(&source_name) {
continue;
}
// Skip nightly-only scripts if on stable config
if cfg!(not(feature = "nightly")) && stable_only.contains(&source_name) {
eprintln!("Skipping nightly-only test {source_name}");
continue;
}
let test_name = source_name.replace('.', "_");
writeln!(
file,
r#"
#[test]
fn check_{test_name}() {{
{{
use std::process::Command;
let output = Command::new("cargo")
.arg("run")
.arg("--")
.arg("-cfgnq{more_options}")
.arg({source_path:?})
.output()
.expect("Failed to execute command");
if !output.status.success() {{
panic!(
"Failed to build file: {source_name}\nstdout: {{}}\nstderr: {{}}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
);
}}
// // Get the file stem
// let file_stem = {source_name:?}.trim_end_matches(".rs");
// // Construct the destination directory path
// let mut dest_dir = env::temp_dir();
// dest_dir.push("thag_rs");
// dest_dir.push(file_stem);
// let target_dir = &dest_dir.join("target/debug");
// // Delete the destination directory after building the file
// if let Err(e) = fs::remove_dir_all(&target_dir) {{
// eprintln!("Failed to remove directory {test_name}: {{}}, {{e:?}}", dest_dir.display());
// }}
}}
}}
"#,
// source_name = &source_name,
source_path = &path.to_str().expect("Failed to get source path"),
more_options = if multimain.contains(&source_name) {
"m"
} else {
""
}
)
.expect("Failed to write test function");
}
}
}