2015-07-07 03:12:24 +08:00
extern crate mdbook ;
2015-08-01 12:59:05 +08:00
#[ macro_use ]
extern crate clap ;
2016-08-14 21:55:10 +08:00
extern crate log ;
extern crate env_logger ;
2017-01-02 01:42:47 +08:00
extern crate open ;
2015-11-09 21:31:00 +08:00
2015-07-07 03:12:24 +08:00
use std ::env ;
2015-08-01 12:59:05 +08:00
use std ::error ::Error ;
2017-01-02 01:42:47 +08:00
use std ::ffi ::OsStr ;
2015-08-01 12:59:05 +08:00
use std ::io ::{ self , Write } ;
use std ::path ::{ Path , PathBuf } ;
2016-03-20 00:45:58 +08:00
use clap ::{ App , ArgMatches , SubCommand , AppSettings } ;
2015-07-07 03:12:24 +08:00
2017-06-26 06:53:58 +08:00
pub mod build ;
2017-06-26 07:02:32 +08:00
pub mod init ;
2017-06-26 03:41:23 +08:00
#[ cfg(feature = " serve " ) ]
pub mod serve ;
2015-09-27 20:38:37 +08:00
#[ cfg(feature = " watch " ) ]
2017-06-26 05:44:28 +08:00
pub mod watch ;
2015-11-09 21:31:00 +08:00
2015-07-07 08:56:19 +08:00
use mdbook ::MDBook ;
2015-07-07 03:12:24 +08:00
const NAME : & 'static str = " mdbook " ;
fn main ( ) {
2016-08-14 21:55:10 +08:00
env_logger ::init ( ) . unwrap ( ) ;
2015-08-01 12:59:05 +08:00
// Create a list of valid arguments and sub-commands
2017-06-26 06:31:42 +08:00
let app = App ::new ( NAME )
2015-08-01 12:59:05 +08:00
. about ( " Create a book in form of a static website from markdown files " )
. author ( " Mathieu David <mathieudavid@mathieudavid.org> " )
// Get the version from our Cargo.toml using clap's crate_version!() macro
2017-06-26 06:31:42 +08:00
. version ( concat! ( " v " , crate_version! ( ) ) )
2016-03-20 00:45:58 +08:00
. setting ( AppSettings ::SubcommandRequired )
2016-06-12 07:08:48 +08:00
. after_help ( " For more information about a specific command, try `mdbook <command> --help` \n Source code for mdbook available at: https://github.com/azerupi/mdBook " )
2017-06-26 07:02:32 +08:00
. subcommand ( init ::make_subcommand ( ) )
2017-06-26 06:53:58 +08:00
. subcommand ( build ::make_subcommand ( ) )
2015-12-16 02:55:23 +08:00
. subcommand ( SubCommand ::with_name ( " test " )
2017-06-26 06:31:42 +08:00
. about ( " Test that code samples compile " ) ) ;
#[ cfg(feature = " watch " ) ]
let app = app . subcommand ( watch ::make_subcommand ( ) ) ;
#[ cfg(feature = " serve " ) ]
let app = app . subcommand ( serve ::make_subcommand ( ) ) ;
2015-08-01 12:59:05 +08:00
// Check which subcomamnd the user ran...
2017-06-26 06:31:42 +08:00
let res = match app . get_matches ( ) . subcommand ( ) {
2017-06-26 07:02:32 +08:00
( " init " , Some ( sub_matches ) ) = > init ::init ( sub_matches ) ,
2017-06-26 06:53:58 +08:00
( " build " , Some ( sub_matches ) ) = > build ::build ( sub_matches ) ,
2015-09-27 20:38:37 +08:00
#[ cfg(feature = " watch " ) ]
2017-06-26 05:44:28 +08:00
( " watch " , Some ( sub_matches ) ) = > watch ::watch ( sub_matches ) ,
2016-04-02 10:46:05 +08:00
#[ cfg(feature = " serve " ) ]
2017-06-14 20:43:43 +08:00
( " serve " , Some ( sub_matches ) ) = > serve ::serve ( sub_matches ) ,
2015-12-16 02:55:23 +08:00
( " test " , Some ( sub_matches ) ) = > test ( sub_matches ) ,
2016-03-18 05:31:28 +08:00
( _ , _ ) = > unreachable! ( ) ,
2015-07-07 03:12:24 +08:00
} ;
2015-08-01 12:59:05 +08:00
if let Err ( e ) = res {
2015-08-11 22:13:41 +08:00
writeln! ( & mut io ::stderr ( ) , " An error occured: \n {} " , e ) . ok ( ) ;
2016-08-07 02:54:07 +08:00
::std ::process ::exit ( 101 ) ;
2015-07-07 03:12:24 +08:00
}
}
2015-11-09 21:31:00 +08:00
// Simple function that user comfirmation
2015-08-11 22:42:19 +08:00
fn confirm ( ) -> bool {
io ::stdout ( ) . flush ( ) . unwrap ( ) ;
let mut s = String ::new ( ) ;
io ::stdin ( ) . read_line ( & mut s ) . ok ( ) ;
match & * s . trim ( ) {
" Y " | " y " | " yes " | " Yes " = > true ,
2016-03-18 05:31:28 +08:00
_ = > false ,
2015-08-11 22:42:19 +08:00
}
}
2015-11-09 21:31:00 +08:00
2015-12-16 02:55:23 +08:00
fn test ( args : & ArgMatches ) -> Result < ( ) , Box < Error > > {
let book_dir = get_book_dir ( args ) ;
2017-05-19 05:52:38 +08:00
let mut book = MDBook ::new ( & book_dir ) . read_config ( ) ? ;
2015-12-16 02:55:23 +08:00
2017-05-19 19:04:37 +08:00
book . test ( ) ? ;
2015-12-16 02:55:23 +08:00
2015-09-27 20:38:37 +08:00
Ok ( ( ) )
}
2015-08-01 12:59:05 +08:00
fn get_book_dir ( args : & ArgMatches ) -> PathBuf {
if let Some ( dir ) = args . value_of ( " dir " ) {
// Check if path is relative from current dir, or absolute...
let p = Path ::new ( dir ) ;
if p . is_relative ( ) {
2016-03-18 05:31:28 +08:00
env ::current_dir ( ) . unwrap ( ) . join ( dir )
2015-08-01 12:59:05 +08:00
} else {
2016-03-18 05:31:28 +08:00
p . to_path_buf ( )
2015-08-01 12:59:05 +08:00
}
2015-07-18 06:04:20 +08:00
} else {
2015-08-01 12:59:05 +08:00
env ::current_dir ( ) . unwrap ( )
2015-07-07 03:12:24 +08:00
}
}
2016-04-02 10:46:05 +08:00
2017-01-02 01:42:47 +08:00
fn open < P : AsRef < OsStr > > ( path : P ) {
if let Err ( e ) = open ::that ( path ) {
println! ( " Error opening web browser: {} " , e ) ;
}
}