Skip to content

Commit 9c6a015

Browse files
Refactor run and mtime functions: safer error handling, cleaner structure
1 parent fc42a20 commit 9c6a015

File tree

1 file changed

+85
-4
lines changed

1 file changed

+85
-4
lines changed

clippy_dev/src/serve.rs

Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,35 @@ use core::mem;
44
use std::path::Path;
55
use std::process::Command;
66
use std::time::{Duration, SystemTime};
7+
<<<<<<< HEAD
78
use std::{fs, thread};
89
use walkdir::WalkDir;
10+
=======
11+
use std::{env, thread};
12+
use std::io;
13+
>>>>>>> 48fa2fac9 (Refactor run and mtime functions: safer error handling, cleaner structure)
914

15+
/// Python binary depending on OS
1016
#[cfg(windows)]
1117
const PYTHON: &str = "python";
12-
1318
#[cfg(not(windows))]
1419
const PYTHON: &str = "python3";
1520

16-
/// # Panics
21+
/// Run a local live server for Clippy docs and lints.
22+
///
23+
/// # Arguments
24+
/// * `port` - Port to run the HTTP server on.
25+
/// * `lint` - Optional lint name to open directly in the browser.
1726
///
18-
/// Panics if the python commands could not be spawned
27+
/// # Panics
28+
/// Panics if spawning processes fails or the HTTP server cannot be launched.
1929
pub fn run(port: u16, lint: Option<String>) -> ! {
2030
let mut url = Some(match lint {
21-
None => format!("http://localhost:{port}"),
2231
Some(lint) => format!("http://localhost:{port}/#{lint}"),
32+
None => format!("http://localhost:{port}"),
2333
});
2434

35+
<<<<<<< HEAD
2536
let mut last_update = mtime("util/gh-pages/index.html");
2637
loop {
2738
if is_metadata_outdated(mem::replace(&mut last_update, SystemTime::now())) {
@@ -54,17 +65,87 @@ pub fn run(port: u16, lint: Option<String>) -> ! {
5465
}
5566

5667
// Delay to avoid updating the metadata too aggressively.
68+
=======
69+
let mut server_started = false;
70+
71+
loop {
72+
// Check last modified times of critical files
73+
let index_time = mtime("util/gh-pages/index.html").unwrap_or(SystemTime::UNIX_EPOCH);
74+
let times = [
75+
"clippy_lints/src",
76+
"util/gh-pages/index_template.html",
77+
"tests/compile-test.rs",
78+
]
79+
.iter()
80+
.filter_map(|p| mtime(p).ok())
81+
.collect::<Vec<_>>();
82+
83+
// Rebuild metadata if any file is newer than index.html
84+
if times.iter().any(|&time| index_time < time) {
85+
Command::new(env::var("CARGO").unwrap_or_else(|_| "cargo".into()))
86+
.arg("collect-metadata")
87+
.spawn()
88+
.expect("Failed to spawn cargo collect-metadata process")
89+
.wait()
90+
.expect("Cargo collect-metadata process failed");
91+
}
92+
93+
// Start HTTP server and open browser once
94+
if !server_started {
95+
if let Some(url) = url.take() {
96+
thread::spawn(move || {
97+
let mut child = Command::new(PYTHON)
98+
.arg("-m")
99+
.arg("http.server")
100+
.arg(port.to_string())
101+
.current_dir("util/gh-pages")
102+
.spawn()
103+
.expect("Failed to spawn Python HTTP server");
104+
105+
// Wait until server starts
106+
thread::sleep(Duration::from_millis(500));
107+
108+
// Open browser after first export
109+
let _ = opener::open(url);
110+
111+
child.wait().expect("Python HTTP server process failed");
112+
});
113+
server_started = true;
114+
}
115+
}
116+
117+
>>>>>>> 48fa2fac9 (Refactor run and mtime functions: safer error handling, cleaner structure)
57118
thread::sleep(Duration::from_millis(1000));
58119
}
59120
}
60121

122+
<<<<<<< HEAD
61123
fn log_err_and_continue<T>(res: Result<T, impl Display>, path: &Path) -> Option<T> {
62124
match res {
63125
Ok(x) => Some(x),
64126
Err(ref e) => {
65127
eprintln!("error reading `{}`: {e}", path.display());
66128
None
67129
},
130+
=======
131+
/// Get the most recent modification time of a file or directory recursively.
132+
/// Returns `io::Result<SystemTime>`.
133+
fn mtime(path: impl AsRef<Path>) -> io::Result<SystemTime> {
134+
let path = path.as_ref();
135+
136+
if path.is_dir() {
137+
let mut latest = SystemTime::UNIX_EPOCH;
138+
for entry in path.read_dir()? {
139+
let entry = entry?;
140+
let entry_time = mtime(entry.path())?;
141+
if entry_time > latest {
142+
latest = entry_time;
143+
}
144+
}
145+
Ok(latest)
146+
} else {
147+
Ok(path.metadata()?.modified()?)
148+
>>>>>>> 48fa2fac9 (Refactor run and mtime functions: safer error handling, cleaner structure)
68149
}
69150
}
70151

0 commit comments

Comments
 (0)