Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions src/commands/init/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,16 @@ pub mod keys;
pub mod path_setup;
pub mod repositories;

use std::io::ErrorKind;
use tracing::{info, warn};

/// Create a friendly error for missing Docker CLI.
fn docker_not_found_error() -> Box<dyn std::error::Error> {
"Docker CLI not found. Install Docker and ensure the 'docker' command is on PATH, then re-run 'foc-devnet init'."
.to_string()
.into()
}

/// Clean up previous foc-devnet installation.
///
/// Removes the entire ~/.foc-devnet directory and optionally all foc-* Docker
Expand Down Expand Up @@ -50,7 +58,11 @@ fn cleanup_previous_installation(remove_images: bool) -> Result<(), Box<dyn std:
info!("Removing existing foc-devnet Docker images");
let output = Command::new("docker")
.args(["images", "--format", "{{.Repository}}:{{.Tag}}"])
.output()?;
.output()
.map_err(|err| match err.kind() {
ErrorKind::NotFound => docker_not_found_error(),
_ => err.into(),
})?;
Comment on lines +61 to +65
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error handling for Docker CLI not found is only applied in the init command's cleanup function, but there are 20+ other locations throughout the codebase that use Command::new("docker") without this error handling. This creates an inconsistent user experience where users might get a helpful error message here but a generic "No such file or directory" error elsewhere.

Consider centralizing this error handling in the docker_command function in src/docker/core.rs (line 51-53), which already serves as the centralized wrapper for Docker commands. This would provide consistent error messages across the entire codebase without requiring changes to every call site.

For example, the run_command function in src/docker/core.rs could be enhanced to detect ErrorKind::NotFound and provide context about which program was not found.

Copilot uses AI. Check for mistakes.

if output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
Expand All @@ -59,7 +71,13 @@ fn cleanup_previous_installation(remove_images: bool) -> Result<(), Box<dyn std:
for line in stdout.lines() {
if line.starts_with("foc-") {
// Remove the image
let remove_output = Command::new("docker").args(["rmi", line]).output()?;
let remove_output = Command::new("docker")
.args(["rmi", line])
.output()
.map_err(|err| match err.kind() {
ErrorKind::NotFound => docker_not_found_error(),
_ => err.into(),
})?;

if remove_output.status.success() {
removed_count += 1;
Expand Down