Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Feature rename #12 #17

Merged
merged 7 commits into from
Feb 18, 2024
Merged
Show file tree
Hide file tree
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
26 changes: 26 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ async-trait = "0.1.73"
clap = { version = "4.4.7", features = ["derive", "cargo"] }
crossterm = "0.27.0"
indicatif = "0.17.7"
dialoguer = "0.11"

# HTTP / Web
serde = { version = "1.0" , features = ["derive"] }
Expand Down
10 changes: 9 additions & 1 deletion src/app/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub trait Backend: Send {
async fn get_request_saved(&mut self, name: String) -> Result<RequestData>;
async fn find_all_request_name(&mut self) -> Result<Vec<String>>;
async fn remove_request_saved(&mut self, name: String) -> Result<()>;
async fn rename_request_saved(&mut self, request_name: String, new_name: String) -> Result<()>;
}

pub struct AppBackend {
Expand Down Expand Up @@ -207,13 +208,20 @@ impl Backend for AppBackend {
}

async fn remove_request_saved(&mut self, name: String) -> Result<()> {

run_command_waiting_response(
&self.file_service,
FileServiceCommandsFactory::remove_file_saved_request(name),
)
.await?
}

async fn rename_request_saved(&mut self, request_name: String, new_name: String) -> Result<()> {
run_command_waiting_response(
&self.file_service,
FileServiceCommandsFactory::rename_file_saved_request(request_name, new_name),
)
.await?
}
}

async fn run_commands<Service, Resp>(
Expand Down
17 changes: 17 additions & 0 deletions src/app/services/files/commands/requests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,21 @@ impl CommandsFactory {
})
.with_response(rx)
}

pub fn rename_file_saved_request(
request_name: String,
new_name: String,
) -> CommandFileService<Result<()>> {
let (tx, rx) = oneshot::channel();

Command::from(move |service: FileServiceInstance| {
let resp = service.rename_data_file(
format!("{REQUESTS_FOLDER}{request_name}"),
format!("{REQUESTS_FOLDER}{new_name}"),
);
tx.send(resp).ok();
service
})
.with_response(rx)
}
}
3 changes: 3 additions & 0 deletions src/app/services/files/facade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@ pub trait FileServiceFacade: Send {
fn remove_file(&self, path: PathBuf) -> Result<()>;
fn remove_data_file(&self, path: String) -> Result<()>;
fn remove_temp_file(&self, path: String) -> Result<()>;
fn rename_file(&self, from: PathBuf, to: PathBuf) -> Result<()>;
fn rename_data_file(&self, from: String, to: String) -> Result<()>;
fn rename_temp_file(&self, from: String, to: String) -> Result<()>;
}
16 changes: 16 additions & 0 deletions src/app/services/files/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,22 @@ impl FileServiceFacade for FileService {
let file_path = self.temp_root_path.join(path);
self.remove_file(file_path)
}

fn rename_file(&self, from: PathBuf, to: PathBuf) -> Result<()> {
Ok(std::fs::rename(from, to)?)
}

fn rename_data_file(&self, from: String, to: String) -> Result<()> {
let from_file_path = self.data_app_root_path.join(from);
let to_file_path = self.data_app_root_path.join(to);
self.rename_file(from_file_path, to_file_path)
}

fn rename_temp_file(&self, from: String, to: String) -> Result<()> {
let from_file_path = self.temp_root_path.join(from);
let to_file_path = self.temp_root_path.join(to);
self.rename_file(from_file_path, to_file_path)
}
}

