use dialoguer::{
FuzzySelect,
theme::ColorfulTheme,
Input,
Confirm,
};
use colored::Colorize;
pub fn get_remaining_subject_length(commit_type: &str, scope: &str) -> usize {
let max_subject_length = 100;
let mut remaining_subject_length = max_subject_length - scope.len() - commit_type.len() - 2;
if scope.len() > 0 {
remaining_subject_length -= 2;
}
remaining_subject_length
}
pub fn get_commit_type() -> String {
let commit_type_options = &[
"feat:\tA new feature",
"fix:\tA bug fix",
"docs:\tDocumentation only changes",
"style:\tChanges that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)",
"refactor:\tA code change that neither fixes a bug nor adds a feature",
"perf:\tA code change that improves performance",
"test:\tAdding missing tests or correcting existing tests",
"build:\tChanges that affect the build system or external dependencies (example scons, gulp, grunt, broccoli, npm, etc.)",
"ci:\tChanges to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs, etc.)",
"chore:\tOther changes that don't modify src/bin files",
"revert:\tReverts a previous commit",
];
let selected_commit_type = FuzzySelect::with_theme(&ColorfulTheme::default())
.with_prompt("Select the type of change that you're committing:")
.default(0)
.items(&commit_type_options[..])
.interact()
.unwrap();
commit_type_options[selected_commit_type].split(":").next().unwrap().to_string()
}
pub fn get_scope() -> String {
Input::new()
.with_prompt(
format!("{}{}:{}", "What is the scope of this change ", "(e.g. component or file name)".yellow().bold(), " (press enter to skip)".black().bold())
)
.interact_text()
.unwrap()
}
pub fn get_subject(commit_type: &str, scope: &str) -> String {
let remaining_subject_length = get_remaining_subject_length(&commit_type, &scope);
let subject: String = Input::new()
.with_prompt(
format!("{}{}{}{}:", "Write a short, imperative tense description of the change ", "(max ".yellow().bold(), remaining_subject_length.to_string().yellow().bold(), " chars)".yellow().bold())
)
.validate_with(|input: &String| -> Result<(), &str> {
if input.len() <= remaining_subject_length {
Ok(())
} else {
Err(
"Provided subject exceeds character limit"
)
}
})
.default("".into())
.interact_text().unwrap();
subject
}
pub fn get_body() -> String {
Input::new()
.with_prompt(
format!("{}:{}", "Provide a longer description of the change", " (press enter to skip)".black().bold())
)
.default("".into())
.interact_text().unwrap()
}
pub fn get_breaking_changes() -> String {
let breaking_changes = Confirm::with_theme(&ColorfulTheme::default())
.with_prompt("Are there any breaking changes?")
.default(false)
.wait_for_newline(true)
.interact()
.unwrap();
let mut breaking_changes_section = String::new();
if breaking_changes {
let breaking_changes_message: String = Input::new()
.with_prompt(
format!("{}", "Provide a description of the breaking changes")
)
.default("".into())
.interact_text().unwrap();
breaking_changes_section = format!("{}", breaking_changes_message)
}
breaking_changes_section
}
pub fn get_referenced_issues() -> String {
let referenced_issues = Confirm::with_theme(&ColorfulTheme::default())
.with_prompt("Does this change affect any open issues")
.default(false)
.wait_for_newline(true)
.interact()
.unwrap();
let mut referenced_issues_section = String::new();
if referenced_issues {
let referenced_issues_message: String = Input::new()
.with_prompt(
format!("{}", r#"Add issue references (e.g. #193, #4892, etc.)"#)
)
.default("".into())
.interact_text().unwrap();
referenced_issues_section = format!("{}", referenced_issues_message)
}
referenced_issues_section
}