git_shortcuts/
lib.rs

1pub mod commit;
2pub mod error;
3
4use color_eyre::eyre::Result;
5use git2::Repository;
6use phf::phf_map;
7use regex::Regex;
8
9use crate::commit::Author;
10use crate::error::Error;
11
12lazy_static::lazy_static! {
13    // safety: if this fails, the program is useless anyway
14    pub static ref BRANCH_NAME_REGEX: Regex = Regex::new("([A-Z])-?([0-9]+).*").unwrap();
15}
16
17// TODO: convert this into a dynamic map, read from a config file
18pub static TEAM_MAPPING: phf::Map<&'static str, &'static str> = phf_map! {
19    "A" => "ANALYTICS"
20};
21
22pub fn extract_from_branch(branch_name: &str) -> Result<(String, u32)> {
23    let captures = BRANCH_NAME_REGEX
24        .captures(branch_name)
25        .map_or(Err(Error::InvalidBranchName(branch_name.to_string())), Ok)?;
26
27    let team_name = TEAM_MAPPING
28        .get(&captures[1])
29        .map_or(Err(Error::UnknownPrefix(captures[1].to_string())), Ok)?;
30
31    let issue_number = captures[2].parse::<u32>()?;
32
33    Ok((String::from(*team_name), issue_number))
34}
35
36pub fn check_staged_changes(repository: &Repository) -> Result<()> {
37    let mut has_staged = false;
38    for status_entry in repository.statuses(None)?.iter() {
39        let status = status_entry.status();
40        has_staged |= status.is_index_deleted()
41            || status.is_index_modified()
42            || status.is_index_new()
43            || status.is_index_renamed()
44            || status.is_index_typechange();
45        if has_staged {
46            return Ok(());
47        }
48    }
49    Err(Error::NoStagedChanges)?
50}
51
52pub fn commit(repository: &Repository, message: &str) -> Result<()> {
53    let tree_oid = repository.index()?.write_tree()?;
54    let tree = repository.find_tree(tree_oid)?;
55    let parent_commit = repository.head()?.resolve()?.peel_to_commit()?;
56    let author = Author::try_from(repository)?;
57    let signature = &author.try_into()?;
58    repository.commit(
59        Some("HEAD"),
60        signature,
61        signature,
62        &message.to_string(),
63        &tree,
64        &[&parent_commit],
65    )?;
66    Ok(())
67}