summaryrefslogtreecommitdiffstats
path: root/src/main.rs
blob: 61d28c6246800f13d317da68eb848c6484c5d526 (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
117
extern crate gitjournal;

#[macro_use]
extern crate clap;

#[macro_use]
extern crate log;

use std::process::exit;
use std::{env, fs};

use clap::{App, Shell};

use gitjournal::GitJournal;
use gitjournal::errors::*;

fn error_and_exit(string: &str, error: Error) {
    error!("{}: {}", string, error);
    exit(1);
}

fn is_program_in_path(program: &str) -> bool {
    if let Ok(path) = env::var("PATH") {
        for p in path.split(':') {
            let p_str = format!("{}/{}", p, program);
            if fs::metadata(p_str).is_ok() {
                return true;
            }
        }
    }
    false
}

fn main() {
    if let Err(error) = run() {
        error_and_exit("Main", error);
    }
}

fn run() -> Result<()> {
    // Load the CLI parameters from the yaml file
    let yaml = load_yaml!("cli.yaml");
    let mut app = App::from_yaml(yaml).version(crate_version!());
    let matches = app.clone().get_matches();
    let path = matches.value_of("path").ok_or_else(|| "No CLI 'path' provided")?;

    // Create the journal
    let mut journal = GitJournal::new(path)?;

    // Check for the subcommand
    match matches.subcommand_name() {
        Some("prepare") => {
            // Prepare a commit message before editing by the user
            if let Some(sub_matches) = matches.subcommand_matches("prepare") {
                match journal.prepare(sub_matches.value_of("message").ok_or_else(|| "No CLI 'message' provided")?,
                                      sub_matches.value_of("type")) {
                    Ok(()) => info!("Commit message prepared."),
                    Err(error) => error_and_exit("Commit message preparation failed", error),
                }
            }
        }
        Some("setup") => {
            // Do the setup procedure
            journal.setup()?;

            // Generate completions if necessary
            if is_program_in_path("bash") {
                app.gen_completions("git-journal", Shell::Bash, path);
                info!("Installed bash completions to the current path.");
            }
            if is_program_in_path("fish") {
                app.gen_completions("git-journal", Shell::Fish, path);
                info!("Installed fish completions to the current path.");
            }
            if is_program_in_path("zsh") {
                app.gen_completions("git-journal", Shell::Zsh, path);
                info!("Installed zsh completions to the current path.");
            }
        }
        Some("verify") => {
            // Verify a commit message
            if let Some(sub_matches) = matches.subcommand_matches("verify") {
                match journal.verify(sub_matches.value_of("message").ok_or_else(|| "No CLI 'message' provided")?) {
                    Ok(()) => info!("Commit message valid."),
                    Err(error) => error_and_exit("Commit message invalid", error),
                }
            }
        }
        _ => {
            // Get all values of the given CLI parameters with default values
            let revision_range = matches.value_of("revision_range").ok_or_else(|| "No CLI 'revision_range' provided")?;
            let tag_skip_pattern = matches.value_of("tag_skip_pattern")
                .ok_or_else(|| "No CLI 'task_skip_pattern' provided")?;
            let tags_count = matches.value_of("tags_count").ok_or_else(|| "No CLI 'tags_count' provided")?;
            let max_tags = tags_count.parse::<u32>()?;

            // Parse the log
            if let Err(error) = journal.parse_log(revision_range,
                                                  tag_skip_pattern,
                                                  &max_tags,
                                                  &matches.is_present("all"),
                                                  &matches.is_present("skip_unreleased")) {
                error_and_exit("Log parsing error", error);
            }

            // Generate the template or print the log
            if matches.is_present("generate") {
                journal.generate_template()?;
            } else {
                journal.print_log(matches.is_present("short"),
                                  matches.value_of("template"),
                                  matches.value_of("output"))?;
            }
        }
    };
    Ok(())
}