Skip to content

Commit

Permalink
Merge pull request #1510 from cachix/propagate-task-failure
Browse files Browse the repository at this point in the history
fix: output non-zero code when `devenv test` fails
  • Loading branch information
domenkozar authored Oct 9, 2024
2 parents e30eb87 + 497332c commit e7a0bc5
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 34 deletions.
1 change: 1 addition & 0 deletions devenv-eval-cache/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ pub fn supports_eval_caching(cmd: &Command) -> bool {
cmd.get_program().to_string_lossy().ends_with("nix")
}

#[derive(Debug)]
pub struct Output {
/// The status code of the command.
pub status: process::ExitStatus,
Expand Down
1 change: 1 addition & 0 deletions devenv-tasks/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,7 @@ impl Tasks {
}
}

#[derive(Debug)]
pub struct TasksStatus {
lines: Vec<String>,
pub pending: usize,
Expand Down
6 changes: 5 additions & 1 deletion devenv-tasks/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = Config { tasks, roots };

let mut tasks_ui = TasksUi::new(config).await?;
tasks_ui.run().await?;
let (status, _outputs) = tasks_ui.run().await?;

if status.failed + status.dependency_failed > 0 {
std::process::exit(1);
}
}
Command::Export { strings } => {
let output_file =
Expand Down
84 changes: 52 additions & 32 deletions devenv/src/cnix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,44 @@ pub struct Nix<'a> {

#[derive(Clone)]
pub struct Options<'a> {
/// Run `exec` to replace the shell with the command.
pub replace_shell: bool,
/// Error out if the command returns a non-zero status code.
pub bail_on_error: bool,
/// Cache the output of the command. This is opt-in per command.
pub cache_output: bool,
/// Enable logging.
pub logging: bool,
/// Log the stdout of the command.
pub logging_stdout: bool,
/// Extra flags to pass to nix commands.
pub nix_flags: &'a [&'a str],
}

impl Default for Options<'_> {
fn default() -> Self {
Self {
replace_shell: false,
bail_on_error: true,
// Individual commands opt into caching
cache_output: false,
logging: true,
logging_stdout: false,
nix_flags: &[
"--show-trace",
"--extra-experimental-features",
"nix-command",
"--extra-experimental-features",
"flakes",
"--option",
"warn-dirty",
"false",
"--keep-going",
],
}
}
}

impl<'a> Nix<'a> {
pub async fn new<P: AsRef<Path>>(
logger: log::Logger,
Expand All @@ -54,24 +85,7 @@ impl<'a> Nix<'a> {
let devenv_root = devenv_root.as_ref().to_path_buf();

let cachix_caches = RefCell::new(None);
let options = Options {
replace_shell: false,
// Individual commands opt into caching
cache_output: false,
logging: true,
logging_stdout: false,
nix_flags: &[
"--show-trace",
"--extra-experimental-features",
"nix-command",
"--extra-experimental-features",
"flakes",
"--option",
"warn-dirty",
"false",
"--keep-going",
],
};
let options = Options::default();

let database_url = format!(
"sqlite:{}/nix-eval-cache.db",
Expand Down Expand Up @@ -106,6 +120,7 @@ impl<'a> Nix<'a> {
// Cannot cache this because we don't get the derivation back.
// We'd need to switch to print-dev-env and our own `nix develop`.
cache_output: false,
bail_on_error: false,
replace_shell,
..self.options
};
Expand Down Expand Up @@ -393,27 +408,32 @@ impl<'a> Nix<'a> {
Some(code) => format!("with exit code {}", code),
None => "without exit code".to_string(),
};
if options.logging {
eprintln!();
self.logger.error(&format!(
"Command produced the following output:\n{}\n{}",
String::from_utf8_lossy(&result.stdout),
String::from_utf8_lossy(&result.stderr),
));
}

if self.global_options.nix_debugger
&& cmd.get_program().to_string_lossy().ends_with("bin/nix")
{
self.logger.info("Starting Nix debugger ...");
cmd.arg("--debugger").exec();
}
bail!(format!(
"Command `{}` failed with {code}",
display_command(&cmd)
))
} else {
Ok(result)

if options.bail_on_error {
if options.logging {
eprintln!();
self.logger.error(&format!(
"Command produced the following output:\n{}\n{}",
String::from_utf8_lossy(&result.stdout),
String::from_utf8_lossy(&result.stderr),
));
}

bail!(format!(
"Command `{}` failed with {code}",
display_command(&cmd)
))
}
}

Ok(result)
}

// We have a separate function to avoid recursion as this needs to call self.prepare_command
Expand Down
2 changes: 1 addition & 1 deletion devenv/src/devenv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ impl Devenv {
.iter()
.map(|s| s.as_str())
.collect::<Vec<&str>>(),
false,
false, // replace_shell
)
.await?
};
Expand Down

0 comments on commit e7a0bc5

Please sign in to comment.