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(())
}
|