pub(crate) const GENERATED_HEADER_LINES: [&str; 5] = [
"# DO NOT EDIT THIS FILE",
"# Generated by gitignore.in",
"# See https://gitignore.in/",
"# Edit .gitignore.in instead of this file",
"# Run `gitignore.in` to build .gitignore",
];
use crate::{
gi::gi_command,
gibo::gibo_command,
script::{Comment, Echo, Gi, Gibo, GitIgnoreIn, GitIgnoreStatement, Meaningless},
};
pub(crate) fn build(script: GitIgnoreIn) -> std::io::Result<String> {
let mut result = String::new();
for line in GENERATED_HEADER_LINES {
result.push_str(line);
result.push('\n');
}
for statement in script.content {
match statement {
GitIgnoreStatement::Comment(Comment::Content(c)) => {
result.push_str(&format!("# {c}\n"));
}
GitIgnoreStatement::Meaningless(Meaningless::Content(_m)) => {}
GitIgnoreStatement::Gibo(Gibo::Target(target)) => {
let content = gibo_command(&target)?;
result.push_str(&separator());
result.push_str(&format!("# gibo dump {target}\n"));
result.push_str(&content);
}
GitIgnoreStatement::Gi(Gi::Target(target)) => {
let content = gi_command(&target)?;
result.push_str(&separator());
result.push_str(&format!("# gi {target}\n"));
result.push_str(&content);
}
GitIgnoreStatement::Echo(Echo::Content(echo)) => {
result.push_str(&separator());
result.push_str(&format!("{echo}\n"));
}
}
}
Ok(result)
}
fn separator() -> String {
"# -----------------------------------------------------------------------------\n".to_string()
}
#[cfg(test)]
mod tests {
use crate::parser::parse_text;
use super::*;
#[test]
fn test_parse_text() {
let text = r#"# comment
function meaningless() { echo "meaningless" }
gibo dump C++
gi C++
echo hello
"#;
let result = parse_text(text);
let result = build(result).unwrap();
assert!(result.contains("# gi C++"));
assert!(result.contains("# Created by https://www.toptal.com/developers/gitignore/api/C++"));
assert!(
result.contains("# Edit at https://www.toptal.com/developers/gitignore?templates=C++")
);
assert!(result.contains("# gibo dump C++"));
assert!(result.contains("# Generated by gibo (https://github.com/simonwhitaker/gibo)"));
assert!(result.contains("hello"));
}
#[test]
fn generated_header_includes_official_site() {
let result = build(GitIgnoreIn {
content: Vec::new(),
})
.unwrap();
assert!(result.contains("# See https://gitignore.in/"));
}
}