@@ -9,6 +9,7 @@ use crate::ClippyWarning;
9
9
#[ derive( Deserialize , Serialize ) ]
10
10
struct LintJson {
11
11
lint : String ,
12
+ krate : String ,
12
13
file_name : String ,
13
14
byte_pos : ( u32 , u32 ) ,
14
15
file_link : String ,
@@ -19,6 +20,10 @@ impl LintJson {
19
20
fn key ( & self ) -> impl Ord + ' _ {
20
21
( self . file_name . as_str ( ) , self . byte_pos , self . lint . as_str ( ) )
21
22
}
23
+
24
+ fn info_text ( & self , action : & str ) -> String {
25
+ format ! ( "{action} `{}` in `{}` at {}" , self . lint, self . krate, self . file_link)
26
+ }
22
27
}
23
28
24
29
/// Creates the log file output for [`crate::config::OutputFormat::Json`]
@@ -30,6 +35,7 @@ pub(crate) fn output(clippy_warnings: Vec<ClippyWarning>) -> String {
30
35
LintJson {
31
36
file_name : span. file_name . clone ( ) ,
32
37
byte_pos : ( span. byte_start , span. byte_end ) ,
38
+ krate : warning. krate ,
33
39
file_link : warning. url ,
34
40
lint : warning. lint ,
35
41
rendered : warning. diag . rendered . unwrap ( ) ,
@@ -51,12 +57,16 @@ fn print_warnings(title: &str, warnings: &[LintJson]) {
51
57
return ;
52
58
}
53
59
54
- println ! ( "### {title}" ) ;
60
+ //We have to use HTML here to be able to manually add an id.
61
+ println ! ( r#"<h3 id="{title}">{title}</h3>"# ) ;
62
+ println ! ( ) ;
55
63
for warning in warnings {
56
- println ! ( "{title} `{}` at {}" , warning. lint, warning. file_link) ;
64
+ println ! ( "{}" , warning. info_text( title) ) ;
65
+ println ! ( ) ;
57
66
println ! ( "```" ) ;
58
- print ! ( "{}" , warning. rendered) ;
67
+ println ! ( "{}" , warning. rendered. trim_end ( ) ) ;
59
68
println ! ( "```" ) ;
69
+ println ! ( ) ;
60
70
}
61
71
}
62
72
@@ -65,11 +75,14 @@ fn print_changed_diff(changed: &[(LintJson, LintJson)]) {
65
75
return ;
66
76
}
67
77
68
- println ! ( "### Changed" ) ;
78
+ //We have to use HTML here to be able to manually add an id.
79
+ println ! ( r#"<h3 id="changed">Changed</h3>"# ) ;
80
+ println ! ( ) ;
69
81
for ( old, new) in changed {
70
- println ! ( "Changed `{}` at {}" , new. lint, new. file_link) ;
82
+ println ! ( "{}" , new. info_text( "Changed" ) ) ;
83
+ println ! ( ) ;
71
84
println ! ( "```diff" ) ;
72
- for change in diff:: lines ( & old. rendered , & new. rendered ) {
85
+ for change in diff:: lines ( old. rendered . trim_end ( ) , new. rendered . trim_end ( ) ) {
73
86
use diff:: Result :: { Both , Left , Right } ;
74
87
75
88
match change {
@@ -109,13 +122,30 @@ pub(crate) fn diff(old_path: &Path, new_path: &Path) {
109
122
}
110
123
111
124
print ! (
112
- "{} added , {} removed , {} changed \n \n " ,
113
- added. len( ) ,
114
- removed. len( ) ,
115
- changed. len( )
125
+ r## "{}, {}, {}"## ,
126
+ count_string ( " added" , added . len( ) ) ,
127
+ count_string ( " removed" , removed . len( ) ) ,
128
+ count_string ( " changed" , changed . len( ) ) ,
116
129
) ;
130
+ println ! ( ) ;
131
+ println ! ( ) ;
117
132
118
133
print_warnings ( "Added" , & added) ;
119
134
print_warnings ( "Removed" , & removed) ;
120
135
print_changed_diff ( & changed) ;
121
136
}
137
+
138
+ /// This generates the `x added` string for the start of the job summery.
139
+ /// It linkifies them if possible to jump to the respective heading.
140
+ fn count_string ( label : & str , count : usize ) -> String {
141
+ // Headlines are only added, if anything will be displayed under the headline.
142
+ // We therefore only want to add links to them if they exist
143
+ if count == 0 {
144
+ format ! ( "0 {label}" )
145
+ } else {
146
+ // GitHub's job summaries don't add HTML ids to headings. That's why we
147
+ // manually have to add them. GitHub prefixes these manual ids with
148
+ // `user-content-` and that's how we end up with these awesome links :D
149
+ format ! ( "[{count} {label}](#user-content-{label})" )
150
+ }
151
+ }
0 commit comments