@@ -114,19 +114,22 @@ pub fn gen_changelog_lint_list(lints: Vec<Lint>) -> Vec<String> {
114
114
115
115
/// Generates the `register_removed` code in `./clippy_lints/src/lib.rs`.
116
116
pub fn gen_deprecated ( lints : & [ Lint ] ) -> Vec < String > {
117
- lints. iter ( )
118
- . filter_map ( |l| {
119
- l. clone ( ) . deprecation . and_then ( |depr_text| {
120
- Some (
121
- format ! (
122
- " store.register_removed(\n \" {}\" ,\n \" {}\" ,\n );" ,
123
- l. name,
124
- depr_text
117
+ itertools:: flatten (
118
+ lints
119
+ . iter ( )
120
+ . filter_map ( |l| {
121
+ l. clone ( ) . deprecation . and_then ( |depr_text| {
122
+ Some (
123
+ vec ! [
124
+ " store.register_removed(" . to_string( ) ,
125
+ format!( " \" {}\" ," , l. name) ,
126
+ format!( " \" {}\" ," , depr_text) ,
127
+ " );" . to_string( )
128
+ ]
125
129
)
126
- )
130
+ } )
127
131
} )
128
- } )
129
- . collect ( )
132
+ ) . collect ( )
130
133
}
131
134
132
135
/// Gathers all files in `src/clippy_lints` and gathers all lints inside
@@ -168,23 +171,33 @@ fn lint_files() -> impl Iterator<Item=walkdir::DirEntry> {
168
171
. filter ( |f| f. path ( ) . extension ( ) == Some ( OsStr :: new ( "rs" ) ) )
169
172
}
170
173
174
+ /// Whether a file has had its text changed or not
175
+ #[ derive( PartialEq , Debug ) ]
176
+ pub struct FileChange {
177
+ pub changed : bool ,
178
+ pub new_lines : String ,
179
+ }
180
+
171
181
/// Replace a region in a file delimited by two lines matching regexes.
172
182
///
173
183
/// `path` is the relative path to the file on which you want to perform the replacement.
174
184
///
175
185
/// See `replace_region_in_text` for documentation of the other options.
176
186
#[ allow( clippy:: expect_fun_call) ]
177
- pub fn replace_region_in_file < F > ( path : & str , start : & str , end : & str , replace_start : bool , replacements : F ) where F : Fn ( ) -> Vec < String > {
187
+ pub fn replace_region_in_file < F > ( path : & str , start : & str , end : & str , replace_start : bool , write_back : bool , replacements : F ) -> FileChange where F : Fn ( ) -> Vec < String > {
178
188
let mut f = fs:: File :: open ( path) . expect ( & format ! ( "File not found: {}" , path) ) ;
179
189
let mut contents = String :: new ( ) ;
180
190
f. read_to_string ( & mut contents) . expect ( "Something went wrong reading the file" ) ;
181
- let replaced = replace_region_in_text ( & contents, start, end, replace_start, replacements) ;
182
-
183
- let mut f = fs:: File :: create ( path) . expect ( & format ! ( "File not found: {}" , path) ) ;
184
- f. write_all ( replaced. as_bytes ( ) ) . expect ( "Unable to write file" ) ;
185
- // Ensure we write the changes with a trailing newline so that
186
- // the file has the proper line endings.
187
- f. write_all ( b"\n " ) . expect ( "Unable to write file" ) ;
191
+ let file_change = replace_region_in_text ( & contents, start, end, replace_start, replacements) ;
192
+
193
+ if write_back {
194
+ let mut f = fs:: File :: create ( path) . expect ( & format ! ( "File not found: {}" , path) ) ;
195
+ f. write_all ( file_change. new_lines . as_bytes ( ) ) . expect ( "Unable to write file" ) ;
196
+ // Ensure we write the changes with a trailing newline so that
197
+ // the file has the proper line endings.
198
+ f. write_all ( b"\n " ) . expect ( "Unable to write file" ) ;
199
+ }
200
+ file_change
188
201
}
189
202
190
203
/// Replace a region in a text delimited by two lines matching regexes.
@@ -213,18 +226,18 @@ pub fn replace_region_in_file<F>(path: &str, start: &str, end: &str, replace_sta
213
226
/// || {
214
227
/// vec!["a different".to_string(), "text".to_string()]
215
228
/// }
216
- /// );
229
+ /// ).new_lines ;
217
230
/// assert_eq!("replace_start\na different\ntext\nreplace_end", result);
218
231
/// ```
219
- pub fn replace_region_in_text < F > ( text : & str , start : & str , end : & str , replace_start : bool , replacements : F ) -> String where F : Fn ( ) -> Vec < String > {
232
+ pub fn replace_region_in_text < F > ( text : & str , start : & str , end : & str , replace_start : bool , replacements : F ) -> FileChange where F : Fn ( ) -> Vec < String > {
220
233
let lines = text. lines ( ) ;
221
234
let mut in_old_region = false ;
222
235
let mut found = false ;
223
236
let mut new_lines = vec ! [ ] ;
224
237
let start = Regex :: new ( start) . unwrap ( ) ;
225
238
let end = Regex :: new ( end) . unwrap ( ) ;
226
239
227
- for line in lines {
240
+ for line in lines. clone ( ) {
228
241
if in_old_region {
229
242
if end. is_match ( & line) {
230
243
in_old_region = false ;
@@ -248,7 +261,11 @@ pub fn replace_region_in_text<F>(text: &str, start: &str, end: &str, replace_sta
248
261
// is incorrect.
249
262
eprintln ! ( "error: regex `{:?}` not found. You may have to update it." , start) ;
250
263
}
251
- new_lines. join ( "\n " )
264
+
265
+ FileChange {
266
+ changed : lines. ne ( new_lines. clone ( ) ) ,
267
+ new_lines : new_lines. join ( "\n " )
268
+ }
252
269
}
253
270
254
271
#[ test]
@@ -292,17 +309,11 @@ declare_deprecated_lint! {
292
309
293
310
#[ test]
294
311
fn test_replace_region ( ) {
295
- let text = r#"
296
- abc
297
- 123
298
- 789
299
- def
300
- ghi"# ;
301
- let expected = r#"
302
- abc
303
- hello world
304
- def
305
- ghi"# ;
312
+ let text = "\n abc\n 123\n 789\n def\n ghi" ;
313
+ let expected = FileChange {
314
+ changed : true ,
315
+ new_lines : "\n abc\n hello world\n def\n ghi" . to_string ( )
316
+ } ;
306
317
let result = replace_region_in_text ( text, r#"^\s*abc$"# , r#"^\s*def"# , false , || {
307
318
vec ! [ "hello world" . to_string( ) ]
308
319
} ) ;
@@ -311,22 +322,30 @@ ghi"#;
311
322
312
323
#[ test]
313
324
fn test_replace_region_with_start ( ) {
314
- let text = r#"
315
- abc
316
- 123
317
- 789
318
- def
319
- ghi"# ;
320
- let expected = r#"
321
- hello world
322
- def
323
- ghi"# ;
325
+ let text = "\n abc\n 123\n 789\n def\n ghi" ;
326
+ let expected = FileChange {
327
+ changed : true ,
328
+ new_lines : "\n hello world\n def\n ghi" . to_string ( )
329
+ } ;
324
330
let result = replace_region_in_text ( text, r#"^\s*abc$"# , r#"^\s*def"# , true , || {
325
331
vec ! [ "hello world" . to_string( ) ]
326
332
} ) ;
327
333
assert_eq ! ( expected, result) ;
328
334
}
329
335
336
+ #[ test]
337
+ fn test_replace_region_no_changes ( ) {
338
+ let text = "123\n 456\n 789" ;
339
+ let expected = FileChange {
340
+ changed : false ,
341
+ new_lines : "123\n 456\n 789" . to_string ( )
342
+ } ;
343
+ let result = replace_region_in_text ( text, r#"^\s*123$"# , r#"^\s*456"# , false , || {
344
+ vec ! [ ]
345
+ } ) ;
346
+ assert_eq ! ( expected, result) ;
347
+ }
348
+
330
349
#[ test]
331
350
fn test_usable_lints ( ) {
332
351
let lints = vec ! [
@@ -377,14 +396,19 @@ fn test_gen_changelog_lint_list() {
377
396
fn test_gen_deprecated ( ) {
378
397
let lints = vec ! [
379
398
Lint :: new( "should_assert_eq" , "group1" , "abc" , Some ( "has been superseeded by should_assert_eq2" ) , "module_name" ) ,
399
+ Lint :: new( "another_deprecated" , "group2" , "abc" , Some ( "will be removed" ) , "module_name" ) ,
380
400
Lint :: new( "should_assert_eq2" , "group2" , "abc" , None , "module_name" )
381
401
] ;
382
402
let expected: Vec < String > = vec ! [
383
- r#" store.register_removed(
384
- "should_assert_eq",
385
- "has been superseeded by should_assert_eq2",
386
- );"# . to_string( )
387
- ] ;
403
+ " store.register_removed(" ,
404
+ " \" should_assert_eq\" ," ,
405
+ " \" has been superseeded by should_assert_eq2\" ," ,
406
+ " );" ,
407
+ " store.register_removed(" ,
408
+ " \" another_deprecated\" ," ,
409
+ " \" will be removed\" ," ,
410
+ " );"
411
+ ] . into_iter ( ) . map ( String :: from) . collect ( ) ;
388
412
assert_eq ! ( expected, gen_deprecated( & lints) ) ;
389
413
}
390
414
0 commit comments