use std::iter::once;
use miette::Diagnostic;
use thiserror::Error;
use crate::{
builder::{Builder, CollectError, InitError, WriteError},
date::{parse, today},
git,
workspace::Workspace,
};
#[derive(Debug, Error, Diagnostic)]
#[error(transparent)]
#[diagnostic(transparent)]
pub enum ErrorSource {
Date(#[from] crate::date::Error),
Init(#[from] InitError),
Write(#[from] WriteError),
Collect(#[from] CollectError),
Git(#[from] crate::git::Error),
}
#[derive(Debug, Error, Diagnostic)]
#[error("failed to build")]
#[diagnostic(
code(changelogging::commands::build),
help("see the report for more information")
)]
pub struct Error {
#[source]
#[diagnostic_source]
pub source: ErrorSource,
}
impl Error {
pub fn new(source: ErrorSource) -> Self {
Self { source }
}
pub fn date(error: crate::date::Error) -> Self {
Self::new(error.into())
}
pub fn init(error: InitError) -> Self {
Self::new(error.into())
}
pub fn write(error: WriteError) -> Self {
Self::new(error.into())
}
pub fn collect(error: CollectError) -> Self {
Self::new(error.into())
}
pub fn git(error: crate::git::Error) -> Self {
Self::new(error.into())
}
}
pub fn build<S: AsRef<str>>(
workspace: Workspace<'_>,
date: Option<S>,
stage: bool,
remove: bool,
) -> Result<(), Error> {
let date = match date {
Some(string) => parse(string).map_err(Error::date)?,
None => today(),
};
let builder = Builder::from_workspace(workspace, date).map_err(Error::init)?;
builder.write().map_err(Error::write)?;
if stage {
let path = builder.config.paths.output.as_ref();
git::add(once(path)).map_err(Error::git)?;
}
if remove {
let paths = builder.collect_paths().map_err(Error::collect)?;
git::remove(paths).map_err(Error::git)?;
}
Ok(())
}