From 002a8cf79d6089da4488580556a9653d56ef0ea6 Mon Sep 17 00:00:00 2001 From: Xiaowei Lu Date: Sun, 20 Oct 2024 11:22:59 -0700 Subject: [PATCH] rust-remove: check path for a regular file Summary: check if a file path to remove is a regular file. If so, the state machine flow should be moving to `RegFile` state (added in this diff) and the operations required should be handled there (to be implemented in future diffs). Reviewed By: MichaelCuevas Differential Revision: D64564138 fbshipit-source-id: 840fb033a865f361fd03447871f82c08e935c021 --- eden/fs/cli_rs/edenfs-commands/src/remove.rs | 60 ++++++++++++++++++-- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/eden/fs/cli_rs/edenfs-commands/src/remove.rs b/eden/fs/cli_rs/edenfs-commands/src/remove.rs index df2bd962f80d3..1d9ab85d9d01d 100644 --- a/eden/fs/cli_rs/edenfs-commands/src/remove.rs +++ b/eden/fs/cli_rs/edenfs-commands/src/remove.rs @@ -17,8 +17,6 @@ use clap::Parser; use dialoguer::Confirm; use tracing::debug; use tracing::error; -use tracing::info; -use tracing::trace; use crate::ExitCode; use crate::Subcommand; @@ -82,12 +80,28 @@ impl SanityCheck { #[derive(Debug)] struct Determination {} impl Determination { + fn next(&self, context: &mut RemoveContext) -> Result> { + let path = context.canonical_path.as_path(); + + if path.is_file() { + debug!("path {} determined to be a regular file", path.display()); + return Ok(Some(State::RegFile(RegFile {}))); + } + + error!("Determination State for directory is not implemented!"); + Err(anyhow!("Rust remove(Determination) is not implemented!")) + } +} + +#[derive(Debug)] +struct RegFile {} +impl RegFile { fn next(&self, _context: &mut RemoveContext) -> Result> { if Confirm::new() - .with_prompt("Determination State is not implemented yet... proceed?") + .with_prompt("RegFile State is not implemented yet... proceed?") .interact()? { - return Err(anyhow!("Rust remove(Determination) is not implemented!")); + return Err(anyhow!("Rust remove(RegFile) is not implemented!")); } Ok(None) } @@ -104,7 +118,7 @@ enum State { // ActiveEdenMount, // InactiveEdenMount, // CleanUp, - // RegFile, + RegFile(RegFile), // Unknown, } @@ -117,6 +131,7 @@ impl State { match self { State::SanityCheck(_) => "SanityCheck", State::Determination(_) => "Determination", + State::RegFile(_) => "RegFile", } } @@ -130,6 +145,7 @@ impl State { match self { State::SanityCheck(inner) => inner.next(context), State::Determination(inner) => inner.next(context), + State::RegFile(inner) => inner.next(context), } } } @@ -162,6 +178,8 @@ impl Subcommand for RemoveCmd { #[cfg(test)] mod tests { + use std::fs; + use anyhow::Context; use tempfile::tempdir; use tempfile::TempDir; @@ -218,4 +236,36 @@ mod tests { .contains(PATH_NOT_FOUND_ERROR_MSG) ); } + + #[test] + fn test_determine_regular_file() { + let temp_dir = prepare_directory(); + let file_path_buf = temp_dir.path().join("temporary-file.txt"); + fs::write(file_path_buf.as_path(), "anything").unwrap_or_else(|err| { + panic!( + "cannot write to a file at {}: {}", + file_path_buf.display(), + err + ) + }); + + // When context includes a path to a regular file + let mut file_context = RemoveContext::new(file_path_buf.display().to_string()); + let mut state = State::start().run(&mut file_context).unwrap().unwrap(); + assert!( + matches!(state, State::Determination(_)), + "Expected Determination state" + ); + state = state.run(&mut file_context).unwrap().unwrap(); + assert!(matches!(state, State::RegFile(_)), "Expected RegFile state"); + + // When context includes a path to a directory + let mut dir_context = RemoveContext::new(temp_dir.path().to_str().unwrap().to_string()); + state = State::start().run(&mut dir_context).unwrap().unwrap(); + assert!( + matches!(state, State::Determination(_)), + "Expected Determination state" + ); + assert!(state.run(&mut dir_context).is_err()); + } }