@@ -8,11 +8,6 @@ use clap::{App, AppSettings, ArgMatches, SubCommand};
88use mdbook:: errors:: Result as Result3 ;
99use mdbook:: MDBook ;
1010
11- #[ cfg( feature = "linkcheck" ) ]
12- use failure:: Error ;
13- #[ cfg( feature = "linkcheck" ) ]
14- use mdbook:: renderer:: RenderContext ;
15-
1611fn main ( ) {
1712 let d_message = "-d, --dest-dir=[dest-dir]
1813'The output directory for your book{n}(Defaults to ./book when omitted)'" ;
@@ -53,8 +48,18 @@ fn main() {
5348 ( "linkcheck" , Some ( sub_matches) ) => {
5449 #[ cfg( feature = "linkcheck" ) ]
5550 {
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+
5863 std:: process:: exit ( 101 ) ;
5964 }
6065 }
@@ -73,14 +78,55 @@ fn main() {
7378}
7479
7580#[ 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+
7786 let book_dir = get_book_dir ( args) ;
87+ let src_dir = book_dir. join ( "src" ) ;
7888 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+ }
84130}
85131
86132// Build command implementation
0 commit comments