File tree 2 files changed +45
-3
lines changed 2 files changed +45
-3
lines changed Original file line number Diff line number Diff line change 1
- use std:: io:: { stdout, Write } ;
1
+ use std:: io:: { stdout, ErrorKind , Write } ;
2
2
use std:: path:: { Path , PathBuf } ;
3
3
4
4
use public_api:: diff:: PublicItemsDiff ;
5
5
use public_api:: { public_api_from_rustdoc_json_str, Options , MINIMUM_RUSTDOC_JSON_VERSION } ;
6
6
7
- type Result < T > = std:: result:: Result < T , Box < dyn std:: error:: Error > > ;
7
+ #[ derive( thiserror:: Error , Debug ) ]
8
+ enum Error {
9
+ #[ error( transparent) ]
10
+ PublicApiError ( #[ from] public_api:: Error ) ,
11
+ #[ error( transparent) ]
12
+ StdIoError ( #[ from] std:: io:: Error ) ,
13
+ }
14
+
15
+ type Result < T > = std:: result:: Result < T , Error > ;
8
16
9
17
#[ derive( Default ) ]
10
18
struct Args {
@@ -13,7 +21,7 @@ struct Args {
13
21
files : Vec < PathBuf > ,
14
22
}
15
23
16
- fn main ( ) -> Result < ( ) > {
24
+ fn main_ ( ) -> Result < ( ) > {
17
25
let args = args ( ) ;
18
26
19
27
let mut options = Options :: default ( ) ;
@@ -155,3 +163,11 @@ fn args() -> Args {
155
163
156
164
args
157
165
}
166
+
167
+ /// Wrapper to handle <https://github.com/rust-lang/rust/issues/46016>
168
+ fn main ( ) -> Result < ( ) > {
169
+ match main_ ( ) {
170
+ Err ( Error :: StdIoError ( e) ) if e. kind ( ) == ErrorKind :: BrokenPipe => std:: process:: exit ( 141 ) ,
171
+ result => result,
172
+ }
173
+ }
Original file line number Diff line number Diff line change
1
+ use std:: { io:: BufRead , str:: from_utf8} ;
2
+
1
3
use assert_cmd:: Command ;
2
4
use public_api:: MINIMUM_RUSTDOC_JSON_VERSION ;
3
5
@@ -120,6 +122,30 @@ Added:
120
122
) ;
121
123
}
122
124
125
+ /// Uses a bash one-liner to test that public-api gracefully handles
126
+ /// `std::io::ErrorKind::BrokenPipe`
127
+ #[ test]
128
+ #[ serial]
129
+ fn broken_pipe ( ) {
130
+ // Use the JSON for a somewhat large API so the pipe has time to become closed
131
+ // before all output has been written to stdout
132
+ let large_api = rustdoc_json_path_for_crate ( "./tests/crates/comprehensive_api" ) ;
133
+
134
+ // Now setup the actual one-liner
135
+ let mut cmd = std:: process:: Command :: new ( "bash" ) ;
136
+ cmd. args ( [
137
+ "-c" ,
138
+ & format ! (
139
+ "./target/debug/public-api {} | head -n 1" ,
140
+ large_api. to_string_lossy( ) ,
141
+ ) ,
142
+ ] ) ;
143
+
144
+ // Run it and assert on that there was no error printed
145
+ assert_eq ! ( cmd. output( ) . unwrap( ) . stdout. lines( ) . count( ) , 1 ) ;
146
+ assert_eq ! ( from_utf8( & cmd. output( ) . unwrap( ) . stderr) , Ok ( "" ) ) ;
147
+ }
148
+
123
149
#[ test]
124
150
fn short_help ( ) {
125
151
let mut cmd = Command :: cargo_bin ( "public-api" ) . unwrap ( ) ;
You can’t perform that action at this time.
0 commit comments