Tweak self-test reporting to make it more clear it may not be a total failure (#559)
This commit is contained in:
parent
e5390faf1a
commit
d076888f88
5 changed files with 45 additions and 29 deletions
|
@ -225,10 +225,10 @@ impl CommandExecute for Install {
|
||||||
|
|
||||||
match install_plan.install(rx1).await {
|
match install_plan.install(rx1).await {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if !no_confirm {
|
// Attempt to copy self to the store if possible, but since the install failed, this might not work, that's ok.
|
||||||
// Attempt to copy self to the store if possible, but since the install failed, this might not work, that's ok.
|
copy_self_to_nix_dir().await.ok();
|
||||||
copy_self_to_nix_dir().await.ok();
|
|
||||||
|
|
||||||
|
if !no_confirm {
|
||||||
let mut was_expected = false;
|
let mut was_expected = false;
|
||||||
if let Some(expected) = err.expected() {
|
if let Some(expected) = err.expected() {
|
||||||
was_expected = true;
|
was_expected = true;
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::process::ExitCode;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
||||||
use crate::cli::CommandExecute;
|
use crate::{cli::CommandExecute, NixInstallerError};
|
||||||
|
|
||||||
/// Run a self test of Nix to ensure that the install worked.
|
/// Run a self test of Nix to ensure that the install worked.
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
|
@ -12,7 +12,9 @@ pub struct SelfTest {}
|
||||||
impl CommandExecute for SelfTest {
|
impl CommandExecute for SelfTest {
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields())]
|
#[tracing::instrument(level = "debug", skip_all, fields())]
|
||||||
async fn execute(self) -> eyre::Result<ExitCode> {
|
async fn execute(self) -> eyre::Result<ExitCode> {
|
||||||
crate::self_test::self_test().await?;
|
crate::self_test::self_test()
|
||||||
|
.await
|
||||||
|
.map_err(NixInstallerError::SelfTest)?;
|
||||||
|
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
shells = ?crate::self_test::Shell::discover()
|
shells = ?crate::self_test::Shell::discover()
|
||||||
|
|
21
src/error.rs
21
src/error.rs
|
@ -15,12 +15,14 @@ pub enum NixInstallerError {
|
||||||
#[error("Error executing action")]
|
#[error("Error executing action")]
|
||||||
Action(#[source] ActionError),
|
Action(#[source] ActionError),
|
||||||
/// An error originating from a [`self_test`](crate::self_test)
|
/// An error originating from a [`self_test`](crate::self_test)
|
||||||
#[error("Self test")]
|
#[error("Self test error, install may be only partially functional\n{}", .0.iter().map(|err| {
|
||||||
SelfTest(
|
if let Some(source) = err.source() {
|
||||||
#[source]
|
format!("{err}\n{source}\n")
|
||||||
#[from]
|
} else {
|
||||||
SelfTestError,
|
format!("{err}\n")
|
||||||
),
|
}
|
||||||
|
}).collect::<Vec<_>>().join("\n"))]
|
||||||
|
SelfTest(Vec<SelfTestError>),
|
||||||
/// An error originating from an [`Action`](crate::action::Action) while reverting
|
/// An error originating from an [`Action`](crate::action::Action) while reverting
|
||||||
#[error("Error reverting\n{}", .0.iter().map(|err| {
|
#[error("Error reverting\n{}", .0.iter().map(|err| {
|
||||||
if let Some(source) = err.source() {
|
if let Some(source) = err.source() {
|
||||||
|
@ -100,7 +102,7 @@ impl HasExpectedErrors for NixInstallerError {
|
||||||
match self {
|
match self {
|
||||||
NixInstallerError::Action(action_error) => action_error.kind().expected(),
|
NixInstallerError::Action(action_error) => action_error.kind().expected(),
|
||||||
NixInstallerError::ActionRevert(_) => None,
|
NixInstallerError::ActionRevert(_) => None,
|
||||||
NixInstallerError::SelfTest(_) => None,
|
this @ NixInstallerError::SelfTest(_) => Some(Box::new(this)),
|
||||||
NixInstallerError::RecordingReceipt(_, _) => None,
|
NixInstallerError::RecordingReceipt(_, _) => None,
|
||||||
NixInstallerError::CopyingSelf(_) => None,
|
NixInstallerError::CopyingSelf(_) => None,
|
||||||
NixInstallerError::SerializingReceipt(_) => None,
|
NixInstallerError::SerializingReceipt(_) => None,
|
||||||
|
@ -124,7 +126,10 @@ impl crate::diagnostics::ErrorDiagnostic for NixInstallerError {
|
||||||
fn diagnostic(&self) -> String {
|
fn diagnostic(&self) -> String {
|
||||||
let static_str: &'static str = (self).into();
|
let static_str: &'static str = (self).into();
|
||||||
let context = match self {
|
let context = match self {
|
||||||
Self::SelfTest(self_test) => vec![self_test.diagnostic().to_string()],
|
Self::SelfTest(self_tests) => self_tests
|
||||||
|
.iter()
|
||||||
|
.map(|self_test| self_test.diagnostic().to_string())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
Self::Action(action_error) => vec![action_error.diagnostic().to_string()],
|
Self::Action(action_error) => vec![action_error.diagnostic().to_string()],
|
||||||
Self::ActionRevert(action_errors) => action_errors
|
Self::ActionRevert(action_errors) => action_errors
|
||||||
.iter()
|
.iter()
|
||||||
|
|
26
src/plan.rs
26
src/plan.rs
|
@ -213,21 +213,21 @@ impl InstallPlan {
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Err(err);
|
Err(err)
|
||||||
}
|
} else {
|
||||||
|
#[cfg(feature = "diagnostics")]
|
||||||
|
if let Some(diagnostic_data) = &self.diagnostic_data {
|
||||||
|
diagnostic_data
|
||||||
|
.clone()
|
||||||
|
.send(
|
||||||
|
crate::diagnostics::DiagnosticAction::Install,
|
||||||
|
crate::diagnostics::DiagnosticStatus::Success,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "diagnostics")]
|
Ok(())
|
||||||
if let Some(diagnostic_data) = &self.diagnostic_data {
|
|
||||||
diagnostic_data
|
|
||||||
.clone()
|
|
||||||
.send(
|
|
||||||
crate::diagnostics::DiagnosticAction::Install,
|
|
||||||
crate::diagnostics::DiagnosticStatus::Success,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all)]
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
|
|
|
@ -149,12 +149,21 @@ impl Shell {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub async fn self_test() -> Result<(), SelfTestError> {
|
pub async fn self_test() -> Result<(), Vec<SelfTestError>> {
|
||||||
let shells = Shell::discover();
|
let shells = Shell::discover();
|
||||||
|
|
||||||
|
let mut failures = vec![];
|
||||||
|
|
||||||
for shell in shells {
|
for shell in shells {
|
||||||
shell.self_test().await?;
|
match shell.self_test().await {
|
||||||
|
Ok(()) => (),
|
||||||
|
Err(err) => failures.push(err),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
if failures.is_empty() {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(failures)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue