Skip to content

Commit 48fa2fa

Browse files
Refactor run and mtime functions: safer error handling, cleaner structure
1 parent 1fd9504 commit 48fa2fa

File tree

1 file changed

+58
-34
lines changed

1 file changed

+58
-34
lines changed

clippy_dev/src/serve.rs

Lines changed: 58 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,72 +2,96 @@ use std::path::Path;
22
use std::process::Command;
33
use std::time::{Duration, SystemTime};
44
use std::{env, thread};
5+
use std::io;
56

7+
/// Python binary depending on OS
68
#[cfg(windows)]
79
const PYTHON: &str = "python";
8-
910
#[cfg(not(windows))]
1011
const PYTHON: &str = "python3";
1112

12-
/// # Panics
13+
/// Run a local live server for Clippy docs and lints.
1314
///
14-
/// Panics if the python commands could not be spawned
15+
/// # Arguments
16+
/// * `port` - Port to run the HTTP server on.
17+
/// * `lint` - Optional lint name to open directly in the browser.
18+
///
19+
/// # Panics
20+
/// Panics if spawning processes fails or the HTTP server cannot be launched.
1521
pub fn run(port: u16, lint: Option<String>) -> ! {
1622
let mut url = Some(match lint {
17-
None => format!("http://localhost:{port}"),
1823
Some(lint) => format!("http://localhost:{port}/#{lint}"),
24+
None => format!("http://localhost:{port}"),
1925
});
2026

27+
let mut server_started = false;
28+
2129
loop {
22-
let index_time = mtime("util/gh-pages/index.html");
30+
// Check last modified times of critical files
31+
let index_time = mtime("util/gh-pages/index.html").unwrap_or(SystemTime::UNIX_EPOCH);
2332
let times = [
2433
"clippy_lints/src",
2534
"util/gh-pages/index_template.html",
2635
"tests/compile-test.rs",
2736
]
28-
.map(mtime);
37+
.iter()
38+
.filter_map(|p| mtime(p).ok())
39+
.collect::<Vec<_>>();
2940

41+
// Rebuild metadata if any file is newer than index.html
3042
if times.iter().any(|&time| index_time < time) {
3143
Command::new(env::var("CARGO").unwrap_or_else(|_| "cargo".into()))
3244
.arg("collect-metadata")
3345
.spawn()
34-
.unwrap()
46+
.expect("Failed to spawn cargo collect-metadata process")
3547
.wait()
36-
.unwrap();
48+
.expect("Cargo collect-metadata process failed");
3749
}
38-
if let Some(url) = url.take() {
39-
thread::spawn(move || {
40-
let mut child = Command::new(PYTHON)
41-
.arg("-m")
42-
.arg("http.server")
43-
.arg(port.to_string())
44-
.current_dir("util/gh-pages")
45-
.spawn()
46-
.unwrap();
47-
// Give some time for python to start
48-
thread::sleep(Duration::from_millis(500));
49-
// Launch browser after first export.py has completed and http.server is up
50-
let _result = opener::open(url);
51-
child.wait().unwrap();
52-
});
50+
51+
// Start HTTP server and open browser once
52+
if !server_started {
53+
if let Some(url) = url.take() {
54+
thread::spawn(move || {
55+
let mut child = Command::new(PYTHON)
56+
.arg("-m")
57+
.arg("http.server")
58+
.arg(port.to_string())
59+
.current_dir("util/gh-pages")
60+
.spawn()
61+
.expect("Failed to spawn Python HTTP server");
62+
63+
// Wait until server starts
64+
thread::sleep(Duration::from_millis(500));
65+
66+
// Open browser after first export
67+
let _ = opener::open(url);
68+
69+
child.wait().expect("Python HTTP server process failed");
70+
});
71+
server_started = true;
72+
}
5373
}
74+
5475
thread::sleep(Duration::from_millis(1000));
5576
}
5677
}
5778

58-
fn mtime(path: impl AsRef<Path>) -> SystemTime {
79+
/// Get the most recent modification time of a file or directory recursively.
80+
/// Returns `io::Result<SystemTime>`.
81+
fn mtime(path: impl AsRef<Path>) -> io::Result<SystemTime> {
5982
let path = path.as_ref();
83+
6084
if path.is_dir() {
61-
path.read_dir()
62-
.into_iter()
63-
.flatten()
64-
.flatten()
65-
.map(|entry| mtime(entry.path()))
66-
.max()
67-
.unwrap_or(SystemTime::UNIX_EPOCH)
85+
let mut latest = SystemTime::UNIX_EPOCH;
86+
for entry in path.read_dir()? {
87+
let entry = entry?;
88+
let entry_time = mtime(entry.path())?;
89+
if entry_time > latest {
90+
latest = entry_time;
91+
}
92+
}
93+
Ok(latest)
6894
} else {
69-
path.metadata()
70-
.and_then(|metadata| metadata.modified())
71-
.unwrap_or(SystemTime::UNIX_EPOCH)
95+
Ok(path.metadata()?.modified()?)
7296
}
7397
}

0 commit comments

Comments
 (0)