use axoproject::errors::AxoprojectError;
use camino::Utf8PathBuf;
use miette::Diagnostic;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, miette::Report>;
pub type DistResult<T> = std::result::Result<T, DistError>;
#[derive(Debug, Error, Diagnostic)]
pub enum DistError {
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
#[diagnostic(transparent)]
Asset(#[from] axoasset::AxoassetError),
#[error(transparent)]
#[diagnostic(transparent)]
Cmd(#[from] axoprocess::AxoprocessError),
#[error(transparent)]
#[diagnostic(transparent)]
Gazenot(#[from] gazenot::error::GazenotError),
#[error(transparent)]
#[diagnostic(transparent)]
Project(#[from] ProjectError),
#[error(transparent)]
FromUtf8Error(#[from] std::string::FromUtf8Error),
#[error("Failed to render template")]
#[diagnostic(help("this is a bug in cargo-dist, let us know and we'll fix it: https://github.com/axodotdev/cargo-dist/issues/new"))]
Jinja {
#[source_code]
source: String,
#[label]
span: Option<miette::SourceSpan>,
#[source]
details: minijinja::Error,
},
#[error("WiX returned an error while building {msi}")]
Wix {
msi: String,
#[source]
details: wix::Error,
},
#[error("Couldn't generate main.wxs for {package}'s msi installer")]
WixInit {
package: String,
#[source]
details: wix::Error,
},
#[error("Malformed metadata.dist in {manifest_path}")]
#[diagnostic(help("you can find a reference for the configuration schema at https://opensource.axo.dev/cargo-dist/book/reference/config.html"))]
CargoTomlParse {
manifest_path: Utf8PathBuf,
#[source]
cause: serde_json::Error,
},
#[error(
"to update your cargo-dist config you must use the version your project is configured for"
)]
#[diagnostic(help(
"you're running {running_version} but the project is configured for {project_version}"
))]
NoUpdateVersion {
project_version: semver::Version,
running_version: semver::Version,
},
#[error("Github CI support requires your crates to agree on the URL of your repository")]
CantEnableGithubUrlInconsistent {
#[diagnostic_source]
inner: AxoprojectError,
},
#[error("Github CI support requires you to specify the URL of your repository")]
#[diagnostic(help(r#"Set the repository = "https://github.com/..." key in your Cargo.toml"#))]
CantEnableGithubNoUrl,
#[error("Cannot enable npm support without forcing artifacts to be .tar.gz")]
MustEnableTarGz,
#[error(r#"install-path = "{path}" has an unknown format (it can either be "CARGO_HOME", "~/subdir/", or "$ENV_VAR/subdir/")"#)]
InstallPathInvalid {
path: String,
},
#[error(r#"install-path = "{path}" is missing a subdirectory (add a trailing slash if you want no subdirectory)"#)]
InstallPathEnvSlash {
path: String,
},
#[error(r#"install-path = "{path}" is missing a subdirectory (installing directly to home isn't allowed)"#)]
InstallPathHomeSubdir {
path: String,
},
#[error("precise-builds = false was set, but some packages have custom build features, making it impossible")]
#[diagnostic(help("these packages customized either features, no-default-features, or all-features: {packages:?}"))]
PreciseImpossible {
packages: Vec<String>,
},
#[error("This workspace doesn't have anything for cargo-dist to Release!")]
NothingToRelease {
#[help]
help: String,
},
#[error("There are too many unrelated apps in your workspace to coherently Announce!")]
TooManyUnrelatedApps {
#[help]
help: String,
},
#[error("{} has out of date contents and needs to be regenerated:\n{diff}", file.origin_path())]
#[diagnostic(help("run 'cargo dist init' to update the file\n('allow-dirty' in Cargo.toml to ignore out of date contents)"))]
CheckFileMismatch {
file: axoasset::SourceFile,
diff: String,
},
#[error(
"'{generate_mode}' is marked as allow-dirty in your cargo-dist config, refusing to run"
)]
ContradictoryGenerateModes {
generate_mode: crate::config::GenerateMode,
},
#[error("{artifact_name} depends on multiple packages, which isn't yet supported")]
#[diagnostic(help("depends on {spec1} and {spec2}"))]
MultiPackageMsi {
artifact_name: String,
spec1: String,
spec2: String,
},
#[error("{artifact_name} has no binaries")]
#[diagnostic(help("This should be impossible, you did nothing wrong, please file an issue!"))]
NoPackageMsi {
artifact_name: String,
},
#[error("missing WiX GUIDs in {manifest_path}: {keys:?}")]
#[diagnostic(help("run 'cargo dist init' to generate them"))]
MissingWixGuids {
manifest_path: Utf8PathBuf,
keys: &'static [&'static str],
},
#[error("{style} is not a recognized value")]
#[diagnostic(help("Jobs that do not come with cargo-dist should be prefixed with ./"))]
UnrecognizedStyle {
style: String,
},
#[error("unable to run linkage report for {target} on {host}")]
LinkageCheckInvalidOS {
host: String,
target: String,
},
#[error("unable to run linkage report for this type of binary")]
LinkageCheckUnsupportedBinary {},
#[error(transparent)]
Goblin(#[from] goblin::error::Error),
#[error(transparent)]
FromPathBufError(#[from] camino::FromPathBufError),
#[error("Unable to parse environment variable as a key/value pair: {line}")]
#[diagnostic(help("This should be impossible, you did nothing wrong, please file an issue!"))]
EnvParseError {
line: String,
},
#[error(transparent)]
DialoguerError(#[from] dialoguer::Error),
#[error(transparent)]
AxotagError(#[from] axotag::errors::TagError),
#[error("We failed to generate a source tarball for your project")]
#[diagnostic(help("This is probably not your fault, please file an issue!"))]
GitArchiveError {},
#[error("{tool}, required to run this task, is missing")]
#[diagnostic(help("Ensure {tool} is installed"))]
ToolMissing {
tool: String,
},
#[error("Failed to check the latest release of axoupdater")]
#[diagnostic(help(
"Is your internet connection working? If not, this may be a bug; please file an issue!"
))]
AxoupdaterReleaseCheckFailed {},
#[error("Failed to determine compression format")]
#[diagnostic(help("File extension of unrecognized file was {extension}"))]
UnrecognizedCompression {
extension: String,
},
#[error("failed to find bin {bin_name} for {pkg_name}")]
#[diagnostic(help("did the above build fail?"))]
MissingBinaries {
pkg_name: String,
bin_name: String,
},
#[error("`cargo dist update` failed; the new version isn't in the place we expected")]
#[diagnostic(help("This is probably not your fault, please file an issue!"))]
UpdateFailed {},
#[error("`cargo dist selfupdate` needs to be run in a project")]
#[diagnostic(help(
"If you just want to update cargo-dist and not your project, pass --skip-init"
))]
UpdateNotInWorkspace {
#[diagnostic_source]
cause: ProjectError,
},
}
#[derive(Debug, Error, Diagnostic)]
pub enum ProjectError {
#[error("No workspace found; either your project doesn't have a Cargo.toml/dist.toml, or we couldn't read it")]
ProjectMissing {
#[related]
sources: Vec<AxoprojectError>,
},
#[error("We encountered an issue trying to read your workspace")]
ProjectBroken {
#[source]
cause: axoproject::errors::AxoprojectError,
},
}
impl From<minijinja::Error> for DistError {
fn from(details: minijinja::Error) -> Self {
let source: String = details.template_source().unwrap_or_default().to_owned();
let span = details.range().map(|r| r.into());
DistError::Jinja {
source,
span,
details,
}
}
}