summaryrefslogtreecommitdiff
path: root/src/bin/riki.rs
blob: 6a9744ebe2246d24d79bc629dd4569089507552e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use clap::Parser;
use log::{debug, error, info};
use riki::error::SiteError;
use riki::site::Site;
use riki::util::{canonicalize, copy_file_from_source, mkdir, set_mtime};
use std::error::Error;
use std::path::PathBuf;

const ENVLOG: &str = "RIKI_LOG";

fn main() {
    if let Err(err) = real_main() {
        error!("ERROR: {}", err);
        let mut source = err.source();
        while source.is_some() {
            let s = source.unwrap();
            error!("  caused by: {}", s);
            source = source.unwrap().source();
        }
        std::process::exit(1);
    }
}

fn real_main() -> Result<(), SiteError> {
    if std::env::var(ENVLOG).is_err() {
        std::env::set_var(ENVLOG, "warn");
    }
    pretty_env_logger::init_custom_env(ENVLOG);

    info!("riki starts");

    let args = Args::parse();
    match args.command {
        Command::Build(cmd) => cmd.run()?,
        Command::List(cmd) => cmd.run()?,
    }

    info!("riki ends OK");
    Ok(())
}

#[derive(Parser)]
struct Args {
    #[clap(subcommand)]
    command: Command,
}

#[derive(Parser)]
enum Command {
    Build(Build),
    List(List),
}

#[derive(Parser)]
struct Build {
    #[clap(long)]
    plain_body: bool,

    srcdir: PathBuf,
    destdir: PathBuf,
}

impl Build {
    fn run(&self) -> Result<(), SiteError> {
        let srcdir = canonicalize(&self.srcdir)?;
        debug!("srcdir={}", srcdir.display());

        mkdir(&self.destdir)?;
        let destdir = canonicalize(&self.destdir)?;
        debug!("destdir={}", destdir.display());

        let mut site = Site::new(&srcdir, &destdir);
        site.scan()?;
        site.process()?;
        debug!("markdown file count: {}", site.markdown_pages().len());

        for page in site.markdown_pages() {
            let htmlpage = if self.plain_body {
                page.body_to_html()?
            } else {
                page.to_html()?
            };
            let output = page.meta().destination_filename(&destdir);
            debug!("writing: {}", output.display());
            htmlpage.write(&output)?;
            set_mtime(&output, page.meta().mtime())?;
        }

        for file in site.files() {
            let input = site.input_filename(file)?;
            let output = site.output_filename(file)?;
            copy_file_from_source(&input, &output)?;
        }

        Ok(())
    }
}

#[derive(Parser)]
struct List {
    srcdir: PathBuf,
}

impl List {
    fn run(&self) -> Result<(), SiteError> {
        let srcdir = canonicalize(&self.srcdir)?;
        let mut site = Site::new(&srcdir, &srcdir);
        site.scan()?;
        let mut filenames = site.included_files().to_vec();
        filenames.sort_unstable();
        for filename in filenames {
            println!("{}", filename.display());
        }
        Ok(())
    }
}