Skip to content

Commit

Permalink
support error+exit
Browse files Browse the repository at this point in the history
  • Loading branch information
shakyShane committed Dec 14, 2024
1 parent 7f765df commit 742edde
Show file tree
Hide file tree
Showing 11 changed files with 363 additions and 352 deletions.
52 changes: 32 additions & 20 deletions crates/bsnext_core/src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use futures_util::future::join_all;
use http::response::Parts;
use std::clone::Clone;
use std::fs;
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use std::time::Duration;

#[derive(Debug)]
Expand All @@ -16,12 +16,13 @@ pub enum ExportEvent {
DryRunFileCreate(PathBuf),
DidCreateFile(PathBuf),
DidCreateDir(PathBuf),
Failed { error: ExportError },
}

#[derive(Debug, thiserror::Error)]
pub enum ExportError {
#[error("{0}")]
Fs(#[from] FsWriteError),
Fs(FsWriteError),
}

#[derive(Debug, clap::Parser)]
Expand Down Expand Up @@ -63,7 +64,7 @@ pub async fn export_one_server(
server: ServerConfig,
cmd: &ExportCommand,
write_mode: WriteMode,
) -> anyhow::Result<Vec<ExportEvent>> {
) -> Result<Vec<ExportEvent>, ExportError> {
let routes = server.combined_routes();
let state = into_state(server);

Expand All @@ -72,22 +73,34 @@ pub async fn export_one_server(
let async_requests = raw_entries.map(|req| uri_to_res_parts(state.clone(), req.url_path));

let ctx = RuntimeCtx::new(cwd);
// let job_count = raw_entry_paths.len();

let job_results = join_all(async_requests)
let results = join_all(async_requests)
.await
.into_iter()
.zip(raw_entry_paths)
.map(to_export_type);

let events = job_results
.map(move |ref ex_type| match cmd.dry_run {
true => print_sink(ex_type, &cmd.out_dir, &ctx),
false => fs_sink(ex_type, &cmd.out_dir, &ctx, &write_mode),
})
.flatten()
.flatten();

Ok(events.collect())
.map(to_export_type)
.try_fold(vec![], move |mut acc, ref ex_type| match cmd.dry_run {
true => match print_sink(ex_type, &cmd.out_dir, &ctx) {
Ok(evts) => {
acc.extend(evts);
Ok(acc)
}
Err(e) => Err(e),
},
false => match fs_sink(ex_type, &cmd.out_dir, &ctx, &write_mode) {
Ok(evts) => {
acc.extend(evts);
Ok(acc)
}
Err(e) => Err(e),
},
});

match results {
Ok(events) => Ok(events),
Err(e) => Ok(vec![ExportEvent::Failed { error: e }]),
}
}

fn fs_sink(
Expand All @@ -102,8 +115,7 @@ fn fs_sink(
filepath,
} => {
let filepath = ctx.cwd().join(out_dir).join(filepath);
write_one(export_result, &filepath, ctx, write_mode)
.map_err(|e| ExportError::Fs(e.into()))
write_one(export_result, &filepath, ctx, write_mode).map_err(ExportError::Fs)
}
ExportType::Excluded { reason: _ } => Ok(vec![]),
}
Expand Down Expand Up @@ -153,17 +165,17 @@ fn only_raw_entries(route: &Route) -> Option<ExportRequest> {

fn write_one(
export_result: &ExportResult,
filepath: &PathBuf,
filepath: &Path,
ctx: &RuntimeCtx,
write_mode: &WriteMode,
) -> Result<Vec<ExportEvent>, FsWriteError> {
let dir = filepath.parent();
let mut events = vec![];
if let Some(dir) = dir {
fs::create_dir_all(dir).map_err(|e| FsWriteError::FailedDir(e.into()))?;
fs::create_dir_all(dir).map_err(FsWriteError::FailedDir)?;
}
let (_, ref body, _) = export_result;
let pb = bsnext_fs_helpers::fs_write_str(ctx.cwd(), &filepath, body, write_mode)?;
let pb = bsnext_fs_helpers::fs_write_str(ctx.cwd(), filepath, body, write_mode)?;
events.push(ExportEvent::DidCreateFile(pb.clone()));
Ok(events)
}
19 changes: 9 additions & 10 deletions crates/bsnext_fs/src/watcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,15 @@ fn is_auto_excluded<P: AsRef<Path>>(cwd: &P, subject: &P) -> bool {
.map(OsStr::new)
.collect();
let rel = subject.as_ref().strip_prefix(cwd.as_ref());
return rel
.map(|p| match p.components().next() {
None => false,
Some(Component::Normal(str)) => excluded.contains(str),
Some(Component::Prefix(_)) => unreachable!("here? Prefix"),
Some(Component::RootDir) => unreachable!("here? RootDir"),
Some(Component::CurDir) => unreachable!("here? CurDir"),
Some(Component::ParentDir) => unreachable!("here? ParentDir"),
})
.unwrap_or(false);
rel.map(|p| match p.components().next() {
None => false,
Some(Component::Normal(str)) => excluded.contains(str),
Some(Component::Prefix(_)) => unreachable!("here? Prefix"),
Some(Component::RootDir) => unreachable!("here? RootDir"),
Some(Component::CurDir) => unreachable!("here? CurDir"),
Some(Component::ParentDir) => unreachable!("here? ParentDir"),
})
.unwrap_or(false)
}

#[test]
Expand Down
9 changes: 7 additions & 2 deletions crates/bsnext_output/src/pretty.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crate::OutputWriter;
use bsnext_core::export::ExportEvent;
use bsnext_core::export::{ExportError, ExportEvent};
use bsnext_dto::internal::{ChildResult, InternalEvents, StartupEvent};
use bsnext_dto::{
ExternalEventsDTO, FileChangedDTO, FilesChangedDTO, InputAcceptedDTO, ServerIdentityDTO,
ServersChangedDTO, StoppedWatchingDTO, WatchingDTO,
};
use bsnext_input::startup::StartupError;
use bsnext_input::InputError;
use std::io::{sink, Write};
use std::io::Write;
use std::marker::PhantomData;
use std::path::PathBuf;

Expand Down Expand Up @@ -119,6 +119,11 @@ impl OutputWriter for PrettyPrint {
ExportEvent::DidCreateDir(file) => {
writeln!(sink, "[export]: did create dir {}", file.display())?;
}
ExportEvent::Failed {
error: ExportError::Fs(fs_write_error),
} => {
writeln!(sink, "[export]: Error! {}", fs_write_error)?;
}
}
Ok(())
}
Expand Down
39 changes: 17 additions & 22 deletions crates/bsnext_system/src/commands/export_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use crate::args::Args;
use crate::start_kind::start_from_inputs::StartFromInputPaths;
use crate::start_kind::StartKind;
use bsnext_core::export::{export_one_server, ExportCommand};
use bsnext_core::export::{export_one_server, ExportCommand, ExportEvent};
use bsnext_fs_helpers::WriteMode;
use bsnext_input::startup::{StartupContext, SystemStart, SystemStartArgs};
use bsnext_input::InputError;
use bsnext_output::{OutputWriter, Writers};
use bsnext_tracing::OutputFormat;
use std::io::Write;
Expand All @@ -16,6 +14,7 @@ pub async fn export_cmd(
args: &Args,
) -> Result<(), anyhow::Error> {
let format_clone = args.format;

let printer = match format_clone {
OutputFormat::Tui => Writers::Pretty,
OutputFormat::Json => Writers::Json,
Expand All @@ -25,21 +24,19 @@ pub async fn export_cmd(
let start_kind = StartKind::from_args(args).input(&ctx);

match start_kind {
Err(e) => eprintln!("an error occured here"),
Ok(SystemStartArgs::InputOnly { input }) => todo!("handle InputOnly"),
Ok(SystemStartArgs::PathWithInput { path, input }) if input.servers.len() == 1 => {
Err(e) => eprintln!("an error occured here?, {}", e),
Ok(SystemStartArgs::InputOnly { input: _ }) => todo!("handle InputOnly"),
Ok(SystemStartArgs::PathWithInput { path: _, input }) if input.servers.len() == 1 => {
let first = &input.servers[0];
let write_mode = if args.force {
WriteMode::Override
} else {
WriteMode::Safe
};
let result = export_one_server(cwd, first.clone(), cmd, write_mode).await?;
dbg!(&result);
let events = export_one_server(cwd, first.clone(), cmd, write_mode).await?;
let stdout = &mut std::io::stdout();
for export_event in result {
// printer.handle_export_event(stdout, &export_event)?;
match printer.handle_export_event(stdout, &export_event) {
for export_event in &events {
match printer.handle_export_event(stdout, export_event) {
Ok(_) => {}
Err(e) => tracing::error!(?e),
};
Expand All @@ -48,21 +45,19 @@ pub async fn export_cmd(
Ok(_) => {}
Err(e) => tracing::error!("could not flush {e}"),
};
if events
.iter()
.any(|e| matches!(e, ExportEvent::Failed { .. }))
{
return Err(anyhow::anyhow!("export failed"));
}
}
Ok(SystemStartArgs::PathWithInput { path, input }) => {
Ok(SystemStartArgs::PathWithInput { path: _, input: _ }) => {
// let first =
// let _result = export_one_server(cwd, cmd).await;
todo!("handle ion")
todo!("handle more than 1 server for export?")
}
Ok(SystemStartArgs::PathWithInvalidInput { .. }) => todo!("handle PathWithInvalidInput"),
Ok(SystemStartArgs::PathWithInvalidInput { .. }) => todo!("handle PathWithInvalidInput?"),
}
//
// // for the startup message, don't allow a TUI yet

// todo!("handle the output from the export command");
// match result {
// Ok(()) => todo!("handle result"),
// Err(_) => todo!("handle error"),
// }
Ok(())
}
2 changes: 1 addition & 1 deletion crates/bsnext_system/src/commands/start_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::start_kind::StartKind;
use crate::{BsSystem, Start};
use actix::Actor;
use bsnext_dto::internal::{AnyEvent, StartupEvent};
use bsnext_input::startup::{DidStart, SystemStart};
use bsnext_input::startup::DidStart;
use bsnext_output::ratatui::Ratatui;
use bsnext_output::{OutputWriter, Writers};
use bsnext_tracing::OutputFormat;
Expand Down
8 changes: 4 additions & 4 deletions crates/bsnext_system/src/start_kind/start_from_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ fn from_dir_paths<T: AsRef<str>>(
.map(|p| {
let pb = PathBuf::from(p.as_ref());
if pb.is_absolute() {
return PathDefinition {
PathDefinition {
input: p.as_ref().to_string(),
cwd: cwd.to_path_buf(),
absolute: pb,
};
}
} else {
return PathDefinition {
PathDefinition {
input: p.as_ref().to_string(),
cwd: cwd.to_path_buf(),
absolute: cwd.join(pb),
};
}
}
})
.map(|path_def| {
Expand Down
Loading

0 comments on commit 742edde

Please sign in to comment.