@@ -8,11 +8,6 @@ use clap::{App, AppSettings, ArgMatches, SubCommand};
8
8
use mdbook:: errors:: Result as Result3 ;
9
9
use mdbook:: MDBook ;
10
10
11
- #[ cfg( feature = "linkcheck" ) ]
12
- use failure:: Error ;
13
- #[ cfg( feature = "linkcheck" ) ]
14
- use mdbook:: renderer:: RenderContext ;
15
-
16
11
fn main ( ) {
17
12
let d_message = "-d, --dest-dir=[dest-dir]
18
13
'The output directory for your book{n}(Defaults to ./book when omitted)'" ;
@@ -53,8 +48,18 @@ fn main() {
53
48
( "linkcheck" , Some ( sub_matches) ) => {
54
49
#[ cfg( feature = "linkcheck" ) ]
55
50
{
56
- if let Err ( err) = linkcheck ( sub_matches) {
57
- eprintln ! ( "Error: {}" , err) ;
51
+ let ( diags, files) = linkcheck ( sub_matches) . expect ( "Error while linkchecking." ) ;
52
+ if !diags. is_empty ( ) {
53
+ let color = codespan_reporting:: term:: termcolor:: ColorChoice :: Auto ;
54
+ let mut writer =
55
+ codespan_reporting:: term:: termcolor:: StandardStream :: stderr ( color) ;
56
+ let cfg = codespan_reporting:: term:: Config :: default ( ) ;
57
+
58
+ for diag in diags {
59
+ codespan_reporting:: term:: emit ( & mut writer, & cfg, & files, & diag)
60
+ . expect ( "Unable to emit linkcheck error." ) ;
61
+ }
62
+
58
63
std:: process:: exit ( 101 ) ;
59
64
}
60
65
}
@@ -73,14 +78,55 @@ fn main() {
73
78
}
74
79
75
80
#[ cfg( feature = "linkcheck" ) ]
76
- pub fn linkcheck ( args : & ArgMatches < ' _ > ) -> Result < ( ) , Error > {
81
+ pub fn linkcheck (
82
+ args : & ArgMatches < ' _ > ,
83
+ ) -> Result < ( Vec < codespan_reporting:: diagnostic:: Diagnostic > , codespan:: Files ) , failure:: Error > {
84
+ use mdbook_linkcheck:: Reason ;
85
+
77
86
let book_dir = get_book_dir ( args) ;
87
+ let src_dir = book_dir. join ( "src" ) ;
78
88
let book = MDBook :: load ( & book_dir) . unwrap ( ) ;
79
- let cfg = book. config ;
80
- let render_ctx = RenderContext :: new ( & book_dir, book. book , cfg, & book_dir) ;
81
- let cache_file = render_ctx. destination . join ( "cache.json" ) ;
82
- let color = codespan_reporting:: term:: termcolor:: ColorChoice :: Auto ;
83
- mdbook_linkcheck:: run ( & cache_file, color, & render_ctx)
89
+ let linkck_cfg = mdbook_linkcheck:: get_config ( & book. config ) ?;
90
+ let mut files = codespan:: Files :: new ( ) ;
91
+ let target_files = mdbook_linkcheck:: load_files_into_memory ( & book. book , & mut files) ;
92
+ let cache = mdbook_linkcheck:: Cache :: default ( ) ;
93
+
94
+ let ( links, incomplete) = mdbook_linkcheck:: extract_links ( target_files, & files) ;
95
+
96
+ let outcome =
97
+ mdbook_linkcheck:: validate ( & links, & linkck_cfg, & src_dir, & cache, & files, incomplete) ?;
98
+
99
+ let mut is_real_error = false ;
100
+
101
+ for link in outcome. invalid_links . iter ( ) {
102
+ match & link. reason {
103
+ Reason :: FileNotFound | Reason :: TraversesParentDirectories => {
104
+ is_real_error = true ;
105
+ }
106
+ Reason :: UnsuccessfulServerResponse ( status) => {
107
+ if status. is_client_error ( ) {
108
+ is_real_error = true ;
109
+ } else {
110
+ eprintln ! ( "Unsuccessful server response for link `{}`" , link. link. uri) ;
111
+ }
112
+ }
113
+ Reason :: Client ( err) => {
114
+ if err. is_timeout ( ) {
115
+ eprintln ! ( "Timeout for link `{}`" , link. link. uri) ;
116
+ } else if err. is_server_error ( ) {
117
+ eprintln ! ( "Server error for link `{}`" , link. link. uri) ;
118
+ } else {
119
+ is_real_error = true ;
120
+ }
121
+ }
122
+ }
123
+ }
124
+
125
+ if is_real_error {
126
+ Ok ( ( outcome. generate_diagnostics ( & files, linkck_cfg. warning_policy ) , files) )
127
+ } else {
128
+ Ok ( ( vec ! [ ] , files) )
129
+ }
84
130
}
85
131
86
132
// Build command implementation
0 commit comments