@@ -114,19 +114,22 @@ pub fn gen_changelog_lint_list(lints: Vec<Lint>) -> Vec<String> {
114114
115115/// Generates the `register_removed` code in `./clippy_lints/src/lib.rs`. 
116116pub  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+                         ] 
125129                    ) 
126-                 ) 
130+                 } ) 
127131            } ) 
128-         } ) 
129-         . collect ( ) 
132+     ) . collect ( ) 
130133} 
131134
132135/// Gathers all files in `src/clippy_lints` and gathers all lints inside 
@@ -168,23 +171,33 @@ fn lint_files() -> impl Iterator<Item=walkdir::DirEntry> {
168171        . filter ( |f| f. path ( ) . extension ( )  == Some ( OsStr :: new ( "rs" ) ) ) 
169172} 
170173
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+ 
171181/// Replace a region in a file delimited by two lines matching regexes. 
172182/// 
173183/// `path` is the relative path to the file on which you want to perform the replacement. 
174184/// 
175185/// See `replace_region_in_text` for documentation of the other options. 
176186#[ 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 >  { 
178188    let  mut  f = fs:: File :: open ( path) . expect ( & format ! ( "File not found: {}" ,  path) ) ; 
179189    let  mut  contents = String :: new ( ) ; 
180190    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
188201} 
189202
190203/// 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
213226///     || { 
214227///         vec!["a different".to_string(), "text".to_string()] 
215228///     } 
216- /// ); 
229+ /// ).new_lines ; 
217230/// assert_eq!("replace_start\na different\ntext\nreplace_end", result); 
218231/// ``` 
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 >  { 
220233    let  lines = text. lines ( ) ; 
221234    let  mut  in_old_region = false ; 
222235    let  mut  found = false ; 
223236    let  mut  new_lines = vec ! [ ] ; 
224237    let  start = Regex :: new ( start) . unwrap ( ) ; 
225238    let  end = Regex :: new ( end) . unwrap ( ) ; 
226239
227-     for  line in  lines { 
240+     for  line in  lines. clone ( )  { 
228241        if  in_old_region { 
229242            if  end. is_match ( & line)  { 
230243                in_old_region = false ; 
@@ -248,7 +261,11 @@ pub fn replace_region_in_text<F>(text: &str, start: &str, end: &str, replace_sta
248261        // is incorrect. 
249262        eprintln ! ( "error: regex `{:?}` not found. You may have to update it." ,  start) ; 
250263    } 
251-     new_lines. join ( "\n " ) 
264+ 
265+     FileChange  { 
266+         changed :  lines. ne ( new_lines. clone ( ) ) , 
267+         new_lines :  new_lines. join ( "\n " ) 
268+     } 
252269} 
253270
254271#[ test]  
@@ -292,17 +309,11 @@ declare_deprecated_lint! {
292309
293310#[ test]  
294311fn  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+     } ; 
306317    let  result = replace_region_in_text ( text,  r#"^\s*abc$"# ,  r#"^\s*def"# ,  false ,  || { 
307318        vec ! [ "hello world" . to_string( ) ] 
308319    } ) ; 
@@ -311,22 +322,30 @@ ghi"#;
311322
312323#[ test]  
313324fn  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+     } ; 
324330    let  result = replace_region_in_text ( text,  r#"^\s*abc$"# ,  r#"^\s*def"# ,  true ,  || { 
325331        vec ! [ "hello world" . to_string( ) ] 
326332    } ) ; 
327333    assert_eq ! ( expected,  result) ; 
328334} 
329335
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+ 
330349#[ test]  
331350fn  test_usable_lints ( )  { 
332351    let  lints = vec ! [ 
@@ -377,14 +396,19 @@ fn test_gen_changelog_lint_list() {
377396fn  test_gen_deprecated ( )  { 
378397    let  lints = vec ! [ 
379398        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" ) , 
380400        Lint :: new( "should_assert_eq2" ,  "group2" ,  "abc" ,  None ,  "module_name" ) 
381401    ] ; 
382402    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 ( ) ; 
388412    assert_eq ! ( expected,  gen_deprecated( & lints) ) ; 
389413} 
390414
0 commit comments