@@ -23,6 +23,11 @@ const CARGO_CLIPPY: &str = "cargo-clippy.exe";
23
23
#[ cfg_attr( feature = "integration" , test) ]
24
24
fn integration_test ( ) {
25
25
let repo_name = env:: var ( "INTEGRATION" ) . expect ( "`INTEGRATION` var not set" ) ;
26
+
27
+ if repo_name == "rust-lang/rust" {
28
+ return ;
29
+ }
30
+
26
31
let repo_url = format ! ( "https://github.com/{repo_name}" ) ;
27
32
let crate_name = repo_name
28
33
. split ( '/' )
@@ -123,3 +128,135 @@ fn integration_test() {
123
128
None => panic ! ( "Process terminated by signal" ) ,
124
129
}
125
130
}
131
+
132
+ #[ cfg_attr( feature = "integration" , test) ]
133
+ fn integration_test_rustc ( ) {
134
+ let repo_name = env:: var ( "INTEGRATION" ) . expect ( "`INTEGRATION` var not set" ) ;
135
+
136
+ if repo_name != "rust-lang/rust" {
137
+ return ;
138
+ }
139
+
140
+ let repo_url = format ! ( "https://github.com/{repo_name}" ) ;
141
+ let crate_name = repo_name
142
+ . split ( '/' )
143
+ . nth ( 1 )
144
+ . expect ( "repo name should have format `<org>/<name>`" ) ;
145
+
146
+ let mut repo_dir = tempfile:: tempdir ( ) . expect ( "couldn't create temp dir" ) . into_path ( ) ;
147
+ repo_dir. push ( crate_name) ;
148
+
149
+ let st_git_cl = Command :: new ( "git" )
150
+ . args ( [
151
+ OsStr :: new ( "clone" ) ,
152
+ OsStr :: new ( "--depth=5000" ) ,
153
+ OsStr :: new ( & repo_url) ,
154
+ OsStr :: new ( & repo_dir) ,
155
+ ] )
156
+ . status ( )
157
+ . expect ( "unable to run git" ) ;
158
+ assert ! ( st_git_cl. success( ) ) ;
159
+
160
+ // clippy is pinned to a specific nightly version
161
+ // check out the commit of that nightly to ensure compatibility
162
+ let rustc_output = Command :: new ( "rustc" )
163
+ . arg ( "--version" )
164
+ . arg ( "--verbose" )
165
+ . output ( )
166
+ . expect ( "failed to run rustc --version" ) ;
167
+
168
+ let commit_line = String :: from_utf8_lossy ( rustc_output. stdout ) ;
169
+ let commit_line_ = commit_line
170
+ . lines ( )
171
+ . find ( |line| line. starts_with ( "commit-hash: " ) )
172
+ . expect ( "did not find 'commit-hash:' in --version output" ) ;
173
+
174
+ let commit = commit_line_
175
+ . strip_prefix ( "commit-hash: " )
176
+ . expect ( "failed parsing commit line" ) ;
177
+
178
+ // check out the commit in the rustc repo to ensure clippy is compatible
179
+
180
+ let st_git_checkout = Command :: new ( "git" )
181
+ . arg ( "checkout" )
182
+ . arg ( commit)
183
+ . status ( )
184
+ . expect ( "git failed to check out commit" ) ;
185
+ assert ! ( st_git_checkout. success( ) ) ;
186
+
187
+ let root_dir = std:: path:: PathBuf :: from ( env ! ( "CARGO_MANIFEST_DIR" ) ) ;
188
+ let target_dir = std:: path:: Path :: new ( & root_dir) . join ( "target" ) ;
189
+ let clippy_binary = target_dir. join ( env ! ( "PROFILE" ) ) . join ( CARGO_CLIPPY ) ;
190
+
191
+ // we need to make sure that `x.py clippy` picks up our self-built clippy
192
+ // try to make the target dir discoverable as PATH
193
+
194
+ let path_env = target_dir. join ( env ! ( "PROFILE" ) ) ;
195
+
196
+ let output = Command :: new ( "x.py" )
197
+ . current_dir ( "rust" )
198
+ . env ( "RUST_BACKTRACE" , "full" )
199
+ . env ( "PATH" , path_env)
200
+ . args ( [ "clippy" , "-Wclippy::pedantic" , "-Wclippy::nursery" ] )
201
+ . output ( )
202
+ . expect ( "unable to run x.py clippy" ) ;
203
+
204
+ let stderr = String :: from_utf8_lossy ( & output. stderr ) ;
205
+
206
+ // debug:
207
+ eprintln ! ( "{stderr}" ) ;
208
+
209
+ // this is an internal test to make sure we would correctly panic on a delay_span_bug
210
+ if repo_name == "matthiaskrgr/clippy_ci_panic_test" {
211
+ // we need to kind of switch around our logic here:
212
+ // if we find a panic, everything is fine, if we don't panic, SOMETHING is broken about our testing
213
+
214
+ // the repo basically just contains a delay_span_bug that forces rustc/clippy to panic:
215
+ /*
216
+ #![feature(rustc_attrs)]
217
+ #[rustc_error(delay_span_bug_from_inside_query)]
218
+ fn main() {}
219
+ */
220
+
221
+ if stderr. find ( "error: internal compiler error" ) . is_some ( ) {
222
+ eprintln ! ( "we saw that we intentionally panicked, yay" ) ;
223
+ return ;
224
+ }
225
+
226
+ panic ! ( "panic caused by delay_span_bug was NOT detected! Something is broken!" ) ;
227
+ }
228
+
229
+ if let Some ( backtrace_start) = stderr. find ( "error: internal compiler error" ) {
230
+ static BACKTRACE_END_MSG : & str = "end of query stack" ;
231
+ let backtrace_end = stderr[ backtrace_start..]
232
+ . find ( BACKTRACE_END_MSG )
233
+ . expect ( "end of backtrace not found" ) ;
234
+
235
+ panic ! (
236
+ "internal compiler error\n Backtrace:\n \n {}" ,
237
+ & stderr[ backtrace_start..backtrace_start + backtrace_end + BACKTRACE_END_MSG . len( ) ]
238
+ ) ;
239
+ } else if stderr. contains ( "query stack during panic" ) {
240
+ panic ! ( "query stack during panic in the output" ) ;
241
+ } else if stderr. contains ( "E0463" ) {
242
+ // Encountering E0463 (can't find crate for `x`) did _not_ cause the build to fail in the
243
+ // past. Even though it should have. That's why we explicitly panic here.
244
+ // See PR #3552 and issue #3523 for more background.
245
+ panic ! ( "error: E0463" ) ;
246
+ } else if stderr. contains ( "E0514" ) {
247
+ panic ! ( "incompatible crate versions" ) ;
248
+ } else if stderr. contains ( "failed to run `rustc` to learn about target-specific information" ) {
249
+ panic ! ( "couldn't find librustc_driver, consider setting `LD_LIBRARY_PATH`" ) ;
250
+ } else {
251
+ assert ! (
252
+ !stderr. contains( "toolchain" ) || !stderr. contains( "is not installed" ) ,
253
+ "missing required toolchain"
254
+ ) ;
255
+ }
256
+
257
+ match output. status . code ( ) {
258
+ Some ( 0 ) => println ! ( "Compilation successful" ) ,
259
+ Some ( code) => eprintln ! ( "Compilation failed. Exit code: {code}" ) ,
260
+ None => panic ! ( "Process terminated by signal" ) ,
261
+ }
262
+ }
0 commit comments