@@ -54,6 +54,15 @@ impl Lint {
54
54
pub fn by_lint_group ( lints : & [ Self ] ) -> HashMap < String , Vec < Self > > {
55
55
lints. iter ( ) . map ( |lint| ( lint. group . to_string ( ) , lint. clone ( ) ) ) . into_group_map ( )
56
56
}
57
+
58
+ /// Generates `pub mod module_name` for the lints in the given `group`
59
+ pub fn gen_pub_mod_for_group ( lints : & [ Lint ] ) -> Vec < String > {
60
+ lints. into_iter ( ) . map ( |l| format ! ( "pub mod {};" , l. module) ) . collect :: < Vec < String > > ( )
61
+ }
62
+
63
+ pub fn gen_lint_group ( lints : & [ Lint ] ) -> Vec < String > {
64
+ lints. into_iter ( ) . map ( |l| format ! ( " {}::{}," , l. module, l. name. to_uppercase( ) ) ) . collect :: < Vec < String > > ( )
65
+ }
57
66
}
58
67
59
68
pub fn gather_all ( ) -> impl Iterator < Item =Lint > {
@@ -86,6 +95,67 @@ fn lint_files() -> impl Iterator<Item=fs::DirEntry> {
86
95
. filter ( |f| f. path ( ) . extension ( ) == Some ( OsStr :: new ( "rs" ) ) )
87
96
}
88
97
98
+
99
+ pub fn clippy_version_from_toml ( ) -> String {
100
+ let mut file = fs:: File :: open ( "../Cargo.toml" ) . unwrap ( ) ;
101
+ let mut content = String :: new ( ) ;
102
+ file. read_to_string ( & mut content) . unwrap ( ) ;
103
+ let version_line = content. lines ( ) . find ( |l| l. starts_with ( "version =" ) ) ;
104
+ if let Some ( version_line) = version_line {
105
+ let split = version_line. split ( " " ) . collect :: < Vec < & str > > ( ) ;
106
+ split[ 2 ] . trim_matches ( '"' ) . to_string ( )
107
+ } else {
108
+ panic ! ( "Error: version not found in Cargo.toml!" ) ;
109
+ }
110
+ }
111
+
112
+ pub fn replace_region_in_file < F > ( path : & str , start : & str , end : & str , replace_start : bool , replacements : F ) where F : Fn ( ) -> Vec < String > {
113
+ let mut f = fs:: File :: open ( path) . expect ( & format ! ( "File not found: {}" , path) ) ;
114
+ let mut contents = String :: new ( ) ;
115
+ f. read_to_string ( & mut contents) . expect ( "Something went wrong reading the file" ) ;
116
+ let replaced = replace_region_in_text ( & contents, start, end, replace_start, replacements) ;
117
+
118
+ let mut f = fs:: File :: create ( path) . expect ( & format ! ( "File not found: {}" , path) ) ;
119
+ f. write_all ( replaced. as_bytes ( ) ) . expect ( "Unable to write file" ) ;
120
+ }
121
+
122
+ // Replace a region in a file delimited by two lines matching regexes.
123
+ //
124
+ // A callback is called to write the new region.
125
+ // If `replace_start` is true, the start delimiter line is replaced as well.
126
+ // The end delimiter line is never replaced.
127
+ pub fn replace_region_in_text < F > ( text : & str , start : & str , end : & str , replace_start : bool , replacements : F ) -> String where F : Fn ( ) -> Vec < String > {
128
+ let lines = text. lines ( ) ;
129
+ let mut in_old_region = false ;
130
+ let mut found = false ;
131
+ let mut new_lines = vec ! [ ] ;
132
+ let start = Regex :: new ( start) . unwrap ( ) ;
133
+ let end = Regex :: new ( end) . unwrap ( ) ;
134
+
135
+ for line in lines {
136
+ if in_old_region {
137
+ if end. is_match ( & line) {
138
+ in_old_region = false ;
139
+ new_lines. extend ( replacements ( ) ) ;
140
+ new_lines. push ( line. to_string ( ) ) ;
141
+ }
142
+ } else if start. is_match ( & line) {
143
+ if !replace_start {
144
+ new_lines. push ( line. to_string ( ) ) ;
145
+ }
146
+ in_old_region = true ;
147
+ found = true ;
148
+ } else {
149
+ new_lines. push ( line. to_string ( ) ) ;
150
+ }
151
+ }
152
+
153
+ if !found {
154
+ println ! ( "regex {:?} not found" , start) ;
155
+ }
156
+ new_lines. join ( "\n " )
157
+ }
158
+
89
159
#[ test]
90
160
fn test_parse_contents ( ) {
91
161
let result: Vec < Lint > = parse_contents (
@@ -125,6 +195,44 @@ declare_deprecated_lint! {
125
195
assert_eq ! ( expected, result) ;
126
196
}
127
197
198
+
199
+ #[ test]
200
+ fn test_replace_region ( ) {
201
+ let text = r#"
202
+ abc
203
+ 123
204
+ 789
205
+ def
206
+ ghi"# ;
207
+ let expected = r#"
208
+ abc
209
+ hello world
210
+ def
211
+ ghi"# ;
212
+ let result = replace_region_in_text ( text, r#"^\s*abc$"# , r#"^\s*def"# , false , || {
213
+ vec ! [ "hello world" . to_string( ) ]
214
+ } ) ;
215
+ assert_eq ! ( expected, result) ;
216
+ }
217
+
218
+ #[ test]
219
+ fn test_replace_region_with_start ( ) {
220
+ let text = r#"
221
+ abc
222
+ 123
223
+ 789
224
+ def
225
+ ghi"# ;
226
+ let expected = r#"
227
+ hello world
228
+ def
229
+ ghi"# ;
230
+ let result = replace_region_in_text ( text, r#"^\s*abc$"# , r#"^\s*def"# , true , || {
231
+ vec ! [ "hello world" . to_string( ) ]
232
+ } ) ;
233
+ assert_eq ! ( expected, result) ;
234
+ }
235
+
128
236
#[ test]
129
237
fn test_active_lints ( ) {
130
238
let lints = vec ! [
@@ -154,3 +262,29 @@ fn test_by_lint_group() {
154
262
] ) ;
155
263
assert_eq ! ( expected, Lint :: by_lint_group( & lints) ) ;
156
264
}
265
+
266
+ #[ test]
267
+ fn test_gen_pub_mod_for_group ( ) {
268
+ let lints = vec ! [
269
+ Lint :: new( "should_assert_eq" , "Deprecated" , "abc" , Some ( "Reason" ) , "abc" ) ,
270
+ Lint :: new( "should_assert_eq2" , "Not Deprecated" , "abc" , None , "module_name" ) ,
271
+ ] ;
272
+ let expected = vec ! [
273
+ "pub mod abc;" . to_string( ) ,
274
+ "pub mod module_name;" . to_string( ) ,
275
+ ] ;
276
+ assert_eq ! ( expected, Lint :: gen_pub_mod_for_group( & lints) ) ;
277
+ }
278
+
279
+ #[ test]
280
+ fn test_gen_lint_group ( ) {
281
+ let lints = vec ! [
282
+ Lint :: new( "should_assert_eq" , "Deprecated" , "abc" , Some ( "Reason" ) , "abc" ) ,
283
+ Lint :: new( "should_assert_eq2" , "Not Deprecated" , "abc" , None , "module_name" ) ,
284
+ ] ; ;
285
+ let expected = vec ! [
286
+ " abc::SHOULD_ASSERT_EQ," . to_string( ) ,
287
+ " module_name::SHOULD_ASSERT_EQ2," . to_string( )
288
+ ] ;
289
+ assert_eq ! ( expected, Lint :: gen_lint_group( & lints) ) ;
290
+ }
0 commit comments