@@ -13,6 +13,7 @@ struct KrateSource {
13
13
struct Krate {
14
14
version : String ,
15
15
name : String ,
16
+ // path to the extracted sources that clippy can check
16
17
path : PathBuf ,
17
18
}
18
19
@@ -23,37 +24,44 @@ impl KrateSource {
23
24
name : name. into ( ) ,
24
25
}
25
26
}
27
+
26
28
fn download_and_extract ( & self ) -> Krate {
27
29
let extract_dir = PathBuf :: from ( "target/crater/crates" ) ;
28
-
29
- // download
30
30
let krate_download_dir = PathBuf :: from ( "target/crater/downloads" ) ;
31
31
32
+ // url to download the crate from crates.io
32
33
let url = format ! (
33
34
"https://crates.io/api/v1/crates/{}/{}/download" ,
34
35
self . name, self . version
35
36
) ;
36
- println ! ( "Downloading {}, {} / {}" , self . name, self . version, url) ;
37
+ println ! ( "Downloading and extracting {} {} from {}" , self . name, self . version, url) ;
37
38
let _ = std:: fs:: create_dir ( "target/crater/" ) ;
38
-
39
39
let _ = std:: fs:: create_dir ( & krate_download_dir) ;
40
40
let _ = std:: fs:: create_dir ( & extract_dir) ;
41
41
42
- let krate_name = format ! ( "{}-{}.crate.tar.gz" , & self . name, & self . version) ;
43
- let krate_file_path = krate_download_dir. join ( krate_name) ;
44
- let mut krate_dest = std:: fs:: File :: create ( & krate_file_path) . unwrap ( ) ;
45
- let mut krate_req = ureq:: get ( & url) . call ( ) . unwrap ( ) . into_reader ( ) ;
46
- std:: io:: copy ( & mut krate_req, & mut krate_dest) . unwrap ( ) ;
47
- // unzip the tarball
48
- let dl = std:: fs:: File :: open ( krate_file_path) . unwrap ( ) ;
49
-
50
- let ungz_tar = flate2:: read:: GzDecoder :: new ( dl) ;
51
- // extract the tar archive
52
- let mut archiv = tar:: Archive :: new ( ungz_tar) ;
53
- let extract_path = extract_dir. clone ( ) ;
54
- archiv. unpack ( & extract_path) . expect ( "Failed to extract!" ) ;
55
- // extracted
56
- dbg ! ( & extract_path) ;
42
+ let krate_file_path = krate_download_dir. join ( format ! ( "{}-{}.crate.tar.gz" , & self . name, & self . version) ) ;
43
+ // don't download/extract if we already have done so
44
+ if !krate_file_path. is_file ( ) {
45
+ // create a file path to download and write the crate data into
46
+ let mut krate_dest = std:: fs:: File :: create ( & krate_file_path) . unwrap ( ) ;
47
+ let mut krate_req = ureq:: get ( & url) . call ( ) . unwrap ( ) . into_reader ( ) ;
48
+ // copy the crate into the file
49
+ std:: io:: copy ( & mut krate_req, & mut krate_dest) . unwrap ( ) ;
50
+
51
+ // unzip the tarball
52
+ let ungz_tar = flate2:: read:: GzDecoder :: new ( std:: fs:: File :: open ( & krate_file_path) . unwrap ( ) ) ;
53
+ // extract the tar archive
54
+ let mut archiv = tar:: Archive :: new ( ungz_tar) ;
55
+ archiv. unpack ( & extract_dir) . expect ( "Failed to extract!" ) ;
56
+
57
+ // unzip the tarball
58
+ let ungz_tar = flate2:: read:: GzDecoder :: new ( std:: fs:: File :: open ( & krate_file_path) . unwrap ( ) ) ;
59
+ // extract the tar archive
60
+ let mut archiv = tar:: Archive :: new ( ungz_tar) ;
61
+ archiv. unpack ( & extract_dir) . expect ( "Failed to extract!" ) ;
62
+ }
63
+ // crate is extracted, return a new Krate object which contains the path to the extracted
64
+ // sources that clippy can check
57
65
Krate {
58
66
version : self . version . clone ( ) ,
59
67
name : self . name . clone ( ) ,
@@ -64,24 +72,37 @@ impl KrateSource {
64
72
65
73
impl Krate {
66
74
fn run_clippy_lints ( & self , cargo_clippy_path : & PathBuf ) -> Vec < String > {
75
+ println ! ( "Linting {} {}..." , & self . name, & self . version) ;
67
76
let cargo_clippy_path = std:: fs:: canonicalize ( cargo_clippy_path) . unwrap ( ) ;
68
- let project_root = & self . path ;
69
- dbg ! ( & cargo_clippy_path) ;
70
- dbg ! ( & project_root) ;
71
77
72
- let output = std:: process:: Command :: new ( cargo_clippy_path)
78
+ let all_output = std:: process:: Command :: new ( cargo_clippy_path)
79
+ // lint warnings will look like this:
80
+ // src/cargo/ops/cargo_compile.rs:127:35: warning: usage of `FromIterator::from_iter`
73
81
. args ( & [ "--" , "--message-format=short" , "--" , "--cap-lints=warn" ] )
74
- . current_dir ( project_root )
82
+ . current_dir ( & self . path )
75
83
. output ( )
76
84
. unwrap ( ) ;
77
- let mut output = String :: from_utf8_lossy ( & output . stderr ) ;
78
- let output : Vec < & str > = output . lines ( ) . collect ( ) ;
79
- let mut output: Vec < String > = output
85
+ let stderr = String :: from_utf8_lossy ( & all_output . stderr ) ;
86
+ let output_lines = stderr . lines ( ) ;
87
+ let mut output: Vec < String > = output_lines
80
88
. into_iter ( )
81
89
. filter ( |line| line. contains ( ": warning: " ) )
82
- . map ( |l| l. to_string ( ) )
90
+ // prefix with the crate name and version
91
+ // cargo-0.49.0/src/cargo/ops/cargo_compile.rs:127:35: warning: usage of `FromIterator::from_iter`
92
+ . map ( |line| format ! ( "{}-{}/{}" , self . name, self . version, line) )
93
+ // remove the "warning: "
94
+ . map ( |line| {
95
+ let remove_pat = "warning: " ;
96
+ let pos = line
97
+ . find ( & remove_pat)
98
+ . expect ( "clippy output did not contain \" warning: \" " ) ;
99
+ let mut new = line[ 0 ..pos] . to_string ( ) ;
100
+ new. push_str ( & line[ pos + remove_pat. len ( ) ..] ) ;
101
+ new
102
+ } )
83
103
. collect ( ) ;
84
104
105
+ // sort messages alphabtically to avoid noise in the logs
85
106
output. sort ( ) ;
86
107
output
87
108
}
@@ -97,7 +118,6 @@ fn build_clippy() {
97
118
// the main fn
98
119
pub fn run ( ) {
99
120
let cargo_clippy_path: PathBuf = PathBuf :: from ( "target/debug/cargo-clippy" ) ;
100
- let clippy_driver_path: PathBuf = PathBuf :: from ( "target/debug/clippy-driver" ) ;
101
121
102
122
// crates we want to check:
103
123
let krates: Vec < KrateSource > = vec ! [ KrateSource :: new( "regex" , "1.4.2" ) , KrateSource :: new( "cargo" , "0.49.0" ) ] ;
@@ -112,11 +132,6 @@ pub fn run() {
112
132
"target/debug/cargo-clippy binary not found! {}" ,
113
133
cargo_clippy_path. display( )
114
134
) ;
115
- assert ! (
116
- clippy_driver_path. is_file( ) ,
117
- "target/debug/clippy-driver binary not found! {}" ,
118
- clippy_driver_path. display( )
119
- ) ;
120
135
121
136
// download and extract the crates, then run clippy on them and collect clippys warnings
122
137
let clippy_lint_results: Vec < Vec < String > > = krates
@@ -125,7 +140,8 @@ pub fn run() {
125
140
. map ( |krate| krate. run_clippy_lints ( & cargo_clippy_path) )
126
141
. collect ( ) ;
127
142
128
- let results : Vec < String > = clippy_lint_results. into_iter ( ) . flatten ( ) . collect ( ) ;
143
+ let all_warnings : Vec < String > = clippy_lint_results. into_iter ( ) . flatten ( ) . collect ( ) ;
129
144
130
- results. iter ( ) . for_each ( |l| println ! ( "{}" , l) ) ;
145
+ // TODO: save these into a file
146
+ all_warnings. iter ( ) . for_each ( |l| println ! ( "{}" , l) ) ;
131
147
}
0 commit comments