use anyhow::{bail, Result};
use owo_colors::OwoColorize;
use crate::changelog::{self, history, Release};
use crate::output::Format;
use crate::render::markdown;
use crate::render::theme;
use crate::render::time::relative_since;
pub struct Query {
pub all: bool,
pub version: Option<String>,
pub since: Option<String>,
pub count: Option<usize>,
}
pub fn show(query: &Query, format: Format) -> Result<()> {
let releases = changelog::releases();
let current = env!("CARGO_PKG_VERSION");
let chosen = match (&query.version, &query.since, query.all) {
(Some(version), _, _) => match changelog::only(releases, version) {
Some(release) => vec![release],
None => bail!("no hay notas de la versión {version} en este binario"),
},
(_, Some(floor), _) => changelog::since(releases, floor),
(_, _, true) => releases,
_ => changelog::running(releases, current).into_iter().collect(),
};
let chosen = match query.count {
Some(count) => chosen.into_iter().take(count).collect(),
None => chosen,
};
if format.answered_in_json(&chosen) {
return Ok(());
}
if chosen.is_empty() {
println!();
println!(" {}", "No hay nada nuevo escrito.".style(theme::muted()));
println!();
return Ok(());
}
print(&chosen, current);
Ok(())
}
pub fn show_history(format: Format) -> Result<()> {
let seen = history::seen();
if format.answered_in_json(&seen) {
return Ok(());
}
println!();
if seen.is_empty() {
println!(
" {}",
"Todavía no hay historial: se escribe la primera vez que cambia la versión."
.style(theme::muted())
);
println!();
return Ok(());
}
let current = env!("CARGO_PKG_VERSION");
for entry in &seen {
let when = if entry.at == 0 {
"sin fecha".to_string()
} else {
relative_since(entry.at as i64 * 1_000)
};
let mark = if entry.version == current {
format!(" {}", "· ahora".style(theme::success()))
} else {
String::new()
};
println!(
" {} {}{}",
entry.version.style(theme::strong()),
when.style(theme::muted()),
mark
);
}
println!();
Ok(())
}
fn print(releases: &[Release], current: &str) {
for release in releases {
println!();
let date = match &release.date {
Some(date) => format!(" {date}"),
None => String::new(),
};
let mark = if release.version == current {
format!(" {}", "· la que estás usando".style(theme::success()))
} else {
String::new()
};
println!(
" {}{}{}",
format!("v{}", release.version).style(theme::accent()),
date.style(theme::muted()),
mark
);
println!();
println!("{}", markdown::body(&release.body));
}
println!();
}