]> git.proxmox.com Git - rustc.git/blame - vendor/mdbook/src/cmd/init.rs
New upstream version 1.51.0+dfsg1
[rustc.git] / vendor / mdbook / src / cmd / init.rs
CommitLineData
dc9dc135 1use crate::get_book_dir;
9fa01778 2use clap::{App, ArgMatches, SubCommand};
9fa01778
XL
3use mdbook::config;
4use mdbook::errors::Result;
5use mdbook::MDBook;
ea8adc8c
XL
6use std::io;
7use std::io::Write;
83c7162d 8use std::process::Command;
ea8adc8c
XL
9
10// Create clap subcommand arguments
11pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
12 SubCommand::with_name("init")
9fa01778 13 .about("Creates the boilerplate structure and files for a new book")
ea8adc8c 14 // the {n} denotes a newline which will properly aligned in all help messages
9fa01778
XL
15 .arg_from_usage(
16 "[dir] 'Directory to create the book in{n}\
17 (Defaults to the Current Directory when omitted)'",
dc9dc135
XL
18 )
19 .arg_from_usage("--theme 'Copies the default theme into your source folder'")
9fa01778 20 .arg_from_usage("--force 'Skips confirmation prompts'")
ea8adc8c
XL
21}
22
23// Init command implementation
24pub fn execute(args: &ArgMatches) -> Result<()> {
ea8adc8c 25 let book_dir = get_book_dir(args);
2c00a5a8 26 let mut builder = MDBook::init(&book_dir);
83c7162d 27 let mut config = config::Config::default();
ea8adc8c
XL
28
29 // If flag `--theme` is present, copy theme to src
30 if args.is_present("theme") {
5869c6ff
XL
31 let theme_dir = book_dir.join("theme");
32 println!();
33 println!("Copying the default theme to {}", theme_dir.display());
ea8adc8c 34 // Skip this if `--force` is present
5869c6ff 35 if !args.is_present("force") && theme_dir.exists() {
2c00a5a8 36 println!("This could potentially overwrite files already present in that directory.");
ea8adc8c
XL
37 print!("\nAre you sure you want to continue? (y/n) ");
38
39 // Read answer from user and exit if it's not 'yes'
2c00a5a8
XL
40 if confirm() {
41 builder.copy_theme(true);
ea8adc8c 42 }
83c7162d
XL
43 } else {
44 builder.copy_theme(true);
ea8adc8c 45 }
ea8adc8c
XL
46 }
47
2c00a5a8 48 println!("\nDo you want a .gitignore to be created? (y/n)");
ea8adc8c 49
2c00a5a8
XL
50 if confirm() {
51 builder.create_gitignore(true);
ea8adc8c
XL
52 }
53
83c7162d
XL
54 config.book.title = request_book_title();
55
56 if let Some(author) = get_author_name() {
57 debug!("Obtained user name from gitconfig: {:?}", author);
58 config.book.authors.push(author);
59 builder.with_config(config);
60 }
61
2c00a5a8 62 builder.build()?;
ea8adc8c
XL
63 println!("\nAll done, no errors...");
64
65 Ok(())
66}
67
83c7162d
XL
68/// Obtains author name from git config file by running the `git config` command.
69fn get_author_name() -> Option<String> {
70 let output = Command::new("git")
71 .args(&["config", "--get", "user.name"])
72 .output()
73 .ok()?;
74
75 if output.status.success() {
76 Some(String::from_utf8_lossy(&output.stdout).trim().to_owned())
77 } else {
78 None
79 }
80}
81
82/// Request book title from user and return if provided.
83fn request_book_title() -> Option<String> {
84 println!("What title would you like to give the book? ");
85 io::stdout().flush().unwrap();
86 let mut resp = String::new();
87 io::stdin().read_line(&mut resp).unwrap();
88 let resp = resp.trim();
89 if resp.is_empty() {
90 None
91 } else {
92 Some(resp.into())
93 }
94}
95
96// Simple function for user confirmation
ea8adc8c
XL
97fn confirm() -> bool {
98 io::stdout().flush().unwrap();
99 let mut s = String::new();
100 io::stdin().read_line(&mut s).ok();
101 match &*s.trim() {
102 "Y" | "y" | "yes" | "Yes" => true,
103 _ => false,
104 }
105}