1
+ use crate :: utils:: { ErrAction , cargo_cmd, expect_action} ;
2
+ use core:: fmt:: Display ;
3
+ use core:: mem;
1
4
use std:: path:: Path ;
2
5
use std:: process:: Command ;
3
6
use std:: time:: { Duration , SystemTime } ;
7
+ improve-serve-function
4
8
use std:: { env, thread} ;
5
9
use std:: io;
10
+ use std:: { fs, thread} ;
11
+ use walkdir:: WalkDir ;
12
+ master
6
13
7
14
/// Python binary depending on OS
8
15
#[ cfg( windows) ]
@@ -24,6 +31,7 @@ pub fn run(port: u16, lint: Option<String>) -> ! {
24
31
None => format ! ( "http://localhost:{port}" ) ,
25
32
} ) ;
26
33
34
+ improve-serve-function
27
35
let mut server_started = false ;
28
36
29
37
loop {
@@ -72,10 +80,45 @@ pub fn run(port: u16, lint: Option<String>) -> ! {
72
80
}
73
81
}
74
82
83
+
84
+ let mut last_update = mtime ( "util/gh-pages/index.html" ) ;
85
+ loop {
86
+ if is_metadata_outdated ( mem:: replace ( & mut last_update, SystemTime :: now ( ) ) ) {
87
+ // Ignore the command result; we'll fall back to displaying the old metadata.
88
+ let _ = expect_action (
89
+ cargo_cmd ( ) . arg ( "collect-metadata" ) . status ( ) ,
90
+ ErrAction :: Run ,
91
+ "cargo collect-metadata" ,
92
+ ) ;
93
+ last_update = SystemTime :: now ( ) ;
94
+ }
95
+
96
+ // Only start the web server the first time around.
97
+ if let Some ( url) = url. take ( ) {
98
+ thread:: spawn ( move || {
99
+ let mut child = expect_action (
100
+ Command :: new ( PYTHON )
101
+ . args ( [ "-m" , "http.server" , port. to_string ( ) . as_str ( ) ] )
102
+ . current_dir ( "util/gh-pages" )
103
+ . spawn ( ) ,
104
+ ErrAction :: Run ,
105
+ "python -m http.server" ,
106
+ ) ;
107
+ // Give some time for python to start
108
+ thread:: sleep ( Duration :: from_millis ( 500 ) ) ;
109
+ // Launch browser after first export.py has completed and http.server is up
110
+ let _result = opener:: open ( url) ;
111
+ expect_action ( child. wait ( ) , ErrAction :: Run , "python -m http.server" ) ;
112
+ } ) ;
113
+ }
114
+
115
+ // Delay to avoid updating the metadata too aggressively.
116
+ master
75
117
thread:: sleep ( Duration :: from_millis ( 1000 ) ) ;
76
118
}
77
119
}
78
120
121
+ improve-serve-function
79
122
/// Get the most recent modification time of a file or directory recursively.
80
123
/// Returns `io::Result<SystemTime>`.
81
124
fn mtime( path: impl AsRef <Path >) -> io:: Result <SystemTime > {
@@ -93,5 +136,49 @@ fn mtime(path: impl AsRef<Path>) -> io::Result<SystemTime> {
93
136
Ok ( latest)
94
137
} else {
95
138
Ok ( path. metadata ( ) ?. modified ( ) ?)
139
+
140
+ fn log_err_and_continue < T > ( res : Result < T , impl Display > , path : & Path ) -> Option < T > {
141
+ match res {
142
+ Ok ( x) => Some ( x) ,
143
+ Err ( ref e) => {
144
+ eprintln ! ( "error reading `{}`: {e}" , path. display( ) ) ;
145
+ None
146
+ } ,
147
+ master
96
148
}
97
149
}
150
+
151
+ fn mtime ( path : & str ) -> SystemTime {
152
+ log_err_and_continue ( fs:: metadata ( path) , path. as_ref ( ) )
153
+ . and_then ( |metadata| log_err_and_continue ( metadata. modified ( ) , path. as_ref ( ) ) )
154
+ . unwrap_or ( SystemTime :: UNIX_EPOCH )
155
+ }
156
+
157
+ fn is_metadata_outdated ( time : SystemTime ) -> bool {
158
+ // Ignore all IO errors here. We don't want to stop them from hosting the server.
159
+ if time < mtime ( "util/gh-pages/index_template.html" ) || time < mtime ( "tests/compile-test.rs" ) {
160
+ return true ;
161
+ }
162
+ let Some ( dir) = log_err_and_continue ( fs:: read_dir ( "." ) , "." . as_ref ( ) ) else {
163
+ return false ;
164
+ } ;
165
+ dir. map_while ( |e| log_err_and_continue ( e, "." . as_ref ( ) ) ) . any ( |e| {
166
+ let name = e. file_name ( ) ;
167
+ let name_bytes = name. as_encoded_bytes ( ) ;
168
+ if ( name_bytes. starts_with ( b"clippy_lints" ) && name_bytes != b"clippy_lints_internal" )
169
+ || name_bytes == b"clippy_config"
170
+ {
171
+ WalkDir :: new ( & name)
172
+ . into_iter ( )
173
+ . map_while ( |e| log_err_and_continue ( e, name. as_ref ( ) ) )
174
+ . filter ( |e| e. file_type ( ) . is_file ( ) )
175
+ . filter_map ( |e| {
176
+ log_err_and_continue ( e. metadata ( ) , e. path ( ) )
177
+ . and_then ( |m| log_err_and_continue ( m. modified ( ) , e. path ( ) ) )
178
+ } )
179
+ . any ( |ftime| time < ftime)
180
+ } else {
181
+ false
182
+ }
183
+ } )
184
+ }
0 commit comments