impl FileService {
Expand Down
16 changes: 13 additions & 3 deletions src/view/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::view::output::writer::CrosstermCliWriter;

pub mod inspect_request;
pub mod remove_request;
pub mod rename_request;
pub mod save_new_request;
pub mod save_request_with_base_request;
pub mod show_list_all_request;
Expand Down Expand Up @@ -50,6 +51,7 @@ pub enum ViewCommandChoice {
RenameSavedRequest {
request_name: String,
new_name: String,
has_to_confirm: bool,
},

ShowRequests,
Expand All @@ -61,7 +63,8 @@ pub enum ViewCommandChoice {
impl ViewCommandChoice {
pub fn get_executor(self) -> Box<dyn ViewCommand> {
use self::inspect_request::InspectRequestExecutor;
use self::remove_request::RemoveRequestExecutir;
use self::remove_request::RemoveRequestExecutor;
use self::rename_request::RenameRequestExecutor;
use self::save_new_request::SaveNewRequestExecutor;
use self::save_request_with_base_request::SaveRequestWithBaseRequestExecutor;
use self::show_list_all_request::ShowListAllRequestExecutor;
Expand Down Expand Up @@ -122,7 +125,7 @@ impl ViewCommandChoice {
}
.into(),

ViewCommandChoice::RemoveSavedRequest { request_name } => RemoveRequestExecutir {
ViewCommandChoice::RemoveSavedRequest { request_name } => RemoveRequestExecutor {
request_name,
writer: writer_stdout,
}
Expand All @@ -131,7 +134,14 @@ impl ViewCommandChoice {
ViewCommandChoice::RenameSavedRequest {
request_name,
new_name,
} => todo!(),
has_to_confirm,
} => RenameRequestExecutor {
request_name,
new_name,
has_to_confirm,
writer: writer_stdout,
}
.into(),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/view/commands/remove_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ use crate::view::output::utils::BREAK_LINE;
use crate::view::output::writer::CliWriterRepository;
use crate::view::style::{Color, StyledStr};

pub struct RemoveRequestExecutir<Writer: CliWriterRepository> {
pub struct RemoveRequestExecutor<Writer: CliWriterRepository> {
pub request_name: String,
pub writer: Writer,
}

#[async_trait]
impl<Writer: CliWriterRepository> ViewCommand for RemoveRequestExecutir<Writer> {
impl<Writer: CliWriterRepository> ViewCommand for RemoveRequestExecutor<Writer> {
async fn execute(mut self: Box<Self>, provider: &mut dyn Backend) -> anyhow::Result<()> {
self.writer.print_lines([BREAK_LINE]);
self.writer.print_lines_styled([[
Expand Down
52 changes: 52 additions & 0 deletions src/view/commands/rename_request.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use anyhow::Ok;
use async_trait::async_trait;
use dialoguer::theme::ColorfulTheme;
use dialoguer::Confirm;

use super::ViewCommand;
use crate::app::backend::Backend;
use crate::view::output::utils::BREAK_LINE;
use crate::view::output::writer::CliWriterRepository;
use crate::view::style::{Color, StyledStr};

pub struct RenameRequestExecutor<Writer: CliWriterRepository> {
pub request_name: String,
pub new_name: String,
pub has_to_confirm: bool,
pub writer: Writer,
}

#[async_trait]
impl<Writer: CliWriterRepository> ViewCommand for RenameRequestExecutor<Writer> {
async fn execute(mut self: Box<Self>, provider: &mut dyn Backend) -> anyhow::Result<()> {
self.writer.print_lines([BREAK_LINE]);
self.writer.print_lines_styled([[
StyledStr::from(" Renaming from: ").with_color_text(Color::Red),
StyledStr::from(&self.request_name).with_color_text(Color::Yellow),
StyledStr::from(" to: ").with_color_text(Color::Red),
StyledStr::from(&self.new_name).with_color_text(Color::Yellow),
]]);
self.writer.print_lines([BREAK_LINE]);

if self.has_to_confirm {
if Confirm::with_theme(&ColorfulTheme::default())
.with_prompt("Do you want to continue?")
.wait_for_newline(true)
.interact()
.unwrap()
{
self.writer.print_lines([BREAK_LINE]);
} else {
return Ok(());
}
}

provider
.rename_request_saved(self.request_name, self.new_name)
.await?;

self.writer.print_lines([" Ok "]);

Ok(())
}
}
10 changes: 9 additions & 1 deletion src/view/input/cli_definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub fn root_command() -> Command {
.subcommand(
Command::new("rename")
.override_usage(format!(
"treq run <OLD_REQUEST_NAME> <NEW_REQUEST_NAME> [OPTIONS]"
"treq rename <OLD_REQUEST_NAME> <NEW_REQUEST_NAME> [OPTIONS]"
))
.about("Rename request")
.arg(
Expand All @@ -77,6 +77,14 @@ pub fn root_command() -> Command {
.required(true)
.num_args(2)
.help("All entrys"),
)
.arg(
// With this flag, the user will not be prompted for confirmation to rename the file
Arg::new("no-confirm")
.long("no-confirm")
.action(ArgAction::SetTrue)
.value_name("NO_CONFIRM")
.help("Do not prompt for confirmation"),
),
)
.subcommand(Command::new("ls").about("List all saved requests"))
Expand Down
3 changes: 3 additions & 0 deletions src/view/input/cli_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub enum CliCommandChoice {
Rename {
request_name: String,
new_name: String,
has_to_confirm: bool,
},
Inspect {
request_name: String,
Expand Down Expand Up @@ -72,11 +73,13 @@ impl CliInput {
let inputs = clap_args_utils::get_many_inputs(matches)?;
let request_name = inputs[0].to_string();
let new_name = inputs[1].to_string();
let has_to_confirm = !*matches.get_one::<bool>("no-confirm").unwrap_or(&false);

Ok(CliInput {
choice: CliCommandChoice::Rename {
request_name,
new_name,
has_to_confirm,
},
request_input,
save_options,
Expand Down
2 changes: 2 additions & 0 deletions src/view/input_parsers/main_command_choices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ pub fn parse_inputs_to_main_command_choices(
CliCommandChoice::Rename {
request_name,
new_name,
has_to_confirm,
} => vec![ViewCommandChoice::RenameSavedRequest {
request_name: request_name.to_string(),
new_name: new_name.to_string(),
has_to_confirm: *has_to_confirm,
}],
CliCommandChoice::Edit { request_name } => {
vec![ViewCommandChoice::SaveRequestWithBaseRequest {
Expand Down
4 changes: 1 addition & 3 deletions src/view/input_parsers/request_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,7 @@ mod parsers_request_items {
let key = matcher.name("key")?.as_str();
let value = matcher.name("value")?.as_str();

let original_body = base_request
.body.as_deref()
.unwrap_or("{}");
let original_body = base_request.body.as_deref().unwrap_or("{}");

let mut request = base_request.clone();

Expand Down
32 changes: 32 additions & 0 deletions tests/e2e/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,38 @@ fn should_remove_requests() {
cmd.assert().failure();
}

#[test]
fn should_rename_requests() {
// Setup
let input = format!("treq GET {}/get --save-as request-to-be-renamed", host());
let mut cmd = run_cmd(&input);
cmd.assert().success();

// Before rename
let input = "treq run request-to-be-renamed";
let mut cmd = run_cmd(&input);
cmd.assert().success();
let input = "treq run request-renamed";
let mut cmd = run_cmd(&input);
cmd.assert().failure();

let input = "treq rename request-to-be-renamed request-renamed --no-confirm";
let mut cmd = run_cmd(&input);
cmd.assert().success();

let input = "treq rename request-to-be-renamed request-renamed --no-confirm";
let mut cmd = run_cmd(&input);
cmd.assert().failure();

// After rename
let input = "treq run request-to-be-renamed";
let mut cmd = run_cmd(&input);
cmd.assert().failure();
let input = "treq run request-renamed";
let mut cmd = run_cmd(&input);
cmd.assert().success();
}

// ------------------
// UTILS
// ------------------
Expand Down
6 changes: 6 additions & 0 deletions tests/mocks/repositories/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ impl Backend for MockAppBackend {
async fn remove_request_saved(&mut self, name: String) -> Result<()> {
self.app_backend.remove_request_saved(name).await
}

async fn rename_request_saved(&mut self, request_name: String, new_name: String) -> Result<()> {
self.app_backend
.rename_request_saved(request_name, new_name)
.await
}
}

pub struct CliWriterUseLess;
Expand Down
Loading